summaryrefslogtreecommitdiffstats
path: root/clang/lib
diff options
context:
space:
mode:
authorTed Kremenek <kremenek@apple.com>2010-02-19 00:42:33 +0000
committerTed Kremenek <kremenek@apple.com>2010-02-19 00:42:33 +0000
commit445a603c78c10b372c20335bcbf803c010a05f29 (patch)
tree0e99facc07cda873468ce78adf4c6ca4605326d8 /clang/lib
parent70127c1dcf66d1d01fd8423c1dc858e9baba714b (diff)
downloadbcm5719-llvm-445a603c78c10b372c20335bcbf803c010a05f29.tar.gz
bcm5719-llvm-445a603c78c10b372c20335bcbf803c010a05f29.zip
Change InitListExpr to allocate the array for holding references
to initializer expressions in an array allocated using ASTContext. This plugs a memory leak when ASTContext uses a BumpPtrAllocator to allocate memory for AST nodes. In my mind this isn't an ideal solution; it would be nice to have a general "vector"-like class that allocates memory using ASTContext, but whose guts could be separated from the methods of InitListExpr itself. I haven't gone and taken this approach yet because it isn't clear yet if we'll eventually want an alternate solution for recylcing memory using by InitListExprs as we are constructing the ASTs. llvm-svn: 96642
Diffstat (limited to 'clang/lib')
-rw-r--r--clang/lib/AST/Expr.cpp85
-rw-r--r--clang/lib/Frontend/PCHReaderStmt.cpp4
-rw-r--r--clang/lib/Frontend/RewriteObjC.cpp16
-rw-r--r--clang/lib/Sema/SemaExpr.cpp10
-rw-r--r--clang/lib/Sema/SemaInit.cpp15
5 files changed, 83 insertions, 47 deletions
diff --git a/clang/lib/AST/Expr.cpp b/clang/lib/AST/Expr.cpp
index fac65064c07..58776f47d97 100644
--- a/clang/lib/AST/Expr.cpp
+++ b/clang/lib/AST/Expr.cpp
@@ -713,40 +713,75 @@ OverloadedOperatorKind BinaryOperator::getOverloadedOperator(Opcode Opc) {
return OverOps[Opc];
}
-InitListExpr::InitListExpr(SourceLocation lbraceloc,
+InitListExpr::InitListExpr(ASTContext &C, SourceLocation lbraceloc,
Expr **initExprs, unsigned numInits,
SourceLocation rbraceloc)
: Expr(InitListExprClass, QualType(), false, false),
+ InitExprs(0), NumInits(numInits), Capacity(numInits),
LBraceLoc(lbraceloc), RBraceLoc(rbraceloc), SyntacticForm(0),
- UnionFieldInit(0), HadArrayRangeDesignator(false)
-{
- for (unsigned I = 0; I != numInits; ++I) {
- if (initExprs[I]->isTypeDependent())
+ UnionFieldInit(0), HadArrayRangeDesignator(false)
+{
+ if (NumInits == 0)
+ return;
+
+ InitExprs = new (C) Stmt*[Capacity];
+
+ for (unsigned I = 0; I != NumInits; ++I) {
+ Expr *Ex = initExprs[I];
+ if (Ex->isTypeDependent())
TypeDependent = true;
- if (initExprs[I]->isValueDependent())
+ if (Ex->isValueDependent())
ValueDependent = true;
+ InitExprs[I] = Ex;
}
-
- InitExprs.insert(InitExprs.end(), initExprs, initExprs+numInits);
}
-void InitListExpr::reserveInits(unsigned NumInits) {
- if (NumInits > InitExprs.size())
- InitExprs.reserve(NumInits);
+void InitListExpr::DoDestroy(ASTContext &C) {
+ DestroyChildren(C);
+ if (InitExprs)
+ C.Deallocate(InitExprs);
+ this->~InitListExpr();
+ C.Deallocate((void*) this);
}
-void InitListExpr::resizeInits(ASTContext &Context, unsigned NumInits) {
- for (unsigned Idx = NumInits, LastIdx = InitExprs.size();
- Idx < LastIdx; ++Idx)
- InitExprs[Idx]->Destroy(Context);
- InitExprs.resize(NumInits, 0);
+void InitListExpr::reserveInits(ASTContext &C, unsigned newCapacity) {
+ if (newCapacity > Capacity) {
+ if (!Capacity)
+ Capacity = newCapacity;
+ else if ((Capacity *= 2) < newCapacity)
+ Capacity = newCapacity;
+
+ Stmt **newInits = new (C) Stmt*[Capacity];
+ if (InitExprs) {
+ memcpy(newInits, InitExprs, NumInits * sizeof(*InitExprs));
+ C.Deallocate(InitExprs);
+ }
+ InitExprs = newInits;
+ }
}
-Expr *InitListExpr::updateInit(unsigned Init, Expr *expr) {
- if (Init >= InitExprs.size()) {
- InitExprs.insert(InitExprs.end(), Init - InitExprs.size() + 1, 0);
- InitExprs.back() = expr;
- return 0;
+void InitListExpr::resizeInits(ASTContext &C, unsigned N) {
+ // If the new number of expressions is less than the old one, destroy
+ // the expressions that are beyond the new size.
+ for (unsigned i = N, LastIdx = NumInits; i < LastIdx; ++i)
+ InitExprs[i]->Destroy(C);
+
+ // If we are expanding the number of expressions, reserve space.
+ reserveInits(C, N);
+
+ // If we are expanding the number of expressions, zero out beyond our
+ // current capacity.
+ for (unsigned i = NumInits; i < N; ++i)
+ InitExprs[i] = 0;
+
+ NumInits = N;
+}
+
+Expr *InitListExpr::updateInit(ASTContext &C, unsigned Init, Expr *expr) {
+ if (Init >= NumInits) {
+ // Resize the number of initializers. This will adjust the amount
+ // of memory allocated as well as zero-pad the initializers.
+ resizeInits(C, Init+1);
}
Expr *Result = cast_or_null<Expr>(InitExprs[Init]);
@@ -2586,12 +2621,8 @@ Stmt::child_iterator VAArgExpr::child_begin() { return &Val; }
Stmt::child_iterator VAArgExpr::child_end() { return &Val+1; }
// InitListExpr
-Stmt::child_iterator InitListExpr::child_begin() {
- return InitExprs.size() ? &InitExprs[0] : 0;
-}
-Stmt::child_iterator InitListExpr::child_end() {
- return InitExprs.size() ? &InitExprs[0] + InitExprs.size() : 0;
-}
+Stmt::child_iterator InitListExpr::child_begin() { return begin(); }
+Stmt::child_iterator InitListExpr::child_end() { return end(); }
// DesignatedInitExpr
Stmt::child_iterator DesignatedInitExpr::child_begin() {
diff --git a/clang/lib/Frontend/PCHReaderStmt.cpp b/clang/lib/Frontend/PCHReaderStmt.cpp
index d123694d699..c69a5dc9dc1 100644
--- a/clang/lib/Frontend/PCHReaderStmt.cpp
+++ b/clang/lib/Frontend/PCHReaderStmt.cpp
@@ -554,9 +554,9 @@ unsigned PCHStmtReader::VisitExtVectorElementExpr(ExtVectorElementExpr *E) {
unsigned PCHStmtReader::VisitInitListExpr(InitListExpr *E) {
VisitExpr(E);
unsigned NumInits = Record[Idx++];
- E->reserveInits(NumInits);
+ E->reserveInits(*Reader.getContext(), NumInits);
for (unsigned I = 0; I != NumInits; ++I)
- E->updateInit(I,
+ E->updateInit(*Reader.getContext(), I,
cast<Expr>(StmtStack[StmtStack.size() - NumInits - 1 + I]));
E->setSyntacticForm(cast_or_null<InitListExpr>(StmtStack.back()));
E->setLBraceLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
diff --git a/clang/lib/Frontend/RewriteObjC.cpp b/clang/lib/Frontend/RewriteObjC.cpp
index fff8b54ba6c..40d444d94e4 100644
--- a/clang/lib/Frontend/RewriteObjC.cpp
+++ b/clang/lib/Frontend/RewriteObjC.cpp
@@ -2613,9 +2613,11 @@ Stmt *RewriteObjC::SynthMessageExpr(ObjCMessageExpr *Exp) {
CastExpr::CK_Unknown, SuperRep);
} else {
// (struct objc_super) { <exprs from above> }
- InitListExpr *ILE = new (Context) InitListExpr(SourceLocation(),
- &InitExprs[0], InitExprs.size(),
- SourceLocation());
+ InitListExpr *ILE = new (Context) InitListExpr(*Context,
+ SourceLocation(),
+ &InitExprs[0],
+ InitExprs.size(),
+ SourceLocation());
TypeSourceInfo *superTInfo
= Context->getTrivialTypeSourceInfo(superType);
SuperRep = new (Context) CompoundLiteralExpr(SourceLocation(), superTInfo,
@@ -2698,9 +2700,11 @@ Stmt *RewriteObjC::SynthMessageExpr(ObjCMessageExpr *Exp) {
CastExpr::CK_Unknown, SuperRep);
} else {
// (struct objc_super) { <exprs from above> }
- InitListExpr *ILE = new (Context) InitListExpr(SourceLocation(),
- &InitExprs[0], InitExprs.size(),
- SourceLocation());
+ InitListExpr *ILE = new (Context) InitListExpr(*Context,
+ SourceLocation(),
+ &InitExprs[0],
+ InitExprs.size(),
+ SourceLocation());
TypeSourceInfo *superTInfo
= Context->getTrivialTypeSourceInfo(superType);
SuperRep = new (Context) CompoundLiteralExpr(SourceLocation(), superTInfo,
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index e950be04858..0d54a164127 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -3763,8 +3763,8 @@ Sema::ActOnInitList(SourceLocation LBraceLoc, MultiExprArg initlist,
// Semantic analysis for initializers is done by ActOnDeclarator() and
// CheckInitializer() - it requires knowledge of the object being intialized.
- InitListExpr *E = new (Context) InitListExpr(LBraceLoc, InitList, NumInit,
- RBraceLoc);
+ InitListExpr *E = new (Context) InitListExpr(Context, LBraceLoc, InitList,
+ NumInit, RBraceLoc);
E->setType(Context.VoidTy); // FIXME: just a place holder for now.
return Owned(E);
}
@@ -4038,7 +4038,8 @@ Sema::ActOnCastOfParenListExpr(Scope *S, SourceLocation LParenLoc,
// FIXME: This means that pretty-printing the final AST will produce curly
// braces instead of the original commas.
Op.release();
- InitListExpr *E = new (Context) InitListExpr(LParenLoc, &initExprs[0],
+ InitListExpr *E = new (Context) InitListExpr(Context, LParenLoc,
+ &initExprs[0],
initExprs.size(), RParenLoc);
E->setType(Ty);
return BuildCompoundLiteralExpr(LParenLoc, TInfo, RParenLoc, Owned(E));
@@ -4752,8 +4753,7 @@ static void ConstructTransparentUnion(ASTContext &C, Expr *&E,
QualType UnionType, FieldDecl *Field) {
// Build an initializer list that designates the appropriate member
// of the transparent union.
- InitListExpr *Initializer = new (C) InitListExpr(SourceLocation(),
- &E, 1,
+ InitListExpr *Initializer = new (C) InitListExpr(C, SourceLocation(), &E, 1,
SourceLocation());
Initializer->setType(UnionType);
Initializer->setInitializedFieldInUnion(Field);
diff --git a/clang/lib/Sema/SemaInit.cpp b/clang/lib/Sema/SemaInit.cpp
index 7b4a41777b6..1c4e2c837ae 100644
--- a/clang/lib/Sema/SemaInit.cpp
+++ b/clang/lib/Sema/SemaInit.cpp
@@ -280,7 +280,7 @@ void InitListChecker::FillInValueInitForField(unsigned Init, FieldDecl *Field,
// extend the initializer list to include the constructor
// call and make a note that we'll need to take another pass
// through the initializer list.
- ILE->updateInit(Init, MemberInit.takeAs<Expr>());
+ ILE->updateInit(SemaRef.Context, Init, MemberInit.takeAs<Expr>());
RequiresSecondPass = true;
}
} else if (InitListExpr *InnerILE
@@ -390,7 +390,7 @@ InitListChecker::FillInValueInitializations(const InitializedEntity &Entity,
// extend the initializer list to include the constructor
// call and make a note that we'll need to take another pass
// through the initializer list.
- ILE->updateInit(Init, ElementInit.takeAs<Expr>());
+ ILE->updateInit(SemaRef.Context, Init, ElementInit.takeAs<Expr>());
RequiresSecondPass = true;
}
} else if (InitListExpr *InnerILE
@@ -1669,8 +1669,8 @@ InitListChecker::getStructuredSubobjectInit(InitListExpr *IList, unsigned Index,
}
InitListExpr *Result
- = new (SemaRef.Context) InitListExpr(InitRange.getBegin(), 0, 0,
- InitRange.getEnd());
+ = new (SemaRef.Context) InitListExpr(SemaRef.Context, InitRange.getBegin(),
+ 0, 0, InitRange.getEnd());
Result->setType(CurrentObjectType.getNonReferenceType());
@@ -1707,12 +1707,12 @@ InitListChecker::getStructuredSubobjectInit(InitListExpr *IList, unsigned Index,
if (NumElements < NumInits)
NumElements = IList->getNumInits();
- Result->reserveInits(NumElements);
+ Result->reserveInits(SemaRef.Context, NumElements);
// Link this new initializer list into the structured initializer
// lists.
if (StructuredList)
- StructuredList->updateInit(StructuredIndex, Result);
+ StructuredList->updateInit(SemaRef.Context, StructuredIndex, Result);
else {
Result->setSyntacticForm(IList);
SyntacticToSemantic[IList] = Result;
@@ -1730,7 +1730,8 @@ void InitListChecker::UpdateStructuredListElement(InitListExpr *StructuredList,
if (!StructuredList)
return;
- if (Expr *PrevInit = StructuredList->updateInit(StructuredIndex, expr)) {
+ if (Expr *PrevInit = StructuredList->updateInit(SemaRef.Context,
+ StructuredIndex, expr)) {
// This initializer overwrites a previous initializer. Warn.
SemaRef.Diag(expr->getSourceRange().getBegin(),
diag::warn_initializer_overrides)
OpenPOWER on IntegriCloud