https://github.com/naveen-seth updated https://github.com/llvm/llvm-project/pull/166762
>From a774b14ab581542bb599c88faf96d4ac6e970798 Mon Sep 17 00:00:00 2001 From: naveen-seth <[email protected]> Date: Thu, 6 Nov 2025 12:59:51 +0100 Subject: [PATCH] [clang][AST] Fix crash in constevaluated switch case statements Fixes #166328. Fixes a crash that occurs when constevaluating a function in a switch case with a missing non-type template parameter. This change guards against calling EvaluateKnownConstInt on value-dependent expressions in switch cases. --- clang/lib/AST/ExprConstant.cpp | 13 +++++--- .../crash-constexpr-dependent-switch-case.cpp | 31 +++++++++++++++++++ 2 files changed, 40 insertions(+), 4 deletions(-) create mode 100644 clang/test/AST/crash-constexpr-dependent-switch-case.cpp diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp index 8fab6efafb983..5320031f585e7 100644 --- a/clang/lib/AST/ExprConstant.cpp +++ b/clang/lib/AST/ExprConstant.cpp @@ -5452,10 +5452,15 @@ static EvalStmtResult EvaluateSwitch(StmtResult &Result, EvalInfo &Info, } const CaseStmt *CS = cast<CaseStmt>(SC); - APSInt LHS = CS->getLHS()->EvaluateKnownConstInt(Info.Ctx); - APSInt RHS = CS->getRHS() ? CS->getRHS()->EvaluateKnownConstInt(Info.Ctx) - : LHS; - if (LHS <= Value && Value <= RHS) { + const Expr *LHSExpr = CS->getLHS(); + const Expr *RHSExpr = CS->getLHS(); + if (LHSExpr->isValueDependent() || (RHSExpr && RHSExpr->isValueDependent())) + return ESR_Failed; + + APSInt LHSValue = LHSExpr->EvaluateKnownConstInt(Info.Ctx); + APSInt RHSValue = + RHSExpr ? RHSExpr->EvaluateKnownConstInt(Info.Ctx) : LHSValue; + if (LHSValue <= Value && Value <= RHSValue) { Found = SC; break; } diff --git a/clang/test/AST/crash-constexpr-dependent-switch-case.cpp b/clang/test/AST/crash-constexpr-dependent-switch-case.cpp new file mode 100644 index 0000000000000..68a62160a2e78 --- /dev/null +++ b/clang/test/AST/crash-constexpr-dependent-switch-case.cpp @@ -0,0 +1,31 @@ +// Fixes #166328 +// RUN: %clang_cc1 -std=c++14 -fsyntax-only -verify= %s + +// This function requires a non-type template argument, but we'll +// intentionally misuse it by omitting the argument. +// This should trigger an error, but must not crash the compiler when +// used in a compile-time evaluated switch case statement. +template<int n> +constexpr int nonTypeTemplateParamFunc() { // expected-note 5 {{candidate template ignored: couldn't infer template argument 'n'}} + return n; +} + +constexpr int switchWithErrs(int n) { + switch (n) { + case int(nonTypeTemplateParamFunc()): // expected-error {{no matching function for call to 'nonTypeTemplateParamFunc'}} + return n; + // GNU Case ranges (Extension) + case 0 ... int(nonTypeTemplateParamFunc()): // expected-error {{no matching function for call to 'nonTypeTemplateParamFunc'}} + return n; + case nonTypeTemplateParamFunc() ... 100: // expected-error {{no matching function for call to 'nonTypeTemplateParamFunc'}} + return n + 1; + case nonTypeTemplateParamFunc() ... nonTypeTemplateParamFunc(): // expected-error 2 {{no matching function for call to 'nonTypeTemplateParamFunc'}} + return n + 2; + default: + return 0; + } +} + +auto main() -> int { + constexpr auto num = switchWithErrs(1); // expected-error {{constexpr variable 'num' must be initialized by a constant expression}} +} _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
