From: Douglas Gregor Date: Mon, 14 Dec 2009 16:27:04 +0000 (+0000) Subject: When rebuilding CXXConstructExprs after a transformation, use X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=4411d2e674b0119f682ac472c3a377f14fa9fa30;p=clang When rebuilding CXXConstructExprs after a transformation, use CompleteConstructorCall to perform type-checking. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@91279 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Sema/TreeTransform.h b/lib/Sema/TreeTransform.h index dc848a53ab..b1d7f06489 100644 --- a/lib/Sema/TreeTransform.h +++ b/lib/Sema/TreeTransform.h @@ -1459,13 +1459,17 @@ public: /// By default, performs semantic analysis to build the new expression. /// Subclasses may override this routine to provide different behavior. OwningExprResult RebuildCXXConstructExpr(QualType T, + SourceLocation Loc, CXXConstructorDecl *Constructor, bool IsElidable, MultiExprArg Args) { - return getSema().BuildCXXConstructExpr(/*FIXME:ConstructLoc*/ - SourceLocation(), - T, Constructor, IsElidable, - move(Args)); + ASTOwningVector<&ActionBase::DeleteExpr> ConvertedArgs(SemaRef); + if (getSema().CompleteConstructorCall(Constructor, move(Args), Loc, + ConvertedArgs)) + return getSema().ExprError(); + + return getSema().BuildCXXConstructExpr(Loc, T, Constructor, IsElidable, + move_arg(ConvertedArgs)); } /// \brief Build a new object-construction expression. @@ -4723,7 +4727,8 @@ TreeTransform::TransformCXXConstructExpr(CXXConstructExpr *E) { !ArgumentChanged) return SemaRef.Owned(E->Retain()); - return getDerived().RebuildCXXConstructExpr(T, Constructor, E->isElidable(), + return getDerived().RebuildCXXConstructExpr(T, /*FIXME:*/E->getLocStart(), + Constructor, E->isElidable(), move_arg(Args)); } diff --git a/test/CodeGenCXX/constructor-convert.cpp b/test/CodeGenCXX/constructor-convert.cpp new file mode 100644 index 0000000000..6fa6d556dc --- /dev/null +++ b/test/CodeGenCXX/constructor-convert.cpp @@ -0,0 +1,19 @@ +// RUN: clang -emit-llvm -S -o - %s + +// PR5775 +class Twine { + Twine(const char *Str) { } +}; + +static void error(const Twine &Message); + +template +struct opt_storage { + void f() { + error("cl::location(x) specified more than once!"); + } +}; + +void f(opt_storage o) { + o.f(); +}