diff options
author | John McCall <rjmccall@apple.com> | 2013-04-11 02:14:26 +0000 |
---|---|---|
committer | John McCall <rjmccall@apple.com> | 2013-04-11 02:14:26 +0000 |
commit | 93b64571e92c10bb168c2a2786c1380f334ba960 (patch) | |
tree | 51d903e13f661e4b76f664532c1a841b6199a78c | |
parent | 411d33aa0b0d3bc9b2faec40cd821bdd836094ab (diff) |
Drop ObjCIndirectCopyRestoreExprs during template instantiation.
It's a kind of implicit conversion, which we generally drop, but
more importantly it's got very specific placement requirements.
rdar://13617051
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@179254 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/Sema/TreeTransform.h | 15 | ||||
-rw-r--r-- | test/CodeGenObjCXX/arc.mm | 22 |
2 files changed, 27 insertions, 10 deletions
diff --git a/lib/Sema/TreeTransform.h b/lib/Sema/TreeTransform.h index 835609585e..81e02f5596 100644 --- a/lib/Sema/TreeTransform.h +++ b/lib/Sema/TreeTransform.h @@ -8608,16 +8608,11 @@ TreeTransform<Derived>::TransformObjCEncodeExpr(ObjCEncodeExpr *E) { template<typename Derived> ExprResult TreeTransform<Derived>:: TransformObjCIndirectCopyRestoreExpr(ObjCIndirectCopyRestoreExpr *E) { - ExprResult result = getDerived().TransformExpr(E->getSubExpr()); - if (result.isInvalid()) return ExprError(); - Expr *subExpr = result.take(); - - if (!getDerived().AlwaysRebuild() && - subExpr == E->getSubExpr()) - return SemaRef.Owned(E); - - return SemaRef.Owned(new(SemaRef.Context) - ObjCIndirectCopyRestoreExpr(subExpr, E->getType(), E->shouldCopy())); + // This is a kind of implicit conversion, and it needs to get dropped + // and recomputed for the same general reasons that ImplicitCastExprs + // do, as well a more specific one: this expression is only valid when + // it appears *immediately* as an argument expression. + return getDerived().TransformExpr(E->getSubExpr()); } template<typename Derived> diff --git a/test/CodeGenObjCXX/arc.mm b/test/CodeGenObjCXX/arc.mm index 1888dbe77d..e3e86a0b0d 100644 --- a/test/CodeGenObjCXX/arc.mm +++ b/test/CodeGenObjCXX/arc.mm @@ -275,3 +275,25 @@ id Test39::bar() { return 0; } // CHECK: define i8* @_ZThn8_N6Test393barEv( // CHECK: call i8* @_ZN6Test393barEv( // CHECK-NEXT: ret i8* + +// rdar://13617051 +// Just a basic sanity-check that IR-gen still works after instantiating +// a non-dependent message send that requires writeback. +@interface Test40 ++ (void) foo:(id *)errorPtr; +@end +template <class T> void test40_helper() { + id x; + [Test40 foo: &x]; +}; +template void test40_helper<int>(); +// CHECK: define weak_odr void @_Z13test40_helperIiEvv() +// CHECK: [[X:%.*]] = alloca i8* +// CHECK-NEXT: [[TEMP:%.*]] = alloca i8* +// CHECK-NEXT: store i8* null, i8** [[X]] +// CHECK: [[T0:%.*]] = load i8** [[X]] +// CHECK-NEXT: store i8* [[T0]], i8** [[TEMP]] +// CHECK: @objc_msgSend +// CHECK-NEXT: [[T0:%.*]] = load i8** [[TEMP]] +// CHECK-NEXT: call i8* @objc_retain(i8* [[T0]]) + |