[clang] 8b5f606 - [Clang] [Parser] Improve diagnostic for `friend concept` (#105121)

via cfe-commits cfe-commits at lists.llvm.org
Thu Aug 22 14:33:43 PDT 2024


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}}
+};


        


More information about the cfe-commits mailing list