Index: cfe/trunk/lib/AST/ExprConstant.cpp =================================================================== --- cfe/trunk/lib/AST/ExprConstant.cpp +++ cfe/trunk/lib/AST/ExprConstant.cpp @@ -48,6 +48,8 @@ #include #include +#define DEBUG_TYPE "exprconstant" + using namespace clang; using llvm::APSInt; using llvm::APFloat; @@ -6780,6 +6782,22 @@ return ArrayExprEvaluator(Info, This, Result).Visit(E); } +// Return true iff the given array filler may depend on the element index. +static bool MaybeElementDependentArrayFiller(const Expr *FillerExpr) { + // For now, just whitelist non-class value-initialization and initialization + // lists comprised of them. + if (isa(FillerExpr)) + return false; + if (const InitListExpr *ILE = dyn_cast(FillerExpr)) { + for (unsigned I = 0, E = ILE->getNumInits(); I != E; ++I) { + if (MaybeElementDependentArrayFiller(ILE->getInit(I))) + return true; + } + return false; + } + return true; +} + bool ArrayExprEvaluator::VisitInitListExpr(const InitListExpr *E) { const ConstantArrayType *CAT = Info.Ctx.getAsConstantArrayType(E->getType()); if (!CAT) @@ -6809,10 +6827,13 @@ const Expr *FillerExpr = E->hasArrayFiller() ? E->getArrayFiller() : nullptr; // If the initializer might depend on the array index, run it for each - // array element. For now, just whitelist non-class value-initialization. - if (NumEltsToInit != NumElts && !isa(FillerExpr)) + // array element. + if (NumEltsToInit != NumElts && MaybeElementDependentArrayFiller(FillerExpr)) NumEltsToInit = NumElts; + DEBUG(llvm::dbgs() << "The number of elements to initialize: " << + NumEltsToInit << ".\n"); + Result = APValue(APValue::UninitArray(), NumEltsToInit, NumElts); // If the array was previously zero-initialized, preserve the Index: cfe/trunk/test/SemaCXX/large-array-init.cpp =================================================================== --- cfe/trunk/test/SemaCXX/large-array-init.cpp +++ cfe/trunk/test/SemaCXX/large-array-init.cpp @@ -0,0 +1,9 @@ +// RUN: %clang_cc1 -S -o %t.ll -mllvm -debug-only=exprconstant %s 2>&1 | \ +// RUN: FileCheck %s + +struct S { int i; }; + +static struct S arr[100000000] = {{ 0 }}; +// CHECK: The number of elements to initialize: 1. + +struct S *foo() { return arr; }