mirror of
https://github.com/llvm/llvm-project.git
synced 2025-04-16 12:56:35 +00:00
[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
This commit is contained in:
parent
27c034a9c6
commit
170b9caf33
@ -350,10 +350,11 @@ def warn_arm_interrupt_vfp_clobber : Warning<
|
||||
InGroup<DiagGroup<"arm-interrupt-vfp-clobber">>;
|
||||
def err_arm_interrupt_called : Error<
|
||||
"interrupt service routine cannot be called directly">;
|
||||
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">,
|
||||
InGroup<IgnoredAttributes>;
|
||||
def warn_interrupt_signal_attribute_invalid : Warning<
|
||||
"%select{MIPS|MSP430|RISC-V|AVR}0 '%select{interrupt|signal}1' "
|
||||
"attribute only applies to functions that have "
|
||||
"%select{no parameters|a 'void' return type}2">,
|
||||
InGroup<IgnoredAttributes>;
|
||||
def warn_riscv_repeated_interrupt_attribute : Warning<
|
||||
"repeated RISC-V 'interrupt' attribute">, InGroup<IgnoredAttributes>;
|
||||
def note_riscv_repeated_interrupt_attribute : Note<
|
||||
|
@ -30,6 +30,18 @@ void SemaAVR::handleInterruptAttr(Decl *D, const ParsedAttr &AL) {
|
||||
if (!AL.checkExactlyNumArgs(SemaRef, 0))
|
||||
return;
|
||||
|
||||
// AVR interrupt handlers must have no parameter and be void type.
|
||||
if (hasFunctionProto(D) && getFunctionOrMethodNumParams(D) != 0) {
|
||||
Diag(D->getLocation(), diag::warn_interrupt_signal_attribute_invalid)
|
||||
<< /*AVR*/ 3 << /*interrupt*/ 0 << 0;
|
||||
return;
|
||||
}
|
||||
if (!getFunctionOrMethodResultType(D)->isVoidType()) {
|
||||
Diag(D->getLocation(), diag::warn_interrupt_signal_attribute_invalid)
|
||||
<< /*AVR*/ 3 << /*interrupt*/ 0 << 1;
|
||||
return;
|
||||
}
|
||||
|
||||
handleSimpleAttribute<AVRInterruptAttr>(*this, D, AL);
|
||||
}
|
||||
|
||||
@ -43,6 +55,18 @@ void SemaAVR::handleSignalAttr(Decl *D, const ParsedAttr &AL) {
|
||||
if (!AL.checkExactlyNumArgs(SemaRef, 0))
|
||||
return;
|
||||
|
||||
// AVR signal handlers must have no parameter and be void type.
|
||||
if (hasFunctionProto(D) && getFunctionOrMethodNumParams(D) != 0) {
|
||||
Diag(D->getLocation(), diag::warn_interrupt_signal_attribute_invalid)
|
||||
<< /*AVR*/ 3 << /*signal*/ 1 << 0;
|
||||
return;
|
||||
}
|
||||
if (!getFunctionOrMethodResultType(D)->isVoidType()) {
|
||||
Diag(D->getLocation(), diag::warn_interrupt_signal_attribute_invalid)
|
||||
<< /*AVR*/ 3 << /*signal*/ 1 << 1;
|
||||
return;
|
||||
}
|
||||
|
||||
handleSimpleAttribute<AVRSignalAttr>(*this, D, AL);
|
||||
}
|
||||
|
||||
|
@ -271,14 +271,14 @@ void SemaMIPS::handleInterruptAttr(Decl *D, const ParsedAttr &AL) {
|
||||
}
|
||||
|
||||
if (hasFunctionProto(D) && getFunctionOrMethodNumParams(D) != 0) {
|
||||
Diag(D->getLocation(), diag::warn_interrupt_attribute_invalid)
|
||||
<< /*MIPS*/ 0 << 0;
|
||||
Diag(D->getLocation(), diag::warn_interrupt_signal_attribute_invalid)
|
||||
<< /*MIPS*/ 0 << /*interrupt*/ 0 << 0;
|
||||
return;
|
||||
}
|
||||
|
||||
if (!getFunctionOrMethodResultType(D)->isVoidType()) {
|
||||
Diag(D->getLocation(), diag::warn_interrupt_attribute_invalid)
|
||||
<< /*MIPS*/ 0 << 1;
|
||||
Diag(D->getLocation(), diag::warn_interrupt_signal_attribute_invalid)
|
||||
<< /*MIPS*/ 0 << /*interrupt*/ 0 << 1;
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -32,14 +32,14 @@ void SemaMSP430::handleInterruptAttr(Decl *D, const ParsedAttr &AL) {
|
||||
}
|
||||
|
||||
if (hasFunctionProto(D) && getFunctionOrMethodNumParams(D) != 0) {
|
||||
Diag(D->getLocation(), diag::warn_interrupt_attribute_invalid)
|
||||
<< /*MSP430*/ 1 << 0;
|
||||
Diag(D->getLocation(), diag::warn_interrupt_signal_attribute_invalid)
|
||||
<< /*MSP430*/ 1 << /*interrupt*/ 0 << 0;
|
||||
return;
|
||||
}
|
||||
|
||||
if (!getFunctionOrMethodResultType(D)->isVoidType()) {
|
||||
Diag(D->getLocation(), diag::warn_interrupt_attribute_invalid)
|
||||
<< /*MSP430*/ 1 << 1;
|
||||
Diag(D->getLocation(), diag::warn_interrupt_signal_attribute_invalid)
|
||||
<< /*MSP430*/ 1 << /*interrupt*/ 0 << 1;
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1457,14 +1457,14 @@ void SemaRISCV::handleInterruptAttr(Decl *D, const ParsedAttr &AL) {
|
||||
}
|
||||
|
||||
if (hasFunctionProto(D) && getFunctionOrMethodNumParams(D) != 0) {
|
||||
Diag(D->getLocation(), diag::warn_interrupt_attribute_invalid)
|
||||
<< /*RISC-V*/ 2 << 0;
|
||||
Diag(D->getLocation(), diag::warn_interrupt_signal_attribute_invalid)
|
||||
<< /*RISC-V*/ 2 << /*interrupt*/ 0 << 0;
|
||||
return;
|
||||
}
|
||||
|
||||
if (!getFunctionOrMethodResultType(D)->isVoidType()) {
|
||||
Diag(D->getLocation(), diag::warn_interrupt_attribute_invalid)
|
||||
<< /*RISC-V*/ 2 << 1;
|
||||
Diag(D->getLocation(), diag::warn_interrupt_signal_attribute_invalid)
|
||||
<< /*RISC-V*/ 2 << /*interrupt*/ 0 << 1;
|
||||
return;
|
||||
}
|
||||
|
||||
|
22
clang/test/Sema/avr-interript-signal-attr.c
Normal file
22
clang/test/Sema/avr-interript-signal-attr.c
Normal file
@ -0,0 +1,22 @@
|
||||
// RUN: %clang_cc1 %s -triple avr-unknown-unknown -verify -fsyntax-only
|
||||
struct a { int b; };
|
||||
|
||||
struct a test __attribute__((interrupt)); // expected-warning {{'interrupt' attribute only applies to functions}}
|
||||
|
||||
__attribute__((interrupt(12))) void foo(void) { } // expected-error {{'interrupt' attribute takes no arguments}}
|
||||
|
||||
__attribute__((interrupt)) int fooa(void) { return 0; } // expected-warning {{'interrupt' attribute only applies to functions that have a 'void' return type}}
|
||||
|
||||
__attribute__((interrupt)) void foob(int a) {} // expected-warning {{'interrupt' attribute only applies to functions that have no parameters}}
|
||||
|
||||
__attribute__((signal)) int fooc(void) { return 0; } // expected-warning {{'signal' attribute only applies to functions that have a 'void' return type}}
|
||||
|
||||
__attribute__((signal)) void food(int a) {} // expected-warning {{'signal' attribute only applies to functions that have no parameters}}
|
||||
|
||||
__attribute__((interrupt)) void fooe(void) {}
|
||||
|
||||
__attribute__((interrupt)) void foof() {}
|
||||
|
||||
__attribute__((signal)) void foog(void) {}
|
||||
|
||||
__attribute__((signal)) void fooh() {}
|
@ -1,8 +0,0 @@
|
||||
// RUN: %clang_cc1 %s -triple avr-unknown-unknown -verify -fsyntax-only
|
||||
struct a { int b; };
|
||||
|
||||
struct a test __attribute__((interrupt)); // expected-warning {{'interrupt' attribute only applies to functions}}
|
||||
|
||||
__attribute__((interrupt(12))) void foo(void) { } // expected-error {{'interrupt' attribute takes no arguments}}
|
||||
|
||||
__attribute__((interrupt)) void food(void) {}
|
@ -1,8 +0,0 @@
|
||||
// RUN: %clang_cc1 %s -triple avr-unknown-unknown -verify -fsyntax-only
|
||||
struct a { int b; };
|
||||
|
||||
struct a test __attribute__((signal)); // expected-warning {{'signal' attribute only applies to functions}}
|
||||
|
||||
__attribute__((signal(12))) void foo(void) { } // expected-error {{'signal' attribute takes no arguments}}
|
||||
|
||||
__attribute__((signal)) void food(void) {}
|
Loading…
x
Reference in New Issue
Block a user