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>
// 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]])
+