diff --git a/clang/include/clang/Basic/DiagnosticParseKinds.td b/clang/include/clang/Basic/DiagnosticParseKinds.td index b0f9b317a020..8b3da909dd11 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, DefaultIgnore; diff --git a/clang/lib/Parse/ParseDeclCXX.cpp b/clang/lib/Parse/ParseDeclCXX.cpp index e1d29f555f42..bc59b4178257 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 6cf27af3230b..424b159667c3 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 22815bbde9db..675ab3e089b8 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 982f18f1e8cd..142d4d6f369f 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 d92356c1ec0b..49c1106b51a5 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 void a4 [[noreturn]] () { return; } // expected-warning {{ // expected-warning@-1 {{function 'a4' declared 'noreturn' should not return}} void a4_test() { a4(); } // expected-note {{in instantiation of function template specialization 'a4' 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 6c9b8a75cb04..2cee3cbcdf8a 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 e5508e0a10f1..baa62aa8f140 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 5d3eb4d47a6e..72cefd10291a 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 f62ba27c12a1..812421757d34 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 107466e33145..44d6d3acddde 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@-1 {{cannot appear multiple times}} unsupported-warning@-1 2{{unknown}} + [[no_unique_address, no_unique_address]] int duplicated; // ok + // unsupported-warning@-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}}