Index: tools/clang/lib/CodeGen/CGDecl.cpp =================================================================== --- tools/clang/lib/CodeGen/CGDecl.cpp +++ tools/clang/lib/CodeGen/CGDecl.cpp @@ -1096,7 +1096,7 @@ static void emitStoresForConstant(CodeGenModule &CGM, const VarDecl &D, Address Loc, bool isVolatile, CGBuilderTy &Builder, - llvm::Constant *constant) { + llvm::Constant *constant, bool forInit) { auto *Ty = constant->getType(); bool isScalar = Ty->isIntOrIntVectorTy() || Ty->isPtrOrPtrVectorTy() || Ty->isFPOrFPVectorTy(); @@ -1138,6 +1138,19 @@ return; } + if (forInit && Ty->isStructTy()) { + const llvm::StructLayout *Layout = + CGM.getDataLayout().getStructLayout(cast(Ty)); + for (unsigned i = 0; i != constant->getNumOperands(); i++) { + auto EltOffset = CharUnits::fromQuantity(Layout->getElementOffset(i)); + Address EltPtr = Builder.CreateStructGEP(Loc, i, EltOffset); + emitStoresForConstant(CGM, D, EltPtr, isVolatile, Builder, + cast(constant->getOperand(i)), + /*forInit*/ true); + } + return; + } + Builder.CreateMemCpy( Loc, createUnnamedGlobalFrom(CGM, D, Builder, constant, Loc.getAlignment()), @@ -1149,7 +1162,8 @@ CGBuilderTy &Builder) { llvm::Type *ElTy = Loc.getElementType(); llvm::Constant *constant = llvm::Constant::getNullValue(ElTy); - emitStoresForConstant(CGM, D, Loc, isVolatile, Builder, constant); + emitStoresForConstant(CGM, D, Loc, isVolatile, Builder, constant, + /*forInit*/ true); } static void emitStoresForPatternInit(CodeGenModule &CGM, const VarDecl &D, @@ -1158,7 +1172,8 @@ llvm::Type *ElTy = Loc.getElementType(); llvm::Constant *constant = patternFor(CGM, ElTy); assert(!isa(constant)); - emitStoresForConstant(CGM, D, Loc, isVolatile, Builder, constant); + emitStoresForConstant(CGM, D, Loc, isVolatile, Builder, constant, + /*forInit*/ true); } static bool containsUndef(llvm::Constant *constant) { @@ -1746,7 +1761,8 @@ if (Loc.getType() != BP) Loc = Builder.CreateBitCast(Loc, BP); - emitStoresForConstant(CGM, D, Loc, isVolatile, Builder, constant); + emitStoresForConstant(CGM, D, Loc, isVolatile, Builder, constant, + /*forInit*/ false); } /// Emit an expression as an initializer for an object (variable, field, etc.)