diff options
author | Fariborz Jahanian <fjahanian@apple.com> | 2009-11-19 18:39:40 +0000 |
---|---|---|
committer | Fariborz Jahanian <fjahanian@apple.com> | 2009-11-19 18:39:40 +0000 |
commit | 498429fa24555ac1c849d8bc6a893d29bd3da4b6 (patch) | |
tree | bdc8b87f4e91d1380cd215f5cc2870fdde44aa93 | |
parent | f010b26b60f3f51b6fa0335218c9a458ec30cff4 (diff) |
Patch to implement new-operators with default args.
Fixes pr5547.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@89370 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/Sema/SemaExprCXX.cpp | 34 | ||||
-rw-r--r-- | test/CodeGenCXX/new-with-default-arg.cpp | 33 |
2 files changed, 64 insertions, 3 deletions
diff --git a/lib/Sema/SemaExprCXX.cpp b/lib/Sema/SemaExprCXX.cpp index 462bf13540..209d3069ca 100644 --- a/lib/Sema/SemaExprCXX.cpp +++ b/lib/Sema/SemaExprCXX.cpp @@ -326,7 +326,7 @@ Sema::ActOnCXXNew(SourceLocation StartLoc, bool UseGlobal, QualType AllocType = GetTypeForDeclarator(D, /*Scope=*/0, &DInfo); if (D.isInvalidType()) return ExprError(); - + return BuildCXXNew(StartLoc, UseGlobal, PlacementLParen, move(PlacementArgs), @@ -394,7 +394,7 @@ Sema::BuildCXXNew(SourceLocation StartLoc, bool UseGlobal, FunctionDecl *OperatorDelete = 0; Expr **PlaceArgs = (Expr**)PlacementArgs.get(); unsigned NumPlaceArgs = PlacementArgs.size(); - + if (!AllocType->isDependentType() && !Expr::hasAnyTypeDependentArguments(PlaceArgs, NumPlaceArgs) && FindAllocationFunctions(StartLoc, @@ -402,7 +402,35 @@ Sema::BuildCXXNew(SourceLocation StartLoc, bool UseGlobal, UseGlobal, AllocType, ArraySize, PlaceArgs, NumPlaceArgs, OperatorNew, OperatorDelete)) return ExprError(); - + llvm::SmallVector<Expr *, 4> AllPlaceArgs; + if (OperatorNew) { + // Add default arguments, if any. + const FunctionProtoType *Proto = + OperatorNew->getType()->getAs<FunctionProtoType>(); + unsigned NumArgsInProto = Proto->getNumArgs(); + for (unsigned i = 1; i != NumArgsInProto; i++) { + QualType ProtoArgType = Proto->getArgType(i); + + Expr *Arg; + if (i <= NumPlaceArgs) { + AllPlaceArgs.push_back(PlaceArgs[i-1]); + continue; + } + ParmVarDecl *Param = OperatorNew->getParamDecl(i); + + OwningExprResult ArgExpr = + BuildCXXDefaultArgExpr(StartLoc, OperatorNew, Param); + if (ArgExpr.isInvalid()) + return ExprError(); + + Arg = ArgExpr.takeAs<Expr>(); + AllPlaceArgs.push_back(Arg); + } + NumPlaceArgs = AllPlaceArgs.size(); + if (NumPlaceArgs > 0) + PlaceArgs = &AllPlaceArgs[0]; + } + bool Init = ConstructorLParen.isValid(); // --- Choosing a constructor --- // C++ 5.3.4p15 diff --git a/test/CodeGenCXX/new-with-default-arg.cpp b/test/CodeGenCXX/new-with-default-arg.cpp new file mode 100644 index 0000000000..b73b7f0865 --- /dev/null +++ b/test/CodeGenCXX/new-with-default-arg.cpp @@ -0,0 +1,33 @@ +// RUN: clang-cc -emit-llvm -o - %s +// pr5547 + +struct A { + void* operator new(__typeof(sizeof(int))); + A(); +}; + +A* x() { + return new A; +} + +struct B { + void* operator new(__typeof(sizeof(int)), int = 1, int = 4); + B(float); +}; + +B* y() { + new (3,4) B(1); + return new(1) B(2); +} + +struct C { + void* operator new(__typeof(sizeof(int)), int, int = 4); + C(); +}; + +C* z() { + new (3,4) C; + return new(1) C; +} + + |