Skip to content

Commit 7054e63

Browse files
committed
[clang][ARM] Emit an error when an interrupt handler is called.
Closes #95359.
1 parent 5597097 commit 7054e63

File tree

4 files changed

+25
-8
lines changed

4 files changed

+25
-8
lines changed

clang/docs/ReleaseNotes.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -696,6 +696,8 @@ Improvements to Clang's diagnostics
696696
- Clang no longer emits a "no previous prototype" warning for Win32 entry points under ``-Wmissing-prototypes``.
697697
Fixes #GH94366.
698698

699+
- For the ARM target, calling an interrupt handler from another function is now an error. #GH95359.
700+
699701
Improvements to Clang's time-trace
700702
----------------------------------
701703

clang/include/clang/Basic/DiagnosticSemaKinds.td

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -340,6 +340,8 @@ def warn_arm_interrupt_vfp_clobber : Warning<
340340
"interrupt service routine with vfp enabled may clobber the "
341341
"interruptee's vfp state">,
342342
InGroup<DiagGroup<"arm-interrupt-vfp-clobber">>;
343+
def err_arm_interrupt_called : Error<
344+
"interrupt service routine cannot be called directly">;
343345
def warn_interrupt_attribute_invalid : Warning<
344346
"%select{MIPS|MSP430|RISC-V}0 'interrupt' attribute only applies to "
345347
"functions that have %select{no parameters|a 'void' return type}1">,

clang/lib/Sema/SemaExpr.cpp

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6625,9 +6625,15 @@ ExprResult Sema::BuildResolvedCallExpr(Expr *Fn, NamedDecl *NDecl,
66256625
unsigned BuiltinID = (FDecl ? FDecl->getBuiltinID() : 0);
66266626

66276627
// Functions with 'interrupt' attribute cannot be called directly.
6628-
if (FDecl && FDecl->hasAttr<AnyX86InterruptAttr>()) {
6629-
Diag(Fn->getExprLoc(), diag::err_anyx86_interrupt_called);
6630-
return ExprError();
6628+
if (FDecl) {
6629+
if (FDecl->hasAttr<AnyX86InterruptAttr>()) {
6630+
Diag(Fn->getExprLoc(), diag::err_anyx86_interrupt_called);
6631+
return ExprError();
6632+
}
6633+
if (FDecl->hasAttr<ARMInterruptAttr>()) {
6634+
Diag(Fn->getExprLoc(), diag::err_arm_interrupt_called);
6635+
return ExprError();
6636+
}
66316637
}
66326638

66336639
// X86 interrupt handlers may only call routines with attribute

clang/test/Sema/arm-interrupt-attr.c

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
1-
// RUN: %clang_cc1 %s -triple arm-none-eabi -DSOFT -verify -fsyntax-only
1+
// RUN: %clang_cc1 %s -triple arm-none-eabi -verify -fsyntax-only
22
// RUN: %clang_cc1 %s -triple arm-none-eabi -target-feature +vfp2 -verify -fsyntax-only
33

44

5-
#ifdef SOFT
5+
#ifdef __ARM_FP
6+
__attribute__((interrupt("IRQ"))) void float_irq(void); // expected-warning {{interrupt service routine with vfp enabled may clobber the interruptee's vfp state}}
7+
#else // !defined(__ARM_FP)
68
__attribute__((interrupt("irq"))) void foo1(void) {} // expected-warning {{'interrupt' attribute argument not supported: irq}}
79
__attribute__((interrupt(IRQ))) void foo(void) {} // expected-error {{'interrupt' attribute requires a string}}
810
__attribute__((interrupt("IRQ", 1))) void foo2(void) {} // expected-error {{'interrupt' attribute takes no more than 1 argument}}
@@ -14,6 +16,11 @@ __attribute__((interrupt("UNDEF"))) void foo7(void) {}
1416
__attribute__((interrupt)) void foo8(void) {}
1517
__attribute__((interrupt())) void foo9(void) {}
1618
__attribute__((interrupt(""))) void foo10(void) {}
17-
#else
18-
__attribute__((interrupt("IRQ"))) void float_irq(void); // expected-warning {{interrupt service routine with vfp enabled may clobber the interruptee's vfp state}}
19-
#endif
19+
20+
__attribute__((interrupt("IRQ"))) void callee(void) {}
21+
22+
void caller(void)
23+
{
24+
callee(); // expected-error {{interrupt service routine cannot be called directly}}
25+
}
26+
#endif // __ARM_FP

0 commit comments

Comments
 (0)