Skip to content

Commit e966913

Browse files
committed
[clang][Sema] Emit warnings about incorrect AVR interrupt/signal handlers
1. interrupt/signal handlers can not have parameters 2. interrupt/signal handlers can only have 'void' type
1 parent 280609c commit e966913

File tree

6 files changed

+43
-9
lines changed

6 files changed

+43
-9
lines changed

clang/include/clang/Basic/DiagnosticSemaKinds.td

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -351,8 +351,8 @@ def warn_arm_interrupt_vfp_clobber : Warning<
351351
def err_arm_interrupt_called : Error<
352352
"interrupt service routine cannot be called directly">;
353353
def warn_interrupt_attribute_invalid : Warning<
354-
"%select{MIPS|MSP430|RISC-V}0 'interrupt' attribute only applies to "
355-
"functions that have %select{no parameters|a 'void' return type}1">,
354+
"%select{MIPS|MSP430|RISC-V|AVR}0 '%1' attribute only applies to "
355+
"functions that have %select{no parameters|a 'void' return type}2">,
356356
InGroup<IgnoredAttributes>;
357357
def warn_riscv_repeated_interrupt_attribute : Warning<
358358
"repeated RISC-V 'interrupt' attribute">, InGroup<IgnoredAttributes>;

clang/lib/Sema/SemaAVR.cpp

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,18 @@ void SemaAVR::handleInterruptAttr(Decl *D, const ParsedAttr &AL) {
3030
if (!AL.checkExactlyNumArgs(SemaRef, 0))
3131
return;
3232

33+
// AVR interrupt handlers must have no parameter and be void type.
34+
if (hasFunctionProto(D) && getFunctionOrMethodNumParams(D) != 0) {
35+
Diag(D->getLocation(), diag::warn_interrupt_attribute_invalid)
36+
<< /*AVR*/ 3 << "interrupt" << 0;
37+
return;
38+
}
39+
if (!getFunctionOrMethodResultType(D)->isVoidType()) {
40+
Diag(D->getLocation(), diag::warn_interrupt_attribute_invalid)
41+
<< /*AVR*/ 3 << "interrupt" << 1;
42+
return;
43+
}
44+
3345
handleSimpleAttribute<AVRInterruptAttr>(*this, D, AL);
3446
}
3547

@@ -43,6 +55,18 @@ void SemaAVR::handleSignalAttr(Decl *D, const ParsedAttr &AL) {
4355
if (!AL.checkExactlyNumArgs(SemaRef, 0))
4456
return;
4557

58+
// AVR signal handlers must have no parameter and be void type.
59+
if (hasFunctionProto(D) && getFunctionOrMethodNumParams(D) != 0) {
60+
Diag(D->getLocation(), diag::warn_interrupt_attribute_invalid)
61+
<< /*AVR*/ 3 << "signal" << 0;
62+
return;
63+
}
64+
if (!getFunctionOrMethodResultType(D)->isVoidType()) {
65+
Diag(D->getLocation(), diag::warn_interrupt_attribute_invalid)
66+
<< /*AVR*/ 3 << "signal" << 1;
67+
return;
68+
}
69+
4670
handleSimpleAttribute<AVRSignalAttr>(*this, D, AL);
4771
}
4872

clang/lib/Sema/SemaMIPS.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -272,13 +272,13 @@ void SemaMIPS::handleInterruptAttr(Decl *D, const ParsedAttr &AL) {
272272

273273
if (hasFunctionProto(D) && getFunctionOrMethodNumParams(D) != 0) {
274274
Diag(D->getLocation(), diag::warn_interrupt_attribute_invalid)
275-
<< /*MIPS*/ 0 << 0;
275+
<< /*MIPS*/ 0 << "interrupt" << 0;
276276
return;
277277
}
278278

279279
if (!getFunctionOrMethodResultType(D)->isVoidType()) {
280280
Diag(D->getLocation(), diag::warn_interrupt_attribute_invalid)
281-
<< /*MIPS*/ 0 << 1;
281+
<< /*MIPS*/ 0 << "interrupt" << 1;
282282
return;
283283
}
284284

clang/lib/Sema/SemaMSP430.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,13 +33,13 @@ void SemaMSP430::handleInterruptAttr(Decl *D, const ParsedAttr &AL) {
3333

3434
if (hasFunctionProto(D) && getFunctionOrMethodNumParams(D) != 0) {
3535
Diag(D->getLocation(), diag::warn_interrupt_attribute_invalid)
36-
<< /*MSP430*/ 1 << 0;
36+
<< /*MSP430*/ 1 << "interrupt" << 0;
3737
return;
3838
}
3939

4040
if (!getFunctionOrMethodResultType(D)->isVoidType()) {
4141
Diag(D->getLocation(), diag::warn_interrupt_attribute_invalid)
42-
<< /*MSP430*/ 1 << 1;
42+
<< /*MSP430*/ 1 << "interrupt" << 1;
4343
return;
4444
}
4545

clang/lib/Sema/SemaRISCV.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1458,13 +1458,13 @@ void SemaRISCV::handleInterruptAttr(Decl *D, const ParsedAttr &AL) {
14581458

14591459
if (hasFunctionProto(D) && getFunctionOrMethodNumParams(D) != 0) {
14601460
Diag(D->getLocation(), diag::warn_interrupt_attribute_invalid)
1461-
<< /*RISC-V*/ 2 << 0;
1461+
<< /*RISC-V*/ 2 << "interrupt" << 0;
14621462
return;
14631463
}
14641464

14651465
if (!getFunctionOrMethodResultType(D)->isVoidType()) {
14661466
Diag(D->getLocation(), diag::warn_interrupt_attribute_invalid)
1467-
<< /*RISC-V*/ 2 << 1;
1467+
<< /*RISC-V*/ 2 << "interrupt" << 1;
14681468
return;
14691469
}
14701470

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

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,14 @@ struct a test __attribute__((interrupt)); // expected-warning {{'interrupt' attr
55

66
__attribute__((interrupt(12))) void foo(void) { } // expected-error {{'interrupt' attribute takes no arguments}}
77

8-
__attribute__((interrupt)) void food(void) {}
8+
__attribute__((interrupt)) int fooa(void) { return 0; } // expected-warning {{'interrupt' attribute only applies to functions that have a 'void' return type}}
9+
10+
__attribute__((interrupt)) void foob(int a) {} // expected-warning {{'interrupt' attribute only applies to functions that have no parameters}}
11+
12+
__attribute__((signal)) int fooc(void) { return 0; } // expected-warning {{'signal' attribute only applies to functions that have a 'void' return type}}
13+
14+
__attribute__((signal)) void food(int a) {} // expected-warning {{'signal' attribute only applies to functions that have no parameters}}
15+
16+
__attribute__((interrupt)) void fooe(void) {}
17+
18+
__attribute__((signal)) void foof(void) {}

0 commit comments

Comments
 (0)