[cfe-commits] r150684 - in /cfe/trunk: include/clang/AST/ExprCXX.h include/clang/Sema/Sema.h lib/AST/Expr.cpp lib/AST/ExprCXX.cpp lib/AST/ItaniumMangle.cpp lib/AST/StmtPrinter.cpp lib/AST/StmtProfile.cpp lib/CodeGen/CGExprCXX.cpp lib/Parse/ParseExprCXX.cpp lib/Sema/SemaExpr.cpp lib/Sema/SemaExprCXX.cpp lib/Sema/TreeTransform.h lib/Serialization/ASTReaderStmt.cpp lib/Serialization/ASTWriterStmt.cpp lib/StaticAnalyzer/Core/ExprEngineCXX.cpp test/Analysis/new.cpp tools/libclang/CIndex.cpp

Sebastian Redl sebastian.redl at getdesigned.at
Thu Feb 16 03:35:52 PST 2012


Author: cornedbee
Date: Thu Feb 16 05:35:52 2012
New Revision: 150684

URL: http://llvm.org/viewvc/llvm-project?rev=150684&view=rev
Log:
Revert "Make CXXNewExpr contain only a single initialier, and not hold the used constructor itself."
It leads to a compiler crash in the Bullet benchmark.

This reverts commit r12014.

Modified:
    cfe/trunk/include/clang/AST/ExprCXX.h
    cfe/trunk/include/clang/Sema/Sema.h
    cfe/trunk/lib/AST/Expr.cpp
    cfe/trunk/lib/AST/ExprCXX.cpp
    cfe/trunk/lib/AST/ItaniumMangle.cpp
    cfe/trunk/lib/AST/StmtPrinter.cpp
    cfe/trunk/lib/AST/StmtProfile.cpp
    cfe/trunk/lib/CodeGen/CGExprCXX.cpp
    cfe/trunk/lib/Parse/ParseExprCXX.cpp
    cfe/trunk/lib/Sema/SemaExpr.cpp
    cfe/trunk/lib/Sema/SemaExprCXX.cpp
    cfe/trunk/lib/Sema/TreeTransform.h
    cfe/trunk/lib/Serialization/ASTReaderStmt.cpp
    cfe/trunk/lib/Serialization/ASTWriterStmt.cpp
    cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
    cfe/trunk/test/Analysis/new.cpp
    cfe/trunk/tools/libclang/CIndex.cpp

Modified: cfe/trunk/include/clang/AST/ExprCXX.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/ExprCXX.h?rev=150684&r1=150683&r2=150684&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/ExprCXX.h (original)
+++ cfe/trunk/include/clang/AST/ExprCXX.h Thu Feb 16 05:35:52 2012
@@ -1359,24 +1359,34 @@
 class CXXNewExpr : public Expr {
   // Was the usage ::new, i.e. is the global new to be used?
   bool GlobalNew : 1;
+  // Is there an initializer? If not, built-ins are uninitialized, else they're
+  // value-initialized.
+  bool Initializer : 1;
   // Do we allocate an array? If so, the first SubExpr is the size expression.
   bool Array : 1;
   // If this is an array allocation, does the usual deallocation
   // function for the allocated type want to know the allocated size?
   bool UsualArrayDeleteWantsSize : 1;
+  // Whether the referred constructor (if any) was resolved from an
+  // overload set having size greater than 1.
+  bool HadMultipleCandidates : 1;
   // The number of placement new arguments.
   unsigned NumPlacementArgs : 13;
-  // What kind of initializer do we have? Could be none, parens, or braces.
-  // In storage, we distinguish between "none, and no initializer expr", and
-  // "none, but an implicit initializer expr".
-  unsigned StoredInitializationStyle : 2;
-  // Contains an optional array size expression, an optional initialization
-  // expression, and any number of optional placement arguments, in that order.
+  // The number of constructor arguments. This may be 1 even for non-class
+  // types; use the pseudo copy constructor.
+  unsigned NumConstructorArgs : 14;
+  // Contains an optional array size expression, any number of optional
+  // placement arguments, and any number of optional constructor arguments,
+  // in that order.
   Stmt **SubExprs;
   // Points to the allocation function used.
   FunctionDecl *OperatorNew;
   // Points to the deallocation function used in case of error. May be null.
   FunctionDecl *OperatorDelete;
+  // Points to the constructor used. Cannot be null if AllocType is a record;
+  // it would still point at the default constructor (even an implicit one).
+  // Must be null for all other types.
+  CXXConstructorDecl *Constructor;
 
   /// \brief The allocated type-source information, as written in the source.
   TypeSourceInfo *AllocatedTypeInfo;
@@ -1385,33 +1395,29 @@
   /// the source range covering the parenthesized type-id.
   SourceRange TypeIdParens;
 
-  /// \brief Location of the first token.
   SourceLocation StartLoc;
-
-  /// \brief Source-range of a paren-delimited initializer.
-  SourceRange DirectInitRange;
+  SourceLocation EndLoc;
+  SourceLocation ConstructorLParen;
+  SourceLocation ConstructorRParen;
 
   friend class ASTStmtReader;
-  friend class ASTStmtWriter;
 public:
-  enum InitializationStyle {
-    NoInit,   ///< New-expression has no initializer as written.
-    CallInit, ///< New-expression has a C++98 paren-delimited initializer.
-    ListInit  ///< New-expression has a C++11 list-initializer.
-  };
-
   CXXNewExpr(ASTContext &C, bool globalNew, FunctionDecl *operatorNew,
-             FunctionDecl *operatorDelete, bool usualArrayDeleteWantsSize,
              Expr **placementArgs, unsigned numPlaceArgs,
-             SourceRange typeIdParens, Expr *arraySize,
-             InitializationStyle initializationStyle, Expr *initializer,
+             SourceRange TypeIdParens,
+             Expr *arraySize, CXXConstructorDecl *constructor, bool initializer,
+             Expr **constructorArgs, unsigned numConsArgs,
+             bool HadMultipleCandidates,
+             FunctionDecl *operatorDelete, bool usualArrayDeleteWantsSize,
              QualType ty, TypeSourceInfo *AllocatedTypeInfo,
-             SourceLocation startLoc, SourceRange directInitRange);
+             SourceLocation startLoc, SourceLocation endLoc,
+             SourceLocation constructorLParen,
+             SourceLocation constructorRParen);
   explicit CXXNewExpr(EmptyShell Shell)
     : Expr(CXXNewExprClass, Shell), SubExprs(0) { }
 
   void AllocateArgsArray(ASTContext &C, bool isArray, unsigned numPlaceArgs,
-                         bool hasInitializer);
+                         unsigned numConsArgs);
 
   QualType getAllocatedType() const {
     assert(getType()->isPointerType());
@@ -1437,6 +1443,8 @@
   void setOperatorNew(FunctionDecl *D) { OperatorNew = D; }
   FunctionDecl *getOperatorDelete() const { return OperatorDelete; }
   void setOperatorDelete(FunctionDecl *D) { OperatorDelete = D; }
+  CXXConstructorDecl *getConstructor() const { return Constructor; }
+  void setConstructor(CXXConstructorDecl *D) { Constructor = D; }
 
   bool isArray() const { return Array; }
   Expr *getArraySize() {
@@ -1448,40 +1456,23 @@
 
   unsigned getNumPlacementArgs() const { return NumPlacementArgs; }
   Expr **getPlacementArgs() {
-    return reinterpret_cast<Expr **>(SubExprs + Array + hasInitializer());
+    return reinterpret_cast<Expr **>(SubExprs + Array);
   }
 
   Expr *getPlacementArg(unsigned i) {
     assert(i < NumPlacementArgs && "Index out of range");
-    return getPlacementArgs()[i];
+    return cast<Expr>(SubExprs[Array + i]);
   }
   const Expr *getPlacementArg(unsigned i) const {
     assert(i < NumPlacementArgs && "Index out of range");
-    return const_cast<CXXNewExpr*>(this)->getPlacementArg(i);
+    return cast<Expr>(SubExprs[Array + i]);
   }
 
   bool isParenTypeId() const { return TypeIdParens.isValid(); }
   SourceRange getTypeIdParens() const { return TypeIdParens; }
 
   bool isGlobalNew() const { return GlobalNew; }
-
-  /// \brief Whether this new-expression has any initializer at all.
-  bool hasInitializer() const { return StoredInitializationStyle > 0; }
-
-  /// \brief The kind of initializer this new-expression has.
-  InitializationStyle getInitializationStyle() const {
-    if (StoredInitializationStyle == 0)
-      return NoInit;
-    return static_cast<InitializationStyle>(StoredInitializationStyle-1);
-  }
-
-  /// \brief The initializer of this new-expression.
-  Expr *getInitializer() {
-    return hasInitializer() ? cast<Expr>(SubExprs[Array]) : 0;
-  }
-  const Expr *getInitializer() const {
-    return hasInitializer() ? cast<Expr>(SubExprs[Array]) : 0;
-  }
+  bool hasInitializer() const { return Initializer; }
 
   /// Answers whether the usual array deallocation function for the
   /// allocated type expects the size of the allocation as a
@@ -1490,39 +1481,71 @@
     return UsualArrayDeleteWantsSize;
   }
 
+  unsigned getNumConstructorArgs() const { return NumConstructorArgs; }
+
+  Expr **getConstructorArgs() {
+    return reinterpret_cast<Expr **>(SubExprs + Array + NumPlacementArgs);
+  }
+
+  Expr *getConstructorArg(unsigned i) {
+    assert(i < NumConstructorArgs && "Index out of range");
+    return cast<Expr>(SubExprs[Array + NumPlacementArgs + i]);
+  }
+  const Expr *getConstructorArg(unsigned i) const {
+    assert(i < NumConstructorArgs && "Index out of range");
+    return cast<Expr>(SubExprs[Array + NumPlacementArgs + i]);
+  }
+
+  /// \brief Whether the new expression refers a constructor that was
+  /// resolved from an overloaded set having size greater than 1.
+  bool hadMultipleCandidates() const { return HadMultipleCandidates; }
+  void setHadMultipleCandidates(bool V) { HadMultipleCandidates = V; }
+
   typedef ExprIterator arg_iterator;
   typedef ConstExprIterator const_arg_iterator;
 
   arg_iterator placement_arg_begin() {
-    return SubExprs + Array + hasInitializer();
+    return SubExprs + Array;
   }
   arg_iterator placement_arg_end() {
-    return SubExprs + Array + hasInitializer() + getNumPlacementArgs();
+    return SubExprs + Array + getNumPlacementArgs();
   }
   const_arg_iterator placement_arg_begin() const {
-    return SubExprs + Array + hasInitializer();
+    return SubExprs + Array;
   }
   const_arg_iterator placement_arg_end() const {
-    return SubExprs + Array + hasInitializer() + getNumPlacementArgs();
+    return SubExprs + Array + getNumPlacementArgs();
+  }
+
+  arg_iterator constructor_arg_begin() {
+    return SubExprs + Array + getNumPlacementArgs();
+  }
+  arg_iterator constructor_arg_end() {
+    return SubExprs + Array + getNumPlacementArgs() + getNumConstructorArgs();
+  }
+  const_arg_iterator constructor_arg_begin() const {
+    return SubExprs + Array + getNumPlacementArgs();
+  }
+  const_arg_iterator constructor_arg_end() const {
+    return SubExprs + Array + getNumPlacementArgs() + getNumConstructorArgs();
   }
 
   typedef Stmt **raw_arg_iterator;
   raw_arg_iterator raw_arg_begin() { return SubExprs; }
   raw_arg_iterator raw_arg_end() {
-    return SubExprs + Array + hasInitializer() + getNumPlacementArgs();
+    return SubExprs + Array + getNumPlacementArgs() + getNumConstructorArgs();
   }
   const_arg_iterator raw_arg_begin() const { return SubExprs; }
-  const_arg_iterator raw_arg_end() const {
-    return SubExprs + Array + hasInitializer() + getNumPlacementArgs();
-  }
+  const_arg_iterator raw_arg_end() const { return constructor_arg_end(); }
 
   SourceLocation getStartLoc() const { return StartLoc; }
-  SourceLocation getEndLoc() const;
+  SourceLocation getEndLoc() const { return EndLoc; }
 
-  SourceRange getDirectInitRange() const { return DirectInitRange; }
+  SourceLocation getConstructorLParen() const { return ConstructorLParen; }
+  SourceLocation getConstructorRParen() const { return ConstructorRParen; }
 
   SourceRange getSourceRange() const {
-    return SourceRange(getStartLoc(), getEndLoc());
+    return SourceRange(StartLoc, EndLoc);
   }
 
   static bool classof(const Stmt *T) {
@@ -1532,7 +1555,9 @@
 
   // Iterators
   child_range children() {
-    return child_range(raw_arg_begin(), raw_arg_end());
+    return child_range(&SubExprs[0],
+                       &SubExprs[0] + Array + getNumPlacementArgs()
+                         + getNumConstructorArgs());
   }
 };
 

Modified: cfe/trunk/include/clang/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=150684&r1=150683&r2=150684&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/Sema.h (original)
+++ cfe/trunk/include/clang/Sema/Sema.h Thu Feb 16 05:35:52 2012
@@ -3194,7 +3194,9 @@
                          MultiExprArg PlacementArgs,
                          SourceLocation PlacementRParen,
                          SourceRange TypeIdParens, Declarator &D,
-                         Expr *Initializer);
+                         SourceLocation ConstructorLParen,
+                         MultiExprArg ConstructorArgs,
+                         SourceLocation ConstructorRParen);
   ExprResult BuildCXXNew(SourceLocation StartLoc, bool UseGlobal,
                          SourceLocation PlacementLParen,
                          MultiExprArg PlacementArgs,
@@ -3203,8 +3205,9 @@
                          QualType AllocType,
                          TypeSourceInfo *AllocTypeInfo,
                          Expr *ArraySize,
-                         SourceRange DirectInitRange,
-                         Expr *Initializer,
+                         SourceLocation ConstructorLParen,
+                         MultiExprArg ConstructorArgs,
+                         SourceLocation ConstructorRParen,
                          bool TypeMayContainAuto = true);
 
   bool CheckAllocatedType(QualType AllocType, SourceLocation Loc,

Modified: cfe/trunk/lib/AST/Expr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Expr.cpp?rev=150684&r1=150683&r2=150684&view=diff
==============================================================================
--- cfe/trunk/lib/AST/Expr.cpp (original)
+++ cfe/trunk/lib/AST/Expr.cpp Thu Feb 16 05:35:52 2012
@@ -2041,7 +2041,10 @@
     if (isTypeDependent())
       CT = CT_Dependent;
     else
-      CT = CanCalleeThrow(C, this, cast<CXXNewExpr>(this)->getOperatorNew());
+      CT = MergeCanThrow(
+        CanCalleeThrow(C, this, cast<CXXNewExpr>(this)->getOperatorNew()),
+        CanCalleeThrow(C, this, cast<CXXNewExpr>(this)->getConstructor(),
+                       /*NullThrows*/false));
     if (CT == CT_Can)
       return CT;
     return MergeCanThrow(CT, CanSubExprsThrow(C, this));

Modified: cfe/trunk/lib/AST/ExprCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ExprCXX.cpp?rev=150684&r1=150683&r2=150684&view=diff
==============================================================================
--- cfe/trunk/lib/AST/ExprCXX.cpp (original)
+++ cfe/trunk/lib/AST/ExprCXX.cpp Thu Feb 16 05:35:52 2012
@@ -45,26 +45,30 @@
 
 // CXXNewExpr
 CXXNewExpr::CXXNewExpr(ASTContext &C, bool globalNew, FunctionDecl *operatorNew,
-                       FunctionDecl *operatorDelete,
-                       bool usualArrayDeleteWantsSize,
                        Expr **placementArgs, unsigned numPlaceArgs,
-                       SourceRange typeIdParens, Expr *arraySize,
-                       InitializationStyle initializationStyle,
-                       Expr *initializer, QualType ty,
-                       TypeSourceInfo *allocatedTypeInfo,
-                       SourceLocation startLoc, SourceRange directInitRange)
+                       SourceRange TypeIdParens, Expr *arraySize,
+                       CXXConstructorDecl *constructor, bool initializer,
+                       Expr **constructorArgs, unsigned numConsArgs,
+                       bool HadMultipleCandidates,
+                       FunctionDecl *operatorDelete,
+                       bool usualArrayDeleteWantsSize, QualType ty,
+                       TypeSourceInfo *AllocatedTypeInfo,
+                       SourceLocation startLoc, SourceLocation endLoc,
+                       SourceLocation constructorLParen,
+                       SourceLocation constructorRParen)
   : Expr(CXXNewExprClass, ty, VK_RValue, OK_Ordinary,
          ty->isDependentType(), ty->isDependentType(),
          ty->isInstantiationDependentType(),
          ty->containsUnexpandedParameterPack()),
-    GlobalNew(globalNew), UsualArrayDeleteWantsSize(usualArrayDeleteWantsSize),
-    SubExprs(0), OperatorNew(operatorNew), OperatorDelete(operatorDelete),
-    AllocatedTypeInfo(allocatedTypeInfo), TypeIdParens(typeIdParens),
-    StartLoc(startLoc), DirectInitRange(directInitRange) {
-  assert((initializer != 0 || initializationStyle == NoInit) &&
-         "Only NoInit can have no initializer.");
-  StoredInitializationStyle = initializer ? initializationStyle + 1 : 0;
-  AllocateArgsArray(C, arraySize != 0, numPlaceArgs, initializer != 0);
+    GlobalNew(globalNew), Initializer(initializer),
+    UsualArrayDeleteWantsSize(usualArrayDeleteWantsSize),
+    HadMultipleCandidates(HadMultipleCandidates),
+    SubExprs(0), OperatorNew(operatorNew),
+    OperatorDelete(operatorDelete), Constructor(constructor),
+    AllocatedTypeInfo(AllocatedTypeInfo), TypeIdParens(TypeIdParens),
+    StartLoc(startLoc), EndLoc(endLoc), ConstructorLParen(constructorLParen),
+    ConstructorRParen(constructorRParen) {
+  AllocateArgsArray(C, arraySize != 0, numPlaceArgs, numConsArgs);
   unsigned i = 0;
   if (Array) {
     if (arraySize->isInstantiationDependent())
@@ -76,33 +80,33 @@
     SubExprs[i++] = arraySize;
   }
 
-  if (initializer) {
-    if (initializer->isInstantiationDependent())
+  for (unsigned j = 0; j < NumPlacementArgs; ++j) {
+    if (placementArgs[j]->isInstantiationDependent())
       ExprBits.InstantiationDependent = true;
-
-    if (initializer->containsUnexpandedParameterPack())
+    if (placementArgs[j]->containsUnexpandedParameterPack())
       ExprBits.ContainsUnexpandedParameterPack = true;
 
-    SubExprs[i++] = initializer;
+    SubExprs[i++] = placementArgs[j];
   }
 
-  for (unsigned j = 0; j < NumPlacementArgs; ++j) {
-    if (placementArgs[j]->isInstantiationDependent())
+  for (unsigned j = 0; j < NumConstructorArgs; ++j) {
+    if (constructorArgs[j]->isInstantiationDependent())
       ExprBits.InstantiationDependent = true;
-    if (placementArgs[j]->containsUnexpandedParameterPack())
+    if (constructorArgs[j]->containsUnexpandedParameterPack())
       ExprBits.ContainsUnexpandedParameterPack = true;
 
-    SubExprs[i++] = placementArgs[j];
+    SubExprs[i++] = constructorArgs[j];
   }
 }
 
 void CXXNewExpr::AllocateArgsArray(ASTContext &C, bool isArray,
-                                   unsigned numPlaceArgs, bool hasInitializer){
+                                   unsigned numPlaceArgs, unsigned numConsArgs){
   assert(SubExprs == 0 && "SubExprs already allocated");
   Array = isArray;
   NumPlacementArgs = numPlaceArgs;
-
-  unsigned TotalSize = Array + hasInitializer + NumPlacementArgs;
+  NumConstructorArgs = numConsArgs; 
+  
+  unsigned TotalSize = Array + NumPlacementArgs + NumConstructorArgs;
   SubExprs = new (C) Stmt*[TotalSize];
 }
 
@@ -111,17 +115,6 @@
     castAs<FunctionProtoType>()->isNothrow(Ctx);
 }
 
-SourceLocation CXXNewExpr::getEndLoc() const {
-  switch (getInitializationStyle()) {
-  case NoInit:
-    return AllocatedTypeInfo->getTypeLoc().getEndLoc();
-  case CallInit:
-    return DirectInitRange.getEnd();
-  case ListInit:
-    return getInitializer()->getSourceRange().getEnd();
-  }
-}
-
 // CXXDeleteExpr
 QualType CXXDeleteExpr::getDestroyedType() const {
   const Expr *Arg = getArgument();

Modified: cfe/trunk/lib/AST/ItaniumMangle.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ItaniumMangle.cpp?rev=150684&r1=150683&r2=150684&view=diff
==============================================================================
--- cfe/trunk/lib/AST/ItaniumMangle.cpp (original)
+++ cfe/trunk/lib/AST/ItaniumMangle.cpp Thu Feb 16 05:35:52 2012
@@ -2351,20 +2351,10 @@
     Out << '_';
     mangleType(New->getAllocatedType());
     if (New->hasInitializer()) {
-      // FIXME: Does this mean "parenthesized initializer"?
       Out << "pi";
-      const Expr *Init = New->getInitializer();
-      if (const CXXConstructExpr *CCE = dyn_cast<CXXConstructExpr>(Init)) {
-        // Directly inline the initializers.
-        for (CXXConstructExpr::const_arg_iterator I = CCE->arg_begin(),
-                                                  E = CCE->arg_end();
-             I != E; ++I)
-          mangleExpression(*I);
-      } else if (const ParenListExpr *PLE = dyn_cast<ParenListExpr>(Init)) {
-        for (unsigned i = 0, e = PLE->getNumExprs(); i != e; ++i)
-          mangleExpression(PLE->getExpr(i));
-      } else
-        mangleExpression(Init);
+      for (CXXNewExpr::const_arg_iterator I = New->constructor_arg_begin(),
+             E = New->constructor_arg_end(); I != E; ++I)
+        mangleExpression(*I);
     }
     Out << 'E';
     break;

Modified: cfe/trunk/lib/AST/StmtPrinter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/StmtPrinter.cpp?rev=150684&r1=150683&r2=150684&view=diff
==============================================================================
--- cfe/trunk/lib/AST/StmtPrinter.cpp (original)
+++ cfe/trunk/lib/AST/StmtPrinter.cpp Thu Feb 16 05:35:52 2012
@@ -1390,13 +1390,17 @@
   if (E->isParenTypeId())
     OS << ")";
 
-  CXXNewExpr::InitializationStyle InitStyle = E->getInitializationStyle();
-  if (InitStyle) {
-    if (InitStyle == CXXNewExpr::CallInit)
-      OS << "(";
-    PrintExpr(E->getInitializer());
-    if (InitStyle == CXXNewExpr::CallInit)
-      OS << ")";
+  if (E->hasInitializer()) {
+    OS << "(";
+    unsigned NumCons = E->getNumConstructorArgs();
+    if (NumCons > 0) {
+      PrintExpr(E->getConstructorArg(0));
+      for (unsigned i = 1; i < NumCons; ++i) {
+        OS << ", ";
+        PrintExpr(E->getConstructorArg(i));
+      }
+    }
+    OS << ")";
   }
 }
 

Modified: cfe/trunk/lib/AST/StmtProfile.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/StmtProfile.cpp?rev=150684&r1=150683&r2=150684&view=diff
==============================================================================
--- cfe/trunk/lib/AST/StmtProfile.cpp (original)
+++ cfe/trunk/lib/AST/StmtProfile.cpp Thu Feb 16 05:35:52 2012
@@ -825,11 +825,13 @@
   VisitType(S->getAllocatedType());
   VisitDecl(S->getOperatorNew());
   VisitDecl(S->getOperatorDelete());
+  VisitDecl(S->getConstructor());
   ID.AddBoolean(S->isArray());
   ID.AddInteger(S->getNumPlacementArgs());
   ID.AddBoolean(S->isGlobalNew());
   ID.AddBoolean(S->isParenTypeId());
-  ID.AddInteger(S->getInitializationStyle());
+  ID.AddBoolean(S->hasInitializer());
+  ID.AddInteger(S->getNumConstructorArgs());
 }
 
 void

Modified: cfe/trunk/lib/CodeGen/CGExprCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExprCXX.cpp?rev=150684&r1=150683&r2=150684&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGExprCXX.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGExprCXX.cpp Thu Feb 16 05:35:52 2012
@@ -743,8 +743,11 @@
 
 static void StoreAnyExprIntoOneUnit(CodeGenFunction &CGF, const CXXNewExpr *E,
                                     llvm::Value *NewPtr) {
-
-  const Expr *Init = E->getInitializer();
+  
+  assert(E->getNumConstructorArgs() == 1 &&
+         "Can only have one argument to initializer of POD type.");
+  
+  const Expr *Init = E->getConstructorArg(0);
   QualType AllocType = E->getAllocatedType();
 
   CharUnits Alignment = CGF.getContext().getTypeAlignInChars(AllocType);
@@ -770,8 +773,9 @@
                                          QualType elementType,
                                          llvm::Value *beginPtr,
                                          llvm::Value *numElements) {
-  if (!E->hasInitializer())
-    return; // We have a POD type.
+  // We have a POD type.
+  if (E->getNumConstructorArgs() == 0)
+    return;
 
   // Check if the number of elements is constant.
   bool checkZero = true;
@@ -854,15 +858,13 @@
                                llvm::Value *NewPtr,
                                llvm::Value *NumElements,
                                llvm::Value *AllocSizeWithoutCookie) {
-  const Expr *Init = E->getInitializer();
   if (E->isArray()) {
-    if (const CXXConstructExpr *CCE = dyn_cast_or_null<CXXConstructExpr>(Init)){
-      CXXConstructorDecl *Ctor = CCE->getConstructor();
+    if (CXXConstructorDecl *Ctor = E->getConstructor()) {
       bool RequiresZeroInitialization = false;
       if (Ctor->getParent()->hasTrivialDefaultConstructor()) {
         // If new expression did not specify value-initialization, then there
         // is no initialization.
-        if (!CCE->requiresZeroInitialization() || Ctor->getParent()->isEmpty())
+        if (!E->hasInitializer() || Ctor->getParent()->isEmpty())
           return;
       
         if (CGF.CGM.getTypes().isZeroInitializable(ElementType)) {
@@ -875,38 +877,43 @@
         RequiresZeroInitialization = true;
       }
 
-      CGF.EmitCXXAggrConstructorCall(Ctor, NumElements, NewPtr,
-                                     CCE->arg_begin(),  CCE->arg_end(),
+      CGF.EmitCXXAggrConstructorCall(Ctor, NumElements, NewPtr, 
+                                     E->constructor_arg_begin(), 
+                                     E->constructor_arg_end(),
                                      RequiresZeroInitialization);
       return;
-    } else if (Init && isa<ImplicitValueInitExpr>(Init) &&
+    } else if (E->getNumConstructorArgs() == 1 &&
+               isa<ImplicitValueInitExpr>(E->getConstructorArg(0)) &&
                CGF.CGM.getTypes().isZeroInitializable(ElementType)) {
       // Optimization: since zero initialization will just set the memory
       // to all zeroes, generate a single memset to do it in one shot.
       EmitZeroMemSet(CGF, ElementType, NewPtr, AllocSizeWithoutCookie);
       return;
+    } else {
+      CGF.EmitNewArrayInitializer(E, ElementType, NewPtr, NumElements);
+      return;
     }
-    CGF.EmitNewArrayInitializer(E, ElementType, NewPtr, NumElements);
-    return;
   }
 
-  if (const CXXConstructExpr *CCE = dyn_cast_or_null<CXXConstructExpr>(Init)) {
-    CXXConstructorDecl *Ctor = CCE->getConstructor();
+  if (CXXConstructorDecl *Ctor = E->getConstructor()) {
     // Per C++ [expr.new]p15, if we have an initializer, then we're performing
     // direct initialization. C++ [dcl.init]p5 requires that we 
     // zero-initialize storage if there are no user-declared constructors.
-    if (!Ctor->getParent()->hasUserDeclaredConstructor() &&
+    if (E->hasInitializer() && 
+        !Ctor->getParent()->hasUserDeclaredConstructor() &&
         !Ctor->getParent()->isEmpty())
       CGF.EmitNullInitialization(NewPtr, ElementType);
+      
+    CGF.EmitCXXConstructorCall(Ctor, Ctor_Complete, /*ForVirtualBase=*/false, 
+                               NewPtr, E->constructor_arg_begin(),
+                               E->constructor_arg_end());
 
-    CGF.EmitCXXConstructorCall(Ctor, Ctor_Complete, /*ForVirtualBase=*/false,
-                               NewPtr, CCE->arg_begin(), CCE->arg_end());
     return;
   }
   // We have a POD type.
-  if (!Init)
+  if (E->getNumConstructorArgs() == 0)
     return;
-
+  
   StoreAnyExprIntoOneUnit(CGF, E, NewPtr);
 }
 
@@ -1138,7 +1145,7 @@
   // CXXNewExpr::shouldNullCheckAllocation()) and we have an
   // interesting initializer.
   bool nullCheck = allocatorType->isNothrow(getContext()) &&
-    (!allocType.isPODType(getContext()) || E->hasInitializer());
+    !(allocType.isPODType(getContext()) && !E->hasInitializer());
 
   llvm::BasicBlock *nullCheckBB = 0;
   llvm::BasicBlock *contBB = 0;
@@ -1204,7 +1211,7 @@
     DeactivateCleanupBlock(operatorDeleteCleanup, cleanupDominator);
     cleanupDominator->eraseFromParent();
   }
-
+  
   if (nullCheck) {
     conditional.end(*this);
 

Modified: cfe/trunk/lib/Parse/ParseExprCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseExprCXX.cpp?rev=150684&r1=150683&r2=150684&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseExprCXX.cpp (original)
+++ cfe/trunk/lib/Parse/ParseExprCXX.cpp Thu Feb 16 05:35:52 2012
@@ -2193,11 +2193,10 @@
     return ExprError();
   }
 
-  ExprResult Initializer;
+  ExprVector ConstructorArgs(Actions);
+  SourceLocation ConstructorLParen, ConstructorRParen;
 
   if (Tok.is(tok::l_paren)) {
-    SourceLocation ConstructorLParen, ConstructorRParen;
-    ExprVector ConstructorArgs(Actions);
     BalancedDelimiterTracker T(*this, tok::l_paren);
     T.consumeOpen();
     ConstructorLParen = T.getOpenLocation();
@@ -2214,20 +2213,19 @@
       SkipUntil(tok::semi, /*StopAtSemi=*/true, /*DontConsume=*/true);
       return ExprError();
     }
-    Initializer = Actions.ActOnParenListExpr(ConstructorLParen,
-                                             ConstructorRParen,
-                                             move_arg(ConstructorArgs));
   } else if (Tok.is(tok::l_brace) && getLang().CPlusPlus0x) {
     Diag(Tok.getLocation(),
          diag::warn_cxx98_compat_generalized_initializer_lists);
-    Initializer = ParseBraceInitializer();
+    ExprResult InitList = ParseBraceInitializer();
+    if (InitList.isInvalid())
+      return InitList;
+    ConstructorArgs.push_back(InitList.take());
   }
-  if (Initializer.isInvalid())
-    return Initializer;
 
   return Actions.ActOnCXXNew(Start, UseGlobal, PlacementLParen,
                              move_arg(PlacementArgs), PlacementRParen,
-                             TypeIdParens, DeclaratorInfo, Initializer.take());
+                             TypeIdParens, DeclaratorInfo, ConstructorLParen,
+                             move_arg(ConstructorArgs), ConstructorRParen);
 }
 
 /// ParseDirectNewDeclarator - Parses a direct-new-declarator. Intended to be

Modified: cfe/trunk/lib/Sema/SemaExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=150684&r1=150683&r2=150684&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExpr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExpr.cpp Thu Feb 16 05:35:52 2012
@@ -10148,13 +10148,15 @@
     }
     
     void VisitCXXNewExpr(CXXNewExpr *E) {
+      if (E->getConstructor())
+        S.MarkFunctionReferenced(E->getLocStart(), E->getConstructor());
       if (E->getOperatorNew())
         S.MarkFunctionReferenced(E->getLocStart(), E->getOperatorNew());
       if (E->getOperatorDelete())
         S.MarkFunctionReferenced(E->getLocStart(), E->getOperatorDelete());
       Inherited::VisitCXXNewExpr(E);
     }
-
+    
     void VisitCXXDeleteExpr(CXXDeleteExpr *E) {
       if (E->getOperatorDelete())
         S.MarkFunctionReferenced(E->getLocStart(), E->getOperatorDelete());

Modified: cfe/trunk/lib/Sema/SemaExprCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExprCXX.cpp?rev=150684&r1=150683&r2=150684&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExprCXX.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExprCXX.cpp Thu Feb 16 05:35:52 2012
@@ -914,7 +914,9 @@
 Sema::ActOnCXXNew(SourceLocation StartLoc, bool UseGlobal,
                   SourceLocation PlacementLParen, MultiExprArg PlacementArgs,
                   SourceLocation PlacementRParen, SourceRange TypeIdParens,
-                  Declarator &D, Expr *Initializer) {
+                  Declarator &D, SourceLocation ConstructorLParen,
+                  MultiExprArg ConstructorArgs,
+                  SourceLocation ConstructorRParen) {
   bool TypeContainsAuto = D.getDeclSpec().getTypeSpecType() == DeclSpec::TST_auto;
 
   Expr *ArraySize = 0;
@@ -959,10 +961,6 @@
   if (D.isInvalidType())
     return ExprError();
 
-  SourceRange DirectInitRange;
-  if (ParenListExpr *List = dyn_cast_or_null<ParenListExpr>(Initializer))
-    DirectInitRange = List->getSourceRange();
-
   return BuildCXXNew(StartLoc, UseGlobal,
                      PlacementLParen,
                      move(PlacementArgs),
@@ -971,27 +969,12 @@
                      AllocType,
                      TInfo,
                      ArraySize,
-                     DirectInitRange,
-                     Initializer,
+                     ConstructorLParen,
+                     move(ConstructorArgs),
+                     ConstructorRParen,
                      TypeContainsAuto);
 }
 
-static bool isLegalArrayNewInitializer(Expr *Init) {
-  if (!Init)
-    return true;
-  if (ParenListExpr *PLE = dyn_cast<ParenListExpr>(Init)) {
-    if (PLE->getNumExprs() != 1)
-      return PLE->getNumExprs() == 0;
-    Init = PLE->getExpr(0);
-  }
-  if (isa<ImplicitValueInitExpr>(Init))
-    return true;
-  else if (CXXConstructExpr *CCE = dyn_cast<CXXConstructExpr>(Init))
-    return !CCE->isListInitialization() &&
-           CCE->getConstructor()->isDefaultConstructor();
-  return false;
-}
-
 ExprResult
 Sema::BuildCXXNew(SourceLocation StartLoc, bool UseGlobal,
                   SourceLocation PlacementLParen,
@@ -1001,56 +984,29 @@
                   QualType AllocType,
                   TypeSourceInfo *AllocTypeInfo,
                   Expr *ArraySize,
-                  SourceRange DirectInitRange,
-                  Expr *Initializer,
+                  SourceLocation ConstructorLParen,
+                  MultiExprArg ConstructorArgs,
+                  SourceLocation ConstructorRParen,
                   bool TypeMayContainAuto) {
   SourceRange TypeRange = AllocTypeInfo->getTypeLoc().getSourceRange();
 
-  CXXNewExpr::InitializationStyle initStyle;
-  if (DirectInitRange.isValid()) {
-    assert(Initializer && "Have parens but no initializer.");
-    initStyle = CXXNewExpr::CallInit;
-  } else if (Initializer && isa<InitListExpr>(Initializer))
-    initStyle = CXXNewExpr::ListInit;
-  else {
-    assert((!Initializer || isa<ImplicitValueInitExpr>(Initializer) ||
-            isa<CXXConstructExpr>(Initializer)) &&
-           "Initializer expression that cannot have been implicitly created.");
-    initStyle = CXXNewExpr::NoInit;
-  }
-
-  Expr **Inits = &Initializer;
-  unsigned NumInits = Initializer ? 1 : 0;
-  if (initStyle == CXXNewExpr::CallInit) {
-    if (ParenListExpr *List = dyn_cast<ParenListExpr>(Initializer)) {
-      Inits = List->getExprs();
-      NumInits = List->getNumExprs();
-    } else if (CXXConstructExpr *CCE = dyn_cast<CXXConstructExpr>(Initializer)){
-      if (!isa<CXXTemporaryObjectExpr>(CCE)) {
-        // Can happen in template instantiation. Since this is just an implicit
-        // construction, we just take it apart and rebuild it.
-        Inits = CCE->getArgs();
-        NumInits = CCE->getNumArgs();
-      }
-    }
-  }
-
   // C++0x [decl.spec.auto]p6. Deduce the type which 'auto' stands in for.
   if (TypeMayContainAuto && AllocType->getContainedAutoType()) {
-    if (initStyle == CXXNewExpr::NoInit || NumInits == 0)
+    if (ConstructorArgs.size() == 0)
       return ExprError(Diag(StartLoc, diag::err_auto_new_requires_ctor_arg)
                        << AllocType << TypeRange);
-    if (initStyle == CXXNewExpr::ListInit)
-      return ExprError(Diag(Inits[0]->getSourceRange().getBegin(),
-                            diag::err_auto_new_requires_parens)
-                       << AllocType << TypeRange);
-    if (NumInits > 1) {
-      Expr *FirstBad = Inits[1];
+    if (ConstructorArgs.size() != 1) {
+      Expr *FirstBad = ConstructorArgs.get()[1];
       return ExprError(Diag(FirstBad->getSourceRange().getBegin(),
                             diag::err_auto_new_ctor_multiple_expressions)
                        << AllocType << TypeRange);
     }
-    Expr *Deduce = Inits[0];
+    Expr *Deduce = ConstructorArgs.get()[0];
+    if (ConstructorLParen.isInvalid()) {
+      return ExprError(Diag(Deduce->getSourceRange().getBegin(),
+                            diag::err_auto_new_requires_parens)
+                       << AllocType << TypeRange);
+    }
     TypeSourceInfo *DeducedType = 0;
     if (DeduceAutoType(AllocTypeInfo, Deduce, DeducedType) ==
             DAR_Failed)
@@ -1079,10 +1035,15 @@
   if (CheckAllocatedType(AllocType, TypeRange.getBegin(), TypeRange))
     return ExprError();
 
-  if (initStyle == CXXNewExpr::ListInit && isStdInitializerList(AllocType, 0)) {
+  bool ListInitialization = ConstructorLParen.isInvalid() &&
+                            ConstructorArgs.size() > 0;
+  assert((!ListInitialization || (ConstructorArgs.size() == 1 &&
+                                  isa<InitListExpr>(ConstructorArgs.get()[0])))
+         && "List initialization means a braced-init-list for arguments.");
+  if (ListInitialization && isStdInitializerList(AllocType, 0)) {
     Diag(AllocTypeInfo->getTypeLoc().getBeginLoc(),
          diag::warn_dangling_std_initializer_list)
-      << /*at end of FE*/0 << Inits[0]->getSourceRange();
+      << /*at end of FE*/0 << ConstructorArgs.get()[0]->getSourceRange();
   }
 
   // In ARC, infer 'retaining' for the allocated 
@@ -1240,18 +1201,25 @@
     }
   }
 
-  // Array 'new' can't have any initializers except empty parentheses.
-  if (!isLegalArrayNewInitializer(Initializer) &&
-      (ResultType->isArrayType() || ArraySize)) {
-    SourceRange InitRange(Inits[0]->getLocStart(),
-                          Inits[NumInits - 1]->getLocEnd());
+  bool Init = ConstructorLParen.isValid() || ConstructorArgs.size() > 0;
+  // --- Choosing a constructor ---
+  CXXConstructorDecl *Constructor = 0;
+  bool HadMultipleCandidates = false;
+  Expr **ConsArgs = (Expr**)ConstructorArgs.get();
+  unsigned NumConsArgs = ConstructorArgs.size();
+  ASTOwningVector<Expr*> ConvertedConstructorArgs(*this);
+
+  // Array 'new' can't have any initializers.
+  if (NumConsArgs && (ResultType->isArrayType() || ArraySize)) {
+    SourceRange InitRange(ConsArgs[0]->getLocStart(),
+                          ConsArgs[NumConsArgs - 1]->getLocEnd());
 
     Diag(StartLoc, diag::err_new_array_init_args) << InitRange;
     return ExprError();
   }
 
   if (!AllocType->isDependentType() &&
-      !Expr::hasAnyTypeDependentArguments(Inits, NumInits)) {
+      !Expr::hasAnyTypeDependentArguments(ConsArgs, NumConsArgs)) {
     // C++11 [expr.new]p15:
     //   A new-expression that creates an object of type T initializes that
     //   object as follows:
@@ -1259,31 +1227,49 @@
     //     - If the new-initializer is omitted, the object is default-
     //       initialized (8.5); if no initialization is performed,
     //       the object has indeterminate value
-      = initStyle == CXXNewExpr::NoInit
-          ? InitializationKind::CreateDefault(TypeRange.getBegin())
+      = !Init? InitializationKind::CreateDefault(TypeRange.getBegin())
     //     - Otherwise, the new-initializer is interpreted according to the
     //       initialization rules of 8.5 for direct-initialization.
-          : initStyle == CXXNewExpr::ListInit
-              ? InitializationKind::CreateDirectList(TypeRange.getBegin())
-              : InitializationKind::CreateDirect(TypeRange.getBegin(),
-                                                 DirectInitRange.getBegin(),
-                                                 DirectInitRange.getEnd());
+             : ListInitialization ? InitializationKind::CreateDirectList(
+                                                          TypeRange.getBegin())
+                                  : InitializationKind::CreateDirect(
+                                                          TypeRange.getBegin(),
+                                                          ConstructorLParen,
+                                                          ConstructorRParen);
 
     InitializedEntity Entity
       = InitializedEntity::InitializeNew(StartLoc, AllocType);
-    InitializationSequence InitSeq(*this, Entity, Kind, Inits, NumInits);
+    InitializationSequence InitSeq(*this, Entity, Kind, ConsArgs, NumConsArgs);
     ExprResult FullInit = InitSeq.Perform(*this, Entity, Kind,
-                                          MultiExprArg(Inits, NumInits));
+                                                move(ConstructorArgs));
     if (FullInit.isInvalid())
       return ExprError();
 
-    // FullInit is our initializer; strip off CXXBindTemporaryExprs, because
-    // we don't want the initialized object to be destructed.
-    if (CXXBindTemporaryExpr *Binder =
-            dyn_cast_or_null<CXXBindTemporaryExpr>(FullInit.get()))
-      FullInit = Owned(Binder->getSubExpr());
+    // FullInit is our initializer; walk through it to determine if it's a
+    // constructor call, which CXXNewExpr handles directly.
+    if (Expr *FullInitExpr = (Expr *)FullInit.get()) {
+      if (CXXBindTemporaryExpr *Binder
+            = dyn_cast<CXXBindTemporaryExpr>(FullInitExpr))
+        FullInitExpr = Binder->getSubExpr();
+      if (CXXConstructExpr *Construct
+                    = dyn_cast<CXXConstructExpr>(FullInitExpr)) {
+        Constructor = Construct->getConstructor();
+        HadMultipleCandidates = Construct->hadMultipleCandidates();
+        for (CXXConstructExpr::arg_iterator A = Construct->arg_begin(),
+                                         AEnd = Construct->arg_end();
+             A != AEnd; ++A)
+          ConvertedConstructorArgs.push_back(*A);
+      } else {
+        // Take the converted initializer.
+        ConvertedConstructorArgs.push_back(FullInit.release());
+      }
+    } else {
+      // No initialization required.
+    }
 
-    Initializer = FullInit.take();
+    // Take the converted arguments and use them for the new expression.
+    NumConsArgs = ConvertedConstructorArgs.size();
+    ConsArgs = (Expr **)ConvertedConstructorArgs.take();
   }
 
   // Mark the new and delete operators as referenced.
@@ -1295,9 +1281,8 @@
   // C++0x [expr.new]p17:
   //   If the new expression creates an array of objects of class type,
   //   access and ambiguity control are done for the destructor.
-  if (ArraySize && AllocType->isRecordType()) {
-    if (CXXDestructorDecl *dtor = LookupDestructor(
-            cast<CXXRecordDecl>(AllocType->getAs<RecordType>()->getDecl()))) {
+  if (ArraySize && Constructor) {
+    if (CXXDestructorDecl *dtor = LookupDestructor(Constructor->getParent())) {
       MarkFunctionReferenced(StartLoc, dtor);
       CheckDestructorAccess(StartLoc, dtor, 
                             PDiag(diag::err_access_dtor)
@@ -1306,18 +1291,25 @@
   }
 
   PlacementArgs.release();
+  ConstructorArgs.release();
 
   return Owned(new (Context) CXXNewExpr(Context, UseGlobal, OperatorNew,
+                                        PlaceArgs, NumPlaceArgs, TypeIdParens,
+                                        ArraySize, Constructor, Init,
+                                        ConsArgs, NumConsArgs,
+                                        HadMultipleCandidates,
                                         OperatorDelete,
                                         UsualArrayDeleteWantsSize,
-                                        PlaceArgs, NumPlaceArgs, TypeIdParens,
-                                        ArraySize, initStyle, Initializer,
                                         ResultType, AllocTypeInfo,
-                                        StartLoc, DirectInitRange));
+                                        StartLoc,
+                                        Init ? ConstructorRParen :
+                                               TypeRange.getEnd(),
+                                        ConstructorLParen, ConstructorRParen));
 }
 
-/// \brief Checks that a type is suitable as the allocated type
+/// CheckAllocatedType - Checks that a type is suitable as the allocated type
 /// in a new-expression.
+/// dimension off and stores the size expression in ArraySize.
 bool Sema::CheckAllocatedType(QualType AllocType, SourceLocation Loc,
                               SourceRange R) {
   // C++ 5.3.4p1: "[The] type shall be a complete object type, but not an

Modified: cfe/trunk/lib/Sema/TreeTransform.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/TreeTransform.h?rev=150684&r1=150683&r2=150684&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/TreeTransform.h (original)
+++ cfe/trunk/lib/Sema/TreeTransform.h Thu Feb 16 05:35:52 2012
@@ -1976,8 +1976,9 @@
                                QualType AllocatedType,
                                TypeSourceInfo *AllocatedTypeInfo,
                                Expr *ArraySize,
-                               SourceRange DirectInitRange,
-                               Expr *Initializer) {
+                               SourceLocation ConstructorLParen,
+                               MultiExprArg ConstructorArgs,
+                               SourceLocation ConstructorRParen) {
     return getSema().BuildCXXNew(StartLoc, UseGlobal,
                                  PlacementLParen,
                                  move(PlacementArgs),
@@ -1986,8 +1987,9 @@
                                  AllocatedType,
                                  AllocatedTypeInfo,
                                  ArraySize,
-                                 DirectInitRange,
-                                 Initializer);
+                                 ConstructorLParen,
+                                 move(ConstructorArgs),
+                                 ConstructorRParen);
   }
 
   /// \brief Build a new C++ "delete" expression.
@@ -7104,17 +7106,29 @@
   if (getDerived().TransformExprs(E->getPlacementArgs(), 
                                   E->getNumPlacementArgs(), true,
                                   PlacementArgs, &ArgumentChanged))
-    return ExprError();
+    return ExprError();  
 
-  // Transform the initializer (if any).
-  Expr *OldInit = E->getInitializer();
-  ExprResult NewInit;
-  if (OldInit)
-    NewInit = getDerived().TransformExpr(OldInit);
-  if (NewInit.isInvalid())
-    return ExprError();
+  // Transform the constructor arguments (if any).
+  // As an annoying corner case, we may have introduced an implicit value-
+  // initialization expression when allocating a new array, which we implicitly
+  // drop. It will be re-created during type checking.
+  ASTOwningVector<Expr*> ConstructorArgs(SemaRef);
+  if (!(E->isArray() && E->getNumConstructorArgs() == 1 &&
+        isa<ImplicitValueInitExpr>(E->getConstructorArgs()[0])) &&
+      TransformExprs(E->getConstructorArgs(), E->getNumConstructorArgs(), true,
+                     ConstructorArgs, &ArgumentChanged))
+    return ExprError();  
+
+  // Transform constructor, new operator, and delete operator.
+  CXXConstructorDecl *Constructor = 0;
+  if (E->getConstructor()) {
+    Constructor = cast_or_null<CXXConstructorDecl>(
+                                   getDerived().TransformDecl(E->getLocStart(),
+                                                         E->getConstructor()));
+    if (!Constructor)
+      return ExprError();
+  }
 
-  // Transform new operator and delete operator.
   FunctionDecl *OperatorNew = 0;
   if (E->getOperatorNew()) {
     OperatorNew = cast_or_null<FunctionDecl>(
@@ -7136,18 +7150,21 @@
   if (!getDerived().AlwaysRebuild() &&
       AllocTypeInfo == E->getAllocatedTypeSourceInfo() &&
       ArraySize.get() == E->getArraySize() &&
-      NewInit.get() == OldInit &&
+      Constructor == E->getConstructor() &&
       OperatorNew == E->getOperatorNew() &&
       OperatorDelete == E->getOperatorDelete() &&
       !ArgumentChanged) {
     // Mark any declarations we need as referenced.
     // FIXME: instantiation-specific.
+    if (Constructor)
+      SemaRef.MarkFunctionReferenced(E->getLocStart(), Constructor);
     if (OperatorNew)
       SemaRef.MarkFunctionReferenced(E->getLocStart(), OperatorNew);
     if (OperatorDelete)
       SemaRef.MarkFunctionReferenced(E->getLocStart(), OperatorDelete);
     
-    if (E->isArray() && !E->getAllocatedType()->isDependentType()) {
+    if (E->isArray() && Constructor && 
+        !E->getAllocatedType()->isDependentType()) {
       QualType ElementType
         = SemaRef.Context.getBaseElementType(E->getAllocatedType());
       if (const RecordType *RecordT = ElementType->getAs<RecordType>()) {
@@ -7157,7 +7174,7 @@
         }
       }
     }
-
+    
     return SemaRef.Owned(E);
   }
 
@@ -7187,7 +7204,7 @@
       }
     }
   }
-
+  
   return getDerived().RebuildCXXNewExpr(E->getLocStart(),
                                         E->isGlobalNew(),
                                         /*FIXME:*/E->getLocStart(),
@@ -7197,8 +7214,9 @@
                                         AllocType,
                                         AllocTypeInfo,
                                         ArraySize.get(),
-                                        E->getDirectInitRange(),
-                                        NewInit.take());
+                                        E->getConstructorLParen(),
+                                        move_arg(ConstructorArgs),
+                                        E->getConstructorRParen());
 }
 
 template<typename Derived>

Modified: cfe/trunk/lib/Serialization/ASTReaderStmt.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReaderStmt.cpp?rev=150684&r1=150683&r2=150684&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTReaderStmt.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTReaderStmt.cpp Thu Feb 16 05:35:52 2012
@@ -1167,24 +1167,27 @@
 void ASTStmtReader::VisitCXXNewExpr(CXXNewExpr *E) {
   VisitExpr(E);
   E->GlobalNew = Record[Idx++];
-  bool isArray = Record[Idx++];
+  E->Initializer = Record[Idx++];
   E->UsualArrayDeleteWantsSize = Record[Idx++];
+  bool isArray = Record[Idx++];
+  E->setHadMultipleCandidates(Record[Idx++]);
   unsigned NumPlacementArgs = Record[Idx++];
-  E->StoredInitializationStyle = Record[Idx++];
+  unsigned NumCtorArgs = Record[Idx++];
   E->setOperatorNew(ReadDeclAs<FunctionDecl>(Record, Idx));
   E->setOperatorDelete(ReadDeclAs<FunctionDecl>(Record, Idx));
+  E->setConstructor(ReadDeclAs<CXXConstructorDecl>(Record, Idx));
   E->AllocatedTypeInfo = GetTypeSourceInfo(Record, Idx);
   SourceRange TypeIdParens;
   TypeIdParens.setBegin(ReadSourceLocation(Record, Idx));
   TypeIdParens.setEnd(ReadSourceLocation(Record, Idx));
   E->TypeIdParens = TypeIdParens;
   E->StartLoc = ReadSourceLocation(Record, Idx);
-  SourceRange DirectInitRange;
-  DirectInitRange.setBegin(ReadSourceLocation(Record, Idx));
-  DirectInitRange.setEnd(ReadSourceLocation(Record, Idx));
+  E->EndLoc = ReadSourceLocation(Record, Idx);
+  E->ConstructorLParen = ReadSourceLocation(Record, Idx);
+  E->ConstructorRParen = ReadSourceLocation(Record, Idx);
 
   E->AllocateArgsArray(Reader.getContext(), isArray, NumPlacementArgs,
-                       E->StoredInitializationStyle != 0);
+                       NumCtorArgs);
 
   // Install all the subexpressions.
   for (CXXNewExpr::raw_arg_iterator I = E->raw_arg_begin(),e = E->raw_arg_end();

Modified: cfe/trunk/lib/Serialization/ASTWriterStmt.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTWriterStmt.cpp?rev=150684&r1=150683&r2=150684&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTWriterStmt.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTWriterStmt.cpp Thu Feb 16 05:35:52 2012
@@ -1158,20 +1158,25 @@
 void ASTStmtWriter::VisitCXXNewExpr(CXXNewExpr *E) {
   VisitExpr(E);
   Record.push_back(E->isGlobalNew());
-  Record.push_back(E->isArray());
+  Record.push_back(E->hasInitializer());
   Record.push_back(E->doesUsualArrayDeleteWantSize());
+  Record.push_back(E->isArray());
+  Record.push_back(E->hadMultipleCandidates());
   Record.push_back(E->getNumPlacementArgs());
-  Record.push_back(E->StoredInitializationStyle);
+  Record.push_back(E->getNumConstructorArgs());
   Writer.AddDeclRef(E->getOperatorNew(), Record);
   Writer.AddDeclRef(E->getOperatorDelete(), Record);
+  Writer.AddDeclRef(E->getConstructor(), Record);
   Writer.AddTypeSourceInfo(E->getAllocatedTypeSourceInfo(), Record);
   Writer.AddSourceRange(E->getTypeIdParens(), Record);
   Writer.AddSourceLocation(E->getStartLoc(), Record);
-  Writer.AddSourceRange(E->getDirectInitRange(), Record);
+  Writer.AddSourceLocation(E->getEndLoc(), Record);
+  Writer.AddSourceLocation(E->getConstructorLParen(), Record);
+  Writer.AddSourceLocation(E->getConstructorRParen(), Record);
   for (CXXNewExpr::arg_iterator I = E->raw_arg_begin(), e = E->raw_arg_end();
        I != e; ++I)
     Writer.AddStmt(*I);
-
+  
   Code = serialization::EXPR_CXX_NEW;
 }
 

Modified: cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp?rev=150684&r1=150683&r2=150684&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp Thu Feb 16 05:35:52 2012
@@ -268,8 +268,6 @@
     return;
   }
 
-  // FIXME: Update for AST changes.
-#if 0
   // Evaluate constructor arguments.
   const FunctionProtoType *FnType = NULL;
   const CXXConstructorDecl *CD = CNE->getConstructor();
@@ -329,7 +327,6 @@
                             loc::MemRegionVal(EleReg));
     Bldr.generateNode(CNE, *I, state);
   }
-#endif
 }
 
 void ExprEngine::VisitCXXDeleteExpr(const CXXDeleteExpr *CDE, 

Modified: cfe/trunk/test/Analysis/new.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/new.cpp?rev=150684&r1=150683&r2=150684&view=diff
==============================================================================
--- cfe/trunk/test/Analysis/new.cpp (original)
+++ cfe/trunk/test/Analysis/new.cpp Thu Feb 16 05:35:52 2012
@@ -1,5 +1,4 @@
 // RUN: %clang_cc1 -analyze -analyzer-checker=core -analyzer-store region -verify %s
-// XFAIL: *
 
 void f1() {
   int *n = new int;

Modified: cfe/trunk/tools/libclang/CIndex.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/libclang/CIndex.cpp?rev=150684&r1=150683&r2=150684&view=diff
==============================================================================
--- cfe/trunk/tools/libclang/CIndex.cpp (original)
+++ cfe/trunk/tools/libclang/CIndex.cpp Thu Feb 16 05:35:52 2012
@@ -1856,8 +1856,9 @@
     AddStmt(E->getBase());
 }
 void EnqueueVisitor::VisitCXXNewExpr(CXXNewExpr *E) {
-  // Enqueue the initializer , if any.
-  AddStmt(E->getInitializer());
+  // Enqueue the initializer or constructor arguments.
+  for (unsigned I = E->getNumConstructorArgs(); I > 0; --I)
+    AddStmt(E->getConstructorArg(I-1));
   // Enqueue the array size, if any.
   AddStmt(E->getArraySize());
   // Enqueue the allocated type.





More information about the cfe-commits mailing list