diff options
| author | Douglas Gregor <dgregor@apple.com> | 2010-02-26 00:38:10 +0000 |
|---|---|---|
| committer | Douglas Gregor <dgregor@apple.com> | 2010-02-26 00:38:10 +0000 |
| commit | d2d9da08f3d6069a98119dc76e0fac17e59eb305 (patch) | |
| tree | 3ec54d5fa903480055966ac8872c65aaf9c20060 | |
| parent | 6f14f6a962b5d7f925c0a04606ca0264a666b61d (diff) | |
| download | bcm5719-llvm-d2d9da08f3d6069a98119dc76e0fac17e59eb305.tar.gz bcm5719-llvm-d2d9da08f3d6069a98119dc76e0fac17e59eb305.zip | |
Make sure to mark constructors, operator new, and operator delete as
used when we instantiate C++ new expressions, delete expressions, and
object-construction expressions. Fixes PR6424, although we can't test
all of it until we finish implementing lookup of "operator delete" for
new expressions (!).
llvm-svn: 97195
| -rw-r--r-- | clang/lib/Sema/TreeTransform.h | 58 | ||||
| -rw-r--r-- | clang/test/SemaTemplate/instantiate-expr-1.cpp | 17 |
2 files changed, 73 insertions, 2 deletions
diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h index 0216621d1e8..95ec5a43136 100644 --- a/clang/lib/Sema/TreeTransform.h +++ b/clang/lib/Sema/TreeTransform.h @@ -4588,11 +4588,48 @@ TreeTransform<Derived>::TransformCXXNewExpr(CXXNewExpr *E) { ConstructorArgs.push_back(Arg.take()); } + // Transform constructor, new operator, and delete operator. + CXXConstructorDecl *Constructor = 0; + if (E->getConstructor()) { + Constructor = cast_or_null<CXXConstructorDecl>( + getDerived().TransformDecl(E->getConstructor())); + if (!Constructor) + return SemaRef.ExprError(); + } + + FunctionDecl *OperatorNew = 0; + if (E->getOperatorNew()) { + OperatorNew = cast_or_null<FunctionDecl>( + getDerived().TransformDecl(E->getOperatorNew())); + if (!OperatorNew) + return SemaRef.ExprError(); + } + + FunctionDecl *OperatorDelete = 0; + if (E->getOperatorDelete()) { + OperatorDelete = cast_or_null<FunctionDecl>( + getDerived().TransformDecl(E->getOperatorDelete())); + if (!OperatorDelete) + return SemaRef.ExprError(); + } + if (!getDerived().AlwaysRebuild() && AllocType == E->getAllocatedType() && ArraySize.get() == E->getArraySize() && - !ArgumentChanged) + Constructor == E->getConstructor() && + OperatorNew == E->getOperatorNew() && + OperatorDelete == E->getOperatorDelete() && + !ArgumentChanged) { + // Mark any declarations we need as referenced. + // FIXME: instantiation-specific. + if (Constructor) + SemaRef.MarkDeclarationReferenced(E->getLocStart(), Constructor); + if (OperatorNew) + SemaRef.MarkDeclarationReferenced(E->getLocStart(), OperatorNew); + if (OperatorDelete) + SemaRef.MarkDeclarationReferenced(E->getLocStart(), OperatorDelete); return SemaRef.Owned(E->Retain()); + } if (!ArraySize.get()) { // If no array size was specified, but the new expression was @@ -4641,9 +4678,24 @@ TreeTransform<Derived>::TransformCXXDeleteExpr(CXXDeleteExpr *E) { if (Operand.isInvalid()) return SemaRef.ExprError(); + // Transform the delete operator, if known. + FunctionDecl *OperatorDelete = 0; + if (E->getOperatorDelete()) { + OperatorDelete = cast_or_null<FunctionDecl>( + getDerived().TransformDecl(E->getOperatorDelete())); + if (!OperatorDelete) + return SemaRef.ExprError(); + } + if (!getDerived().AlwaysRebuild() && - Operand.get() == E->getArgument()) + Operand.get() == E->getArgument() && + OperatorDelete == E->getOperatorDelete()) { + // Mark any declarations we need as referenced. + // FIXME: instantiation-specific. + if (OperatorDelete) + SemaRef.MarkDeclarationReferenced(E->getLocStart(), OperatorDelete); return SemaRef.Owned(E->Retain()); + } return getDerived().RebuildCXXDeleteExpr(E->getLocStart(), E->isGlobalDelete(), @@ -4907,6 +4959,8 @@ TreeTransform<Derived>::TransformCXXConstructExpr(CXXConstructExpr *E) { T == E->getType() && Constructor == E->getConstructor() && !ArgumentChanged) { + // Mark the constructor as referenced. + // FIXME: Instantiation-specific SemaRef.MarkDeclarationReferenced(E->getLocStart(), Constructor); return SemaRef.Owned(E->Retain()); } diff --git a/clang/test/SemaTemplate/instantiate-expr-1.cpp b/clang/test/SemaTemplate/instantiate-expr-1.cpp index 4594621103f..37145b63b61 100644 --- a/clang/test/SemaTemplate/instantiate-expr-1.cpp +++ b/clang/test/SemaTemplate/instantiate-expr-1.cpp @@ -152,4 +152,21 @@ namespace PR6424 { }; template void Y<3>::f(); + + template<int I> + struct X2 { + void *operator new(__SIZE_TYPE__) { + int *ip = I; // expected-error{{cannot initialize a variable of type 'int *' with an rvalue of type 'int'}} + return ip; + } + }; + + template<int> struct Y2 { + typedef X2<7> X; + void f() { + new X(); // expected-note{{instantiation of}} + } + }; + + template void Y2<3>::f(); } |

