Skip to content

Commit bb78a0b

Browse files
authored
[clang] Fix the local parameter of void type inside the Requires expression. (#109831)
Fixes #109538. In this patch, we introduce diagnostic for required expression parameters in the same way as function parameters, fix the issue of handling void type parameters, and align the behavior with GCC and other compilers.
1 parent be6b4f6 commit bb78a0b

File tree

3 files changed

+29
-1
lines changed

3 files changed

+29
-1
lines changed

clang/docs/ReleaseNotes.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -362,6 +362,8 @@ Improvements to Clang's diagnostics
362362

363363
- Clang now diagnoses cases where a dangling ``GSLOwner<GSLPointer>`` object is constructed, e.g. ``std::vector<string_view> v = {std::string()};`` (#GH100526).
364364

365+
- Clang now diagnoses when a ``requires`` expression has a local parameter of void type, aligning with the function parameter (#GH109831).
366+
365367
Improvements to Clang's time-trace
366368
----------------------------------
367369

clang/lib/Sema/SemaExprCXX.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9509,6 +9509,18 @@ Sema::ActOnStartRequiresExpr(SourceLocation RequiresKWLoc,
95099509
PushDeclContext(BodyScope, Body);
95109510

95119511
for (ParmVarDecl *Param : LocalParameters) {
9512+
if (Param->getType()->isVoidType()) {
9513+
if (LocalParameters.size() > 1) {
9514+
Diag(Param->getBeginLoc(), diag::err_void_only_param);
9515+
Param->setType(Context.IntTy);
9516+
} else if (Param->getIdentifier()) {
9517+
Diag(Param->getBeginLoc(), diag::err_param_with_void_type);
9518+
Param->setType(Context.IntTy);
9519+
} else if (Param->getType().hasQualifiers()) {
9520+
Diag(Param->getBeginLoc(), diag::err_void_param_qualified);
9521+
}
9522+
}
9523+
95129524
if (Param->hasDefaultArg())
95139525
// C++2a [expr.prim.req] p4
95149526
// [...] A local parameter of a requires-expression shall not have a

clang/test/CXX/expr/expr.prim/expr.prim.req/requires-expr.cpp

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,4 +65,18 @@ template<typename T> requires requires { T::value; S<T>::s; }
6565
struct r4 { };
6666

6767
using r4i = r4<int>;
68-
// expected-error@-1 {{constraints not satisfied for class template 'r4' [with T = int]}}
68+
// expected-error@-1 {{constraints not satisfied for class template 'r4' [with T = int]}}
69+
70+
namespace GH109538 {
71+
static_assert(requires(void *t) { t; });
72+
static_assert(requires(void) { 42; });
73+
static_assert(requires(void t) { // expected-error {{argument may not have 'void' type}}
74+
t;
75+
});
76+
static_assert(requires(void t, int a) { // expected-error {{'void' must be the first and only parameter if specified}}
77+
t;
78+
});
79+
static_assert(requires(const void) { // expected-error {{'void' as parameter must not have type qualifiers}}
80+
42;
81+
});
82+
} // namespace GH109538

0 commit comments

Comments
 (0)