https://github.com/llukito updated 
https://github.com/llvm/llvm-project/pull/179233

>From 6ab49ef74a8de1b59aadad09681cbe62c159e1f7 Mon Sep 17 00:00:00 2001
From: Luka Aladashvili <[email protected]>
Date: Mon, 2 Feb 2026 17:38:34 +0400
Subject: [PATCH 1/2] [clang][diagnostics] Refactor constexpr diagnostics to
 use enum_select

Replaces %select{function|constructor} with %enum_select to improve clarity and 
type safety.
---
 clang/include/clang/Basic/DiagnosticSemaKinds.td | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 807440c107897..4d55ef460c928 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -23,9 +23,9 @@ defm typename_outside_of_template : CXX11Compat<"'typename' 
outside of a templat
 
 // C++14 compatibility with C++11 and earlier.
 defm constexpr_type_definition : CXX14Compat<
-  "type definition in a constexpr %select{function|constructor}0 is">;
+  "type definition in a constexpr %enum_select<Function, Constructor>0 is">;
 defm constexpr_local_var : CXX14Compat<
-  "variable declaration in a constexpr %select{function|constructor}0 is">;
+  "variable declaration in a constexpr %enum_select<Function, Constructor>0 
is">;
 defm constexpr_body_multiple_return : CXX14Compat<
   "multiple return statements in constexpr function is">;
 defm variable_template : CXX14Compat<"variable templates are">;
@@ -38,9 +38,9 @@ defm inline_variable : CXX17Compat<"inline variables are">;
 defm decomp_decl_spec
     : CXX20Compat<"structured binding declaration declared '%0' is">;
 defm constexpr_local_var_no_init : CXX20Compat<
-  "uninitialized variable in a constexpr %select{function|constructor}0 is">;
+  "uninitialized variable in a constexpr %enum_select<Function, Constructor>0 
is">;
 defm constexpr_function_try_block : CXX20Compat<
-  "function try block in constexpr %select{function|constructor}0 is">;
+  "function try block in constexpr %enum_select<Function, Constructor>0 is">;
 defm constexpr_union_ctor_no_init : CXX20Compat<
   "constexpr union constructor that does not initialize any member is">;
 defm constexpr_ctor_missing_init : CXX20Compat<
@@ -56,7 +56,7 @@ defm implicit_typename
 // C++23 compatibility with C++20 and earlier.
 defm constexpr_static_var : CXX23Compat<
   "definition of a %select{static|thread_local}1 variable "
-  "in a constexpr %select{function|constructor}0 "
+  "in a constexpr %enum_select<Function, Constructor>0 "
   "is">;
 
 // C++26 compatibility with C++23 and earlier.
@@ -65,7 +65,7 @@ defm decomp_decl_cond : CXX26Compat<"structured binding 
declaration in a conditi
 // Compatibility warnings duplicated across multiple language versions.
 foreach std = [14, 20, 23] in {
   defm cxx#std#_constexpr_body_invalid_stmt : CXXCompat<
-    "use of this statement in a constexpr %select{function|constructor}0 is", 
std>;
+    "use of this statement in a constexpr %enum_select<Function, Constructor>0 
is", std>;
 }
 
 def note_previous_decl : Note<"%0 declared here">;

>From 71e1f6b3df0179dcebec2fc5fa1771fb7ae4be9c Mon Sep 17 00:00:00 2001
From: Luka Aladashvili <[email protected]>
Date: Mon, 2 Feb 2026 18:33:57 +0400
Subject: [PATCH 2/2] Fix constexpr indentation and logic

---
 clang/lib/Sema/SemaDeclCXX.cpp | 35 ++++++++++++++++++++++++----------
 1 file changed, 25 insertions(+), 10 deletions(-)

diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp
index 5837ecd6b9163..3b20a254c4a60 100644
--- a/clang/lib/Sema/SemaDeclCXX.cpp
+++ b/clang/lib/Sema/SemaDeclCXX.cpp
@@ -2073,33 +2073,39 @@ static bool CheckConstexprDeclStmt(Sema &SemaRef, const 
FunctionDecl *Dcl,
       //   thread storage duration or [before C++2a] for which no
       //   initialization is performed.
       const auto *VD = cast<VarDecl>(DclIt);
+
+      // Define the enum UP HERE so it is visible to all the checks below
+      enum { Function, Constructor };
+
       if (VD->isThisDeclarationADefinition()) {
         if (VD->isStaticLocal()) {
           if (Kind == Sema::CheckConstexprKind::Diagnose) {
             SemaRef.DiagCompat(VD->getLocation(),
                                diag_compat::constexpr_static_var)
-                << isa<CXXConstructorDecl>(Dcl)
+                << (isa<CXXConstructorDecl>(Dcl) ? Constructor : Function)
                 << (VD->getTLSKind() == VarDecl::TLS_Dynamic);
           } else if (!SemaRef.getLangOpts().CPlusPlus23) {
             return false;
           }
         }
+
         if (SemaRef.LangOpts.CPlusPlus23) {
           CheckLiteralType(SemaRef, Kind, VD->getLocation(), VD->getType(),
                            diag::warn_cxx20_compat_constexpr_var,
-                           isa<CXXConstructorDecl>(Dcl));
+                           isa<CXXConstructorDecl>(Dcl) ? Constructor
+                                                        : Function);
         } else if (CheckLiteralType(
                        SemaRef, Kind, VD->getLocation(), VD->getType(),
                        diag::err_constexpr_local_var_non_literal_type,
-                       isa<CXXConstructorDecl>(Dcl))) {
+                       isa<CXXConstructorDecl>(Dcl) ? Constructor : Function)) 
{
           return false;
         }
-        if (!VD->getType()->isDependentType() &&
-            !VD->hasInit() && !VD->isCXXForRangeDecl()) {
+        if (!VD->getType()->isDependentType() && !VD->hasInit() &&
+            !VD->isCXXForRangeDecl()) {
           if (Kind == Sema::CheckConstexprKind::Diagnose) {
             SemaRef.DiagCompat(VD->getLocation(),
                                diag_compat::constexpr_local_var_no_init)
-                << isa<CXXConstructorDecl>(Dcl);
+                << (isa<CXXConstructorDecl>(Dcl) ? Constructor : Function);
           } else if (!SemaRef.getLangOpts().CPlusPlus20) {
             return false;
           }
@@ -2108,7 +2114,7 @@ static bool CheckConstexprDeclStmt(Sema &SemaRef, const 
FunctionDecl *Dcl,
       }
       if (Kind == Sema::CheckConstexprKind::Diagnose) {
         SemaRef.DiagCompat(VD->getLocation(), diag_compat::constexpr_local_var)
-            << isa<CXXConstructorDecl>(Dcl);
+            << (isa<CXXConstructorDecl>(Dcl) ? Constructor : Function);
       } else if (!SemaRef.getLangOpts().CPlusPlus14) {
         return false;
       }
@@ -2382,6 +2388,10 @@ static bool CheckConstexprFunctionBody(Sema &SemaRef, 
const FunctionDecl *Dcl,
     //
     // This restriction is lifted in C++2a, as long as inner statements also
     // apply the general constexpr rules.
+    
+    // <--- START FIX
+    enum { Function, Constructor }; // Defined locally for this block
+
     switch (Kind) {
     case Sema::CheckConstexprKind::CheckValid:
       if (!SemaRef.getLangOpts().CPlusPlus20)
@@ -2391,11 +2401,12 @@ static bool CheckConstexprFunctionBody(Sema &SemaRef, 
const FunctionDecl *Dcl,
     case Sema::CheckConstexprKind::Diagnose:
       SemaRef.DiagCompat(Body->getBeginLoc(),
                          diag_compat::constexpr_function_try_block)
-          << isa<CXXConstructorDecl>(Dcl);
+          << (isa<CXXConstructorDecl>(Dcl) ? Constructor : Function);
       break;
     }
+    // <--- END FIX
   }
-
+    
   // - its function-body shall be [...] a compound-statement that contains only
   //   [... list of cases ...]
   //
@@ -2502,10 +2513,14 @@ static bool CheckConstexprFunctionBody(Sema &SemaRef, 
const FunctionDecl *Dcl,
         break;
       }
     } else if (ReturnStmts.size() > 1) {
+      // Define the enum locally again because the previous one is out of scope
+      enum { Function, Constructor };
+        
       switch (Kind) {
       case Sema::CheckConstexprKind::Diagnose:
         SemaRef.DiagCompat(ReturnStmts.back(),
-                           diag_compat::constexpr_body_multiple_return);
+                           diag_compat::constexpr_body_multiple_return)
+            << (isa<CXXConstructorDecl>(Dcl) ? Constructor : Function);
         for (unsigned I = 0; I < ReturnStmts.size() - 1; ++I)
           SemaRef.Diag(ReturnStmts[I],
                        diag::note_constexpr_body_previous_return);

_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to