r325120 - [AST] Refine the condition for element-dependent array fillers

Ivan A. Kosarev via cfe-commits cfe-commits at lists.llvm.org
Wed Feb 14 05:10:35 PST 2018


Author: kosarev
Date: Wed Feb 14 05:10:35 2018
New Revision: 325120

URL: http://llvm.org/viewvc/llvm-project?rev=325120&view=rev
Log:
[AST] Refine the condition for element-dependent array fillers

This patch fixes clang to not consider braced initializers for
aggregate elements of arrays to be potentially dependent on the
indices of the initialized elements. Resolves bug 18978:
initialize a large static array = clang oom?
https://bugs.llvm.org/show_bug.cgi?id=18978

Differential Revision: https://reviews.llvm.org/D43187

Added:
    cfe/trunk/test/SemaCXX/large-array-init.cpp
Modified:
    cfe/trunk/lib/AST/ExprConstant.cpp

Modified: cfe/trunk/lib/AST/ExprConstant.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ExprConstant.cpp?rev=325120&r1=325119&r2=325120&view=diff
==============================================================================
--- cfe/trunk/lib/AST/ExprConstant.cpp (original)
+++ cfe/trunk/lib/AST/ExprConstant.cpp Wed Feb 14 05:10:35 2018
@@ -48,6 +48,8 @@
 #include <cstring>
 #include <functional>
 
+#define DEBUG_TYPE "exprconstant"
+
 using namespace clang;
 using llvm::APSInt;
 using llvm::APFloat;
@@ -6780,6 +6782,22 @@ static bool EvaluateArray(const Expr *E,
   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<ImplicitValueInitExpr>(FillerExpr))
+    return false;
+  if (const InitListExpr *ILE = dyn_cast<InitListExpr>(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 @@ bool ArrayExprEvaluator::VisitInitListEx
   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<ImplicitValueInitExpr>(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

Added: cfe/trunk/test/SemaCXX/large-array-init.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/large-array-init.cpp?rev=325120&view=auto
==============================================================================
--- cfe/trunk/test/SemaCXX/large-array-init.cpp (added)
+++ cfe/trunk/test/SemaCXX/large-array-init.cpp Wed Feb 14 05:10:35 2018
@@ -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; }




More information about the cfe-commits mailing list