Skip to content

Commit 9d72dc0

Browse files
c8efSterling-Augustine
authored andcommitted
[clang] Fix the local parameter of void type inside the Requires expression. (llvm#109831)
Fixes llvm#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 c6b3042 commit 9d72dc0

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)