https://github.com/tbaederr updated 
https://github.com/llvm/llvm-project/pull/229761

>From 3700d860ccfe6e00b0f0607a9a6e73b24367e3fc Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Timm=20B=C3=A4der?= <[email protected]>
Date: Wed, 7 Oct 2026 13:56:06 +0200
Subject: [PATCH] ConstantExpr

---
 clang/include/clang/AST/Expr.h      |   4 +-
 clang/lib/CodeGen/CGStmt.cpp        |  20 ++---
 clang/lib/Sema/SemaChecking.cpp     |   2 +-
 clang/lib/Sema/SemaExpr.cpp         |  16 ++--
 clang/lib/Sema/SemaStmtAsm.cpp      |   5 +-
 clang/test/AST/ast-dump-stmt-json.c | 130 +++-------------------------
 clang/test/AST/ast-dump-stmt.c      |  26 +++---
 7 files changed, 41 insertions(+), 162 deletions(-)

diff --git a/clang/include/clang/AST/Expr.h b/clang/include/clang/AST/Expr.h
index d77efd9bea6058..b28b9a7a27019a 100644
--- a/clang/include/clang/AST/Expr.h
+++ b/clang/include/clang/AST/Expr.h
@@ -1120,8 +1120,8 @@ class FullExpr : public Expr {
 /// Describes the kind of result that can be tail-allocated.
 enum class ConstantResultStorageKind { None, Int64, APValue };
 
-/// ConstantExpr - An expression that occurs in a constant context and
-/// optionally the result of evaluating the expression.
+/// An expression that occurs in a constant context and
+/// the result of evaluating the expression.
 class ConstantExpr final
     : public FullExpr,
       private llvm::TrailingObjects<ConstantExpr, APValue, uint64_t> {
diff --git a/clang/lib/CodeGen/CGStmt.cpp b/clang/lib/CodeGen/CGStmt.cpp
index 42bbbf88a3f07b..01b0b8cd191de2 100644
--- a/clang/lib/CodeGen/CGStmt.cpp
+++ b/clang/lib/CodeGen/CGStmt.cpp
@@ -1848,18 +1848,14 @@ void CodeGenFunction::EmitCaseStmt(const CaseStmt &S,
     Builder.getInt(S.getLHS()->EvaluateKnownConstInt(getContext()));
 
   // Emit debuginfo for the case value if it is an enum value.
-  const ConstantExpr *CE;
-  if (auto ICE = dyn_cast<ImplicitCastExpr>(S.getLHS()))
-    CE = dyn_cast<ConstantExpr>(ICE->getSubExpr());
-  else
-    CE = dyn_cast<ConstantExpr>(S.getLHS());
-  if (CE) {
-    if (auto DE = dyn_cast<DeclRefExpr>(CE->getSubExpr()))
-      if (CGDebugInfo *Dbg = getDebugInfo())
-        if (CGM.getCodeGenOpts().hasReducedDebugInfo())
-          Dbg->EmitGlobalVariable(DE->getDecl(),
-              APValue(llvm::APSInt(CaseVal->getValue())));
-  }
+  // Look through implicit casts and check the subexpression of ConstantExpr.
+  const auto *CE = dyn_cast<ConstantExpr>(S.getLHS()->IgnoreImpCasts());
+  const Expr *SubExpr = CE ? CE->getSubExpr() : S.getLHS()->IgnoreImpCasts();
+  if (const auto *DRE = dyn_cast<DeclRefExpr>(SubExpr))
+    if (CGDebugInfo *Dbg = getDebugInfo())
+      if (CGM.getCodeGenOpts().hasReducedDebugInfo())
+        Dbg->EmitGlobalVariable(DRE->getDecl(),
+                                APValue(llvm::APSInt(CaseVal->getValue())));
 
   if (SwitchLikelihood)
     SwitchLikelihood->push_back(Stmt::getLikelihood(Attrs));
diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp
index 675975168e5048..cbadd5cf6fb0c0 100644
--- a/clang/lib/Sema/SemaChecking.cpp
+++ b/clang/lib/Sema/SemaChecking.cpp
@@ -15696,7 +15696,7 @@ void Sema::CheckCompletedExpr(Expr *E, SourceLocation 
CheckLoc,
   CheckImplicitConversions(E, CheckLoc);
   if (!E->isInstantiationDependent())
     CheckUnsequencedOperations(E);
-  if (!IsConstexpr && !E->isValueDependent())
+  if (!IsConstexpr && !E->isValueDependent() && !isa<ConstantExpr>(E))
     CheckForIntOverflow(E);
 }
 
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index 43b0c86132172b..00dd8acf1f68dd 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -7734,12 +7734,12 @@ Sema::BuildCompoundLiteralExpr(SourceLocation 
LParenLoc, TypeSourceInfo *TInfo,
     // constant context.
     auto CheckElement = [&](Expr *Init) -> Expr * {
       if (Init->isTypeDependent() || Init->isValueDependent())
-        return ConstantExpr::Create(Context, Init);
+        return Init;
       if (DeferImmediate) {
         ImmediateCallVisitor V(Context);
         V.TraverseStmt(Init);
         if (V.HasImmediateCalls)
-          return ConstantExpr::Create(Context, Init);
+          return Init;
       }
       Expr::EvalResult Eval;
       if (!Init->EvaluateAsConstantExpr(Eval, Context,
@@ -18381,12 +18381,14 @@ Sema::VerifyIntegerConstantExpression(Expr *E, 
llvm::APSInt *Result,
   // Circumvent ICE checking in C++11 to avoid evaluating the expression twice
   // in the non-ICE case.
   if (!getLangOpts().CPlusPlus11 && E->isIntegerConstantExpr(Context)) {
+
+    if (!Result)
+      return E;
+
     SmallVector<PartialDiagnosticAt, 8> Notes;
-    if (Result)
-      *Result = E->EvaluateKnownConstIntCheckOverflow(Context, &Notes);
+    *Result = E->EvaluateKnownConstIntCheckOverflow(Context, &Notes);
     if (!isa<ConstantExpr>(E))
-      E = Result ? ConstantExpr::Create(Context, E, APValue(*Result))
-                 : ConstantExpr::Create(Context, E);
+      E = ConstantExpr::Create(Context, E, APValue(*Result));
 
     if (Notes.empty())
       return E;
@@ -18433,7 +18435,7 @@ Sema::VerifyIntegerConstantExpression(Expr *E, 
llvm::APSInt *Result,
       EvalResult.Val.isInt() && !EvalResult.HasSideEffects &&
       (!getLangOpts().CPlusPlus || !EvalResult.HasUndefinedBehavior);
 
-  if (!isa<ConstantExpr>(E))
+  if (Folded && !isa<ConstantExpr>(E))
     E = ConstantExpr::Create(Context, E, EvalResult.Val);
 
   // For -fms-compatibility mode we relax some requirements
diff --git a/clang/lib/Sema/SemaStmtAsm.cpp b/clang/lib/Sema/SemaStmtAsm.cpp
index 6bf12d9cd98da7..bf460ebe75ef10 100644
--- a/clang/lib/Sema/SemaStmtAsm.cpp
+++ b/clang/lib/Sema/SemaStmtAsm.cpp
@@ -260,10 +260,7 @@ ExprResult Sema::ActOnGCCAsmStmtString(Expr *Expr, bool 
ForAsmLabel) {
     Diag(Expr->getBeginLoc(), diag::err_asm_operand_empty_string);
   }
 
-  ConstantExpr *Res = ConstantExpr::Create(getASTContext(), Expr,
-                                           ConstantResultStorageKind::APValue);
-  Res->SetResult(V, getASTContext());
-  return Res;
+  return ConstantExpr::Create(getASTContext(), Expr, V);
 }
 
 StmtResult Sema::ActOnGCCAsmStmt(SourceLocation AsmLoc, bool IsSimple,
diff --git a/clang/test/AST/ast-dump-stmt-json.c 
b/clang/test/AST/ast-dump-stmt-json.c
index a7f5648b8075fd..97e3981afa3c4d 100644
--- a/clang/test/AST/ast-dump-stmt-json.c
+++ b/clang/test/AST/ast-dump-stmt-json.c
@@ -2470,7 +2470,7 @@ void TestVLA(int n) {
 // CHECK-NEXT:        "inner": [
 // CHECK-NEXT:         {
 // CHECK-NEXT:          "id": "0x{{.*}}",
-// CHECK-NEXT:          "kind": "ConstantExpr",
+// CHECK-NEXT:          "kind": "IntegerLiteral",
 // CHECK-NEXT:          "range": {
 // CHECK-NEXT:           "begin": {
 // CHECK-NEXT:            "offset": {{[0-9]+}},
@@ -2488,29 +2488,7 @@ void TestVLA(int n) {
 // CHECK-NEXT:           "qualType": "int"
 // CHECK-NEXT:          },
 // CHECK-NEXT:          "valueCategory": "prvalue",
-// CHECK-NEXT:          "inner": [
-// CHECK-NEXT:           {
-// CHECK-NEXT:            "id": "0x{{.*}}",
-// CHECK-NEXT:            "kind": "IntegerLiteral",
-// CHECK-NEXT:            "range": {
-// CHECK-NEXT:             "begin": {
-// CHECK-NEXT:              "offset": {{[0-9]+}},
-// CHECK-NEXT:              "col": 8,
-// CHECK-NEXT:              "tokLen": 1
-// CHECK-NEXT:             },
-// CHECK-NEXT:             "end": {
-// CHECK-NEXT:              "offset": {{[0-9]+}},
-// CHECK-NEXT:              "col": 8,
-// CHECK-NEXT:              "tokLen": 1
-// CHECK-NEXT:             }
-// CHECK-NEXT:            },
-// CHECK-NEXT:            "type": {
-// CHECK-NEXT:             "qualType": "int"
-// CHECK-NEXT:            },
-// CHECK-NEXT:            "valueCategory": "prvalue",
-// CHECK-NEXT:            "value": "0"
-// CHECK-NEXT:           }
-// CHECK-NEXT:          ]
+// CHECK-NEXT:          "value": "0"
 // CHECK-NEXT:         },
 // CHECK-NEXT:         {
 // CHECK-NEXT:          "id": "0x{{.*}}",
@@ -2551,7 +2529,7 @@ void TestVLA(int n) {
 // CHECK-NEXT:        "inner": [
 // CHECK-NEXT:         {
 // CHECK-NEXT:          "id": "0x{{.*}}",
-// CHECK-NEXT:          "kind": "ConstantExpr",
+// CHECK-NEXT:          "kind": "IntegerLiteral",
 // CHECK-NEXT:          "range": {
 // CHECK-NEXT:           "begin": {
 // CHECK-NEXT:            "offset": {{[0-9]+}},
@@ -2569,29 +2547,7 @@ void TestVLA(int n) {
 // CHECK-NEXT:           "qualType": "int"
 // CHECK-NEXT:          },
 // CHECK-NEXT:          "valueCategory": "prvalue",
-// CHECK-NEXT:          "inner": [
-// CHECK-NEXT:           {
-// CHECK-NEXT:            "id": "0x{{.*}}",
-// CHECK-NEXT:            "kind": "IntegerLiteral",
-// CHECK-NEXT:            "range": {
-// CHECK-NEXT:             "begin": {
-// CHECK-NEXT:              "offset": {{[0-9]+}},
-// CHECK-NEXT:              "col": 8,
-// CHECK-NEXT:              "tokLen": 1
-// CHECK-NEXT:             },
-// CHECK-NEXT:             "end": {
-// CHECK-NEXT:              "offset": {{[0-9]+}},
-// CHECK-NEXT:              "col": 8,
-// CHECK-NEXT:              "tokLen": 1
-// CHECK-NEXT:             }
-// CHECK-NEXT:            },
-// CHECK-NEXT:            "type": {
-// CHECK-NEXT:             "qualType": "int"
-// CHECK-NEXT:            },
-// CHECK-NEXT:            "valueCategory": "prvalue",
-// CHECK-NEXT:            "value": "1"
-// CHECK-NEXT:           }
-// CHECK-NEXT:          ]
+// CHECK-NEXT:          "value": "1"
 // CHECK-NEXT:         },
 // CHECK-NEXT:         {
 // CHECK-NEXT:          "id": "0x{{.*}}",
@@ -2613,7 +2569,7 @@ void TestVLA(int n) {
 // CHECK-NEXT:          "inner": [
 // CHECK-NEXT:           {
 // CHECK-NEXT:            "id": "0x{{.*}}",
-// CHECK-NEXT:            "kind": "ConstantExpr",
+// CHECK-NEXT:            "kind": "IntegerLiteral",
 // CHECK-NEXT:            "range": {
 // CHECK-NEXT:             "begin": {
 // CHECK-NEXT:              "offset": {{[0-9]+}},
@@ -2631,29 +2587,7 @@ void TestVLA(int n) {
 // CHECK-NEXT:             "qualType": "int"
 // CHECK-NEXT:            },
 // CHECK-NEXT:            "valueCategory": "prvalue",
-// CHECK-NEXT:            "inner": [
-// CHECK-NEXT:             {
-// CHECK-NEXT:              "id": "0x{{.*}}",
-// CHECK-NEXT:              "kind": "IntegerLiteral",
-// CHECK-NEXT:              "range": {
-// CHECK-NEXT:               "begin": {
-// CHECK-NEXT:                "offset": {{[0-9]+}},
-// CHECK-NEXT:                "col": 8,
-// CHECK-NEXT:                "tokLen": 1
-// CHECK-NEXT:               },
-// CHECK-NEXT:               "end": {
-// CHECK-NEXT:                "offset": {{[0-9]+}},
-// CHECK-NEXT:                "col": 8,
-// CHECK-NEXT:                "tokLen": 1
-// CHECK-NEXT:               }
-// CHECK-NEXT:              },
-// CHECK-NEXT:              "type": {
-// CHECK-NEXT:               "qualType": "int"
-// CHECK-NEXT:              },
-// CHECK-NEXT:              "valueCategory": "prvalue",
-// CHECK-NEXT:              "value": "2"
-// CHECK-NEXT:             }
-// CHECK-NEXT:            ]
+// CHECK-NEXT:            "value": "2"
 // CHECK-NEXT:           },
 // CHECK-NEXT:           {
 // CHECK-NEXT:            "id": "0x{{.*}}",
@@ -2733,7 +2667,7 @@ void TestVLA(int n) {
 // CHECK-NEXT:        "inner": [
 // CHECK-NEXT:         {
 // CHECK-NEXT:          "id": "0x{{.*}}",
-// CHECK-NEXT:          "kind": "ConstantExpr",
+// CHECK-NEXT:          "kind": "IntegerLiteral",
 // CHECK-NEXT:          "range": {
 // CHECK-NEXT:           "begin": {
 // CHECK-NEXT:            "offset": {{[0-9]+}},
@@ -2751,33 +2685,11 @@ void TestVLA(int n) {
 // CHECK-NEXT:           "qualType": "int"
 // CHECK-NEXT:          },
 // CHECK-NEXT:          "valueCategory": "prvalue",
-// CHECK-NEXT:          "inner": [
-// CHECK-NEXT:           {
-// CHECK-NEXT:            "id": "0x{{.*}}",
-// CHECK-NEXT:            "kind": "IntegerLiteral",
-// CHECK-NEXT:            "range": {
-// CHECK-NEXT:             "begin": {
-// CHECK-NEXT:              "offset": {{[0-9]+}},
-// CHECK-NEXT:              "col": 8,
-// CHECK-NEXT:              "tokLen": 1
-// CHECK-NEXT:             },
-// CHECK-NEXT:             "end": {
-// CHECK-NEXT:              "offset": {{[0-9]+}},
-// CHECK-NEXT:              "col": 8,
-// CHECK-NEXT:              "tokLen": 1
-// CHECK-NEXT:             }
-// CHECK-NEXT:            },
-// CHECK-NEXT:            "type": {
-// CHECK-NEXT:             "qualType": "int"
-// CHECK-NEXT:            },
-// CHECK-NEXT:            "valueCategory": "prvalue",
-// CHECK-NEXT:            "value": "3"
-// CHECK-NEXT:           }
-// CHECK-NEXT:          ]
+// CHECK-NEXT:          "value": "3"
 // CHECK-NEXT:         },
 // CHECK-NEXT:         {
 // CHECK-NEXT:          "id": "0x{{.*}}",
-// CHECK-NEXT:          "kind": "ConstantExpr",
+// CHECK-NEXT:          "kind": "IntegerLiteral",
 // CHECK-NEXT:          "range": {
 // CHECK-NEXT:           "begin": {
 // CHECK-NEXT:            "offset": {{[0-9]+}},
@@ -2794,29 +2706,7 @@ void TestVLA(int n) {
 // CHECK-NEXT:           "qualType": "int"
 // CHECK-NEXT:          },
 // CHECK-NEXT:          "valueCategory": "prvalue",
-// CHECK-NEXT:          "inner": [
-// CHECK-NEXT:           {
-// CHECK-NEXT:            "id": "0x{{.*}}",
-// CHECK-NEXT:            "kind": "IntegerLiteral",
-// CHECK-NEXT:            "range": {
-// CHECK-NEXT:             "begin": {
-// CHECK-NEXT:              "offset": {{[0-9]+}},
-// CHECK-NEXT:              "col": 14,
-// CHECK-NEXT:              "tokLen": 1
-// CHECK-NEXT:             },
-// CHECK-NEXT:             "end": {
-// CHECK-NEXT:              "offset": {{[0-9]+}},
-// CHECK-NEXT:              "col": 14,
-// CHECK-NEXT:              "tokLen": 1
-// CHECK-NEXT:             }
-// CHECK-NEXT:            },
-// CHECK-NEXT:            "type": {
-// CHECK-NEXT:             "qualType": "int"
-// CHECK-NEXT:            },
-// CHECK-NEXT:            "valueCategory": "prvalue",
-// CHECK-NEXT:            "value": "5"
-// CHECK-NEXT:           }
-// CHECK-NEXT:          ]
+// CHECK-NEXT:          "value": "5"
 // CHECK-NEXT:         },
 // CHECK-NEXT:         {
 // CHECK-NEXT:          "id": "0x{{.*}}",
diff --git a/clang/test/AST/ast-dump-stmt.c b/clang/test/AST/ast-dump-stmt.c
index 6fb01a4b159fa1..406f702b51fa75 100644
--- a/clang/test/AST/ast-dump-stmt.c
+++ b/clang/test/AST/ast-dump-stmt.c
@@ -169,26 +169,23 @@ void TestLabelsAndGoto(void) {
 
 void TestSwitch(int i) {
   switch (i) {
-  // CHECK: SwitchStmt 0x{{[^ ]*}} <line:[[@LINE-1]]:3, line:[[@LINE+37]]:3>
+  // CHECK: SwitchStmt 0x{{[^ ]*}} <line:[[@LINE-1]]:3, line:[[@LINE+31]]:3>
   // CHECK-NEXT: ImplicitCastExpr
   // CHECK-NEXT: DeclRefExpr 0x{{[^ ]*}} <col:11> 'int' lvalue ParmVar 0x{{[^ 
]*}} 'i' 'int'
-  // CHECK-NEXT: CompoundStmt 0x{{[^ ]*}} <col:14, line:[[@LINE+34]]:3>
+  // CHECK-NEXT: CompoundStmt 0x{{[^ ]*}} <col:14, line:[[@LINE+28]]:3>
   case 0:
     break;
   // CHECK-NEXT: CaseStmt 0x{{[^ ]*}} <line:[[@LINE-2]]:3, line:[[@LINE-1]]:5>
-  // CHECK-NEXT: ConstantExpr
-  // CHECK-NEXT: IntegerLiteral 0x{{[^ ]*}} <col:8> 'int' 0
-  // CHECK-NEXT: BreakStmt 0x{{[^ ]*}} <line:[[@LINE-4]]:5>
+  // CHECK-NEXT: IntegerLiteral 0x{{[^ ]*}} <line:[[@LINE-3]]:8> 'int' 0
+  // CHECK-NEXT: BreakStmt 0x{{[^ ]*}} <line:[[@LINE-3]]:5>
   case 1:
   case 2:
     break;
   // CHECK-NEXT: CaseStmt 0x{{[^ ]*}} <line:[[@LINE-3]]:3, line:[[@LINE-1]]:5>
-  // CHECK-NEXT: ConstantExpr
-  // CHECK-NEXT: IntegerLiteral 0x{{[^ ]*}} <col:8> 'int' 1
-  // CHECK-NEXT: CaseStmt 0x{{[^ ]*}} <line:[[@LINE-5]]:3, line:[[@LINE-4]]:5>
-  // CHECK-NEXT: ConstantExpr
-  // CHECK-NEXT: IntegerLiteral 0x{{[^ ]*}} <col:8> 'int' 2
-  // CHECK-NEXT: BreakStmt 0x{{[^ ]*}} <line:[[@LINE-7]]:5>
+  // CHECK-NEXT: IntegerLiteral 0x{{[^ ]*}} <line:[[@LINE-4]]:8> 'int' 1
+  // CHECK-NEXT: CaseStmt 0x{{[^ ]*}} <line:[[@LINE-4]]:3, line:[[@LINE-3]]:5>
+  // CHECK-NEXT: IntegerLiteral 0x{{[^ ]*}} <line:[[@LINE-5]]:8> 'int' 2
+  // CHECK-NEXT: BreakStmt 0x{{[^ ]*}} <line:[[@LINE-5]]:5>
   default:
     break;
   // CHECK-NEXT: DefaultStmt 0x{{[^ ]*}} <line:[[@LINE-2]]:3, 
line:[[@LINE-1]]:5>
@@ -196,14 +193,11 @@ void TestSwitch(int i) {
   case 3 ... 5:
     break;
   // CHECK-NEXT: CaseStmt 0x{{[^ ]*}} <line:[[@LINE-2]]:3, line:[[@LINE-1]]:5> 
gnu_range
-  // CHECK-NEXT: ConstantExpr
-  // CHECK-NEXT: IntegerLiteral 0x{{[^ ]*}} <col:8> 'int' 3
-  // CHECK-NEXT: ConstantExpr
+  // CHECK-NEXT: IntegerLiteral 0x{{[^ ]*}} <line:[[@LINE-3]]:8> 'int' 3
   // CHECK-NEXT: IntegerLiteral 0x{{[^ ]*}} <col:14> 'int' 5
-  // CHECK-NEXT: BreakStmt 0x{{[^ ]*}} <line:[[@LINE-6]]:5>
+  // CHECK-NEXT: BreakStmt 0x{{[^ ]*}} <line:[[@LINE-4]]:5>
   case 6:
   // CHECK-NEXT: CaseStmt 0x{{[^ ]*}} <line:[[@LINE-1]]:3, col:9>
-  // CHECK-NEXT: ConstantExpr
   // CHECK-NEXT: IntegerLiteral 0x{{[^ ]*}} <col:8> 'int' 6
   // CHECK-NEXT: NullStmt 0x{{[^ ]*}} <col:9>
   }

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

Reply via email to