]> granicus.if.org Git - clang/commitdiff
Fix a thinko in the pre-allocation strategy for structured initializer
authorDouglas Gregor <dgregor@apple.com>
Sat, 21 Mar 2009 18:13:52 +0000 (18:13 +0000)
committerDouglas Gregor <dgregor@apple.com>
Sat, 21 Mar 2009 18:13:52 +0000 (18:13 +0000)
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 (<rdar://problem/6707362>).

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@67452 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Sema/SemaInit.cpp

index 336413291081397809e59ed32d2d85cc7d76308a..600dc34351761b0ee777f3645a80b59f9fbf7530 100644 (file)
@@ -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<InitListExpr>(IList->getInit(Index)))
+      NumInits = SubList->getNumInits();
+  }
+
   if (const ArrayType *AType 
       = SemaRef.Context.getAsArrayType(CurrentObjectType)) {
     if (const ConstantArrayType *CAType = dyn_cast<ConstantArrayType>(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);