Walk over MaterializeTemporaryExpr when reverting an initializer to its

syntactic form in template instantiation. Previously, this blocked the
reversion and we ended up losing inner CXXBindTemporaryExprs (and thus
forgetting to call destructors!).

llvm-svn: 182969
This commit is contained in:
Richard Smith 2013-05-30 22:40:16 +00:00
parent c07e8934a0
commit e6ca47586d
2 changed files with 19 additions and 0 deletions

View File

@ -2630,6 +2630,9 @@ ExprResult TreeTransform<Derived>::TransformInitializer(Expr *Init,
if (ExprWithCleanups *ExprTemp = dyn_cast<ExprWithCleanups>(Init))
Init = ExprTemp->getSubExpr();
if (MaterializeTemporaryExpr *MTE = dyn_cast<MaterializeTemporaryExpr>(Init))
Init = MTE->GetTemporaryExpr();
while (CXXBindTemporaryExpr *Binder = dyn_cast<CXXBindTemporaryExpr>(Init))
Init = Binder->getSubExpr();

View File

@ -35,3 +35,19 @@ void fn4() {
// CHECK: call void @_ZN1SC1Eidd(%struct.S* %{{.+}}, i32 1, double 2.000000e+00, double 3.000000e+00)
// CHECK: call void @_ZN1SC1Eidd(%struct.S* %{{.+}}, i32 4, double 5.000000e+00, double 6.000000e+00)
}
namespace TreeTransformBracedInit {
struct S {};
struct T { T(const S &); T(const T&); ~T(); };
void x(const T &);
template<typename> void foo(const S &s) {
// Instantiation of this expression used to lose the CXXBindTemporaryExpr
// node and thus not destroy the temporary.
x({s});
}
template void foo<void>(const S&);
// CHECK: define {{.*}} void @_ZN23TreeTransformBracedInit3fooIvEEvRKNS_1SE(
// CHECK: call void @_ZN23TreeTransformBracedInit1TC1ERKNS_1SE(
// CHECK-NEXT: call void @_ZN23TreeTransformBracedInit1xERKNS_1TE(
// CHECK-NEXT: call void @_ZN23TreeTransformBracedInit1TD1Ev(
}