summaryrefslogtreecommitdiffstats
path: root/clang/lib/AST/ExprConstant.cpp
diff options
context:
space:
mode:
authorIvan A. Kosarev <ikosarev@accesssoftek.com>2018-02-14 13:10:35 +0000
committerIvan A. Kosarev <ikosarev@accesssoftek.com>2018-02-14 13:10:35 +0000
commit01df519f7efd3ebd8237fb1a7e4042be85f18d12 (patch)
tree0808c24fb0701378ed82b46f10ac2098fc9e7eb1 /clang/lib/AST/ExprConstant.cpp
parent1768957c822faa1425285d2c49b4e73d9b4ee886 (diff)
downloadbcm5719-llvm-01df519f7efd3ebd8237fb1a7e4042be85f18d12.tar.gz
bcm5719-llvm-01df519f7efd3ebd8237fb1a7e4042be85f18d12.zip
[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 llvm-svn: 325120
Diffstat (limited to 'clang/lib/AST/ExprConstant.cpp')
-rw-r--r--clang/lib/AST/ExprConstant.cpp25
1 files changed, 23 insertions, 2 deletions
diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp
index 61bd1e5f129..e56569dc6c7 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/lib/AST/ExprConstant.cpp
@@ -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, const LValue &This,
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::VisitInitListExpr(const InitListExpr *E) {
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
OpenPOWER on IntegriCloud