aboutsummaryrefslogtreecommitdiff
path: root/clang
diff options
context:
space:
mode:
authorOleksandr T. <oleksandr.tarasiuk@outlook.com>2024-10-24 11:34:58 +0300
committerGitHub <noreply@github.com>2024-10-24 10:34:58 +0200
commit61a456bd5ae88eeccc39b28a30be4eb03289446d (patch)
tree4d033f64302982f81d7aa695e237df19f9725cf7 /clang
parent17bfd21391d080afbf2697a0a1a631a1be76a2e4 (diff)
downloadllvm-61a456bd5ae88eeccc39b28a30be4eb03289446d.zip
llvm-61a456bd5ae88eeccc39b28a30be4eb03289446d.tar.gz
llvm-61a456bd5ae88eeccc39b28a30be4eb03289446d.tar.bz2
[Clang] prevent assertion failure in value-dependent initializer expressions (#112612)
Fixes #112140 --- ``` CXXConstructExpr 0x14209e580 'const S':'const struct S' contains-errors 'void (const int &)' list `-CXXDefaultArgExpr 0x14209e500 'const int' contains-errors `-RecoveryExpr 0x14209daf0 'const int' contains-errors ``` This change resolves an issue with evaluating `ArrayFiller` initializers in _dependent_ contexts, especially when they involve a `RecoveryExpr`. In certain cases, `ArrayFiller` initializers containing a `RecoveryExpr` from earlier errors are incorrectly passed to `EvaluateInPlace`, causing evaluation failures when they are value-dependent. When this is the case, the initializer is processed through `EvaluateDependentExpr`, which prevents unnecessary evaluation attempts and ensures proper handling of value-dependent initializers in `ArrayFillers`.
Diffstat (limited to 'clang')
-rw-r--r--clang/docs/ReleaseNotes.rst1
-rw-r--r--clang/lib/AST/ExprConstant.cpp3
-rw-r--r--clang/test/SemaCXX/constant-expression-cxx11.cpp10
3 files changed, 14 insertions, 0 deletions
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index ce046a3..46021c9 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -544,6 +544,7 @@ Bug Fixes to C++ Support
- Clang incorrectly considered a class with an anonymous union member to not be
const-default-constructible even if a union member has a default member initializer.
(#GH95854).
+- Fixed an assertion failure when evaluating an invalid expression in an array initializer (#GH112140)
Bug Fixes to AST Handling
^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp
index 8e36cad..d664c50 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/lib/AST/ExprConstant.cpp
@@ -11579,6 +11579,9 @@ bool ArrayExprEvaluator::VisitCXXParenListOrInitListExpr(
LValue Subobject = This;
Subobject.addArray(Info, ExprToVisit, CAT);
auto Eval = [&](const Expr *Init, unsigned ArrayIndex) {
+ if (Init->isValueDependent())
+ return EvaluateDependentExpr(Init, Info);
+
if (!EvaluateInPlace(Result.getArrayInitializedElt(ArrayIndex), Info,
Subobject, Init) ||
!HandleLValueArrayAdjustment(Info, Init, Subobject,
diff --git a/clang/test/SemaCXX/constant-expression-cxx11.cpp b/clang/test/SemaCXX/constant-expression-cxx11.cpp
index e2ea984..0c34933 100644
--- a/clang/test/SemaCXX/constant-expression-cxx11.cpp
+++ b/clang/test/SemaCXX/constant-expression-cxx11.cpp
@@ -2564,3 +2564,13 @@ GH50055::E2 GlobalInitNotCE2 = GH50055::testDefaultArgForParam(); // ok, not a c
constexpr GH50055::E2 GlobalInitCE = (GH50055::E2)-1;
// expected-error@-1 {{constexpr variable 'GlobalInitCE' must be initialized by a constant expression}}
// expected-note@-2 {{integer value -1 is outside the valid range of values [0, 7] for the enumeration type 'E2'}}
+
+namespace GH112140 {
+struct S {
+ constexpr S(const int &a = ) { } // expected-error {{expected expression}}
+};
+
+void foo() {
+ constexpr S s[2] = { }; // expected-error {{constexpr variable 's' must be initialized by a constant expression}}
+}
+}