From 5ae6554a1dcd2e39346030c06d364492901c9e8d Mon Sep 17 00:00:00 2001 From: Richard Smith Date: Thu, 30 Jan 2020 17:42:17 -0800 Subject: [PATCH] PR41991: Accept attributes on defaulted and deleted friends. Attributes are permitted on friend definitions, but we only checked for a proper function body, not for the =default / =delete cases. --- clang/lib/Parse/ParseDeclCXX.cpp | 2 +- clang/test/Parser/cxx-default-delete.cpp | 4 ++++ clang/test/Parser/cxx2a-spaceship.cpp | 6 ++++++ 3 files changed, 11 insertions(+), 1 deletion(-) diff --git a/clang/lib/Parse/ParseDeclCXX.cpp b/clang/lib/Parse/ParseDeclCXX.cpp index f872aa3a950c..09e5c7996fcd 100644 --- a/clang/lib/Parse/ParseDeclCXX.cpp +++ b/clang/lib/Parse/ParseDeclCXX.cpp @@ -2716,7 +2716,7 @@ Parser::ParseCXXClassMemberDeclaration(AccessSpecifier AS, // C++11 [dcl.attr.grammar] p4: If an attribute-specifier-seq appertains // to a friend declaration, that declaration shall be a definition. if (DeclaratorInfo.isFunctionDeclarator() && - DefinitionKind != FDK_Definition && DS.isFriendSpecified()) { + DefinitionKind == FDK_Declaration && DS.isFriendSpecified()) { // Diagnose attributes that appear before decl specifier: // [[]] friend int foo(); ProhibitAttributes(FnAttrs); diff --git a/clang/test/Parser/cxx-default-delete.cpp b/clang/test/Parser/cxx-default-delete.cpp index 8766d861732e..6c74937504b0 100644 --- a/clang/test/Parser/cxx-default-delete.cpp +++ b/clang/test/Parser/cxx-default-delete.cpp @@ -21,3 +21,7 @@ void baz() = delete; struct quux { int quux() = default; // expected-error{{constructor cannot have a return type}} }; + +struct attrs { + [[noreturn]] friend void deleted_with_attrs() = delete; +}; diff --git a/clang/test/Parser/cxx2a-spaceship.cpp b/clang/test/Parser/cxx2a-spaceship.cpp index 24cece3eaa9d..f80420f89862 100644 --- a/clang/test/Parser/cxx2a-spaceship.cpp +++ b/clang/test/Parser/cxx2a-spaceship.cpp @@ -16,3 +16,9 @@ void f(X<0> x0, X<1> x1) { X<3> e = x0 < x0 <=> x0 << x0; X<3> f = x0 << x0 <=> x0 < x0; // expected-warning {{overloaded operator << has higher precedence than comparison operator}} expected-note 2{{}} } + +struct PR41991 { + [[nodiscard]] friend bool operator==(const PR41991&, const PR41991&) = default; + [[nodiscard]] friend bool operator!=(const PR41991&, const PR41991&) = delete; + [[nodiscard]] friend bool operator<(const PR41991&, const PR41991&); // expected-error {{an attribute list cannot appear here}} +};