Index: clang/lib/AST/ExprConstant.cpp =================================================================== --- clang/lib/AST/ExprConstant.cpp +++ clang/lib/AST/ExprConstant.cpp @@ -10833,6 +10833,9 @@ if (FinalSize == 0) return true; + bool HasTrivialConstructor = CheckTrivialDefaultConstructor( + Info, E->getExprLoc(), E->getConstructor(), + E->requiresZeroInitialization()); LValue ArrayElt = Subobject; ArrayElt.addArray(Info, E, CAT); // We do the whole initialization in two passes, first for just one element, @@ -10856,19 +10859,26 @@ for (unsigned I = OldElts; I < N; ++I) Value->getArrayInitializedElt(I) = Filler; - // Initialize the elements. - for (unsigned I = OldElts; I < N; ++I) { - if (!VisitCXXConstructExpr(E, ArrayElt, - &Value->getArrayInitializedElt(I), - CAT->getElementType()) || - !HandleLValueArrayAdjustment(Info, E, ArrayElt, - CAT->getElementType(), 1)) - return false; - // When checking for const initilization any diagnostic is considered - // an error. - if (Info.EvalStatus.Diag && !Info.EvalStatus.Diag->empty() && - !Info.keepEvaluatingAfterFailure()) - return false; + if (HasTrivialConstructor && N == FinalSize) { + // If we have a trivial constructor, only evaluate it once and copy + // the result into all the array elements. + APValue &FirstResult = Value->getArrayInitializedElt(0); + for (unsigned I = OldElts; I < FinalSize; ++I) + Value->getArrayInitializedElt(I) = FirstResult; + } else { + for (unsigned I = OldElts; I < N; ++I) { + if (!VisitCXXConstructExpr(E, ArrayElt, + &Value->getArrayInitializedElt(I), + CAT->getElementType()) || + !HandleLValueArrayAdjustment(Info, E, ArrayElt, + CAT->getElementType(), 1)) + return false; + // When checking for const initilization any diagnostic is considered + // an error. + if (Info.EvalStatus.Diag && !Info.EvalStatus.Diag->empty() && + !Info.keepEvaluatingAfterFailure()) + return false; + } } }