From: Douglas Gregor Date: Sat, 21 Mar 2009 18:13:52 +0000 (+0000) Subject: Fix a thinko in the pre-allocation strategy for structured initializer X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=08457737b60ba2e7f58ecf3062010843268fc6ea;p=clang Fix a thinko in the pre-allocation strategy for structured initializer lists. The code wasn't accounting for the distinction between the top-level call to getStructuredSubobjectInit and later calls that occur deeper in the hierarchy. This problem manifested itself as over-allocation in cases where we have large arrays of small structures (). git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@67452 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Sema/SemaInit.cpp b/lib/Sema/SemaInit.cpp index 3364132910..600dc34351 100644 --- a/lib/Sema/SemaInit.cpp +++ b/lib/Sema/SemaInit.cpp @@ -1452,13 +1452,21 @@ InitListChecker::getStructuredSubobjectInit(InitListExpr *IList, unsigned Index, // Pre-allocate storage for the structured initializer list. unsigned NumElements = 0; + unsigned NumInits = 0; + if (!StructuredList) + NumInits = IList->getNumInits(); + else if (Index < IList->getNumInits()) { + if (InitListExpr *SubList = dyn_cast(IList->getInit(Index))) + NumInits = SubList->getNumInits(); + } + if (const ArrayType *AType = SemaRef.Context.getAsArrayType(CurrentObjectType)) { if (const ConstantArrayType *CAType = dyn_cast(AType)) { NumElements = CAType->getSize().getZExtValue(); // Simple heuristic so that we don't allocate a very large // initializer with many empty entries at the end. - if (IList && NumElements > IList->getNumInits()) + if (NumInits && NumElements > NumInits) NumElements = 0; } } else if (const VectorType *VType = CurrentObjectType->getAsVectorType()) @@ -1471,7 +1479,7 @@ InitListChecker::getStructuredSubobjectInit(InitListExpr *IList, unsigned Index, NumElements = std::distance(RDecl->field_begin(), RDecl->field_end()); } - if (IList && NumElements < IList->getNumInits()) + if (NumElements < NumInits) NumElements = IList->getNumInits(); Result->reserveInits(NumElements);