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 _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
