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
