]> granicus.if.org Git - clang/commitdiff
In ARC, non-atomic getters do not need to retain and autorelease
authorJohn McCall <rjmccall@apple.com>
Fri, 22 Jul 2011 05:23:13 +0000 (05:23 +0000)
committerJohn McCall <rjmccall@apple.com>
Fri, 22 Jul 2011 05:23:13 +0000 (05:23 +0000)
their loaded values, although it still worth doing this for __weak
properties to get the autoreleased-return-value optimization.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@135747 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/CGObjC.cpp
test/CodeGenObjC/arc.m

index 4beb704d1596dd8f7ae3d29ad2f4bcd28aa6f838..fd686cc6a0cc9cd4f0b6cf5954dde7f02723f29d 100644 (file)
@@ -465,27 +465,30 @@ void CodeGenFunction::GenerateObjCGetter(ObjCImplementationDecl *IMP,
           EmitAggregateCopy(ReturnValue, LV.getAddress(), IVART);
         }
       }
-    } 
-    else {
-        LValue LV = EmitLValueForIvar(TypeOfSelfObject(), LoadObjCSelf(), 
-                                      Ivar, 0);
-        QualType propType = PD->getType();
+    } else {
+      LValue LV = EmitLValueForIvar(TypeOfSelfObject(), LoadObjCSelf(), 
+                                    Ivar, 0);
+      QualType propType = PD->getType();
 
-        llvm::Value *value;
-        if (propType->isReferenceType()) {
-          value = LV.getAddress();
+      llvm::Value *value;
+      if (propType->isReferenceType()) {
+        value = LV.getAddress();
+      } else {
+        // We want to load and autoreleaseReturnValue ARC __weak ivars.
+        if (LV.getQuals().getObjCLifetime() == Qualifiers::OCL_Weak) {
+          value = emitARCRetainLoadOfScalar(*this, LV, IVART);
+
+        // Otherwise we want to do a simple load, suppressing the
+        // final autorelease.
         } else {
-          // In ARC, we want to emit this retained.
-          if (getLangOptions().ObjCAutoRefCount &&
-              PD->getType()->isObjCRetainableType())
-            value = emitARCRetainLoadOfScalar(*this, LV, IVART);
-          else
-            value = EmitLoadOfLValue(LV).getScalarVal();
-
-          value = Builder.CreateBitCast(value, ConvertType(propType));
+          value = EmitLoadOfLValue(LV).getScalarVal();
+          AutoreleaseResult = false;
         }
 
-        EmitReturnOfRValue(RValue::get(value), propType);
+        value = Builder.CreateBitCast(value, ConvertType(propType));
+      }
+      
+      EmitReturnOfRValue(RValue::get(value), propType);
     }
   }
 
index f6bd434195993595f23dafc0596bf296aaefa12c..8d74ab2a6a9fd545ba8f69867b07c4863e22edb2 100644 (file)
@@ -1578,3 +1578,41 @@ void test56_test(void) {
   // CHECK-NEXT: call void @objc_release(i8* [[T0]])
   // CHECK-NEXT: ret void
 }
+
+// rdar://problem/9784964
+@interface Test57
+@property (nonatomic, strong) id strong;
+@property (nonatomic, weak) id weak;
+@property (nonatomic, unsafe_unretained) id unsafe;
+@end
+@implementation Test57
+@synthesize strong, weak, unsafe;
+@end
+// CHECK: define internal i8* @"\01-[Test57 strong]"(
+// CHECK:      [[T0:%.*]] = load [[TEST57:%.*]]** {{%.*}}
+// CHECK-NEXT: [[T1:%.*]] = load i64* @"OBJC_IVAR_$_Test57.strong"
+// CHECK-NEXT: [[T2:%.*]] = bitcast [[TEST57]]* [[T0]] to i8*
+// CHECK-NEXT: [[T3:%.*]] = getelementptr inbounds i8* [[T2]], i64 [[T1]]
+// CHECK-NEXT: [[T4:%.*]] = bitcast i8* [[T3]] to i8**
+// CHECK-NEXT: [[T5:%.*]] = load i8** [[T4]]
+// CHECK-NEXT: ret i8* [[T5]]
+
+// CHECK: define internal i8* @"\01-[Test57 weak]"(
+// CHECK:      [[T0:%.*]] = load [[TEST57]]** {{%.*}}
+// CHECK-NEXT: [[T1:%.*]] = load i64* @"OBJC_IVAR_$_Test57.weak"
+// CHECK-NEXT: [[T2:%.*]] = bitcast [[TEST57]]* [[T0]] to i8*
+// CHECK-NEXT: [[T3:%.*]] = getelementptr inbounds i8* [[T2]], i64 [[T1]]
+// CHECK-NEXT: [[T4:%.*]] = bitcast i8* [[T3]] to i8**
+// CHECK-NEXT: [[T5:%.*]] = call i8* @objc_loadWeakRetained(i8** [[T4]])
+// CHECK-NEXT: [[T6:%.*]] = call i8* @objc_autoreleaseReturnValue(i8* [[T5]])
+// CHECK-NEXT: ret i8* [[T6]]
+
+// CHECK: define internal i8* @"\01-[Test57 unsafe]"(
+// CHECK:      [[T0:%.*]] = load [[TEST57]]** {{%.*}}
+// CHECK-NEXT: [[T1:%.*]] = load i64* @"OBJC_IVAR_$_Test57.unsafe"
+// CHECK-NEXT: [[T2:%.*]] = bitcast [[TEST57]]* [[T0]] to i8*
+// CHECK-NEXT: [[T3:%.*]] = getelementptr inbounds i8* [[T2]], i64 [[T1]]
+// CHECK-NEXT: [[T4:%.*]] = bitcast i8* [[T3]] to i8**
+// CHECK-NEXT: [[T5:%.*]] = load i8** [[T4]]
+// CHECK-NEXT: ret i8* [[T5]]
+