jroelofs created this revision.
jroelofs added reviewers: efriedma, weimingz, EricWF.
Herald added subscribers: cfe-commits, kristof.beyls.
Herald added a project: clang.

Fixes:

  https://bugs.llvm.org/show_bug.cgi?id=35527
  https://bugs.llvm.org/show_bug.cgi?id=35528


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D74812

Files:
  clang/include/clang/Basic/DiagnosticGroups.td
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/lib/Sema/SemaExpr.cpp
  clang/test/Sema/arm-interrupt-attr.c

Index: clang/test/Sema/arm-interrupt-attr.c
===================================================================
--- clang/test/Sema/arm-interrupt-attr.c
+++ clang/test/Sema/arm-interrupt-attr.c
@@ -1,8 +1,8 @@
-// RUN: %clang_cc1 %s -triple arm-apple-darwin  -target-feature +vfp2 -verify -fsyntax-only
-// RUN: %clang_cc1 %s -triple thumb-apple-darwin  -target-feature +vfp3 -verify -fsyntax-only
-// RUN: %clang_cc1 %s -triple armeb-none-eabi  -target-feature +vfp4 -verify -fsyntax-only
-// RUN: %clang_cc1 %s -triple thumbeb-none-eabi  -target-feature +neon -verify -fsyntax-only
-// RUN: %clang_cc1 %s -triple thumbeb-none-eabi -target-feature +neon -target-feature +soft-float -DSOFT -verify -fsyntax-only
+// RUN: %clang_cc1 %s -Warm-interrupt-safety -triple arm-apple-darwin  -target-feature +vfp2 -verify -fsyntax-only
+// RUN: %clang_cc1 %s -Warm-interrupt-safety -triple thumb-apple-darwin  -target-feature +vfp3 -verify -fsyntax-only
+// RUN: %clang_cc1 %s -Warm-interrupt-safety -triple armeb-none-eabi  -target-feature +vfp4 -verify -fsyntax-only
+// RUN: %clang_cc1 %s -Warm-interrupt-safety -triple thumbeb-none-eabi  -target-feature +neon -verify -fsyntax-only
+// RUN: %clang_cc1 %s -Warm-interrupt-safety -triple thumbeb-none-eabi -target-feature +neon -target-feature +soft-float -DSOFT -verify -fsyntax-only
 
 __attribute__((interrupt(IRQ))) void foo() {} // expected-error {{'interrupt' attribute requires a string}}
 __attribute__((interrupt("irq"))) void foo1() {} // expected-warning {{'interrupt' attribute argument not supported: irq}}
@@ -26,24 +26,36 @@
   callee2();
 }
 
-#ifndef SOFT
 __attribute__((interrupt("IRQ"))) void caller2() {
+#ifndef SOFT
   callee1(); // expected-warning {{call to function without interrupt attribute could clobber interruptee's VFP registers}}
-  callee2();
-}
-
-void (*callee3)();
-__attribute__((interrupt("IRQ"))) void caller3() {
-  callee3(); // expected-warning {{call to function without interrupt attribute could clobber interruptee's VFP registers}}
-}
 #else
-__attribute__((interrupt("IRQ"))) void caller2() {
   callee1();
+#endif
   callee2();
 }
 
 void (*callee3)();
 __attribute__((interrupt("IRQ"))) void caller3() {
+#ifndef SOFT
+  callee3(); // expected-warning {{call to function without interrupt attribute could clobber interruptee's VFP registers}}
+#else
   callee3();
+#endif
 }
+
+void __attribute__((interrupt("IRQ"))) bugzilla35527() {
+  typedef void __attribute__((interrupt("IRQ"))) (*interrupt_callback_t)(int i, void *ctx);
+  interrupt_callback_t interrupt_callee;
+  interrupt_callee(42, 0);
+  (interrupt_callee)(42, 0);
+  (*interrupt_callee)(42, 0);
+
+  typedef void (*callback_t)(int i, void *ctx);
+  callback_t callee;
+#ifndef SOFT
+  callee(37, 0); // expected-warning {{call to function without interrupt attribute could clobber interruptee's VFP registers}}
+#else
+  callee(37, 0);
 #endif
+}
Index: clang/lib/Sema/SemaExpr.cpp
===================================================================
--- clang/lib/Sema/SemaExpr.cpp
+++ clang/lib/Sema/SemaExpr.cpp
@@ -5925,12 +5925,20 @@
   // so there's some risk when calling out to non-interrupt handler functions
   // that the callee might not preserve them. This is easy to diagnose here,
   // but can be very challenging to debug.
-  if (auto *Caller = getCurFunctionDecl())
-    if (Caller->hasAttr<ARMInterruptAttr>()) {
-      bool VFP = Context.getTargetInfo().hasFeature("vfp");
-      if (VFP && (!FDecl || !FDecl->hasAttr<ARMInterruptAttr>()))
-        Diag(Fn->getExprLoc(), diag::warn_arm_interrupt_calling_convention);
-    }
+  if (Context.getTargetInfo().hasFeature("vfp"))
+    if (auto *Caller = getCurFunctionDecl())
+      if (Caller->hasAttr<ARMInterruptAttr>()) {
+        const Decl *CalleeDecl = FDecl;
+        if (const auto *UO = dyn_cast<UnaryOperator>(Fn->IgnoreParens())) {
+          if (const auto *TT =
+                  dyn_cast<TypedefType>(UO->getSubExpr()->getType()))
+            CalleeDecl = TT->getDecl();
+        } else if (const auto *TT = Fn->getType()->getAs<TypedefType>()) {
+          CalleeDecl = TT->getDecl();
+        }
+        if (!CalleeDecl || !CalleeDecl->hasAttr<ARMInterruptAttr>())
+          Diag(Fn->getExprLoc(), diag::warn_arm_interrupt_calling_convention);
+      }
 
   // Promote the function operand.
   // We special-case function promotion here because we only allow promoting
Index: clang/include/clang/Basic/DiagnosticSemaKinds.td
===================================================================
--- clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -285,7 +285,7 @@
   "interrupt service routine cannot be called directly">;
 def warn_arm_interrupt_calling_convention : Warning<
    "call to function without interrupt attribute could clobber interruptee's VFP registers">,
-   InGroup<Extra>;
+   InGroup<ARMInterruptSafety>;
 def warn_interrupt_attribute_invalid : Warning<
    "%select{MIPS|MSP430|RISC-V}0 'interrupt' attribute only applies to "
    "functions that have %select{no parameters|a 'void' return type}1">,
Index: clang/include/clang/Basic/DiagnosticGroups.td
===================================================================
--- clang/include/clang/Basic/DiagnosticGroups.td
+++ clang/include/clang/Basic/DiagnosticGroups.td
@@ -1129,6 +1129,9 @@
 // libc and the CRT to be skipped.
 def AVRRtlibLinkingQuirks : DiagGroup<"avr-rtlib-linking-quirks">;
 
+// A warning group for specific gotchas surrounding use of interrupt handlers on ARM
+def ARMInterruptSafety : DiagGroup<"arm-interrupt-safety">;
+
 // A warning group for things that will change semantics in the future.
 def FutureCompat : DiagGroup<"future-compat">;
 
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to