Index: clang/docs/ReleaseNotes.rst =================================================================== --- clang/docs/ReleaseNotes.rst +++ clang/docs/ReleaseNotes.rst @@ -175,6 +175,8 @@ emitted as a dynamic initializer. Previously the variable would incorrectly be zero-initialized. In contexts where a dynamic initializer is not allowed this is now diagnosed as an error. +- Fixed an assertion failure when evaluating a constexpr constructor + in an array initializer. Improvements to Clang's diagnostics ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Index: clang/lib/AST/ExprConstant.cpp =================================================================== --- clang/lib/AST/ExprConstant.cpp +++ clang/lib/AST/ExprConstant.cpp @@ -10754,17 +10754,18 @@ for (unsigned Index = 0; Index != NumEltsToInit; ++Index) { const Expr *Init = Index < E->getNumInits() ? E->getInit(Index) : FillerExpr; - if (!EvaluateInPlace(Result.getArrayInitializedElt(Index), - Info, Subobject, Init) || - !HandleLValueArrayAdjustment(Info, Init, Subobject, - CAT->getElementType(), 1)) { + if (Result.isArray() && + (!EvaluateInPlace(Result.getArrayInitializedElt(Index), Info, Subobject, + Init) || + !HandleLValueArrayAdjustment(Info, Init, Subobject, + CAT->getElementType(), 1))) { if (!Info.noteFailure()) return false; Success = false; } } - if (!Result.hasArrayFiller()) + if (!Result.isArray() || !Result.hasArrayFiller()) return Success; // If we get here, we have a trivial filler, which we can just evaluate Index: clang/test/SemaCXX/constexpr-array-init.cpp =================================================================== --- /dev/null +++ clang/test/SemaCXX/constexpr-array-init.cpp @@ -0,0 +1,19 @@ +// RUN: %clang_cc1 -std=c++20 -verify %s + +// FIXME: This code should compile without errors but as of right now doesn't. +// We're only testing that clang doesn't crash or run into an assertion. +struct Foo { + int a; // expected-note {{subobject declared here}} + constexpr Foo() + : a(get_int()) { + } + + constexpr int get_int() { + return 5; + } +}; + +static constexpr Foo bar[2][1] = { // expected-error {{constexpr variable 'bar' must be initialized by a constant expression}} \ + // expected-note {{subobject of type 'int' is not initialized}} + {{}}, +};