Fix leak in CXXNewExpr where the SubExprs array would get allocated directly using 'new[]' instead of the allocator associated with ASTContext.


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@95933 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/include/clang/AST/ExprCXX.h b/include/clang/AST/ExprCXX.h
index 6567b14..e4bc4b7 100644
--- a/include/clang/AST/ExprCXX.h
+++ b/include/clang/AST/ExprCXX.h
@@ -862,15 +862,14 @@
   SourceLocation EndLoc;
 
 public:
-  CXXNewExpr(bool globalNew, FunctionDecl *operatorNew, Expr **placementArgs,
-             unsigned numPlaceArgs, bool ParenTypeId, Expr *arraySize,
-             CXXConstructorDecl *constructor, bool initializer,
+  CXXNewExpr(ASTContext &C, bool globalNew, FunctionDecl *operatorNew,
+             Expr **placementArgs, unsigned numPlaceArgs, bool ParenTypeId,
+             Expr *arraySize, CXXConstructorDecl *constructor, bool initializer,
              Expr **constructorArgs, unsigned numConsArgs,
              FunctionDecl *operatorDelete, QualType ty,
              SourceLocation startLoc, SourceLocation endLoc);
-  ~CXXNewExpr() {
-    delete[] SubExprs;
-  }
+  
+  virtual void DoDestroy(ASTContext &C);
 
   QualType getAllocatedType() const {
     assert(getType()->isPointerType());
diff --git a/lib/AST/ExprCXX.cpp b/lib/AST/ExprCXX.cpp
index 7c68290..f4b8333 100644
--- a/lib/AST/ExprCXX.cpp
+++ b/lib/AST/ExprCXX.cpp
@@ -73,7 +73,7 @@
 }
 
 // CXXNewExpr
-CXXNewExpr::CXXNewExpr(bool globalNew, FunctionDecl *operatorNew,
+CXXNewExpr::CXXNewExpr(ASTContext &C, bool globalNew, FunctionDecl *operatorNew,
                        Expr **placementArgs, unsigned numPlaceArgs,
                        bool parenTypeId, Expr *arraySize,
                        CXXConstructorDecl *constructor, bool initializer,
@@ -87,7 +87,7 @@
     OperatorDelete(operatorDelete), Constructor(constructor),
     StartLoc(startLoc), EndLoc(endLoc) {
   unsigned TotalSize = Array + NumPlacementArgs + NumConstructorArgs;
-  SubExprs = new Stmt*[TotalSize];
+  SubExprs = new (C) Stmt*[TotalSize];
   unsigned i = 0;
   if (Array)
     SubExprs[i++] = arraySize;
@@ -98,6 +98,14 @@
   assert(i == TotalSize);
 }
 
+void CXXNewExpr::DoDestroy(ASTContext &C) {
+  DestroyChildren(C);
+  if (SubExprs)
+    C.Deallocate(SubExprs);
+  this->~CXXNewExpr();
+  C.Deallocate((void*)this);
+}
+
 Stmt::child_iterator CXXNewExpr::child_begin() { return &SubExprs[0]; }
 Stmt::child_iterator CXXNewExpr::child_end() {
   return &SubExprs[0] + Array + getNumPlacementArgs() + getNumConstructorArgs();
diff --git a/lib/Sema/SemaExprCXX.cpp b/lib/Sema/SemaExprCXX.cpp
index 877ac2a..9eeda54 100644
--- a/lib/Sema/SemaExprCXX.cpp
+++ b/lib/Sema/SemaExprCXX.cpp
@@ -520,10 +520,13 @@
   PlacementArgs.release();
   ConstructorArgs.release();
   ArraySizeE.release();
-  return Owned(new (Context) CXXNewExpr(UseGlobal, OperatorNew, PlaceArgs,
-                        NumPlaceArgs, ParenTypeId, ArraySize, Constructor, Init,
-                        ConsArgs, NumConsArgs, OperatorDelete, ResultType,
-                        StartLoc, Init ? ConstructorRParen : SourceLocation()));
+  return Owned(new (Context) CXXNewExpr(Context, UseGlobal, OperatorNew,
+                                        PlaceArgs, NumPlaceArgs, ParenTypeId,
+                                        ArraySize, Constructor, Init,
+                                        ConsArgs, NumConsArgs, OperatorDelete,
+                                        ResultType, StartLoc,
+                                        Init ? ConstructorRParen :
+                                               SourceLocation()));
 }
 
 /// CheckAllocatedType - Checks that a type is suitable as the allocated type