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

via cfe-commits cfe-commits at lists.llvm.org
Tue Sep 24 09:56:36 PDT 2024


https://github.com/c8ef created https://github.com/llvm/llvm-project/pull/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.

>From 9c112e7f88be2fc71f33ce4332d2ea500e479963 Mon Sep 17 00:00:00 2001
From: c8ef <c8ef at outlook.com>
Date: Tue, 24 Sep 2024 16:48:39 +0000
Subject: [PATCH 1/2] require void

---
 clang/lib/Sema/SemaExprCXX.cpp                    | 11 +++++++++++
 .../invalid-requirement-requires-parameter.cpp    | 15 +++++++++++++++
 2 files changed, 26 insertions(+)
 create mode 100644 clang/test/SemaCXX/invalid-requirement-requires-parameter.cpp

diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp
index ac3fe6ab8f9bd0..2dc7f46837f6d1 100644
--- a/clang/lib/Sema/SemaExprCXX.cpp
+++ b/clang/lib/Sema/SemaExprCXX.cpp
@@ -9509,6 +9509,17 @@ 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);
+      } else if (Param->getIdentifier()) {
+        Diag(Param->getBeginLoc(), diag::err_param_with_void_type);
+      } else if (Param->getType().hasQualifiers()) {
+        Diag(Param->getBeginLoc(), diag::err_void_param_qualified);
+        Body->setInvalidDecl();
+      }
+    }
+
     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/SemaCXX/invalid-requirement-requires-parameter.cpp b/clang/test/SemaCXX/invalid-requirement-requires-parameter.cpp
new file mode 100644
index 00000000000000..01aa0ca4d229b5
--- /dev/null
+++ b/clang/test/SemaCXX/invalid-requirement-requires-parameter.cpp
@@ -0,0 +1,15 @@
+// RUN: %clang -fsyntax-only -std=c++2a -Xclang -verify %s
+
+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

>From 8206940c634a3f32d273c75d499fdc4beb683e88 Mon Sep 17 00:00:00 2001
From: c8ef <c8ef at outlook.com>
Date: Tue, 24 Sep 2024 16:52:05 +0000
Subject: [PATCH 2/2] fix

---
 clang/lib/Sema/SemaExprCXX.cpp | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp
index 2dc7f46837f6d1..d0914d990be6a7 100644
--- a/clang/lib/Sema/SemaExprCXX.cpp
+++ b/clang/lib/Sema/SemaExprCXX.cpp
@@ -9512,8 +9512,10 @@ Sema::ActOnStartRequiresExpr(SourceLocation RequiresKWLoc,
     if (Param->getType()->isVoidType()) {
       if (LocalParameters.size() > 1) {
         Diag(Param->getBeginLoc(), diag::err_void_only_param);
+        Body->setInvalidDecl();
       } else if (Param->getIdentifier()) {
         Diag(Param->getBeginLoc(), diag::err_param_with_void_type);
+        Body->setInvalidDecl();
       } else if (Param->getType().hasQualifiers()) {
         Diag(Param->getBeginLoc(), diag::err_void_param_qualified);
         Body->setInvalidDecl();



More information about the cfe-commits mailing list