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=CHECK 2// 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=CHECK 3 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 ptr 14// 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.end 18// CHECK-NEXT: ret void 19 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 ptr 26// CHECK: [[Y:%.*]] = alloca ptr 27// 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.end 32// CHECK-NEXT: lifetime.end 33// CHECK-NEXT: ret void 34 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 ptr 42// CHECK: [[Y:%.*]] = alloca ptr 43// 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.end 50// CHECK-NEXT: [[T0:%.*]] = load ptr, ptr [[X]] 51// CHECK-NEXT: call void @llvm.objc.release(ptr [[T0]]) 52// CHECK-NEXT: lifetime.end 53// CHECK-NEXT: ret void 54 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 ptr 62// CHECK: [[Y:%.*]] = alloca ptr 63// 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.end 72// CHECK-NEXT: lifetime.end 73// CHECK-NEXT: ret void 74 75void test_init(void) { 76 __unsafe_unretained id x = makeA(); 77} 78// CHECK-LABEL: define{{.*}} void @test_init() 79// CHECK: [[X:%.*]] = alloca ptr 80// 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.end 84// CHECK-NEXT: ret void 85 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 ptr 92// CHECK: [[Y:%.*]] = alloca ptr 93// 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.end 98// CHECK-NEXT: lifetime.end 99// CHECK-NEXT: ret void 100 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 ptr 107// CHECK: [[Y:%.*]] = alloca ptr 108// 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.end 115// CHECK-NEXT: lifetime.end 116// CHECK-NEXT: ret void 117 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 ptr 124// CHECK: [[Y:%.*]] = alloca ptr 125// 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.end 132// CHECK-NEXT: [[T0:%.*]] = load ptr, ptr [[X]] 133// CHECK-NEXT: call void @llvm.objc.release(ptr [[T0]]) 134// CHECK-NEXT: lifetime.end 135// CHECK-NEXT: ret void 136 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 void 144 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 void 152 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