diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index b510fa5034891..e13de5ecb8d15 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -338,6 +338,8 @@ Bug Fixes to C++ Support - Fix the parsing of variadic member functions when the ellipis immediately follows a default argument.(#GH153445) - Fixed a bug that caused ``this`` captured by value in a lambda with a dependent explicit object parameter to not be instantiated properly. (#GH154054) +- Fixed a crash when implicit conversions from initialize list to arrays of + unknown bound during constant evaluation. (#GH151716) Bug Fixes to AST Handling ^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp index 66362d44976c4..f0592b0cd51c2 100644 --- a/clang/lib/AST/ExprConstant.cpp +++ b/clang/lib/AST/ExprConstant.cpp @@ -4030,10 +4030,12 @@ findSubobject(EvalInfo &Info, const Expr *E, const CompleteObject &Obj, LastField = nullptr; if (ObjType->isArrayType()) { // Next subobject is an array element. - const ConstantArrayType *CAT = Info.Ctx.getAsConstantArrayType(ObjType); - assert(CAT && "vla in literal type?"); + const ArrayType *AT = Info.Ctx.getAsArrayType(ObjType); + assert((isa(AT) || isa(AT)) && + "vla in literal type?"); uint64_t Index = Sub.Entries[I].getAsArrayIndex(); - if (CAT->getSize().ule(Index)) { + if (const auto *CAT = dyn_cast(AT); + CAT && CAT->getSize().ule(Index)) { // Note, it should not be possible to form a pointer with a valid // designator which points more than one past the end of the array. if (Info.getLangOpts().CPlusPlus11) @@ -4044,12 +4046,13 @@ findSubobject(EvalInfo &Info, const Expr *E, const CompleteObject &Obj, return handler.failed(); } - ObjType = CAT->getElementType(); + ObjType = AT->getElementType(); if (O->getArrayInitializedElts() > Index) O = &O->getArrayInitializedElt(Index); else if (!isRead(handler.AccessKind)) { - if (!CheckArraySize(Info, CAT, E->getExprLoc())) + if (const auto *CAT = dyn_cast(AT); + CAT && !CheckArraySize(Info, CAT, E->getExprLoc())) return handler.failed(); expandArray(*O, Index); diff --git a/clang/test/CodeGenCXX/cxx20-p0388-unbound-ary.cpp b/clang/test/CodeGenCXX/cxx20-p0388-unbound-ary.cpp index a29f4d720c1de..007b47c441b2f 100644 --- a/clang/test/CodeGenCXX/cxx20-p0388-unbound-ary.cpp +++ b/clang/test/CodeGenCXX/cxx20-p0388-unbound-ary.cpp @@ -32,4 +32,19 @@ void foo(int a) { f({a}); } +constexpr int gh151716() { + int(&&g)[]{0,1,2}; + return g[2]; +} +// CHECK-LABEL: @_ZN3One10gh151716_fEv +// CHECK-NEXT: entry: +// CHECK-NEXT: %v = alloca i32, align 4 +// CHECK-NEXT: call void @llvm.lifetime.start.p0(ptr nonnull %v) +// CHECK-NEXT: store volatile i32 2, ptr %v, align 4 +// CHECK-NEXT: call void @llvm.lifetime.end.p0(ptr nonnull %v) +// CHECK-NEXT: ret void +void gh151716_f() { + volatile const int v = gh151716(); +} + } // namespace One