[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