[clang] [clang] Return early if a value dependent recovery init appeared in constant evaluation context in legacy constant evaluator (PR #225027)
via cfe-commits
cfe-commits at lists.llvm.org
Mon Sep 21 01:37:25 PDT 2026
llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-clang
Author: Yihan Wang (yronglin)
<details>
<summary>Changes</summary>
A recovery default member initializer can be value-dependent even when the expression referring to the variable is not. Clang should return early to avoid crash.
This fix the issue found in https://github.com/llvm/llvm-project/issues/185874#issuecomment-4058045596.
---
Full diff: https://github.com/llvm/llvm-project/pull/225027.diff
3 Files Affected:
- (modified) clang/docs/ReleaseNotes.md (+3)
- (modified) clang/lib/AST/ExprConstant.cpp (+5)
- (modified) clang/test/SemaCXX/recovery-expr-type.cpp (+10)
``````````diff
diff --git a/clang/docs/ReleaseNotes.md b/clang/docs/ReleaseNotes.md
index 7e3e8468914c7..025c332ceb831 100644
--- a/clang/docs/ReleaseNotes.md
+++ b/clang/docs/ReleaseNotes.md
@@ -673,6 +673,9 @@ features cannot lower the translation-unit ABI level;
using ``__is_constructible`` on a nested class template inside the definition
of the containing class. (#GH215166)
+- Fixed a crash issue when a value dependent recovery init appeared in constant
+ evaluation context in legacy constant evaluator.
+
- Fixed a bug where Clang incorrectly required `promise.return_value()` for a
dependent `co_return` operand that inits to `void`, instead of using
`promise.return_void()`. (#GH218368)
diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp
index 9242491832841..2f75e69e55aaf 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/lib/AST/ExprConstant.cpp
@@ -3520,6 +3520,11 @@ static bool evaluateVarDeclInit(EvalInfo &Info, const Expr *E,
// Used to be C++20 [expr.const]p5.12:
// ... reference has a preceding initialization and either ...
if (Init && Init->isValueDependent()) {
+ // A recovery initializer can be value-dependent even when the expression
+ // referring to the variable is not.
+ if (Init->containsErrors())
+ return false;
+
// The DeclRefExpr is not value-dependent, but the variable it refers to
// has a value-dependent initializer. This should only happen in
// constant-folding cases, where the variable is not actually of a suitable
diff --git a/clang/test/SemaCXX/recovery-expr-type.cpp b/clang/test/SemaCXX/recovery-expr-type.cpp
index bdab2940d6597..542a2fae5d849 100644
--- a/clang/test/SemaCXX/recovery-expr-type.cpp
+++ b/clang/test/SemaCXX/recovery-expr-type.cpp
@@ -199,3 +199,13 @@ template<int*> struct P;
S<P> s;
} // namespace GH202117
+namespace test17 {
+struct A { int arr[1]; };
+struct B {
+ static constexpr A &a = A{{0}}; // expected-error {{non-const lvalue reference to type 'A' cannot bind to a temporary of type 'A'}}
+};
+
+B x;
+
+int v = x.a.arr[0]; // Do not crash when evaluating a static reference with an invalid initializer.
+} // namespace test17
``````````
</details>
https://github.com/llvm/llvm-project/pull/225027
More information about the cfe-commits
mailing list