Author: Sirraide Date: 2024-08-22T23:33:40+02:00 New Revision: 8b5f606612de30ece5e113517decacca0d8ccb35
URL: https://github.com/llvm/llvm-project/commit/8b5f606612de30ece5e113517decacca0d8ccb35 DIFF: https://github.com/llvm/llvm-project/commit/8b5f606612de30ece5e113517decacca0d8ccb35.diff LOG: [Clang] [Parser] Improve diagnostic for `friend concept` (#105121) Diagnose this early after parsing declaration specifiers; this allows us to issue a better diagnostic. This also checks for `concept friend` and concept declarations w/o a template-head because it’s easiest to do that at the same time. Fixes #45182. Added: clang/test/Parser/friend-concept.cpp Modified: clang/docs/ReleaseNotes.rst clang/include/clang/Basic/DiagnosticParseKinds.td clang/lib/Parse/ParseDeclCXX.cpp Removed: ################################################################################ diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index 5f5bf51849e602..e0ede62b80c2ee 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -241,6 +241,8 @@ Improvements to Clang's diagnostics - Don't emit duplicated dangling diagnostics. (#GH93386). +- Improved diagnostic when trying to befriend a concept. (#GH45182). + Improvements to Clang's time-trace ---------------------------------- diff --git a/clang/include/clang/Basic/DiagnosticParseKinds.td b/clang/include/clang/Basic/DiagnosticParseKinds.td index 464f08637332d4..0b8ab4bf092509 100644 --- a/clang/include/clang/Basic/DiagnosticParseKinds.td +++ b/clang/include/clang/Basic/DiagnosticParseKinds.td @@ -974,6 +974,9 @@ def warn_cxx23_variadic_friends : Warning< "variadic 'friend' declarations are incompatible with C++ standards before C++2c">, DefaultIgnore, InGroup<CXXPre26Compat>; +def err_friend_concept : Error< + "friend declaration cannot be a concept">; + // C++11 default member initialization def ext_nonstatic_member_init : ExtWarn< "default member initializer for non-static data member is a C++11 " diff --git a/clang/lib/Parse/ParseDeclCXX.cpp b/clang/lib/Parse/ParseDeclCXX.cpp index 18c5fe6056b472..7ca27d00c0bcbf 100644 --- a/clang/lib/Parse/ParseDeclCXX.cpp +++ b/clang/lib/Parse/ParseDeclCXX.cpp @@ -3139,6 +3139,19 @@ Parser::DeclGroupPtrTy Parser::ParseCXXClassMemberDeclaration( return Actions.BuildDeclaratorGroup(Decls); } + // Befriending a concept is invalid and would already fail if + // we did nothing here, but this allows us to issue a more + // helpful diagnostic. + if (Tok.is(tok::kw_concept)) { + Diag(Tok.getLocation(), + DS.isFriendSpecified() || NextToken().is(tok::kw_friend) + ? diag::err_friend_concept + : diag:: + err_concept_decls_may_only_appear_in_global_namespace_scope); + SkipUntil(tok::semi, tok::r_brace, StopBeforeMatch); + return nullptr; + } + ParsingDeclarator DeclaratorInfo(*this, DS, DeclAttrs, DeclaratorContext::Member); if (TemplateInfo.TemplateParams) diff --git a/clang/test/Parser/friend-concept.cpp b/clang/test/Parser/friend-concept.cpp new file mode 100644 index 00000000000000..d771ca4d4178ed --- /dev/null +++ b/clang/test/Parser/friend-concept.cpp @@ -0,0 +1,13 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -std=c++20 %s + +template<class> +concept fooable = true; + +struct S { + template<class> friend concept x = requires { requires true; }; // expected-error {{friend declaration cannot be a concept}} + template<class> friend concept fooable; // expected-error {{friend declaration cannot be a concept}} + template<class> concept friend fooable; // expected-error {{expected unqualified-id}} + friend concept fooable; // expected-error {{friend declaration cannot be a concept}} + concept friend fooable; // expected-error {{friend declaration cannot be a concept}} + concept fooable; // expected-error {{concept declarations may only appear in global or namespace scope}} +}; _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits