llvmorg-github-actions[bot] wrote:

<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-backend-risc-v

Author: Zeyi Xu (zeyi2)

<details>
<summary>Changes</summary>

The RISC-V interrupt attribute previously accepted the same type more than 
once. This commit emits a warning instead (since a duplicate is almost 
certainly a mistake).

The warning is emitted at most once per attribute and is controlled by the new 
`-Wduplicate-interrupt-type` flag. 

Follow up of #<!-- -->216159

---
Full diff: https://github.com/llvm/llvm-project/pull/217358.diff


7 Files Affected:

- (modified) clang/docs/ReleaseNotes.md (+3) 
- (modified) clang/include/clang/Basic/DiagnosticSemaKinds.td (+3) 
- (modified) clang/lib/Sema/SemaRISCV.cpp (+6-1) 
- (modified) clang/test/Sema/riscv-interrupt-attr-qci.c (+8-24) 
- (modified) clang/test/Sema/riscv-interrupt-attr-rnmi.c (+4-12) 
- (modified) clang/test/Sema/riscv-interrupt-attr-sifive.c (+6-13) 
- (modified) clang/test/Sema/riscv-interrupt-attr.c (+6-5) 


``````````diff
diff --git a/clang/docs/ReleaseNotes.md b/clang/docs/ReleaseNotes.md
index b585161ba3ff4..4f87cfc3f378a 100644
--- a/clang/docs/ReleaseNotes.md
+++ b/clang/docs/ReleaseNotes.md
@@ -565,6 +565,9 @@ features cannot lower the translation-unit ABI level;
 - Fixed a bug where the `interrupt` attribute did not accept `machine` together
   with both `SiFive-CLIC-preemptible` and `SiFive-CLIC-stack-swap`.
 
+- Added a new warning when the same interrupt type is specified more than
+  once in a RISC-V `interrupt` attribute.
+
 - Added `-march=native` for better compatibility with ARM, AArch64, and X86. 
This
   option will be treated like `-mcpu=native` if `-mcpu` is not present. If
   `-mcpu` is present, the ISA will be selected from the host CPU and the tune
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 73d6680aa5453..d7f25cf109523 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -13679,6 +13679,9 @@ def err_riscv_type_requires_extension : Error<
   "RISC-V type %0 requires the '%1' extension">;
 def err_riscv_attribute_interrupt_requires_extension : Error<
   "RISC-V 'interrupt' attribute '%0' requires extension '%1'">;
+def warn_riscv_attribute_interrupt_duplicate_type : Warning<
+  "RISC-V 'interrupt' attribute type '%0' specified more than once">,
+  InGroup<DiagGroup<"duplicate-interrupt-type">>;
 def err_riscv_attribute_interrupt_invalid_combination : Error<
   "RISC-V 'interrupt' attribute contains invalid combination of interrupt 
types">;
 def err_riscv_builtin_invalid_twiden : Error<"RISC-V XSfmm twiden must be 1, 2 
or 4">;
diff --git a/clang/lib/Sema/SemaRISCV.cpp b/clang/lib/Sema/SemaRISCV.cpp
index d4c6495fbacfb..c76830467a60d 100644
--- a/clang/lib/Sema/SemaRISCV.cpp
+++ b/clang/lib/Sema/SemaRISCV.cpp
@@ -1646,6 +1646,7 @@ void SemaRISCV::handleInterruptAttr(Decl *D, const 
ParsedAttr &AL) {
 
   bool HasSiFiveCLICType = false;
   bool HasUnaryType = false;
+  bool ReportedDuplicateType = false;
 
   SmallSet<RISCVInterruptAttr::InterruptType, 3> Types;
   for (unsigned ArgIndex = 0; ArgIndex < AL.getNumArgs(); ++ArgIndex) {
@@ -1683,7 +1684,11 @@ void SemaRISCV::handleInterruptAttr(Decl *D, const 
ParsedAttr &AL) {
       break;
     }
 
-    Types.insert(Type);
+    if (!Types.insert(Type).second && !ReportedDuplicateType) {
+      Diag(Loc, diag::warn_riscv_attribute_interrupt_duplicate_type)
+          << TypeString;
+      ReportedDuplicateType = true;
+    }
   }
 
   if (HasUnaryType && Types.size() > 1) {
diff --git a/clang/test/Sema/riscv-interrupt-attr-qci.c 
b/clang/test/Sema/riscv-interrupt-attr-qci.c
index 63ff61a2c0de4..44484cc6f1341 100644
--- a/clang/test/Sema/riscv-interrupt-attr-qci.c
+++ b/clang/test/Sema/riscv-interrupt-attr-qci.c
@@ -11,31 +11,11 @@
 __attribute__((interrupt("qci-nest")))
 void foo_nest_interrupt(void) {}
 
-// CHECK-LABEL: @foo_nest_nest_interrupt() #0
-// CHECK: ret void
-__attribute__((interrupt("qci-nest", "qci-nest")))
-void foo_nest_nest_interrupt(void) {}
-
-// CHECK-LABEL: @foo_nest_nest_nest_interrupt() #0
-// CHECK: ret void
-__attribute__((interrupt("qci-nest", "qci-nest", "qci-nest")))
-void foo_nest_nest_nest_interrupt(void) {}
-
 // CHECK-LABEL: @foo_nonest_interrupt() #1
 // CHECK: ret void
 __attribute__((interrupt("qci-nonest")))
 void foo_nonest_interrupt(void) {}
 
-// CHECK-LABEL: @foo_nonest_nonest_interrupt() #1
-// CHECK: ret void
-__attribute__((interrupt("qci-nonest", "qci-nonest")))
-void foo_nonest_nonest_interrupt(void) {}
-
-// CHECK-LABEL: @foo_nonest_nonest_nonest_interrupt() #1
-// CHECK: ret void
-__attribute__((interrupt("qci-nonest", "qci-nonest", "qci-nonest")))
-void foo_nonest_nonest_nonest_interrupt(void) {}
-
 // CHECK: attributes #0
 // CHECK: "interrupt"="qci-nest"
 // CHECK: attributes #1
@@ -56,10 +36,14 @@ __attribute__((interrupt("qci-nest", "qci-nonest"))) void 
foo_nest5(void) {} //
 __attribute__((interrupt("qci-nest"))) void foo_nest(void) {} // 
disabled-error {{RISC-V 'interrupt' attribute 'qci-nest' requires extension 
'Xqciint'}}
 __attribute__((interrupt("qci-nonest"))) void foo_nonest(void) {} // 
disabled-error {{RISC-V 'interrupt' attribute 'qci-nonest' requires extension 
'Xqciint'}}
 
-__attribute__((interrupt("qci-nest", "qci-nest"))) void foo_nest_nest(void) {} 
// disabled-error {{RISC-V 'interrupt' attribute 'qci-nest' requires extension 
'Xqciint'}}
-__attribute__((interrupt("qci-nonest", "qci-nonest"))) void 
foo_nonest_nonest(void) {} // disabled-error {{RISC-V 'interrupt' attribute 
'qci-nonest' requires extension 'Xqciint'}}
-__attribute__((interrupt("qci-nest", "qci-nest", "qci-nest"))) void 
foo_nest_nest_nest(void) {} // disabled-error {{RISC-V 'interrupt' attribute 
'qci-nest' requires extension 'Xqciint'}}
-__attribute__((interrupt("qci-nonest", "qci-nonest", "qci-nonest"))) void 
foo_nonest_nonest_nonest(void) {} // disabled-error {{RISC-V 'interrupt' 
attribute 'qci-nonest' requires extension 'Xqciint'}}
+__attribute__((interrupt("qci-nest", "qci-nest"))) void foo_nest_nest(void) {} 
// both-warning {{RISC-V 'interrupt' attribute type 'qci-nest' specified more 
than once}} \
+  // disabled-error {{RISC-V 'interrupt' attribute 'qci-nest' requires 
extension 'Xqciint'}}
+__attribute__((interrupt("qci-nonest", "qci-nonest"))) void 
foo_nonest_nonest(void) {} // both-warning {{RISC-V 'interrupt' attribute type 
'qci-nonest' specified more than once}} \
+  // disabled-error {{RISC-V 'interrupt' attribute 'qci-nonest' requires 
extension 'Xqciint'}}
+__attribute__((interrupt("qci-nest", "qci-nest", "qci-nest"))) void 
foo_nest_nest_nest(void) {} // both-warning {{RISC-V 'interrupt' attribute type 
'qci-nest' specified more than once}} \
+  // disabled-error {{RISC-V 'interrupt' attribute 'qci-nest' requires 
extension 'Xqciint'}}
+__attribute__((interrupt("qci-nonest", "qci-nonest", "qci-nonest"))) void 
foo_nonest_nonest_nonest(void) {} // both-warning {{RISC-V 'interrupt' 
attribute type 'qci-nonest' specified more than once}} \
+  // disabled-error {{RISC-V 'interrupt' attribute 'qci-nonest' requires 
extension 'Xqciint'}}
 
 
 // This tests the errors for the qci interrupts when using
diff --git a/clang/test/Sema/riscv-interrupt-attr-rnmi.c 
b/clang/test/Sema/riscv-interrupt-attr-rnmi.c
index 02d25d357306f..4c792f7f3655b 100644
--- a/clang/test/Sema/riscv-interrupt-attr-rnmi.c
+++ b/clang/test/Sema/riscv-interrupt-attr-rnmi.c
@@ -9,23 +9,15 @@
 __attribute__((interrupt("rnmi")))
 void foo_rnmi_interrupt(void) {}
 
-// CHECK-LABEL: @foo_rnmi_rnmi_interrupt() #0
-// CHECK: ret void
-__attribute__((interrupt("rnmi", "rnmi")))
-void foo_rnmi_rnmi_interrupt(void) {}
-
-// CHECK-LABEL: @foo_rnmi_rnmi_rnmi_interrupt() #0
-// CHECK: ret void
-__attribute__((interrupt("rnmi", "rnmi", "rnmi")))
-void foo_rnmi_rnmi_rnmi_interrupt(void) {}
-
 // CHECK: attributes #0
 // CHECK: "interrupt"="rnmi"
 #else
 
 __attribute__((interrupt("rnmi"))) void test_rnmi(void) {} // disabled-error 
{{RISC-V 'interrupt' attribute 'rnmi' requires extension 'Smrnmi'}}
-__attribute__((interrupt("rnmi", "rnmi"))) void test_rnmi_rnmi(void) {} // 
disabled-error {{RISC-V 'interrupt' attribute 'rnmi' requires extension 
'Smrnmi'}}
-__attribute__((interrupt("rnmi", "rnmi", "rnmi"))) void 
test_rnmi_rnmi_rnmi(void) {} // disabled-error {{RISC-V 'interrupt' attribute 
'rnmi' requires extension 'Smrnmi'}}
+__attribute__((interrupt("rnmi", "rnmi"))) void test_rnmi_rnmi(void) {} // 
both-warning {{RISC-V 'interrupt' attribute type 'rnmi' specified more than 
once}} \
+  // disabled-error {{RISC-V 'interrupt' attribute 'rnmi' requires extension 
'Smrnmi'}}
+__attribute__((interrupt("rnmi", "rnmi", "rnmi"))) void 
test_rnmi_rnmi_rnmi(void) {} // both-warning {{RISC-V 'interrupt' attribute 
type 'rnmi' specified more than once}} \
+  // disabled-error {{RISC-V 'interrupt' attribute 'rnmi' requires extension 
'Smrnmi'}}
 
 __attribute__((interrupt("rnmi", "supervisor"))) void 
foo_rnmi_supervisor(void) {}  // both-error {{RISC-V 'interrupt' attribute 
contains invalid combination of interrupt types}}
 __attribute__((interrupt("rnmi", "machine"))) void foo_rnmi_machine(void) {}  
// both-error {{RISC-V 'interrupt' attribute contains invalid combination of 
interrupt types}}
diff --git a/clang/test/Sema/riscv-interrupt-attr-sifive.c 
b/clang/test/Sema/riscv-interrupt-attr-sifive.c
index 2e7c7a8e03075..9bd6d4d945612 100644
--- a/clang/test/Sema/riscv-interrupt-attr-sifive.c
+++ b/clang/test/Sema/riscv-interrupt-attr-sifive.c
@@ -26,16 +26,6 @@ void foo_stack_swap_preemptible(void) {}
 __attribute__((interrupt("SiFive-CLIC-preemptible", "SiFive-CLIC-stack-swap")))
 void foo_preemptible_stack_swap(void) {}
 
-// CHECK-LABEL:  @foo_stack_swap_repeat() #0
-// CHECK: ret void
-__attribute__((interrupt("SiFive-CLIC-stack-swap", "SiFive-CLIC-stack-swap")))
-void foo_stack_swap_repeat(void) {}
-
-// CHECK-LABEL:  @foo_preemptible_repeat() #1
-// CHECK: ret void
-__attribute__((interrupt("SiFive-CLIC-preemptible", 
"SiFive-CLIC-preemptible")))
-void foo_preemptible_repeat(void) {}
-
 // CHECK-LABEL:  @foo_machine_stack_swap() #0
 // CHECK: ret void
 __attribute__((interrupt("machine", "SiFive-CLIC-stack-swap")))
@@ -77,12 +67,14 @@ void foo_preemptible_stack_swap_machine(void) {}
 #else
 
 __attribute__((interrupt("SiFive-CLIC-stack-swap"))) void foo15(void); // 
disabled-error {{RISC-V 'interrupt' attribute 'SiFive-CLIC-stack-swap' requires 
extension 'XSfmclic'}}
-__attribute__((interrupt("SiFive-CLIC-stack-swap", "SiFive-CLIC-stack-swap"))) 
void foo15(void); // disabled-error {{RISC-V 'interrupt' attribute 
'SiFive-CLIC-stack-swap' requires extension 'XSfmclic'}}
+__attribute__((interrupt("SiFive-CLIC-stack-swap", "SiFive-CLIC-stack-swap"))) 
void foo15(void); // both-warning {{RISC-V 'interrupt' attribute type 
'SiFive-CLIC-stack-swap' specified more than once}} \
+  // disabled-error {{RISC-V 'interrupt' attribute 'SiFive-CLIC-stack-swap' 
requires extension 'XSfmclic'}}
 __attribute__((interrupt("SiFive-CLIC-stack-swap", "machine"))) void 
foo15(void); // disabled-error {{RISC-V 'interrupt' attribute 
'SiFive-CLIC-stack-swap' requires extension 'XSfmclic'}}
 __attribute__((interrupt("machine", "SiFive-CLIC-stack-swap"))) void 
foo15(void); // disabled-error {{RISC-V 'interrupt' attribute 
'SiFive-CLIC-stack-swap' requires extension 'XSfmclic'}}
 
 __attribute__((interrupt("SiFive-CLIC-preemptible"))) void foo15(void); // 
disabled-error {{RISC-V 'interrupt' attribute 'SiFive-CLIC-preemptible' 
requires extension 'XSfmclic'}}
-__attribute__((interrupt("SiFive-CLIC-preemptible", 
"SiFive-CLIC-preemptible"))) void foo15(void); // disabled-error {{RISC-V 
'interrupt' attribute 'SiFive-CLIC-preemptible' requires extension 'XSfmclic'}}
+__attribute__((interrupt("SiFive-CLIC-preemptible", 
"SiFive-CLIC-preemptible"))) void foo15(void); // both-warning {{RISC-V 
'interrupt' attribute type 'SiFive-CLIC-preemptible' specified more than once}} 
\
+  // disabled-error {{RISC-V 'interrupt' attribute 'SiFive-CLIC-preemptible' 
requires extension 'XSfmclic'}}
 __attribute__((interrupt("SiFive-CLIC-preemptible", "machine"))) void 
foo15(void); // disabled-error {{RISC-V 'interrupt' attribute 
'SiFive-CLIC-preemptible' requires extension 'XSfmclic'}}
 __attribute__((interrupt("machine", "SiFive-CLIC-preemptible"))) void 
foo15(void); // disabled-error {{RISC-V 'interrupt' attribute 
'SiFive-CLIC-preemptible' requires extension 'XSfmclic'}}
 
@@ -90,7 +82,8 @@ __attribute__((interrupt("SiFive-CLIC-preemptible", 
"SiFive-CLIC-stack-swap")))
 __attribute__((interrupt("SiFive-CLIC-stack-swap", 
"SiFive-CLIC-preemptible"))) void foo17(void) {} // disabled-error {{RISC-V 
'interrupt' attribute 'SiFive-CLIC-stack-swap' requires extension 'XSfmclic'}}
 __attribute__((interrupt("machine", "SiFive-CLIC-stack-swap", 
"SiFive-CLIC-preemptible"))) void foo18(void) {} // disabled-error {{requires 
extension 'XSfmclic'}}
 
-__attribute__((interrupt("machine", "machine", "SiFive-CLIC-preemptible"))) 
void foo24(void) {} // disabled-error {{requires extension 'XSfmclic'}}
+__attribute__((interrupt("machine", "machine", "SiFive-CLIC-preemptible"))) 
void foo24(void) {} // both-warning {{RISC-V 'interrupt' attribute type 
'machine' specified more than once}} \
+  // disabled-error {{requires extension 'XSfmclic'}}
 __attribute__((interrupt("machine", "machine", "SiFive-CLIC-preemptible", 
"SiFive-CLIC-stack-swap"))) void foo25(void) {} // both-error {{'interrupt' 
attribute takes no more than 3 arguments}}
 
 __attribute__((interrupt("SiFive-CLIC-preemptible", "supervisor"))) void 
foo27(void) {} // both-error {{RISC-V 'interrupt' attribute contains invalid 
combination of interrupt types}}
diff --git a/clang/test/Sema/riscv-interrupt-attr.c 
b/clang/test/Sema/riscv-interrupt-attr.c
index 9f503a806703c..1b80f1ce0b3d9 100644
--- a/clang/test/Sema/riscv-interrupt-attr.c
+++ b/clang/test/Sema/riscv-interrupt-attr.c
@@ -42,7 +42,8 @@ struct a test __attribute__((interrupt)); // expected-warning 
{{'interrupt' attr
 __attribute__((interrupt)) int foo3(void) {return 0;} // expected-warning 
{{RISC-V 'interrupt' attribute only applies to functions that have a 'void' 
return type}}
 __attribute__((interrupt())) void foo5(int a) {} // expected-warning {{RISC-V 
'interrupt' attribute only applies to functions that have no parameters}}
 
-__attribute__((interrupt("machine", "supervisor", "machine"))) void 
foo15(void) {} // expected-error {{RISC-V 'interrupt' attribute contains 
invalid combination of interrupt types}}
+__attribute__((interrupt("machine", "supervisor", "machine"))) void 
foo15(void) {} // expected-warning {{RISC-V 'interrupt' attribute type 
'machine' specified more than once}} \
+  // expected-error {{RISC-V 'interrupt' attribute contains invalid 
combination of interrupt types}}
 
 __attribute__((interrupt("machine", "machine", "machine", "machine"))) void 
foo_too_many_args(void) {} // expected-error {{'interrupt' attribute takes no 
more than 3 arguments}}
 
@@ -68,10 +69,10 @@ __attribute__((interrupt("machine"))) void foo12(void) {}
 __attribute__((interrupt())) void foo13(void) {}
 __attribute__((interrupt)) void foo14(void) {}
 
-__attribute__((interrupt("machine", "machine"))) void foo_machine_twice(void) 
{}
-__attribute__((interrupt("supervisor", "supervisor"))) void 
foo_supervisor_supervisor(void) {}
-__attribute__((interrupt("machine", "machine", "machine"))) void 
foo_three_machine_args(void) {}
-__attribute__((interrupt("supervisor", "supervisor", "supervisor"))) void 
foo_three_supervisor_args(void) {}
+__attribute__((interrupt("machine", "machine"))) void foo_machine_twice(void) 
{} // expected-warning {{RISC-V 'interrupt' attribute type 'machine' specified 
more than once}}
+__attribute__((interrupt("supervisor", "supervisor"))) void 
foo_supervisor_supervisor(void) {} // expected-warning {{RISC-V 'interrupt' 
attribute type 'supervisor' specified more than once}}
+__attribute__((interrupt("machine", "machine", "machine"))) void 
foo_three_machine_args(void) {} // expected-warning {{RISC-V 'interrupt' 
attribute type 'machine' specified more than once}}
+__attribute__((interrupt("supervisor", "supervisor", "supervisor"))) void 
foo_three_supervisor_args(void) {} // expected-warning {{RISC-V 'interrupt' 
attribute type 'supervisor' specified more than once}}
 
 
 #endif

``````````

</details>


https://github.com/llvm/llvm-project/pull/217358
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to