2012-11-28 07:02:53 +08:00
|
|
|
// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -emit-llvm -fblocks -fobjc-arc -fobjc-runtime-has-weak -o - %s | FileCheck %s
|
|
|
|
// rdar://10849570
|
|
|
|
|
|
|
|
@interface NSObject @end
|
|
|
|
|
|
|
|
@interface SomeClass : NSObject
|
|
|
|
- (id) init;
|
|
|
|
@end
|
|
|
|
|
|
|
|
@implementation SomeClass
|
|
|
|
- (void)foo {
|
|
|
|
}
|
|
|
|
- (id) init {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
+ alloc { return 0; }
|
|
|
|
@end
|
|
|
|
|
|
|
|
int main (int argc, const char * argv[]) {
|
|
|
|
@autoreleasepool {
|
|
|
|
SomeClass *objPtr1 = [[SomeClass alloc] init];
|
|
|
|
__weak SomeClass *weakRef = objPtr1;
|
|
|
|
|
|
|
|
[weakRef foo];
|
|
|
|
|
|
|
|
objPtr1 = (void *)0;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-12-19 04:33:00 +08:00
|
|
|
// CHECK: [[SIXTEEN:%.*]] = call i8* @llvm.objc.loadWeakRetained(i8** {{%.*}})
|
2012-11-28 07:02:53 +08:00
|
|
|
// CHECK-NEXT: [[SEVENTEEN:%.*]] = bitcast i8* [[SIXTEEN]] to {{%.*}}
|
2015-05-13 00:48:43 +08:00
|
|
|
// CHECK-NEXT: [[EIGHTEEN:%.*]] = load i8*, i8** @OBJC_SELECTOR_REFERENCES_.6
|
2012-11-28 07:02:53 +08:00
|
|
|
// CHECK-NEXT: [[NINETEEN:%.*]] = bitcast %0* [[SEVENTEEN]] to i8*
|
|
|
|
// CHECK-NEXT: call void bitcast (i8* (i8*, i8*, ...)* @objc_msgSend
|
|
|
|
// CHECK-NEXT: [[TWENTY:%.*]] = bitcast %0* [[SEVENTEEN]] to i8*
|
2018-12-19 04:33:00 +08:00
|
|
|
// CHECK-NEXT: call void @llvm.objc.release(i8* [[TWENTY]])
|
2012-11-28 07:02:53 +08:00
|
|
|
|
|
|
|
void test1(int cond) {
|
|
|
|
extern void test34_sink(id *);
|
|
|
|
__weak id weak;
|
|
|
|
test34_sink(cond ? &weak : 0);
|
|
|
|
}
|
|
|
|
|
2013-08-15 14:47:53 +08:00
|
|
|
// CHECK-LABEL: define void @test1(
|
2012-11-28 07:02:53 +08:00
|
|
|
// CHECK: [[CONDADDR:%.*]] = alloca i32
|
|
|
|
// CHECK-NEXT: [[WEAK:%.*]] = alloca i8*
|
|
|
|
// CHECK-NEXT: [[INCRTEMP:%.*]] = alloca i8*
|
|
|
|
// CHECK-NEXT: [[CONDCLEANUPSAVE:%.*]] = alloca i8*
|
|
|
|
// CHECK-NEXT: [[CONDCLEANUP:%.*]] = alloca i1
|
|
|
|
// CHECK-NEXT: store i32
|
|
|
|
// CHECK-NEXT: store i8* null, i8** [[WEAK]]
|
|
|
|
// CHECK: [[COND1:%.*]] = phi i8**
|
|
|
|
// CHECK-NEXT: [[ICRISNULL:%.*]] = icmp eq i8** [[COND1]], null
|
|
|
|
// CHECK-NEXT: [[ICRARGUMENT:%.*]] = select i1 [[ICRISNULL]], i8** null, i8** [[INCRTEMP]]
|
|
|
|
// CHECK-NEXT: store i1 false, i1* [[CONDCLEANUP]]
|
|
|
|
// CHECK-NEXT: br i1 [[ICRISNULL]], label [[ICRCONT:%.*]], label [[ICRCOPY:%.*]]
|
2018-12-19 04:33:00 +08:00
|
|
|
// CHECK: [[ONE:%.*]] = call i8* @llvm.objc.loadWeakRetained(
|
2012-11-28 07:02:53 +08:00
|
|
|
// CHECK-NEXT: store i8* [[ONE]], i8** [[CONDCLEANUPSAVE]]
|
|
|
|
// CHECK-NEXT: store i1 true, i1* [[CONDCLEANUP]]
|
|
|
|
// CHECK-NEXT: store i8* [[ONE]], i8** [[INCRTEMP]]
|
|
|
|
// CHECK-NEXT: br label
|
|
|
|
|
|
|
|
// CHECK: call void @test34_sink(
|
|
|
|
// CHECK-NEXT: [[ICRISNULL1:%.*]] = icmp eq i8** [[COND1]], null
|
|
|
|
// CHECK-NEXT: br i1 [[ICRISNULL1]], label [[ICRDONE:%.*]], label [[ICRWRITEBACK:%.*]]
|
2015-02-28 05:19:58 +08:00
|
|
|
// CHECK: [[TWO:%.*]] = load i8*, i8** [[INCRTEMP]]
|
2018-12-19 04:33:00 +08:00
|
|
|
// CHECK-NEXT: [[THREE:%.*]] = call i8* @llvm.objc.storeWeak(
|
2015-09-01 05:48:52 +08:00
|
|
|
// CHECK-NEXT: br label [[ICRDONE]]
|
2015-02-28 05:19:58 +08:00
|
|
|
// CHECK: [[CLEANUPISACTIVE:%.*]] = load i1, i1* [[CONDCLEANUP]]
|
2012-11-28 07:02:53 +08:00
|
|
|
// CHECK-NEXT: br i1 [[CLEANUPISACTIVE]], label [[CLEASNUPACTION:%.*]], label [[CLEANUPDONE:%.*]]
|
|
|
|
|
2015-02-28 05:19:58 +08:00
|
|
|
// CHECK: [[FOUR:%.*]] = load i8*, i8** [[CONDCLEANUPSAVE]]
|
2018-12-19 04:33:00 +08:00
|
|
|
// CHECK-NEXT: call void @llvm.objc.release(i8* [[FOUR]])
|
2012-11-28 07:02:53 +08:00
|
|
|
// CHECK-NEXT: br label
|
2018-12-19 04:33:00 +08:00
|
|
|
// CHECK: call void @llvm.objc.destroyWeak(i8** [[WEAK]])
|
2012-11-28 07:02:53 +08:00
|
|
|
// CHECK-NEXT: ret void
|