Skip to content

Commit a3186be

Browse files
authored
[clang][initlist] handle incomplete array type in Constant Expr Calculation (#155080)
fix: #151716 In #65918, support of incomplete array type is added in TryReferenceListInitialization. It causes the crash in Constant Expr Calculation since it only considers the case where it is ConstantArrayType. This patch wants to add support for incomplete array type also.
1 parent 3e10bdd commit a3186be

File tree

3 files changed

+25
-5
lines changed

3 files changed

+25
-5
lines changed

clang/docs/ReleaseNotes.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -338,6 +338,8 @@ Bug Fixes to C++ Support
338338
- Fix the parsing of variadic member functions when the ellipis immediately follows a default argument.(#GH153445)
339339
- Fixed a bug that caused ``this`` captured by value in a lambda with a dependent explicit object parameter to not be
340340
instantiated properly. (#GH154054)
341+
- Fixed a crash when implicit conversions from initialize list to arrays of
342+
unknown bound during constant evaluation. (#GH151716)
341343

342344
Bug Fixes to AST Handling
343345
^^^^^^^^^^^^^^^^^^^^^^^^^

clang/lib/AST/ExprConstant.cpp

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4030,10 +4030,12 @@ findSubobject(EvalInfo &Info, const Expr *E, const CompleteObject &Obj,
40304030
LastField = nullptr;
40314031
if (ObjType->isArrayType()) {
40324032
// Next subobject is an array element.
4033-
const ConstantArrayType *CAT = Info.Ctx.getAsConstantArrayType(ObjType);
4034-
assert(CAT && "vla in literal type?");
4033+
const ArrayType *AT = Info.Ctx.getAsArrayType(ObjType);
4034+
assert((isa<ConstantArrayType>(AT) || isa<IncompleteArrayType>(AT)) &&
4035+
"vla in literal type?");
40354036
uint64_t Index = Sub.Entries[I].getAsArrayIndex();
4036-
if (CAT->getSize().ule(Index)) {
4037+
if (const auto *CAT = dyn_cast<ConstantArrayType>(AT);
4038+
CAT && CAT->getSize().ule(Index)) {
40374039
// Note, it should not be possible to form a pointer with a valid
40384040
// designator which points more than one past the end of the array.
40394041
if (Info.getLangOpts().CPlusPlus11)
@@ -4044,12 +4046,13 @@ findSubobject(EvalInfo &Info, const Expr *E, const CompleteObject &Obj,
40444046
return handler.failed();
40454047
}
40464048

4047-
ObjType = CAT->getElementType();
4049+
ObjType = AT->getElementType();
40484050

40494051
if (O->getArrayInitializedElts() > Index)
40504052
O = &O->getArrayInitializedElt(Index);
40514053
else if (!isRead(handler.AccessKind)) {
4052-
if (!CheckArraySize(Info, CAT, E->getExprLoc()))
4054+
if (const auto *CAT = dyn_cast<ConstantArrayType>(AT);
4055+
CAT && !CheckArraySize(Info, CAT, E->getExprLoc()))
40534056
return handler.failed();
40544057

40554058
expandArray(*O, Index);

clang/test/CodeGenCXX/cxx20-p0388-unbound-ary.cpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,4 +32,19 @@ void foo(int a) {
3232
f({a});
3333
}
3434

35+
constexpr int gh151716() {
36+
int(&&g)[]{0,1,2};
37+
return g[2];
38+
}
39+
// CHECK-LABEL: @_ZN3One10gh151716_fEv
40+
// CHECK-NEXT: entry:
41+
// CHECK-NEXT: %v = alloca i32, align 4
42+
// CHECK-NEXT: call void @llvm.lifetime.start.p0(ptr nonnull %v)
43+
// CHECK-NEXT: store volatile i32 2, ptr %v, align 4
44+
// CHECK-NEXT: call void @llvm.lifetime.end.p0(ptr nonnull %v)
45+
// CHECK-NEXT: ret void
46+
void gh151716_f() {
47+
volatile const int v = gh151716();
48+
}
49+
3550
} // namespace One

0 commit comments

Comments
 (0)