[clang] [Clang] [Parser] Improve diagnostic for `friend concept` (PR #105121)
via cfe-commits
cfe-commits at lists.llvm.org
Tue Aug 20 10:06:06 PDT 2024
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-clang
Author: None (Sirraide)
<details>
<summary>Changes</summary>
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.
---
Full diff: https://github.com/llvm/llvm-project/pull/105121.diff
4 Files Affected:
- (modified) clang/docs/ReleaseNotes.rst (+2)
- (modified) clang/include/clang/Basic/DiagnosticParseKinds.td (+3)
- (modified) clang/lib/Parse/ParseDeclCXX.cpp (+13)
- (added) clang/test/Parser/friend-concept.cpp (+13)
``````````diff
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index e3fac712de4662..7fd856a8e6d16b 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -233,6 +233,8 @@ Improvements to Clang's diagnostics
- Clang now diagnoses when the result of a [[nodiscard]] function is discarded after being cast in C. Fixes #GH104391.
+- 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 62a97b36737e72..953d40b8e5fa56 100644
--- a/clang/include/clang/Basic/DiagnosticParseKinds.td
+++ b/clang/include/clang/Basic/DiagnosticParseKinds.td
@@ -971,6 +971,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}}
+};
``````````
</details>
https://github.com/llvm/llvm-project/pull/105121
More information about the cfe-commits
mailing list