Skip to content

Commit 8656d4c

Browse files
authored
[Clang][Parse] Diagnose requires expressions with explicit object parameters (#88974)
Clang currently allows the following: ``` auto x = requires (this int) { true; }; ``` This patch addresses that.
1 parent b854a23 commit 8656d4c

File tree

4 files changed

+25
-1
lines changed

4 files changed

+25
-1
lines changed

clang/docs/ReleaseNotes.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -364,6 +364,8 @@ Improvements to Clang's diagnostics
364364
- Clang now uses the correct type-parameter-key (``class`` or ``typename``) when printing
365365
template template parameter declarations.
366366

367+
- Clang now diagnoses requires expressions with explicit object parameters.
368+
367369
Improvements to Clang's time-trace
368370
----------------------------------
369371

clang/include/clang/Basic/DiagnosticParseKinds.td

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -863,6 +863,8 @@ def err_empty_requires_expr : Error<
863863
"a requires expression must contain at least one requirement">;
864864
def err_requires_expr_parameter_list_ellipsis : Error<
865865
"varargs not allowed in requires expression">;
866+
def err_requires_expr_explicit_object_parameter: Error<
867+
"a requires expression cannot have an explicit object parameter">;
866868
def err_expected_semi_requirement : Error<
867869
"expected ';' at end of requirement">;
868870
def err_requires_expr_missing_arrow : Error<

clang/lib/Parse/ParseDecl.cpp

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7660,8 +7660,21 @@ void Parser::ParseParameterDeclarationClause(
76607660
// Parse a C++23 Explicit Object Parameter
76617661
// We do that in all language modes to produce a better diagnostic.
76627662
SourceLocation ThisLoc;
7663-
if (getLangOpts().CPlusPlus && Tok.is(tok::kw_this))
7663+
if (getLangOpts().CPlusPlus && Tok.is(tok::kw_this)) {
76647664
ThisLoc = ConsumeToken();
7665+
// C++23 [dcl.fct]p6:
7666+
// An explicit-object-parameter-declaration is a parameter-declaration
7667+
// with a this specifier. An explicit-object-parameter-declaration
7668+
// shall appear only as the first parameter-declaration of a
7669+
// parameter-declaration-list of either:
7670+
// - a member-declarator that declares a member function, or
7671+
// - a lambda-declarator.
7672+
//
7673+
// The parameter-declaration-list of a requires-expression is not such
7674+
// a context.
7675+
if (DeclaratorCtx == DeclaratorContext::RequiresExpr)
7676+
Diag(ThisLoc, diag::err_requires_expr_explicit_object_parameter);
7677+
}
76657678

76667679
ParseDeclarationSpecifiers(DS, /*TemplateInfo=*/ParsedTemplateInfo(),
76677680
AS_none, DeclSpecContext::DSC_normal,
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
// RUN: %clang_cc1 -std=c++23 -fsyntax-only -verify %s
2+
3+
auto x0 = requires (this int) { true; }; // expected-error {{a requires expression cannot have an explicit object parameter}}
4+
auto x1 = requires (int, this int) { true; }; // expected-error {{a requires expression cannot have an explicit object parameter}}
5+
6+
template<this auto> // expected-error {{expected template parameter}}
7+
void f(); // expected-error {{no function template matches function template specialization 'f'}}

0 commit comments

Comments
 (0)