llvmbot wrote:

<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-clang

Author: Vedant Neve (0bVdnt)

<details>
<summary>Changes</summary>

Diagnose duplicate [[maybe_unused]], [[noreturn]], and [[fallthrough]]
attributes as required by the C++17 standard (attribute shall appear at
most once in each attribute-list).

- [X] Tested locally

Fixes #<!-- -->176136 

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


3 Files Affected:

- (modified) clang/lib/Sema/SemaDeclAttr.cpp (+11) 
- (modified) clang/lib/Sema/SemaStmtAttr.cpp (+13) 
- (added) clang/test/SemaCXX/cxx17-duplicate-attrs.cpp (+19) 


``````````diff
diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp
index d762bcd789bf5..d770d513f108a 100644
--- a/clang/lib/Sema/SemaDeclAttr.cpp
+++ b/clang/lib/Sema/SemaDeclAttr.cpp
@@ -2099,6 +2099,12 @@ static void handleStandardNoReturnAttr(Sema &S, Decl *D, 
const ParsedAttr &A) {
         S.getSourceManager().isInSystemMacro(A.getLoc())))
     S.Diag(A.getLoc(), diag::warn_deprecated_noreturn_spelling) << 
A.getRange();
 
+  // Check for duplicate attribute - warn if already applied.
+  if (D->hasAttr<CXX11NoReturnAttr>()) {
+    S.Diag(A.getLoc(), diag::warn_duplicate_attribute_exact) << A;
+    return;
+  }
+
   D->addAttr(::new (S.Context) CXX11NoReturnAttr(S.Context, A));
 }
 
@@ -2230,6 +2236,11 @@ static void handleUnusedAttr(Sema &S, Decl *D, const 
ParsedAttr &AL) {
   if (!S.getLangOpts().CPlusPlus17 && IsCXX17Attr)
     S.Diag(AL.getLoc(), diag::ext_cxx17_attr) << AL;
 
+  // Check for duplicate attribute - warn if already applied.
+  if (D->hasAttr<UnusedAttr>()) {
+    S.Diag(AL.getLoc(), diag::warn_duplicate_attribute_exact) << AL;
+    return;
+  }
   D->addAttr(::new (S.Context) UnusedAttr(S.Context, AL));
 }
 
diff --git a/clang/lib/Sema/SemaStmtAttr.cpp b/clang/lib/Sema/SemaStmtAttr.cpp
index 27fd5563cc40e..c440ec3fe7735 100644
--- a/clang/lib/Sema/SemaStmtAttr.cpp
+++ b/clang/lib/Sema/SemaStmtAttr.cpp
@@ -16,6 +16,7 @@
 #include "clang/Sema/DelayedDiagnostic.h"
 #include "clang/Sema/ParsedAttr.h"
 #include "clang/Sema/ScopeInfo.h"
+#include "llvm/ADT/SmallPtrSet.h"
 #include <optional>
 
 using namespace clang;
@@ -740,7 +741,19 @@ static Attr *ProcessStmtAttribute(Sema &S, Stmt *St, const 
ParsedAttr &A,
 
 void Sema::ProcessStmtAttributes(Stmt *S, const ParsedAttributes &InAttrs,
                                  SmallVectorImpl<const Attr *> &OutAttrs) {
+  // Track standard attributes without arguments to detect duplicates.
+  llvm::SmallPtrSet<const IdentifierInfo *, 8> SeenStdAttrs;
+
   for (const ParsedAttr &AL : InAttrs) {
+    // Check for duplicate standard attributes without arguments.
+    if (AL.isStandardAttributeSyntax() && !AL.getScopeName() &&
+        AL.getNumArgs() == 0 && AL.getAttrName()) {
+      if (!SeenStdAttrs.insert(AL.getAttrName()).second) {
+        Diag(AL.getLoc(), diag::warn_duplicate_attribute_exact) << AL;
+        continue;
+      }
+    }
+
     if (const Attr *A = ProcessStmtAttribute(*this, S, AL, InAttrs.Range))
       OutAttrs.push_back(A);
   }
diff --git a/clang/test/SemaCXX/cxx17-duplicate-attrs.cpp 
b/clang/test/SemaCXX/cxx17-duplicate-attrs.cpp
new file mode 100644
index 0000000000000..67bea30e30f35
--- /dev/null
+++ b/clang/test/SemaCXX/cxx17-duplicate-attrs.cpp
@@ -0,0 +1,19 @@
+// RUN: %clang_cc1 -fsyntax-only -std=c++17 -verify %s
+
+int foo([[maybe_unused, maybe_unused]] int a) { // expected-warning 
{{attribute 'maybe_unused' is already applied}}
+    return 1;
+}
+
+[[noreturn, noreturn]] void g() { // expected-warning {{attribute 'noreturn' 
is already applied}}
+    __builtin_unreachable();
+}
+
+int h(int n) {
+    switch (n) {
+    case 1:
+        [[fallthrough, fallthrough]]; // expected-warning {{attribute 
'fallthrough' is already applied}}
+    case 2:
+        return 1;
+    }
+    return 0;
+}
\ No newline at end of file

``````````

</details>


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

Reply via email to