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...

llvm-svn: 92135
This commit is contained in:
Douglas Gregor 2009-12-24 18:51:59 +00:00
parent 5c13090bd4
commit 363b151ff7
4 changed files with 23 additions and 21 deletions

View File

@ -2096,6 +2096,8 @@ Sema::OwningExprResult Sema::MaybeBindToTemporary(Expr *E) {
if (!Context.getLangOptions().CPlusPlus) if (!Context.getLangOptions().CPlusPlus)
return Owned(E); return Owned(E);
assert(!isa<CXXBindTemporaryExpr>(E) && "Double-bound temporary?");
const RecordType *RT = E->getType()->getAs<RecordType>(); const RecordType *RT = E->getType()->getAs<RecordType>();
if (!RT) if (!RT)
return Owned(E); return Owned(E);

View File

@ -554,7 +554,6 @@ namespace {
Sema::OwningExprResult TransformPredefinedExpr(PredefinedExpr *E); Sema::OwningExprResult TransformPredefinedExpr(PredefinedExpr *E);
Sema::OwningExprResult TransformDeclRefExpr(DeclRefExpr *E); Sema::OwningExprResult TransformDeclRefExpr(DeclRefExpr *E);
Sema::OwningExprResult TransformCXXDefaultArgExpr(CXXDefaultArgExpr *E); Sema::OwningExprResult TransformCXXDefaultArgExpr(CXXDefaultArgExpr *E);
/// \brief Transforms a template type parameter type by performing /// \brief Transforms a template type parameter type by performing

View File

@ -4757,37 +4757,24 @@ TreeTransform<Derived>::TransformCXXConstructExpr(CXXConstructExpr *E) {
/// \brief Transform a C++ temporary-binding expression. /// \brief Transform a C++ temporary-binding expression.
/// ///
/// The transformation of a temporary-binding expression always attempts to /// Since CXXBindTemporaryExpr nodes are implicitly generated, we just
/// bind a new temporary variable to its subexpression, even if the /// transform the subexpression and return that.
/// subexpression itself did not change, because the temporary variable itself
/// must be unique.
template<typename Derived> template<typename Derived>
Sema::OwningExprResult Sema::OwningExprResult
TreeTransform<Derived>::TransformCXXBindTemporaryExpr(CXXBindTemporaryExpr *E) { TreeTransform<Derived>::TransformCXXBindTemporaryExpr(CXXBindTemporaryExpr *E) {
OwningExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr()); return getDerived().TransformExpr(E->getSubExpr());
if (SubExpr.isInvalid())
return SemaRef.ExprError();
return SemaRef.MaybeBindToTemporary(SubExpr.takeAs<Expr>());
} }
/// \brief Transform a C++ expression that contains temporaries that should /// \brief Transform a C++ expression that contains temporaries that should
/// be destroyed after the expression is evaluated. /// be destroyed after the expression is evaluated.
/// ///
/// The transformation of a full expression always attempts to build a new /// Since CXXExprWithTemporaries nodes are implicitly generated, we
/// CXXExprWithTemporaries expression, even if the /// just transform the subexpression and return that.
/// subexpression itself did not change, because it will need to capture the
/// the new temporary variables introduced in the subexpression.
template<typename Derived> template<typename Derived>
Sema::OwningExprResult Sema::OwningExprResult
TreeTransform<Derived>::TransformCXXExprWithTemporaries( TreeTransform<Derived>::TransformCXXExprWithTemporaries(
CXXExprWithTemporaries *E) { CXXExprWithTemporaries *E) {
OwningExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr()); return getDerived().TransformExpr(E->getSubExpr());
if (SubExpr.isInvalid())
return SemaRef.ExprError();
return SemaRef.Owned(
SemaRef.MaybeCreateCXXExprWithTemporaries(SubExpr.takeAs<Expr>()));
} }
template<typename Derived> template<typename Derived>

View File

@ -234,4 +234,18 @@ namespace PR5867 {
// CHECK-NEXT: ret void // CHECK-NEXT: ret void
(f)(S(), 0); (f)(S(), 0);
} }
// CHECK: define linkonce_odr void @_ZN6PR58672g2IiEEvT_
template<typename T>
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);
}
} }