Home | History | Annotate | Download | only in CodeGenObjCXX
      1 // RUN: %clang_cc1 -triple x86_64-apple-darwin10 -emit-llvm -fobjc-arc -fexceptions -fobjc-exceptions -fcxx-exceptions -fobjc-runtime-has-weak -o - -fobjc-arc-exceptions %s | FileCheck %s
      2 
      3 @class Ety;
      4 
      5 // These first four tests are all PR11732 / rdar://problem/10667070.
      6 
      7 void test0_helper(void);
      8 void test0(void) {
      9   @try {
     10     test0_helper();
     11   } @catch (Ety *e) {
     12   }
     13 }
     14 // CHECK: define void @_Z5test0v()
     15 // CHECK:      [[E:%.*]] = alloca [[ETY:%.*]]*, align 8
     16 // CHECK-NEXT: invoke void @_Z12test0_helperv()
     17 // CHECK:      [[T0:%.*]] = call i8* @objc_begin_catch(
     18 // CHECK-NEXT: [[T1:%.*]] = bitcast i8* [[T0]] to [[ETY]]*
     19 // CHECK-NEXT: [[T2:%.*]] = bitcast [[ETY]]* [[T1]] to i8*
     20 // CHECK-NEXT: [[T3:%.*]] = call i8* @objc_retain(i8* [[T2]]) [[NUW:#[0-9]+]]
     21 // CHECK-NEXT: [[T4:%.*]] = bitcast i8* [[T3]] to [[ETY]]*
     22 // CHECK-NEXT: store [[ETY]]* [[T4]], [[ETY]]** [[E]]
     23 // CHECK-NEXT: [[T0:%.*]] = bitcast [[ETY]]** [[E]] to i8**
     24 // CHECK-NEXT: call void @objc_storeStrong(i8** [[T0]], i8* null) [[NUW]]
     25 // CHECK-NEXT: call void @objc_end_catch() [[NUW]]
     26 
     27 void test1_helper(void);
     28 void test1(void) {
     29   @try {
     30     test1_helper();
     31   } @catch (__weak Ety *e) {
     32   }
     33 }
     34 // CHECK: define void @_Z5test1v()
     35 // CHECK:      [[E:%.*]] = alloca [[ETY:%.*]]*, align 8
     36 // CHECK-NEXT: invoke void @_Z12test1_helperv()
     37 // CHECK:      [[T0:%.*]] = call i8* @objc_begin_catch(
     38 // CHECK-NEXT: [[T1:%.*]] = bitcast i8* [[T0]] to [[ETY]]*
     39 // CHECK-NEXT: [[T2:%.*]] = bitcast [[ETY]]** [[E]] to i8**
     40 // CHECK-NEXT: [[T3:%.*]] = bitcast [[ETY]]* [[T1]] to i8*
     41 // CHECK-NEXT: call i8* @objc_initWeak(i8** [[T2]], i8* [[T3]]) [[NUW]]
     42 // CHECK-NEXT: [[T0:%.*]] = bitcast [[ETY]]** [[E]] to i8**
     43 // CHECK-NEXT: call void @objc_destroyWeak(i8** [[T0]]) [[NUW]]
     44 // CHECK-NEXT: call void @objc_end_catch() [[NUW]]
     45 
     46 void test2_helper(void);
     47 void test2(void) {
     48   try {
     49     test2_helper();
     50   } catch (Ety *e) {
     51   }
     52 }
     53 // CHECK: define void @_Z5test2v()
     54 // CHECK:      [[E:%.*]] = alloca [[ETY:%.*]]*, align 8
     55 // CHECK-NEXT: invoke void @_Z12test2_helperv()
     56 // CHECK:      [[T0:%.*]] = call i8* @__cxa_begin_catch(
     57 // CHECK-NEXT: [[T1:%.*]] = bitcast i8* [[T0]] to [[ETY]]*
     58 // CHECK-NEXT: [[T2:%.*]] = bitcast [[ETY]]* [[T1]] to i8*
     59 // CHECK-NEXT: [[T3:%.*]] = call i8* @objc_retain(i8* [[T2]]) [[NUW]]
     60 // CHECK-NEXT: [[T4:%.*]] = bitcast i8* [[T3]] to [[ETY]]*
     61 // CHECK-NEXT: store [[ETY]]* [[T4]], [[ETY]]** [[E]]
     62 // CHECK-NEXT: [[T0:%.*]] = bitcast [[ETY]]** [[E]] to i8**
     63 // CHECK-NEXT: call void @objc_storeStrong(i8** [[T0]], i8* null) [[NUW]]
     64 // CHECK-NEXT: call void @__cxa_end_catch() [[NUW]]
     65 
     66 void test3_helper(void);
     67 void test3(void) {
     68   try {
     69     test3_helper();
     70   } catch (Ety * __weak e) {
     71   }
     72 }
     73 // CHECK: define void @_Z5test3v()
     74 // CHECK:      [[E:%.*]] = alloca [[ETY:%.*]]*, align 8
     75 // CHECK-NEXT: invoke void @_Z12test3_helperv()
     76 // CHECK:      [[T0:%.*]] = call i8* @__cxa_begin_catch(
     77 // CHECK-NEXT: [[T1:%.*]] = bitcast i8* [[T0]] to [[ETY]]*
     78 // CHECK-NEXT: [[T2:%.*]] = bitcast [[ETY]]** [[E]] to i8**
     79 // CHECK-NEXT: [[T3:%.*]] = bitcast [[ETY]]* [[T1]] to i8*
     80 // CHECK-NEXT: call i8* @objc_initWeak(i8** [[T2]], i8* [[T3]]) [[NUW]]
     81 // CHECK-NEXT: [[T0:%.*]] = bitcast [[ETY]]** [[E]] to i8**
     82 // CHECK-NEXT: call void @objc_destroyWeak(i8** [[T0]]) [[NUW]]
     83 // CHECK-NEXT: call void @__cxa_end_catch() [[NUW]]
     84 
     85 namespace test4 {
     86   struct A {
     87     id single;
     88     id array[2][3];
     89 
     90     A();
     91   };
     92 
     93   A::A() {
     94     throw 0;
     95   }
     96   // CHECK:    define void @_ZN5test41AC2Ev(
     97   // CHECK:      [[THIS:%.*]] = load [[A:%.*]]** {{%.*}}
     98   //   Construct single.
     99   // CHECK-NEXT: [[SINGLE:%.*]] = getelementptr inbounds [[A]]* [[THIS]], i32 0, i32 0
    100   // CHECK-NEXT: store i8* null, i8** [[SINGLE]], align 8
    101   //   Construct array.
    102   // CHECK-NEXT: [[ARRAY:%.*]] = getelementptr inbounds [[A]]* [[THIS]], i32 0, i32 1
    103   // CHECK-NEXT: [[T0:%.*]] = bitcast [2 x [3 x i8*]]* [[ARRAY]] to i8*
    104   // CHECK-NEXT: call void @llvm.memset.p0i8.i64(i8* [[T0]], i8 0, i64 48, i32 8, i1 false)
    105   //   throw 0;
    106   // CHECK:      invoke void @__cxa_throw(
    107   //   Landing pad from throw site:
    108   // CHECK:      landingpad
    109   //     - First, destroy all of array.
    110   // CHECK:      [[ARRAYBEGIN:%.*]] = getelementptr inbounds [2 x [3 x i8*]]* [[ARRAY]], i32 0, i32 0, i32 0
    111   // CHECK-NEXT: [[ARRAYEND:%.*]] = getelementptr inbounds i8** [[ARRAYBEGIN]], i64 6
    112   // CHECK-NEXT: br label
    113   // CHECK:      [[AFTER:%.*]] = phi i8** [ [[ARRAYEND]], {{%.*}} ], [ [[ELT:%.*]], {{%.*}} ]
    114   // CHECK-NEXT: [[ELT]] = getelementptr inbounds i8** [[AFTER]], i64 -1
    115   // CHECK-NEXT: call void @objc_storeStrong(i8** [[ELT]], i8* null) [[NUW]]
    116   // CHECK-NEXT: [[DONE:%.*]] = icmp eq i8** [[ELT]], [[ARRAYBEGIN]]
    117   // CHECK-NEXT: br i1 [[DONE]],
    118   //     - Next, destroy single.
    119   // CHECK:      call void @objc_storeStrong(i8** [[SINGLE]], i8* null) [[NUW]]
    120   // CHECK:      br label
    121   // CHECK:      resume
    122 }
    123 
    124 // CHECK: attributes [[NUW]] = { nounwind }
    125