[clang] [Clang][Parse] Diagnose requires expressions with explicit object parameters (PR #88974)

Krystian Stasiowski via cfe-commits cfe-commits at lists.llvm.org
Wed Apr 17 07:00:33 PDT 2024


https://github.com/sdkrystian updated https://github.com/llvm/llvm-project/pull/88974

>From f81f0582dd7ee8d951128917398319c052371b3e Mon Sep 17 00:00:00 2001
From: Krystian Stasiowski <sdkrystian at gmail.com>
Date: Tue, 16 Apr 2024 15:42:45 -0400
Subject: [PATCH 1/3] [Clang][Parse] Diagnose requires expressions with
 explicit object parameters

---
 clang/docs/ReleaseNotes.rst                       |  2 ++
 clang/include/clang/Basic/DiagnosticParseKinds.td |  2 ++
 clang/lib/Parse/ParseDecl.cpp                     | 15 ++++++++++++++-
 .../CXX/dcl.decl/dcl.meaning/dcl.fct/p6-cxx23.cpp |  4 ++++
 4 files changed, 22 insertions(+), 1 deletion(-)
 create mode 100644 clang/test/CXX/dcl.decl/dcl.meaning/dcl.fct/p6-cxx23.cpp

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 96ad92b540b47f..c19ad9fba58f37 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -364,6 +364,8 @@ Improvements to Clang's diagnostics
 - Clang now uses the correct type-parameter-key (``class`` or ``typename``) when printing
   template template parameter declarations.
 
+- Clang now diagnoses requires expressions with explicit object parameters.
+
 Improvements to Clang's time-trace
 ----------------------------------
 
diff --git a/clang/include/clang/Basic/DiagnosticParseKinds.td b/clang/include/clang/Basic/DiagnosticParseKinds.td
index bb9ca2a50cc06c..217ea9380f3b99 100644
--- a/clang/include/clang/Basic/DiagnosticParseKinds.td
+++ b/clang/include/clang/Basic/DiagnosticParseKinds.td
@@ -373,6 +373,8 @@ def err_requires_clause_must_appear_after_trailing_return : Error<
   "trailing return type must appear before trailing requires clause">;
 def err_requires_clause_on_declarator_not_declaring_a_function : Error<
   "trailing requires clause can only be used when declaring a function">;
+def err_requires_clause_explicit_object_parameter: Error<
+  "a requires clause cannot have an explicit object parameter">;
 def err_requires_clause_inside_parens : Error<
   "trailing requires clause should be placed outside parentheses">;
 def ext_auto_storage_class : ExtWarn<
diff --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp
index 274ee7b10c1787..76444597d4cb2a 100644
--- a/clang/lib/Parse/ParseDecl.cpp
+++ b/clang/lib/Parse/ParseDecl.cpp
@@ -7660,8 +7660,21 @@ void Parser::ParseParameterDeclarationClause(
     // Parse a C++23 Explicit Object Parameter
     // We do that in all language modes to produce a better diagnostic.
     SourceLocation ThisLoc;
-    if (getLangOpts().CPlusPlus && Tok.is(tok::kw_this))
+    if (getLangOpts().CPlusPlus && Tok.is(tok::kw_this)) {
       ThisLoc = ConsumeToken();
+      // C++23 [dcl.fct]p6:
+      //   An explicit-object-parameter-declaration is a parameter-declaration
+      //   with a this specifier. An explicit-object-parameter-declaration
+      //   shall appear only as the first parameter-declaration of a
+      //   parameter-declaration-list of either:
+      //   - a member-declarator that declares a member function, or
+      //   - a lambda-declarator.
+      //
+      // The parameter-declaration-list of a requires-expression is not such
+      // a context.
+      if (DeclaratorCtx == DeclaratorContext::RequiresExpr)
+        Diag(ThisLoc, diag::err_requires_clause_explicit_object_parameter);
+    }
 
     ParseDeclarationSpecifiers(DS, /*TemplateInfo=*/ParsedTemplateInfo(),
                                AS_none, DeclSpecContext::DSC_normal,
diff --git a/clang/test/CXX/dcl.decl/dcl.meaning/dcl.fct/p6-cxx23.cpp b/clang/test/CXX/dcl.decl/dcl.meaning/dcl.fct/p6-cxx23.cpp
new file mode 100644
index 00000000000000..d31e68acb64ac5
--- /dev/null
+++ b/clang/test/CXX/dcl.decl/dcl.meaning/dcl.fct/p6-cxx23.cpp
@@ -0,0 +1,4 @@
+// RUN: %clang_cc1 -std=c++23 -fsyntax-only -verify %s
+
+auto x0 = requires (this int) { true; }; // expected-error {{a requires clause cannot have an explicit object parameter}}
+auto x1 = requires (int, this int) { true; }; // expected-error {{a requires clause cannot have an explicit object parameter}}

>From e382e2f24df53b73d3bb28a51eea71c89d20d86c Mon Sep 17 00:00:00 2001
From: Krystian Stasiowski <sdkrystian at gmail.com>
Date: Wed, 17 Apr 2024 08:39:46 -0400
Subject: [PATCH 2/3] [FOLD] address review feedback, reword diagnostic

---
 clang/include/clang/Basic/DiagnosticParseKinds.td        | 4 ++--
 clang/lib/Parse/ParseDecl.cpp                            | 2 +-
 clang/test/CXX/dcl.decl/dcl.meaning/dcl.fct/p6-cxx23.cpp | 8 ++++++--
 3 files changed, 9 insertions(+), 5 deletions(-)

diff --git a/clang/include/clang/Basic/DiagnosticParseKinds.td b/clang/include/clang/Basic/DiagnosticParseKinds.td
index 217ea9380f3b99..66405095d51de8 100644
--- a/clang/include/clang/Basic/DiagnosticParseKinds.td
+++ b/clang/include/clang/Basic/DiagnosticParseKinds.td
@@ -373,8 +373,6 @@ def err_requires_clause_must_appear_after_trailing_return : Error<
   "trailing return type must appear before trailing requires clause">;
 def err_requires_clause_on_declarator_not_declaring_a_function : Error<
   "trailing requires clause can only be used when declaring a function">;
-def err_requires_clause_explicit_object_parameter: Error<
-  "a requires clause cannot have an explicit object parameter">;
 def err_requires_clause_inside_parens : Error<
   "trailing requires clause should be placed outside parentheses">;
 def ext_auto_storage_class : ExtWarn<
@@ -865,6 +863,8 @@ def err_empty_requires_expr : Error<
   "a requires expression must contain at least one requirement">;
 def err_requires_expr_parameter_list_ellipsis : Error<
   "varargs not allowed in requires expression">;
+def err_requires_expr_explicit_object_parameter: Error<
+  "a requires expression cannot have an explicit object parameter">;
 def err_expected_semi_requirement : Error<
   "expected ';' at end of requirement">;
 def err_requires_expr_missing_arrow : Error<
diff --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp
index 76444597d4cb2a..5f26b5a9e46bef 100644
--- a/clang/lib/Parse/ParseDecl.cpp
+++ b/clang/lib/Parse/ParseDecl.cpp
@@ -7673,7 +7673,7 @@ void Parser::ParseParameterDeclarationClause(
       // The parameter-declaration-list of a requires-expression is not such
       // a context.
       if (DeclaratorCtx == DeclaratorContext::RequiresExpr)
-        Diag(ThisLoc, diag::err_requires_clause_explicit_object_parameter);
+        Diag(ThisLoc, diag::err_requires_expr_explicit_object_parameter);
     }
 
     ParseDeclarationSpecifiers(DS, /*TemplateInfo=*/ParsedTemplateInfo(),
diff --git a/clang/test/CXX/dcl.decl/dcl.meaning/dcl.fct/p6-cxx23.cpp b/clang/test/CXX/dcl.decl/dcl.meaning/dcl.fct/p6-cxx23.cpp
index d31e68acb64ac5..3ad5c96b561ca2 100644
--- a/clang/test/CXX/dcl.decl/dcl.meaning/dcl.fct/p6-cxx23.cpp
+++ b/clang/test/CXX/dcl.decl/dcl.meaning/dcl.fct/p6-cxx23.cpp
@@ -1,4 +1,8 @@
 // RUN: %clang_cc1 -std=c++23 -fsyntax-only -verify %s
 
-auto x0 = requires (this int) { true; }; // expected-error {{a requires clause cannot have an explicit object parameter}}
-auto x1 = requires (int, this int) { true; }; // expected-error {{a requires clause cannot have an explicit object parameter}}
+auto x0 = requires (this int) { true; }; // expected-error {{a requires expression cannot have an explicit object parameter}}
+auto x1 = requires (int, this int) { true; }; // expected-error {{a requires expression cannot have an explicit object parameter}}
+
+template<this auto>
+void f(); // expected-error {{expected template parameter}}
+          // expected-error at -1 {{no function template matches function template specialization 'f'}}

>From 586649aef02281367b6f26278051febe653f8036 Mon Sep 17 00:00:00 2001
From: Krystian Stasiowski <sdkrystian at gmail.com>
Date: Wed, 17 Apr 2024 10:00:19 -0400
Subject: [PATCH 3/3] [FOLD] fix test

---
 clang/test/CXX/dcl.decl/dcl.meaning/dcl.fct/p6-cxx23.cpp | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/clang/test/CXX/dcl.decl/dcl.meaning/dcl.fct/p6-cxx23.cpp b/clang/test/CXX/dcl.decl/dcl.meaning/dcl.fct/p6-cxx23.cpp
index 3ad5c96b561ca2..9c1f30f81a0115 100644
--- a/clang/test/CXX/dcl.decl/dcl.meaning/dcl.fct/p6-cxx23.cpp
+++ b/clang/test/CXX/dcl.decl/dcl.meaning/dcl.fct/p6-cxx23.cpp
@@ -3,6 +3,5 @@
 auto x0 = requires (this int) { true; }; // expected-error {{a requires expression cannot have an explicit object parameter}}
 auto x1 = requires (int, this int) { true; }; // expected-error {{a requires expression cannot have an explicit object parameter}}
 
-template<this auto>
-void f(); // expected-error {{expected template parameter}}
-          // expected-error at -1 {{no function template matches function template specialization 'f'}}
+template<this auto> // expected-error {{expected template parameter}}
+void f(); // expected-error {{no function template matches function template specialization 'f'}}



More information about the cfe-commits mailing list