157 lines · plain
1// RUN: %clang_cc1 -triple arm64-apple-ios9 -fobjc-runtime=ios-9.0 -fobjc-arc -O -disable-llvm-passes -emit-llvm -o - %s | FileCheck %s -check-prefix=CHECK2// RUN: %clang_cc1 -triple x86_64-apple-macosx10 -fobjc-runtime=ios-9.0 -fobjc-arc -O -disable-llvm-passes -emit-llvm -o - %s | FileCheck %s -check-prefix=CHECK3 4@class A;5 6A *makeA(void);7 8void test_assign(void) {9 __unsafe_unretained id x;10 x = makeA();11}12// CHECK-LABEL: define{{.*}} void @test_assign()13// CHECK: [[X:%.*]] = alloca ptr14// CHECK: [[T0:%.*]] = call ptr @makeA() [ "clang.arc.attachedcall"(ptr @llvm.objc.unsafeClaimAutoreleasedReturnValue) ]15// CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use({{.*}} [[T0]])16// CHECK-NEXT: store ptr [[T0]], ptr [[X]]17// CHECK-NEXT: lifetime.end18// CHECK-NEXT: ret void19 20void test_assign_assign(void) {21 __unsafe_unretained id x, y;22 x = y = makeA();23}24// CHECK-LABEL: define{{.*}} void @test_assign_assign()25// CHECK: [[X:%.*]] = alloca ptr26// CHECK: [[Y:%.*]] = alloca ptr27// CHECK: [[T0:%.*]] = call ptr @makeA() [ "clang.arc.attachedcall"(ptr @llvm.objc.unsafeClaimAutoreleasedReturnValue) ]28// CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use({{.*}} [[T0]])29// CHECK-NEXT: store ptr [[T0]], ptr [[Y]]30// CHECK-NEXT: store ptr [[T0]], ptr [[X]]31// CHECK-NEXT: lifetime.end32// CHECK-NEXT: lifetime.end33// CHECK-NEXT: ret void34 35void test_strong_assign_assign(void) {36 __strong id x;37 __unsafe_unretained id y;38 x = y = makeA();39}40// CHECK-LABEL: define{{.*}} void @test_strong_assign_assign()41// CHECK: [[X:%.*]] = alloca ptr42// CHECK: [[Y:%.*]] = alloca ptr43// CHECK: [[T0:%.*]] = call ptr @makeA() [ "clang.arc.attachedcall"(ptr @llvm.objc.retainAutoreleasedReturnValue) ]44// CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use({{.*}} [[T0]])45// CHECK-NEXT: store ptr [[T0]], ptr [[Y]]46// CHECK-NEXT: [[OLD:%.*]] = load ptr, ptr [[X]]47// CHECK-NEXT: store ptr [[T0]], ptr [[X]]48// CHECK-NEXT: call void @llvm.objc.release(ptr [[OLD]]49// CHECK-NEXT: lifetime.end50// CHECK-NEXT: [[T0:%.*]] = load ptr, ptr [[X]]51// CHECK-NEXT: call void @llvm.objc.release(ptr [[T0]])52// CHECK-NEXT: lifetime.end53// CHECK-NEXT: ret void54 55void test_assign_strong_assign(void) {56 __unsafe_unretained id x;57 __strong id y;58 x = y = makeA();59}60// CHECK-LABEL: define{{.*}} void @test_assign_strong_assign()61// CHECK: [[X:%.*]] = alloca ptr62// CHECK: [[Y:%.*]] = alloca ptr63// CHECK: [[T0:%.*]] = call ptr @makeA() [ "clang.arc.attachedcall"(ptr @llvm.objc.retainAutoreleasedReturnValue) ]64// CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use({{.*}} [[T0]])65// CHECK-NEXT: [[OLD:%.*]] = load ptr, ptr [[Y]]66// CHECK-NEXT: store ptr [[T0]], ptr [[Y]]67// CHECK-NEXT: call void @llvm.objc.release(ptr [[OLD]]68// CHECK-NEXT: store ptr [[T0]], ptr [[X]]69// CHECK-NEXT: [[T0:%.*]] = load ptr, ptr [[Y]]70// CHECK-NEXT: call void @llvm.objc.release(ptr [[T0]])71// CHECK-NEXT: lifetime.end72// CHECK-NEXT: lifetime.end73// CHECK-NEXT: ret void74 75void test_init(void) {76 __unsafe_unretained id x = makeA();77}78// CHECK-LABEL: define{{.*}} void @test_init()79// CHECK: [[X:%.*]] = alloca ptr80// CHECK: [[T0:%.*]] = call ptr @makeA() [ "clang.arc.attachedcall"(ptr @llvm.objc.unsafeClaimAutoreleasedReturnValue) ]81// CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use({{.*}} [[T0]])82// CHECK-NEXT: store ptr [[T0]], ptr [[X]]83// CHECK-NEXT: lifetime.end84// CHECK-NEXT: ret void85 86void test_init_assignment(void) {87 __unsafe_unretained id x;88 __unsafe_unretained id y = x = makeA();89}90// CHECK-LABEL: define{{.*}} void @test_init_assignment()91// CHECK: [[X:%.*]] = alloca ptr92// CHECK: [[Y:%.*]] = alloca ptr93// CHECK: [[T0:%.*]] = call ptr @makeA() [ "clang.arc.attachedcall"(ptr @llvm.objc.unsafeClaimAutoreleasedReturnValue) ]94// CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use({{.*}} [[T0]])95// CHECK-NEXT: store ptr [[T0]], ptr [[X]]96// CHECK-NEXT: store ptr [[T0]], ptr [[Y]]97// CHECK-NEXT: lifetime.end98// CHECK-NEXT: lifetime.end99// CHECK-NEXT: ret void100 101void test_strong_init_assignment(void) {102 __unsafe_unretained id x;103 __strong id y = x = makeA();104}105// CHECK-LABEL: define{{.*}} void @test_strong_init_assignment()106// CHECK: [[X:%.*]] = alloca ptr107// CHECK: [[Y:%.*]] = alloca ptr108// CHECK: [[T0:%.*]] = call ptr @makeA() [ "clang.arc.attachedcall"(ptr @llvm.objc.retainAutoreleasedReturnValue) ]109// CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use({{.*}} [[T0]])110// CHECK-NEXT: store ptr [[T0]], ptr [[X]]111// CHECK-NEXT: store ptr [[T0]], ptr [[Y]]112// CHECK-NEXT: [[T0:%.*]] = load ptr, ptr [[Y]]113// CHECK-NEXT: call void @llvm.objc.release(ptr [[T0]])114// CHECK-NEXT: lifetime.end115// CHECK-NEXT: lifetime.end116// CHECK-NEXT: ret void117 118void test_init_strong_assignment(void) {119 __strong id x;120 __unsafe_unretained id y = x = makeA();121}122// CHECK-LABEL: define{{.*}} void @test_init_strong_assignment()123// CHECK: [[X:%.*]] = alloca ptr124// CHECK: [[Y:%.*]] = alloca ptr125// CHECK: [[T0:%.*]] = call ptr @makeA() [ "clang.arc.attachedcall"(ptr @llvm.objc.retainAutoreleasedReturnValue) ]126// CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use({{.*}} [[T0]])127// CHECK-NEXT: [[OLD:%.*]] = load ptr, ptr [[X]]128// CHECK-NEXT: store ptr [[T0]], ptr [[X]]129// CHECK-NEXT: call void @llvm.objc.release(ptr [[OLD]])130// CHECK-NEXT: store ptr [[T0]], ptr [[Y]]131// CHECK-NEXT: lifetime.end132// CHECK-NEXT: [[T0:%.*]] = load ptr, ptr [[X]]133// CHECK-NEXT: call void @llvm.objc.release(ptr [[T0]])134// CHECK-NEXT: lifetime.end135// CHECK-NEXT: ret void136 137void test_ignored(void) {138 makeA();139}140// CHECK-LABEL: define{{.*}} void @test_ignored()141// CHECK: [[T0:%.*]] = call ptr @makeA() [ "clang.arc.attachedcall"(ptr @llvm.objc.unsafeClaimAutoreleasedReturnValue) ]142// CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use({{.*}} [[T0]])143// CHECK-NEXT: ret void144 145void test_cast_to_void(void) {146 (void) makeA();147}148// CHECK-LABEL: define{{.*}} void @test_cast_to_void()149// CHECK: [[T0:%.*]] = call ptr @makeA() [ "clang.arc.attachedcall"(ptr @llvm.objc.unsafeClaimAutoreleasedReturnValue) ]150// CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use({{.*}} [[T0]])151// CHECK-NEXT: ret void152 153// This is always at the end of the module.154 155// CHECK-OPTIMIZED: !llvm.module.flags = !{!0,156// CHECK-OPTIMIZED: !0 = !{i32 1, !"clang.arc.retainAutoreleasedReturnValueMarker", !"mov{{.*}}marker for objc_retainAutoreleaseReturnValue"}157