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
