Skip to content

Commit 170b9ca

Browse files
authored
[clang][Sema] Emit warnings about incorrect AVR interrupt/signal handlers (#125997)
1. interrupt/signal handlers can not have parameters 2. interrupt/signal handlers must be 'void' type
1 parent 27c034a commit 170b9ca

File tree

8 files changed

+63
-32
lines changed

8 files changed

+63
-32
lines changed

clang/include/clang/Basic/DiagnosticSemaKinds.td

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -350,10 +350,11 @@ def warn_arm_interrupt_vfp_clobber : Warning<
350350
InGroup<DiagGroup<"arm-interrupt-vfp-clobber">>;
351351
def err_arm_interrupt_called : Error<
352352
"interrupt service routine cannot be called directly">;
353-
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">,
356-
InGroup<IgnoredAttributes>;
353+
def warn_interrupt_signal_attribute_invalid : Warning<
354+
"%select{MIPS|MSP430|RISC-V|AVR}0 '%select{interrupt|signal}1' "
355+
"attribute only applies to functions that have "
356+
"%select{no parameters|a 'void' return type}2">,
357+
InGroup<IgnoredAttributes>;
357358
def warn_riscv_repeated_interrupt_attribute : Warning<
358359
"repeated RISC-V 'interrupt' attribute">, InGroup<IgnoredAttributes>;
359360
def note_riscv_repeated_interrupt_attribute : Note<

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_signal_attribute_invalid)
36+
<< /*AVR*/ 3 << /*interrupt*/ 0 << 0;
37+
return;
38+
}
39+
if (!getFunctionOrMethodResultType(D)->isVoidType()) {
40+
Diag(D->getLocation(), diag::warn_interrupt_signal_attribute_invalid)
41+
<< /*AVR*/ 3 << /*interrupt*/ 0 << 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_signal_attribute_invalid)
61+
<< /*AVR*/ 3 << /*signal*/ 1 << 0;
62+
return;
63+
}
64+
if (!getFunctionOrMethodResultType(D)->isVoidType()) {
65+
Diag(D->getLocation(), diag::warn_interrupt_signal_attribute_invalid)
66+
<< /*AVR*/ 3 << /*signal*/ 1 << 1;
67+
return;
68+
}
69+
4670
handleSimpleAttribute<AVRSignalAttr>(*this, D, AL);
4771
}
4872

clang/lib/Sema/SemaMIPS.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -271,14 +271,14 @@ void SemaMIPS::handleInterruptAttr(Decl *D, const ParsedAttr &AL) {
271271
}
272272

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

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

clang/lib/Sema/SemaMSP430.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -32,14 +32,14 @@ void SemaMSP430::handleInterruptAttr(Decl *D, const ParsedAttr &AL) {
3232
}
3333

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

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

clang/lib/Sema/SemaRISCV.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1457,14 +1457,14 @@ void SemaRISCV::handleInterruptAttr(Decl *D, const ParsedAttr &AL) {
14571457
}
14581458

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

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

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
// RUN: %clang_cc1 %s -triple avr-unknown-unknown -verify -fsyntax-only
2+
struct a { int b; };
3+
4+
struct a test __attribute__((interrupt)); // expected-warning {{'interrupt' attribute only applies to functions}}
5+
6+
__attribute__((interrupt(12))) void foo(void) { } // expected-error {{'interrupt' attribute takes no arguments}}
7+
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__((interrupt)) void foof() {}
19+
20+
__attribute__((signal)) void foog(void) {}
21+
22+
__attribute__((signal)) void fooh() {}

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

Lines changed: 0 additions & 8 deletions
This file was deleted.

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

Lines changed: 0 additions & 8 deletions
This file was deleted.

0 commit comments

Comments
 (0)