Skip to content

Commit 64be697

Browse files
a-tarasyukNoumanAmir657
authored andcommitted
[Clang] prevent assertion failure in value-dependent initializer expressions (llvm#112612)
Fixes llvm#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`.
1 parent 5433095 commit 64be697

File tree

3 files changed

+14
-0
lines changed

3 files changed

+14
-0
lines changed

clang/docs/ReleaseNotes.rst

+1
Original file line numberDiff line numberDiff line change
@@ -544,6 +544,7 @@ Bug Fixes to C++ Support
544544
- Clang incorrectly considered a class with an anonymous union member to not be
545545
const-default-constructible even if a union member has a default member initializer.
546546
(#GH95854).
547+
- Fixed an assertion failure when evaluating an invalid expression in an array initializer (#GH112140)
547548

548549
Bug Fixes to AST Handling
549550
^^^^^^^^^^^^^^^^^^^^^^^^^

clang/lib/AST/ExprConstant.cpp

+3
Original file line numberDiff line numberDiff line change
@@ -11579,6 +11579,9 @@ bool ArrayExprEvaluator::VisitCXXParenListOrInitListExpr(
1157911579
LValue Subobject = This;
1158011580
Subobject.addArray(Info, ExprToVisit, CAT);
1158111581
auto Eval = [&](const Expr *Init, unsigned ArrayIndex) {
11582+
if (Init->isValueDependent())
11583+
return EvaluateDependentExpr(Init, Info);
11584+
1158211585
if (!EvaluateInPlace(Result.getArrayInitializedElt(ArrayIndex), Info,
1158311586
Subobject, Init) ||
1158411587
!HandleLValueArrayAdjustment(Info, Init, Subobject,

clang/test/SemaCXX/constant-expression-cxx11.cpp

+10
Original file line numberDiff line numberDiff line change
@@ -2564,3 +2564,13 @@ GH50055::E2 GlobalInitNotCE2 = GH50055::testDefaultArgForParam(); // ok, not a c
25642564
constexpr GH50055::E2 GlobalInitCE = (GH50055::E2)-1;
25652565
// expected-error@-1 {{constexpr variable 'GlobalInitCE' must be initialized by a constant expression}}
25662566
// expected-note@-2 {{integer value -1 is outside the valid range of values [0, 7] for the enumeration type 'E2'}}
2567+
2568+
namespace GH112140 {
2569+
struct S {
2570+
constexpr S(const int &a = ) { } // expected-error {{expected expression}}
2571+
};
2572+
2573+
void foo() {
2574+
constexpr S s[2] = { }; // expected-error {{constexpr variable 's' must be initialized by a constant expression}}
2575+
}
2576+
}

0 commit comments

Comments
 (0)