[clang] bb78a0b - [clang] Fix the local parameter of void type inside the `Requires` expression. (#109831)

via cfe-commits cfe-commits at lists.llvm.org
Tue Oct 1 06:39:14 PDT 2024


Author: c8ef
Date: 2024-10-01T06:39:10-07:00
New Revision: bb78a0b33496fb0140cec1a92a689505f53253b7

URL: https://github.com/llvm/llvm-project/commit/bb78a0b33496fb0140cec1a92a689505f53253b7
DIFF: https://github.com/llvm/llvm-project/commit/bb78a0b33496fb0140cec1a92a689505f53253b7.diff

LOG: [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.

Added: 
    

Modified: 
    clang/docs/ReleaseNotes.rst
    clang/lib/Sema/SemaExprCXX.cpp
    clang/test/CXX/expr/expr.prim/expr.prim.req/requires-expr.cpp

Removed: 
    


################################################################################
diff  --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index a55a3b8687e46e..7e64134f7eb199 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -362,6 +362,8 @@ Improvements to Clang's diagnostics
 
 - Clang now diagnoses cases where a dangling ``GSLOwner<GSLPointer>`` object is constructed, e.g. ``std::vector<string_view> v = {std::string()};`` (#GH100526).
 
+- Clang now diagnoses when a ``requires`` expression has a local parameter of void type, aligning with the function parameter (#GH109831).
+
 Improvements to Clang's time-trace
 ----------------------------------
 

diff  --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp
index ac3fe6ab8f9bd0..b30414a8a8277a 100644
--- a/clang/lib/Sema/SemaExprCXX.cpp
+++ b/clang/lib/Sema/SemaExprCXX.cpp
@@ -9509,6 +9509,18 @@ Sema::ActOnStartRequiresExpr(SourceLocation RequiresKWLoc,
   PushDeclContext(BodyScope, Body);
 
   for (ParmVarDecl *Param : LocalParameters) {
+    if (Param->getType()->isVoidType()) {
+      if (LocalParameters.size() > 1) {
+        Diag(Param->getBeginLoc(), diag::err_void_only_param);
+        Param->setType(Context.IntTy);
+      } else if (Param->getIdentifier()) {
+        Diag(Param->getBeginLoc(), diag::err_param_with_void_type);
+        Param->setType(Context.IntTy);
+      } else if (Param->getType().hasQualifiers()) {
+        Diag(Param->getBeginLoc(), diag::err_void_param_qualified);
+      }
+    }
+
     if (Param->hasDefaultArg())
       // C++2a [expr.prim.req] p4
       //     [...] A local parameter of a requires-expression shall not have a

diff  --git a/clang/test/CXX/expr/expr.prim/expr.prim.req/requires-expr.cpp b/clang/test/CXX/expr/expr.prim/expr.prim.req/requires-expr.cpp
index 90a38292d15d35..09f8f36d3c5baa 100644
--- a/clang/test/CXX/expr/expr.prim/expr.prim.req/requires-expr.cpp
+++ b/clang/test/CXX/expr/expr.prim/expr.prim.req/requires-expr.cpp
@@ -65,4 +65,18 @@ template<typename T> requires requires { T::value; S<T>::s; }
 struct r4 { };
 
 using r4i = r4<int>;
-// expected-error at -1 {{constraints not satisfied for class template 'r4' [with T = int]}}
\ No newline at end of file
+// expected-error at -1 {{constraints not satisfied for class template 'r4' [with T = int]}}
+
+namespace GH109538 {
+static_assert(requires(void *t) { t; });
+static_assert(requires(void) { 42; });
+static_assert(requires(void t) { // expected-error {{argument may not have 'void' type}}
+  t;
+});
+static_assert(requires(void t, int a) {  // expected-error {{'void' must be the first and only parameter if specified}}
+  t;
+});
+static_assert(requires(const void) { // expected-error {{'void' as parameter must not have type qualifiers}}
+  42;
+});
+} // namespace GH109538


        


More information about the cfe-commits mailing list