From: Douglas Gregor Date: Thu, 24 Dec 2009 18:51:59 +0000 (+0000) Subject: When transforming CXXExprWithTemporaries and CXXBindTemporaryExpr X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=5132655e4296b780672e9a96b46a740135073534;p=clang When transforming CXXExprWithTemporaries and CXXBindTemporaryExpr expressions (e.g., for template instantiation), just transform the subexpressions and return those, since the temporary-related nodes will be implicitly regenerated. Fixes PR5867, but I said that before... git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@92135 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Sema/SemaExprCXX.cpp b/lib/Sema/SemaExprCXX.cpp index 06f8e7aed8..5f723f9214 100644 --- a/lib/Sema/SemaExprCXX.cpp +++ b/lib/Sema/SemaExprCXX.cpp @@ -2096,6 +2096,8 @@ Sema::OwningExprResult Sema::MaybeBindToTemporary(Expr *E) { if (!Context.getLangOptions().CPlusPlus) return Owned(E); + assert(!isa(E) && "Double-bound temporary?"); + const RecordType *RT = E->getType()->getAs(); if (!RT) return Owned(E); diff --git a/lib/Sema/SemaTemplateInstantiate.cpp b/lib/Sema/SemaTemplateInstantiate.cpp index d65b246567..d974f89bc6 100644 --- a/lib/Sema/SemaTemplateInstantiate.cpp +++ b/lib/Sema/SemaTemplateInstantiate.cpp @@ -554,7 +554,6 @@ namespace { Sema::OwningExprResult TransformPredefinedExpr(PredefinedExpr *E); Sema::OwningExprResult TransformDeclRefExpr(DeclRefExpr *E); - Sema::OwningExprResult TransformCXXDefaultArgExpr(CXXDefaultArgExpr *E); /// \brief Transforms a template type parameter type by performing diff --git a/lib/Sema/TreeTransform.h b/lib/Sema/TreeTransform.h index e062a37f8e..cf424aa8c1 100644 --- a/lib/Sema/TreeTransform.h +++ b/lib/Sema/TreeTransform.h @@ -4757,37 +4757,24 @@ TreeTransform::TransformCXXConstructExpr(CXXConstructExpr *E) { /// \brief Transform a C++ temporary-binding expression. /// -/// The transformation of a temporary-binding expression always attempts to -/// bind a new temporary variable to its subexpression, even if the -/// subexpression itself did not change, because the temporary variable itself -/// must be unique. +/// Since CXXBindTemporaryExpr nodes are implicitly generated, we just +/// transform the subexpression and return that. template Sema::OwningExprResult TreeTransform::TransformCXXBindTemporaryExpr(CXXBindTemporaryExpr *E) { - OwningExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr()); - if (SubExpr.isInvalid()) - return SemaRef.ExprError(); - - return SemaRef.MaybeBindToTemporary(SubExpr.takeAs()); + return getDerived().TransformExpr(E->getSubExpr()); } /// \brief Transform a C++ expression that contains temporaries that should /// be destroyed after the expression is evaluated. /// -/// The transformation of a full expression always attempts to build a new -/// CXXExprWithTemporaries expression, even if the -/// subexpression itself did not change, because it will need to capture the -/// the new temporary variables introduced in the subexpression. +/// Since CXXExprWithTemporaries nodes are implicitly generated, we +/// just transform the subexpression and return that. template Sema::OwningExprResult TreeTransform::TransformCXXExprWithTemporaries( - CXXExprWithTemporaries *E) { - OwningExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr()); - if (SubExpr.isInvalid()) - return SemaRef.ExprError(); - - return SemaRef.Owned( - SemaRef.MaybeCreateCXXExprWithTemporaries(SubExpr.takeAs())); + CXXExprWithTemporaries *E) { + return getDerived().TransformExpr(E->getSubExpr()); } template diff --git a/test/CodeGenCXX/temporaries.cpp b/test/CodeGenCXX/temporaries.cpp index 3fd7cfec78..611781886b 100644 --- a/test/CodeGenCXX/temporaries.cpp +++ b/test/CodeGenCXX/temporaries.cpp @@ -234,4 +234,18 @@ namespace PR5867 { // CHECK-NEXT: ret void (f)(S(), 0); } + + // CHECK: define linkonce_odr void @_ZN6PR58672g2IiEEvT_ + template + void g2(T) { + // CHECK: call void @_ZN6PR58671SC1Ev + // CHECK-NEXT: call void @_ZN6PR58671fENS_1SEi + // CHECK-NEXT: call void @_ZN6PR58671SD1Ev + // CHECK-NEXT: ret void + (f)(S(), 0); + } + + void h() { + g2(17); + } }