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

Reply via email to