Allocate the SubExprs array in ObjCMessageExpr using the allocator associated with ASTContext.  This fixes yet another leak (<rdar://problem/7639260>).


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@95930 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/include/clang/AST/ExprObjC.h b/include/clang/AST/ExprObjC.h
index 0b0cd64..df39b53 100644
--- a/include/clang/AST/ExprObjC.h
+++ b/include/clang/AST/ExprObjC.h
@@ -367,7 +367,7 @@
 public:
   /// This constructor is used to represent class messages where the
   /// ObjCInterfaceDecl* of the receiver is not known.
-  ObjCMessageExpr(IdentifierInfo *clsName, Selector selInfo,
+  ObjCMessageExpr(ASTContext &C, IdentifierInfo *clsName, Selector selInfo,
                   QualType retType, ObjCMethodDecl *methDecl,
                   SourceLocation LBrac, SourceLocation RBrac,
                   Expr **ArgExprs, unsigned NumArgs);
@@ -375,13 +375,13 @@
   /// This constructor is used to represent class messages where the
   /// ObjCInterfaceDecl* of the receiver is known.
   // FIXME: clsName should be typed to ObjCInterfaceType
-  ObjCMessageExpr(ObjCInterfaceDecl *cls, Selector selInfo,
+  ObjCMessageExpr(ASTContext &C, ObjCInterfaceDecl *cls, Selector selInfo,
                   QualType retType, ObjCMethodDecl *methDecl,
                   SourceLocation LBrac, SourceLocation RBrac,
                   Expr **ArgExprs, unsigned NumArgs);
 
   // constructor for instance messages.
-  ObjCMessageExpr(Expr *receiver, Selector selInfo,
+  ObjCMessageExpr(ASTContext &C, Expr *receiver, Selector selInfo,
                   QualType retType, ObjCMethodDecl *methDecl,
                   SourceLocation LBrac, SourceLocation RBrac,
                   Expr **ArgExprs, unsigned NumArgs);
@@ -389,9 +389,7 @@
   explicit ObjCMessageExpr(EmptyShell Empty)
     : Expr(ObjCMessageExprClass, Empty), SubExprs(0), NumArgs(0) {}
 
-  ~ObjCMessageExpr() {
-    delete [] SubExprs;
-  }
+  virtual void DoDestroy(ASTContext &C);
 
   /// getReceiver - Returns the receiver of the message expression.
   ///  This can be NULL if the message is for class methods.  For
diff --git a/lib/AST/Expr.cpp b/lib/AST/Expr.cpp
index 73f6a2c..73a650f 100644
--- a/lib/AST/Expr.cpp
+++ b/lib/AST/Expr.cpp
@@ -2057,14 +2057,15 @@
 }
 
 // constructor for instance messages.
-ObjCMessageExpr::ObjCMessageExpr(Expr *receiver, Selector selInfo,
-                QualType retType, ObjCMethodDecl *mproto,
-                SourceLocation LBrac, SourceLocation RBrac,
-                Expr **ArgExprs, unsigned nargs)
+ObjCMessageExpr::ObjCMessageExpr(ASTContext &C, Expr *receiver,
+                                 Selector selInfo,
+                                 QualType retType, ObjCMethodDecl *mproto,
+                                 SourceLocation LBrac, SourceLocation RBrac,
+                                 Expr **ArgExprs, unsigned nargs)
   : Expr(ObjCMessageExprClass, retType, false, false), SelName(selInfo),
     MethodProto(mproto) {
   NumArgs = nargs;
-  SubExprs = new Stmt*[NumArgs+1];
+  SubExprs = new (C) Stmt*[NumArgs+1];
   SubExprs[RECEIVER] = receiver;
   if (NumArgs) {
     for (unsigned i = 0; i != NumArgs; ++i)
@@ -2076,14 +2077,15 @@
 
 // constructor for class messages.
 // FIXME: clsName should be typed to ObjCInterfaceType
-ObjCMessageExpr::ObjCMessageExpr(IdentifierInfo *clsName, Selector selInfo,
-                QualType retType, ObjCMethodDecl *mproto,
-                SourceLocation LBrac, SourceLocation RBrac,
-                Expr **ArgExprs, unsigned nargs)
+ObjCMessageExpr::ObjCMessageExpr(ASTContext &C, IdentifierInfo *clsName,
+                                 Selector selInfo, QualType retType,
+                                 ObjCMethodDecl *mproto,
+                                 SourceLocation LBrac, SourceLocation RBrac,
+                                 Expr **ArgExprs, unsigned nargs)
   : Expr(ObjCMessageExprClass, retType, false, false), SelName(selInfo),
     MethodProto(mproto) {
   NumArgs = nargs;
-  SubExprs = new Stmt*[NumArgs+1];
+  SubExprs = new (C) Stmt*[NumArgs+1];
   SubExprs[RECEIVER] = (Expr*) ((uintptr_t) clsName | IsClsMethDeclUnknown);
   if (NumArgs) {
     for (unsigned i = 0; i != NumArgs; ++i)
@@ -2094,14 +2096,15 @@
 }
 
 // constructor for class messages.
-ObjCMessageExpr::ObjCMessageExpr(ObjCInterfaceDecl *cls, Selector selInfo,
-                                 QualType retType, ObjCMethodDecl *mproto,
-                                 SourceLocation LBrac, SourceLocation RBrac,
-                                 Expr **ArgExprs, unsigned nargs)
+ObjCMessageExpr::ObjCMessageExpr(ASTContext &C, ObjCInterfaceDecl *cls,
+                                 Selector selInfo, QualType retType,
+                                 ObjCMethodDecl *mproto, SourceLocation LBrac,
+                                 SourceLocation RBrac, Expr **ArgExprs,
+                                 unsigned nargs)
 : Expr(ObjCMessageExprClass, retType, false, false), SelName(selInfo),
 MethodProto(mproto) {
   NumArgs = nargs;
-  SubExprs = new Stmt*[NumArgs+1];
+  SubExprs = new (C) Stmt*[NumArgs+1];
   SubExprs[RECEIVER] = (Expr*) ((uintptr_t) cls | IsClsMethDeclKnown);
   if (NumArgs) {
     for (unsigned i = 0; i != NumArgs; ++i)
@@ -2136,6 +2139,13 @@
     SubExprs[RECEIVER] = (Expr*)((uintptr_t)CI.first | IsClsMethDeclKnown);
 }
 
+void ObjCMessageExpr::DoDestroy(ASTContext &C) {
+  DestroyChildren(C);
+  if (SubExprs)
+    C.Deallocate(SubExprs);
+  this->~ObjCMessageExpr();
+  C.Deallocate((void*) this);
+}
 
 bool ChooseExpr::isConditionTrue(ASTContext &C) const {
   return getCond()->EvaluateAsInt(C) != 0;
diff --git a/lib/Frontend/RewriteObjC.cpp b/lib/Frontend/RewriteObjC.cpp
index dde4b0f..a2dd8d3 100644
--- a/lib/Frontend/RewriteObjC.cpp
+++ b/lib/Frontend/RewriteObjC.cpp
@@ -1159,7 +1159,7 @@
     // This allows us to handle chain/nested property getters.
     Receiver = PropGetters[PRE];
   }
-  MsgExpr = new (Context) ObjCMessageExpr(dyn_cast<Expr>(Receiver),
+  MsgExpr = new (Context) ObjCMessageExpr(*Context, dyn_cast<Expr>(Receiver),
                                 PDecl->getSetterName(), PDecl->getType(),
                                 PDecl->getSetterMethodDecl(),
                                 SourceLocation(), SourceLocation(),
@@ -1188,7 +1188,7 @@
     // This allows us to handle chain/nested property getters.
     Receiver = PropGetters[PRE];
   }
-  MsgExpr = new (Context) ObjCMessageExpr(dyn_cast<Expr>(Receiver),
+  MsgExpr = new (Context) ObjCMessageExpr(*Context, dyn_cast<Expr>(Receiver),
                                 PDecl->getGetterName(), PDecl->getType(),
                                 PDecl->getGetterMethodDecl(),
                                 SourceLocation(), SourceLocation(),
diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp
index 3ce3c28..0563428 100644
--- a/lib/Sema/SemaExpr.cpp
+++ b/lib/Sema/SemaExpr.cpp
@@ -3043,7 +3043,7 @@
         if (DiagnoseUseOfDecl(OMD, MemberLoc))
           return ExprError();
 
-        return Owned(new (Context) ObjCMessageExpr(BaseExpr, Sel,
+        return Owned(new (Context) ObjCMessageExpr(Context, BaseExpr, Sel,
                                                    OMD->getResultType(),
                                                    OMD, OpLoc, MemberLoc,
                                                    NULL, 0));
diff --git a/lib/Sema/SemaExprObjC.cpp b/lib/Sema/SemaExprObjC.cpp
index 85956c3..0c5d8ef 100644
--- a/lib/Sema/SemaExprObjC.cpp
+++ b/lib/Sema/SemaExprObjC.cpp
@@ -470,11 +470,13 @@
   // now, we simply pass the "super" identifier through (which isn't consistent
   // with instance methods.
   if (isSuper)
-    return new (Context) ObjCMessageExpr(receiverName, Sel, returnType, Method,
-                                         lbrac, rbrac, ArgExprs, NumArgs);
+    return new (Context) ObjCMessageExpr(Context, receiverName, Sel, returnType,
+                                         Method, lbrac, rbrac, ArgExprs,
+                                         NumArgs);
   else
-    return new (Context) ObjCMessageExpr(ClassDecl, Sel, returnType, Method,
-                                         lbrac, rbrac, ArgExprs, NumArgs);
+    return new (Context) ObjCMessageExpr(Context, ClassDecl, Sel, returnType,
+                                         Method, lbrac, rbrac, ArgExprs,
+                                         NumArgs);
 }
 
 // ActOnInstanceMessage - used for both unary and keyword messages.
@@ -521,8 +523,9 @@
       return true;
 
     returnType = returnType.getNonReferenceType();
-    return new (Context) ObjCMessageExpr(RExpr, Sel, returnType, Method, lbrac,
-                                         rbrac, ArgExprs, NumArgs);
+    return new (Context) ObjCMessageExpr(Context, RExpr, Sel, returnType,
+                                         Method, lbrac, rbrac,
+                                         ArgExprs, NumArgs);
   }
 
   // Handle messages to id.
@@ -536,8 +539,9 @@
                                   lbrac, rbrac, returnType))
       return true;
     returnType = returnType.getNonReferenceType();
-    return new (Context) ObjCMessageExpr(RExpr, Sel, returnType, Method, lbrac,
-                                         rbrac, ArgExprs, NumArgs);
+    return new (Context) ObjCMessageExpr(Context, RExpr, Sel, returnType,
+                                         Method, lbrac, rbrac,
+                                         ArgExprs, NumArgs);
   }
 
   // Handle messages to Class.
@@ -582,8 +586,9 @@
                                   lbrac, rbrac, returnType))
       return true;
     returnType = returnType.getNonReferenceType();
-    return new (Context) ObjCMessageExpr(RExpr, Sel, returnType, Method, lbrac,
-                                         rbrac, ArgExprs, NumArgs);
+    return new (Context) ObjCMessageExpr(Context, RExpr, Sel, returnType,
+                                         Method, lbrac, rbrac,
+                                         ArgExprs, NumArgs);
   }
 
   ObjCMethodDecl *Method = 0;
@@ -665,7 +670,7 @@
                                 lbrac, rbrac, returnType))
     return true;
   returnType = returnType.getNonReferenceType();
-  return new (Context) ObjCMessageExpr(RExpr, Sel, returnType, Method, lbrac,
-                                       rbrac, ArgExprs, NumArgs);
+  return new (Context) ObjCMessageExpr(Context, RExpr, Sel, returnType, Method,
+                                       lbrac, rbrac, ArgExprs, NumArgs);
 }