[clang] 62328f2 - Implement WG21 P2156R1/WG14 N2557 on duplicate attributes

Aaron Ballman via cfe-commits cfe-commits at lists.llvm.org
Tue Apr 13 09:30:19 PDT 2021


Author: Aaron Ballman
Date: 2021-04-13T12:30:04-04:00
New Revision: 62328f2f29b432dadbd327ff91ba3914c478e3fc

URL: https://github.com/llvm/llvm-project/commit/62328f2f29b432dadbd327ff91ba3914c478e3fc
DIFF: https://github.com/llvm/llvm-project/commit/62328f2f29b432dadbd327ff91ba3914c478e3fc.diff

LOG: Implement WG21 P2156R1/WG14 N2557 on duplicate attributes

These proposals make the same changes to both C++ and C and remove a
restriction on standard attributes appearing multiple times in the same
attribute list.

We could warn on the duplicate attributes, but do not. This is for
consistency as we do not warn on attributes duplicated within the
attribute specifier sequence. If we want to warn on duplicated
standard attributes, we should do so both for both situations:
[[foo, foo]] and [[foo]][[foo]].

Added: 
    

Modified: 
    clang/include/clang/Basic/DiagnosticParseKinds.td
    clang/lib/Parse/ParseDeclCXX.cpp
    clang/test/CXX/dcl.dcl/dcl.attr/dcl.attr.depend/p1.cpp
    clang/test/CXX/dcl.dcl/dcl.attr/dcl.attr.fallthrough/p1.cpp
    clang/test/CXX/dcl.dcl/dcl.attr/dcl.attr.nodiscard/p1.cpp
    clang/test/CXX/dcl.dcl/dcl.attr/dcl.attr.noreturn/p1.cpp
    clang/test/CXX/dcl.dcl/dcl.attr/dcl.attr.unused/p1.cpp
    clang/test/Sema/c2x-fallthrough.c
    clang/test/Sema/c2x-maybe_unused-errors.c
    clang/test/Sema/c2x-nodiscard.c
    clang/test/SemaCXX/cxx2a-no-unique-address.cpp

Removed: 
    


################################################################################
diff  --git a/clang/include/clang/Basic/DiagnosticParseKinds.td b/clang/include/clang/Basic/DiagnosticParseKinds.td
index b0f9b317a020d..8b3da909dd118 100644
--- a/clang/include/clang/Basic/DiagnosticParseKinds.td
+++ b/clang/include/clang/Basic/DiagnosticParseKinds.td
@@ -684,8 +684,6 @@ def err_attribute_requires_arguments : Error<
   "parentheses must be omitted if %0 attribute's argument list is empty">;
 def err_cxx11_attribute_forbids_ellipsis : Error<
   "attribute %0 cannot be used as an attribute pack">;
-def err_cxx11_attribute_repeated : Error<
-  "attribute %0 cannot appear multiple times in an attribute specifier">;
 def warn_cxx14_compat_using_attribute_ns : Warning<
   "default scope specifier for attributes is incompatible with C++ standards "
   "before C++17">, InGroup<CXXPre17Compat>, DefaultIgnore;

diff  --git a/clang/lib/Parse/ParseDeclCXX.cpp b/clang/lib/Parse/ParseDeclCXX.cpp
index e1d29f555f425..bc59b41782577 100644
--- a/clang/lib/Parse/ParseDeclCXX.cpp
+++ b/clang/lib/Parse/ParseDeclCXX.cpp
@@ -4260,13 +4260,6 @@ void Parser::ParseCXX11AttributeSpecifier(ParsedAttributes &attrs,
       }
     }
 
-    bool StandardAttr = IsBuiltInOrStandardCXX11Attribute(AttrName, ScopeName);
-
-    if (StandardAttr &&
-        !SeenAttrs.insert(std::make_pair(AttrName, AttrLoc)).second)
-      Diag(AttrLoc, diag::err_cxx11_attribute_repeated)
-          << AttrName << SourceRange(SeenAttrs[AttrName]);
-
     // Parse attribute arguments
     if (Tok.is(tok::l_paren))
       AttrParsed = ParseCXX11AttributeArgs(AttrName, AttrLoc, attrs, endLoc,

diff  --git a/clang/test/CXX/dcl.dcl/dcl.attr/dcl.attr.depend/p1.cpp b/clang/test/CXX/dcl.dcl/dcl.attr/dcl.attr.depend/p1.cpp
index 6cf27af3230bd..424b159667c3b 100644
--- a/clang/test/CXX/dcl.dcl/dcl.attr/dcl.attr.depend/p1.cpp
+++ b/clang/test/CXX/dcl.dcl/dcl.attr/dcl.attr.depend/p1.cpp
@@ -1,6 +1,6 @@
 // RUN: %clang_cc1 -verify -std=c++11 %s
 
-[[carries_dependency, carries_dependency]] int m1(); // expected-error {{attribute 'carries_dependency' cannot appear multiple times in an attribute specifier}}
+[[carries_dependency, carries_dependency]] int m1(); // ok
 [[carries_dependency]] [[carries_dependency]] int m2(); // ok
 [[carries_dependency()]] int m3(); // expected-error {{attribute 'carries_dependency' cannot have an argument list}}
 

diff  --git a/clang/test/CXX/dcl.dcl/dcl.attr/dcl.attr.fallthrough/p1.cpp b/clang/test/CXX/dcl.dcl/dcl.attr/dcl.attr.fallthrough/p1.cpp
index 22815bbde9db4..675ab3e089b86 100644
--- a/clang/test/CXX/dcl.dcl/dcl.attr/dcl.attr.fallthrough/p1.cpp
+++ b/clang/test/CXX/dcl.dcl/dcl.attr/dcl.attr.fallthrough/p1.cpp
@@ -61,7 +61,7 @@ void g() {
     return;
 
   case 0:
-    [[fallthrough, fallthrough]]; // expected-error {{multiple times}}
+    [[fallthrough, fallthrough]]; // ok
   case 1:
     [[fallthrough(0)]]; // expected-error {{argument list}}
   case 2:

diff  --git a/clang/test/CXX/dcl.dcl/dcl.attr/dcl.attr.nodiscard/p1.cpp b/clang/test/CXX/dcl.dcl/dcl.attr/dcl.attr.nodiscard/p1.cpp
index 982f18f1e8cdf..142d4d6f369f6 100644
--- a/clang/test/CXX/dcl.dcl/dcl.attr/dcl.attr.nodiscard/p1.cpp
+++ b/clang/test/CXX/dcl.dcl/dcl.attr/dcl.attr.nodiscard/p1.cpp
@@ -1,7 +1,7 @@
 // RUN: %clang_cc1 -fsyntax-only -std=c++2a -verify %s
 
 struct [[nodiscard]] S1 {}; // ok
-struct [[nodiscard, nodiscard]] S2 {}; // expected-error {{attribute 'nodiscard' cannot appear multiple times in an attribute specifier}}
+struct [[nodiscard, nodiscard]] S2 {}; // ok
 struct [[nodiscard("Wrong")]] S3 {};
 
 [[nodiscard]] int f();

diff  --git a/clang/test/CXX/dcl.dcl/dcl.attr/dcl.attr.noreturn/p1.cpp b/clang/test/CXX/dcl.dcl/dcl.attr/dcl.attr.noreturn/p1.cpp
index d92356c1ec0b2..49c1106b51a51 100644
--- a/clang/test/CXX/dcl.dcl/dcl.attr/dcl.attr.noreturn/p1.cpp
+++ b/clang/test/CXX/dcl.dcl/dcl.attr/dcl.attr.noreturn/p1.cpp
@@ -14,7 +14,7 @@ template <typename T> void a4 [[noreturn]] () { return; } // expected-warning {{
                                                           // expected-warning at -1 {{function 'a4<long>' declared 'noreturn' should not return}}
 void a4_test() { a4<long>(); } // expected-note {{in instantiation of function template specialization 'a4<long>' requested here}}
 
-[[noreturn, noreturn]] void b() { throw 0; } // expected-error {{attribute 'noreturn' cannot appear multiple times in an attribute specifier}}
+[[noreturn, noreturn]] void b() { throw 0; } // ok
 [[noreturn]] [[noreturn]] void b2() { throw 0; } // ok
 
 [[noreturn()]] void c(); // expected-error {{attribute 'noreturn' cannot have an argument list}}

diff  --git a/clang/test/CXX/dcl.dcl/dcl.attr/dcl.attr.unused/p1.cpp b/clang/test/CXX/dcl.dcl/dcl.attr/dcl.attr.unused/p1.cpp
index 6c9b8a75cb04e..2cee3cbcdf8a0 100644
--- a/clang/test/CXX/dcl.dcl/dcl.attr/dcl.attr.unused/p1.cpp
+++ b/clang/test/CXX/dcl.dcl/dcl.attr/dcl.attr.unused/p1.cpp
@@ -1,5 +1,5 @@
 // RUN: %clang_cc1 -fsyntax-only -Wunused -std=c++1z -verify %s
 
 struct [[maybe_unused]] S1 {}; // ok
-struct [[maybe_unused, maybe_unused]] S2 {}; // expected-error {{attribute 'maybe_unused' cannot appear multiple times in an attribute specifier}}
+struct [[maybe_unused, maybe_unused]] S2 {}; // ok
 struct [[maybe_unused("Wrong")]] S3 {}; // expected-error {{'maybe_unused' cannot have an argument list}}

diff  --git a/clang/test/Sema/c2x-fallthrough.c b/clang/test/Sema/c2x-fallthrough.c
index e5508e0a10f1d..baa62aa8f1401 100644
--- a/clang/test/Sema/c2x-fallthrough.c
+++ b/clang/test/Sema/c2x-fallthrough.c
@@ -65,7 +65,7 @@ void g(void) {
     return;
 
   case 0:
-    [[fallthrough, fallthrough]]; // expected-error {{multiple times}}
+    [[fallthrough, fallthrough]]; // ok
   case 1:
     [[fallthrough(0)]]; // expected-error {{argument list}}
   case 2:

diff  --git a/clang/test/Sema/c2x-maybe_unused-errors.c b/clang/test/Sema/c2x-maybe_unused-errors.c
index 5d3eb4d47a6ef..72cefd10291a9 100644
--- a/clang/test/Sema/c2x-maybe_unused-errors.c
+++ b/clang/test/Sema/c2x-maybe_unused-errors.c
@@ -3,7 +3,7 @@
 struct [[maybe_unused]] S1 { // ok
   int a [[maybe_unused]];
 };
-struct [[maybe_unused, maybe_unused]] S2 { // expected-error {{attribute 'maybe_unused' cannot appear multiple times in an attribute specifier}}
+struct [[maybe_unused, maybe_unused]] S2 { // ok
   int a;
 };
 struct [[maybe_unused("Wrong")]] S3 { // expected-error {{'maybe_unused' cannot have an argument list}}

diff  --git a/clang/test/Sema/c2x-nodiscard.c b/clang/test/Sema/c2x-nodiscard.c
index f62ba27c12a13..812421757d347 100644
--- a/clang/test/Sema/c2x-nodiscard.c
+++ b/clang/test/Sema/c2x-nodiscard.c
@@ -3,7 +3,7 @@
 struct [[nodiscard]] S1 { // ok
   int i;
 };
-struct [[nodiscard, nodiscard]] S2 { // expected-error {{attribute 'nodiscard' cannot appear multiple times in an attribute specifier}}
+struct [[nodiscard, nodiscard]] S2 { // ok
   int i;
 };
 struct [[nodiscard("Wrong")]] S3 { // FIXME: may need an extension warning.

diff  --git a/clang/test/SemaCXX/cxx2a-no-unique-address.cpp b/clang/test/SemaCXX/cxx2a-no-unique-address.cpp
index 107466e33145b..44d6d3acdddef 100644
--- a/clang/test/SemaCXX/cxx2a-no-unique-address.cpp
+++ b/clang/test/SemaCXX/cxx2a-no-unique-address.cpp
@@ -10,8 +10,8 @@ struct [[no_unique_address]] S { // expected-error {{only applies to non-bit-fie
   [[no_unique_address]] static void sf(); // expected-error {{only applies to non-bit-field non-static data members}} unsupported-warning {{unknown}}
   [[no_unique_address]] int b : 3; // expected-error {{only applies to non-bit-field non-static data members}} unsupported-warning {{unknown}}
 
-  [[no_unique_address, no_unique_address]] int duplicated; // expected-error {{cannot appear multiple times}}
-  // unsupported-error at -1 {{cannot appear multiple times}} unsupported-warning at -1 2{{unknown}}
+  [[no_unique_address, no_unique_address]] int duplicated; // ok
+  // unsupported-warning at -1 2{{unknown}}
   [[no_unique_address]] [[no_unique_address]] int duplicated2; // unsupported-warning 2{{unknown}}
   [[no_unique_address()]] int arglist; // expected-error {{cannot have an argument list}} unsupported-warning {{unknown}}
 


        


More information about the cfe-commits mailing list