Index: clang/lib/AST/Interp/ByteCodeExprGen.cpp =================================================================== --- clang/lib/AST/Interp/ByteCodeExprGen.cpp +++ clang/lib/AST/Interp/ByteCodeExprGen.cpp @@ -721,6 +721,27 @@ if (!this->emitPopPtr(Initializer)) return false; } + return true; + } else if (const auto *IVIE = dyn_cast(Initializer)) { + const ArrayType *ArrayType = IVIE->getType()->getAsArrayTypeUnsafe(); + assert(ArrayType); + const auto *CAT = cast(ArrayType); + size_t NumElems = CAT->getSize().getZExtValue(); + + if (Optional ElemT = classify(CAT->getElementType())) { + // TODO(perf): For int and bool types, we can probably just skip this + // since we memset our Block*s to 0 and so we have the desired value + // without this. + for (size_t I = 0; I != NumElems; ++I) { + if (!this->emitZero(*ElemT, Initializer)) + return false; + if (!this->emitInitElem(*ElemT, I, Initializer)) + return false; + } + } else { + assert(false && "default initializer for non-primitive type"); + } + return true; } Index: clang/test/AST/Interp/arrays.cpp =================================================================== --- clang/test/AST/Interp/arrays.cpp +++ clang/test/AST/Interp/arrays.cpp @@ -117,3 +117,15 @@ // expected-error {{must be initialized by a constant expression}} \ // expected-note {{cannot refer to element -2 of array of 10}} }; + +namespace DefaultInit { + template + struct B { + T a[N]; + }; + + int f() { + constexpr B arr = {}; + constexpr int x = arr.a[0]; + } +};