Index: clang/lib/AST/Interp/ByteCodeExprGen.cpp =================================================================== --- clang/lib/AST/Interp/ByteCodeExprGen.cpp +++ clang/lib/AST/Interp/ByteCodeExprGen.cpp @@ -1129,6 +1129,46 @@ return false; } return true; + } else if (const auto *SL = dyn_cast(Initializer)) { + const ArrayType *AT = SL->getType()->getAsArrayTypeUnsafe(); + const auto *CAT = cast(AT); + size_t NumElems = CAT->getSize().getZExtValue(); + + // FIXME: There is a certain code duplication between here + // and Porgram::createGlobalString(). + const size_t CharWidth = SL->getCharByteWidth(); + PrimType CharType; + switch (CharWidth) { + case 1: + CharType = PT_Sint8; + break; + case 2: + CharType = PT_Uint16; + break; + case 4: + CharType = PT_Uint32; + break; + default: + llvm_unreachable("unsupported character width"); + } + + unsigned N = SL->getLength(); + for (size_t I = 0; I != NumElems; ++I) { + const uint32_t CodePoint = I < N ? SL->getCodeUnit(I) : 0; + // TODO(Perf): 0 is implicit; we can just stop iterating at that point. + if (CharWidth == 1) + this->emitConstSint8(CodePoint, SL); + else if (CharWidth == 2) + this->emitConstUint16(CodePoint, SL); + else if (CharWidth == 4) + this->emitConstUint32(CodePoint, SL); + else + return false; + + if (!this->emitInitElem(CharType, I, SL)) + return false; + } + return true; } assert(false && "Unknown expression for array initialization"); Index: clang/test/AST/Interp/literals.cpp =================================================================== --- clang/test/AST/Interp/literals.cpp +++ clang/test/AST/Interp/literals.cpp @@ -350,6 +350,13 @@ #endif #pragma clang diagnostic pop + + constexpr char foo[12] = "abc"; + static_assert(foo[0] == 'a', ""); + static_assert(foo[1] == 'b', ""); + static_assert(foo[2] == 'c', ""); + static_assert(foo[3] == 0, ""); + static_assert(foo[11] == 0, ""); }; #if __cplusplus > 201402L