forked from OSchip/llvm-project
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]].
This commit is contained in:
parent
6666e0d7a2
commit
62328f2f29
|
@ -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;
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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}}
|
||||
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -14,7 +14,7 @@ template <typename T> void a4 [[noreturn]] () { return; } // expected-warning {{
|
|||
// expected-warning@-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}}
|
||||
|
|
|
@ -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}}
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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}}
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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}}
|
||||
|
||||
|
|
Loading…
Reference in New Issue