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:
parent
5c13090bd4
commit
363b151ff7
|
@ -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);
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue