Home | History | Annotate | Download | only in CodeGenObjC
      1 //   Make sure it works on x86-64.
      2 // RUN: %clang_cc1 -triple x86_64-apple-darwin11 -fobjc-runtime=macosx-10.11 -fobjc-arc -emit-llvm -o - %s | FileCheck %s -check-prefix=CHECK -check-prefix=CHECK-UNOPTIMIZED
      3 
      4 //   Make sure it works on ARM.
      5 // RUN: %clang_cc1 -triple arm64-apple-ios9 -fobjc-runtime=ios-9.0 -fobjc-arc -emit-llvm -o - %s | FileCheck %s -check-prefix=CHECK -check-prefix=CHECK-UNOPTIMIZED -check-prefix=CHECK-MARKED
      6 // RUN: %clang_cc1 -triple arm64-apple-ios9 -fobjc-runtime=ios-9.0 -fobjc-arc -O -disable-llvm-optzns -emit-llvm -o - %s | FileCheck %s -check-prefix=CHECK -check-prefix=CHECK-OPTIMIZED
      7 
      8 //   Make sure it works on ARM64.
      9 // RUN: %clang_cc1 -triple armv7-apple-ios9 -fobjc-runtime=ios-9.0 -fobjc-arc -emit-llvm -o - %s | FileCheck %s -check-prefix=CHECK -check-prefix=CHECK-UNOPTIMIZED -check-prefix=CHECK-MARKED
     10 // RUN: %clang_cc1 -triple armv7-apple-ios9 -fobjc-runtime=ios-9.0 -fobjc-arc -O -disable-llvm-optzns -emit-llvm -o - %s | FileCheck %s -check-prefix=CHECK -check-prefix=CHECK-OPTIMIZED
     11 
     12 //   Make sure that it's implicitly disabled if the runtime version isn't high enough.
     13 // RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fobjc-runtime=macosx-10.10 -fobjc-arc -emit-llvm -o - %s | FileCheck %s -check-prefix=DISABLED
     14 // RUN: %clang_cc1 -triple arm64-apple-ios8 -fobjc-runtime=ios-8 -fobjc-arc -emit-llvm -o - %s | FileCheck %s -check-prefix=DISABLED -check-prefix=DISABLED-MARKED
     15 
     16 @class A;
     17 
     18 A *makeA(void);
     19 
     20 void test_assign() {
     21   __unsafe_unretained id x;
     22   x = makeA();
     23 }
     24 // CHECK-LABEL:        define void @test_assign()
     25 // CHECK:                [[X:%.*]] = alloca i8*
     26 // CHECK:                [[T0:%.*]] = call [[A:.*]]* @makeA()
     27 // CHECK-MARKED-NEXT:    call void asm sideeffect
     28 // CHECK-NEXT:           [[T1:%.*]] = bitcast [[A]]* [[T0]] to i8*
     29 // CHECK-NEXT:           [[T2:%.*]] = call i8* @objc_unsafeClaimAutoreleasedReturnValue(i8* [[T1]])
     30 // CHECK-NEXT:           [[T3:%.*]] = bitcast i8* [[T2]] to [[A]]*
     31 // CHECK-NEXT:           [[T4:%.*]] = bitcast [[A]]* [[T3]] to i8*
     32 // CHECK-NEXT:           store i8* [[T4]], i8** [[X]]
     33 // CHECK-OPTIMIZED-NEXT: bitcast
     34 // CHECK-OPTIMIZED-NEXT: lifetime.end
     35 // CHECK-NEXT:           ret void
     36 
     37 // DISABLED-LABEL:     define void @test_assign()
     38 // DISABLED:             [[T0:%.*]] = call [[A:.*]]* @makeA()
     39 // DISABLED-MARKED-NEXT: call void asm sideeffect
     40 // DISABLED-NEXT:        [[T1:%.*]] = bitcast [[A]]* [[T0]] to i8*
     41 // DISABLED-NEXT:        [[T2:%.*]] = call i8* @objc_retainAutoreleasedReturnValue(i8* [[T1]])
     42 
     43 void test_assign_assign() {
     44   __unsafe_unretained id x, y;
     45   x = y = makeA();
     46 }
     47 // CHECK-LABEL:        define void @test_assign_assign()
     48 // CHECK:                [[X:%.*]] = alloca i8*
     49 // CHECK:                [[Y:%.*]] = alloca i8*
     50 // CHECK:                [[T0:%.*]] = call [[A]]* @makeA()
     51 // CHECK-MARKED-NEXT:    call void asm sideeffect
     52 // CHECK-NEXT:           [[T1:%.*]] = bitcast [[A]]* [[T0]] to i8*
     53 // CHECK-NEXT:           [[T2:%.*]] = call i8* @objc_unsafeClaimAutoreleasedReturnValue(i8* [[T1]])
     54 // CHECK-NEXT:           [[T3:%.*]] = bitcast i8* [[T2]] to [[A]]*
     55 // CHECK-NEXT:           [[T4:%.*]] = bitcast [[A]]* [[T3]] to i8*
     56 // CHECK-NEXT:           store i8* [[T4]], i8** [[Y]]
     57 // CHECK-NEXT:           store i8* [[T4]], i8** [[X]]
     58 // CHECK-OPTIMIZED-NEXT: bitcast
     59 // CHECK-OPTIMIZED-NEXT: lifetime.end
     60 // CHECK-OPTIMIZED-NEXT: bitcast
     61 // CHECK-OPTIMIZED-NEXT: lifetime.end
     62 // CHECK-NEXT:           ret void
     63 
     64 void test_strong_assign_assign() {
     65   __strong id x;
     66   __unsafe_unretained id y;
     67   x = y = makeA();
     68 }
     69 // CHECK-LABEL:        define void @test_strong_assign_assign()
     70 // CHECK:                [[X:%.*]] = alloca i8*
     71 // CHECK:                [[Y:%.*]] = alloca i8*
     72 // CHECK:                [[T0:%.*]] = call [[A]]* @makeA()
     73 // CHECK-MARKED-NEXT:    call void asm sideeffect
     74 // CHECK-NEXT:           [[T1:%.*]] = bitcast [[A]]* [[T0]] to i8*
     75 // CHECK-NEXT:           [[T2:%.*]] = call i8* @objc_retainAutoreleasedReturnValue(i8* [[T1]])
     76 // CHECK-NEXT:           [[T3:%.*]] = bitcast i8* [[T2]] to [[A]]*
     77 // CHECK-NEXT:           [[T4:%.*]] = bitcast [[A]]* [[T3]] to i8*
     78 // CHECK-NEXT:           store i8* [[T4]], i8** [[Y]]
     79 // CHECK-NEXT:           [[OLD:%.*]] = load i8*, i8** [[X]]
     80 // CHECK-NEXT:           store i8* [[T4]], i8** [[X]]
     81 // CHECK-NEXT:           call void @objc_release(i8* [[OLD]]
     82 // CHECK-OPTIMIZED-NEXT: bitcast
     83 // CHECK-OPTIMIZED-NEXT: lifetime.end
     84 // CHECK-UNOPTIMIZED-NEXT: call void @objc_storeStrong(i8** [[X]], i8* null)
     85 // CHECK-OPTIMIZED-NEXT: [[T0:%.*]] = load i8*, i8** [[X]]
     86 // CHECK-OPTIMIZED-NEXT: call void @objc_release(i8* [[T0]])
     87 // CHECK-OPTIMIZED-NEXT: bitcast
     88 // CHECK-OPTIMIZED-NEXT: lifetime.end
     89 // CHECK-NEXT:           ret void
     90 
     91 void test_assign_strong_assign() {
     92   __unsafe_unretained id x;
     93   __strong id y;
     94   x = y = makeA();
     95 }
     96 // CHECK-LABEL:        define void @test_assign_strong_assign()
     97 // CHECK:                [[X:%.*]] = alloca i8*
     98 // CHECK:                [[Y:%.*]] = alloca i8*
     99 // CHECK:                [[T0:%.*]] = call [[A]]* @makeA()
    100 // CHECK-MARKED-NEXT:    call void asm sideeffect
    101 // CHECK-NEXT:           [[T1:%.*]] = bitcast [[A]]* [[T0]] to i8*
    102 // CHECK-NEXT:           [[T2:%.*]] = call i8* @objc_retainAutoreleasedReturnValue(i8* [[T1]])
    103 // CHECK-NEXT:           [[T3:%.*]] = bitcast i8* [[T2]] to [[A]]*
    104 // CHECK-NEXT:           [[T4:%.*]] = bitcast [[A]]* [[T3]] to i8*
    105 // CHECK-NEXT:           [[OLD:%.*]] = load i8*, i8** [[Y]]
    106 // CHECK-NEXT:           store i8* [[T4]], i8** [[Y]]
    107 // CHECK-NEXT:           call void @objc_release(i8* [[OLD]]
    108 // CHECK-NEXT:           store i8* [[T4]], i8** [[X]]
    109 // CHECK-UNOPTIMIZED-NEXT: call void @objc_storeStrong(i8** [[Y]], i8* null)
    110 // CHECK-OPTIMIZED-NEXT: [[T0:%.*]] = load i8*, i8** [[Y]]
    111 // CHECK-OPTIMIZED-NEXT: call void @objc_release(i8* [[T0]])
    112 // CHECK-OPTIMIZED-NEXT: bitcast
    113 // CHECK-OPTIMIZED-NEXT: lifetime.end
    114 // CHECK-OPTIMIZED-NEXT: bitcast
    115 // CHECK-OPTIMIZED-NEXT: lifetime.end
    116 // CHECK-NEXT:           ret void
    117 
    118 void test_init() {
    119   __unsafe_unretained id x = makeA();
    120 }
    121 // CHECK-LABEL:        define void @test_init()
    122 // CHECK:                [[X:%.*]] = alloca i8*
    123 // CHECK:                [[T0:%.*]] = call [[A]]* @makeA()
    124 // CHECK-MARKED-NEXT:    call void asm sideeffect
    125 // CHECK-NEXT:           [[T1:%.*]] = bitcast [[A]]* [[T0]] to i8*
    126 // CHECK-NEXT:           [[T2:%.*]] = call i8* @objc_unsafeClaimAutoreleasedReturnValue(i8* [[T1]])
    127 // CHECK-NEXT:           [[T3:%.*]] = bitcast i8* [[T2]] to [[A]]*
    128 // CHECK-NEXT:           [[T4:%.*]] = bitcast [[A]]* [[T3]] to i8*
    129 // CHECK-NEXT:           store i8* [[T4]], i8** [[X]]
    130 // CHECK-OPTIMIZED-NEXT: bitcast
    131 // CHECK-OPTIMIZED-NEXT: lifetime.end
    132 // CHECK-NEXT:           ret void
    133 
    134 void test_init_assignment() {
    135   __unsafe_unretained id x;
    136   __unsafe_unretained id y = x = makeA();
    137 }
    138 // CHECK-LABEL:        define void @test_init_assignment()
    139 // CHECK:                [[X:%.*]] = alloca i8*
    140 // CHECK:                [[Y:%.*]] = alloca i8*
    141 // CHECK:                [[T0:%.*]] = call [[A]]* @makeA()
    142 // CHECK-MARKED-NEXT:    call void asm sideeffect
    143 // CHECK-NEXT:           [[T1:%.*]] = bitcast [[A]]* [[T0]] to i8*
    144 // CHECK-NEXT:           [[T2:%.*]] = call i8* @objc_unsafeClaimAutoreleasedReturnValue(i8* [[T1]])
    145 // CHECK-NEXT:           [[T3:%.*]] = bitcast i8* [[T2]] to [[A]]*
    146 // CHECK-NEXT:           [[T4:%.*]] = bitcast [[A]]* [[T3]] to i8*
    147 // CHECK-NEXT:           store i8* [[T4]], i8** [[X]]
    148 // CHECK-NEXT:           store i8* [[T4]], i8** [[Y]]
    149 // CHECK-OPTIMIZED-NEXT: bitcast
    150 // CHECK-OPTIMIZED-NEXT: lifetime.end
    151 // CHECK-OPTIMIZED-NEXT: bitcast
    152 // CHECK-OPTIMIZED-NEXT: lifetime.end
    153 // CHECK-NEXT: ret void
    154 
    155 void test_strong_init_assignment() {
    156   __unsafe_unretained id x;
    157   __strong id y = x = makeA();
    158 }
    159 // CHECK-LABEL:        define void @test_strong_init_assignment()
    160 // CHECK:                [[X:%.*]] = alloca i8*
    161 // CHECK:                [[Y:%.*]] = alloca i8*
    162 // CHECK:                [[T0:%.*]] = call [[A]]* @makeA()
    163 // CHECK-MARKED-NEXT:    call void asm sideeffect
    164 // CHECK-NEXT:           [[T1:%.*]] = bitcast [[A]]* [[T0]] to i8*
    165 // CHECK-NEXT:           [[T2:%.*]] = call i8* @objc_retainAutoreleasedReturnValue(i8* [[T1]])
    166 // CHECK-NEXT:           [[T3:%.*]] = bitcast i8* [[T2]] to [[A]]*
    167 // CHECK-NEXT:           [[T4:%.*]] = bitcast [[A]]* [[T3]] to i8*
    168 // CHECK-NEXT:           store i8* [[T4]], i8** [[X]]
    169 // CHECK-NEXT:           store i8* [[T4]], i8** [[Y]]
    170 // CHECK-UNOPTIMIZED-NEXT: call void @objc_storeStrong(i8** [[Y]], i8* null)
    171 // CHECK-OPTIMIZED-NEXT: [[T0:%.*]] = load i8*, i8** [[Y]]
    172 // CHECK-OPTIMIZED-NEXT: call void @objc_release(i8* [[T0]])
    173 // CHECK-OPTIMIZED-NEXT: bitcast
    174 // CHECK-OPTIMIZED-NEXT: lifetime.end
    175 // CHECK-OPTIMIZED-NEXT: bitcast
    176 // CHECK-OPTIMIZED-NEXT: lifetime.end
    177 // CHECK-NEXT: ret void
    178 
    179 void test_init_strong_assignment() {
    180   __strong id x;
    181   __unsafe_unretained id y = x = makeA();
    182 }
    183 // CHECK-LABEL:        define void @test_init_strong_assignment()
    184 // CHECK:                [[X:%.*]] = alloca i8*
    185 // CHECK:                [[Y:%.*]] = alloca i8*
    186 // CHECK:                [[T0:%.*]] = call [[A]]* @makeA()
    187 // CHECK-MARKED-NEXT:    call void asm sideeffect
    188 // CHECK-NEXT:           [[T1:%.*]] = bitcast [[A]]* [[T0]] to i8*
    189 // CHECK-NEXT:           [[T2:%.*]] = call i8* @objc_retainAutoreleasedReturnValue(i8* [[T1]])
    190 // CHECK-NEXT:           [[T3:%.*]] = bitcast i8* [[T2]] to [[A]]*
    191 // CHECK-NEXT:           [[T4:%.*]] = bitcast [[A]]* [[T3]] to i8*
    192 // CHECK-NEXT:           [[OLD:%.*]] = load i8*, i8** [[X]]
    193 // CHECK-NEXT:           store i8* [[T4]], i8** [[X]]
    194 // CHECK-NEXT:           call void @objc_release(i8* [[OLD]])
    195 // CHECK-NEXT:           store i8* [[T4]], i8** [[Y]]
    196 // CHECK-OPTIMIZED-NEXT: bitcast
    197 // CHECK-OPTIMIZED-NEXT: lifetime.end
    198 // CHECK-UNOPTIMIZED-NEXT: call void @objc_storeStrong(i8** [[X]], i8* null)
    199 // CHECK-OPTIMIZED-NEXT: [[T0:%.*]] = load i8*, i8** [[X]]
    200 // CHECK-OPTIMIZED-NEXT: call void @objc_release(i8* [[T0]])
    201 // CHECK-OPTIMIZED-NEXT: bitcast
    202 // CHECK-OPTIMIZED-NEXT: lifetime.end
    203 // CHECK-NEXT: ret void
    204 
    205 void test_ignored() {
    206   makeA();
    207 }
    208 // CHECK-LABEL:     define void @test_ignored()
    209 // CHECK:             [[T0:%.*]] = call [[A]]* @makeA()
    210 // CHECK-MARKED-NEXT: call void asm sideeffect
    211 // CHECK-NEXT:        [[T1:%.*]] = bitcast [[A]]* [[T0]] to i8*
    212 // CHECK-NEXT:        [[T2:%.*]] = call i8* @objc_unsafeClaimAutoreleasedReturnValue(i8* [[T1]])
    213 // CHECK-NEXT:        bitcast i8* [[T2]] to [[A]]*
    214 // CHECK-NEXT:        ret void
    215 
    216 void test_cast_to_void() {
    217   (void) makeA();
    218 }
    219 // CHECK-LABEL:     define void @test_cast_to_void()
    220 // CHECK:             [[T0:%.*]] = call [[A]]* @makeA()
    221 // CHECK-MARKED-NEXT: call void asm sideeffect
    222 // CHECK-NEXT:        [[T1:%.*]] = bitcast [[A]]* [[T0]] to i8*
    223 // CHECK-NEXT:        [[T2:%.*]] = call i8* @objc_unsafeClaimAutoreleasedReturnValue(i8* [[T1]])
    224 // CHECK-NEXT:        bitcast i8* [[T2]] to [[A]]*
    225 // CHECK-NEXT:        ret void
    226 
    227 
    228 
    229 // This is always at the end of the module.
    230 
    231 // CHECK-OPTIMIZED: !clang.arc.retainAutoreleasedReturnValueMarker = !{!0}
    232