aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/CodeGen/CGExprScalar.cpp19
-rw-r--r--test/CodeGenObjC/id-isa-codegen.m14
2 files changed, 28 insertions, 5 deletions
diff --git a/lib/CodeGen/CGExprScalar.cpp b/lib/CodeGen/CGExprScalar.cpp
index f58d6e871b..cb3fb61cf3 100644
--- a/lib/CodeGen/CGExprScalar.cpp
+++ b/lib/CodeGen/CGExprScalar.cpp
@@ -1880,14 +1880,23 @@ LValue CodeGenFunction::EmitObjCIsaExpr(const ObjCIsaExpr *E) {
llvm::Value *V;
// object->isa or (*object).isa
// Generate code as for: *(Class*)object
+ // build Class* type
+ const llvm::Type *ClassPtrTy = ConvertType(E->getType());
+
Expr *BaseExpr = E->getBase();
- if (E->isArrow())
- V = ScalarExprEmitter(*this).EmitLoadOfLValue(BaseExpr);
- else
- V = EmitLValue(BaseExpr).getAddress();
+ if (BaseExpr->isLvalue(getContext()) != Expr::LV_Valid) {
+ V = CreateTempAlloca(ClassPtrTy, "resval");
+ llvm::Value *Src = EmitScalarExpr(BaseExpr);
+ Builder.CreateStore(Src, V);
+ }
+ else {
+ if (E->isArrow())
+ V = ScalarExprEmitter(*this).EmitLoadOfLValue(BaseExpr);
+ else
+ V = EmitLValue(BaseExpr).getAddress();
+ }
// build Class* type
- const llvm::Type *ClassPtrTy = ConvertType(E->getType());
ClassPtrTy = ClassPtrTy->getPointerTo();
V = Builder.CreateBitCast(V, ClassPtrTy);
LValue LV = LValue::MakeAddr(V, MakeQualifiers(E->getType()));
diff --git a/test/CodeGenObjC/id-isa-codegen.m b/test/CodeGenObjC/id-isa-codegen.m
index 89e9922090..3179e11b7f 100644
--- a/test/CodeGenObjC/id-isa-codegen.m
+++ b/test/CodeGenObjC/id-isa-codegen.m
@@ -34,3 +34,17 @@ Class Test(const void *inObject1) {
return ((id)inObject1)->isa;
return (id)0;
}
+
+// rdar 7609722
+@interface Foo {
+@public
+ id isa;
+}
++(id)method;
+@end
+
+id Test2() {
+ if([Foo method]->isa)
+ return (*[Foo method]).isa;
+ return [Foo method]->isa;
+}