[clang][modules] Don't prevent translation of FW_Private includes when explicitly...
[llvm-project.git] / clang / test / CodeGenObjCXX / arc-exceptions.mm
blob709afa32ac7d81f833ccefa27a18f4cfef8beebd
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
3 @class Ety;
5 // These first four tests are all PR11732.
7 void test0_helper(void);
8 void test0(void) {
9   @try {
10     test0_helper();
11   } @catch (Ety *e) {
12   }
14 // CHECK-LABEL: define{{.*}} void @_Z5test0v()
15 // CHECK:      [[E:%e]] = alloca ptr, align 8
16 // CHECK-NEXT: invoke void @_Z12test0_helperv()
17 // CHECK:      [[T0:%.*]] = call ptr @objc_begin_catch(
18 // CHECK-NEXT: [[T3:%.*]] = call ptr @llvm.objc.retain(ptr [[T0]]) [[NUW:#[0-9]+]]
19 // CHECK-NEXT: store ptr [[T3]], ptr [[E]]
20 // CHECK-NEXT: call void @llvm.objc.storeStrong(ptr [[E]], ptr null) [[NUW]]
21 // CHECK-NEXT: call void @objc_end_catch() [[NUW]]
23 void test1_helper(void);
24 void test1(void) {
25   @try {
26     test1_helper();
27   } @catch (__weak Ety *e) {
28   }
30 // CHECK-LABEL: define{{.*}} void @_Z5test1v()
31 // CHECK:      [[E:%e]] = alloca ptr, align 8
32 // CHECK-NEXT: invoke void @_Z12test1_helperv()
33 // CHECK:      [[T0:%.*]] = call ptr @objc_begin_catch(
34 // CHECK-NEXT: call ptr @llvm.objc.initWeak(ptr [[E]], ptr [[T0]]) [[NUW]]
35 // CHECK-NEXT: call void @llvm.objc.destroyWeak(ptr [[E]]) [[NUW]]
36 // CHECK-NEXT: call void @objc_end_catch() [[NUW]]
38 void test2_helper(void);
39 void test2(void) {
40   try {
41     test2_helper();
42   } catch (Ety *e) {
43   }
45 // CHECK-LABEL: define{{.*}} void @_Z5test2v()
46 // CHECK:      [[E:%e]] = alloca ptr, align 8
47 // CHECK-NEXT: invoke void @_Z12test2_helperv()
48 // CHECK:      [[T0:%.*]] = call ptr @__cxa_begin_catch(
49 // CHECK-NEXT: [[T3:%.*]] = call ptr @llvm.objc.retain(ptr [[T0]]) [[NUW]]
50 // CHECK-NEXT: store ptr [[T3]], ptr [[E]]
51 // CHECK-NEXT: call void @llvm.objc.storeStrong(ptr [[E]], ptr null) [[NUW]]
52 // CHECK-NEXT: call void @__cxa_end_catch() [[NUW]]
54 void test3_helper(void);
55 void test3(void) {
56   try {
57     test3_helper();
58   } catch (Ety * __weak e) {
59   }
61 // CHECK-LABEL: define{{.*}} void @_Z5test3v()
62 // CHECK:      [[E:%e]] = alloca ptr, align 8
63 // CHECK-NEXT: invoke void @_Z12test3_helperv()
64 // CHECK:      [[T0:%.*]] = call ptr @__cxa_begin_catch(
65 // CHECK-NEXT: call ptr @llvm.objc.initWeak(ptr [[E]], ptr [[T0]]) [[NUW]]
66 // CHECK-NEXT: call void @llvm.objc.destroyWeak(ptr [[E]]) [[NUW]]
67 // CHECK-NEXT: call void @__cxa_end_catch() [[NUW]]
69 namespace test4 {
70   struct A {
71     id single;
72     id array[2][3];
74     A();
75   };
77   A::A() {
78     throw 0;
79   }
80   // CHECK-LABEL:    define{{.*}} void @_ZN5test41AC2Ev(
81   // CHECK:      [[THIS:%.*]] = load ptr, ptr {{%.*}}
82   //   Construct single.
83   // CHECK-NEXT: [[SINGLE:%.*]] = getelementptr inbounds [[A:%.*]], ptr [[THIS]], i32 0, i32 0
84   // CHECK-NEXT: store ptr null, ptr [[SINGLE]], align 8
85   //   Construct array.
86   // CHECK-NEXT: [[ARRAY:%.*]] = getelementptr inbounds [[A:%.*]], ptr [[THIS]], i32 0, i32 1
87   // CHECK-NEXT: call void @llvm.memset.p0.i64(ptr align 8 [[ARRAY]], i8 0, i64 48, i1 false)
88   //   throw 0;
89   // CHECK:      invoke void @__cxa_throw(
90   //   Landing pad from throw site:
91   // CHECK:      landingpad
92   //     - First, destroy all of array.
93   // CHECK:      [[ARRAYBEGIN:%.*]] = getelementptr inbounds [2 x [3 x ptr]], ptr [[ARRAY]], i32 0, i32 0, i32 0
94   // CHECK-NEXT: [[ARRAYEND:%.*]] = getelementptr inbounds ptr, ptr [[ARRAYBEGIN]], i64 6
95   // CHECK-NEXT: br label
96   // CHECK:      [[AFTER:%.*]] = phi ptr [ [[ARRAYEND]], {{%.*}} ], [ [[ELT:%.*]], {{%.*}} ]
97   // CHECK-NEXT: [[ELT]] = getelementptr inbounds ptr, ptr [[AFTER]], i64 -1
98   // CHECK-NEXT: call void @llvm.objc.storeStrong(ptr [[ELT]], ptr null) [[NUW]]
99   // CHECK-NEXT: [[DONE:%.*]] = icmp eq ptr [[ELT]], [[ARRAYBEGIN]]
100   // CHECK-NEXT: br i1 [[DONE]],
101   //     - Next, destroy single.
102   // CHECK:      call void @llvm.objc.storeStrong(ptr [[SINGLE]], ptr null) [[NUW]]
103   // CHECK:      br label
104   // CHECK:      resume
107 __attribute__((ns_returns_retained)) id test5_helper(unsigned);
108 void test5(void) {
109   id array[][2] = {
110     test5_helper(0),
111     test5_helper(1),
112     test5_helper(2),
113     test5_helper(3)
114   };
116 // CHECK-LABEL: define{{.*}} void @_Z5test5v()
117 // CHECK:       [[ARRAY:%.*]] = alloca [2 x [2 x ptr]], align
118 // CHECK:       [[A0:%.*]] = getelementptr inbounds [2 x [2 x ptr]], ptr [[ARRAY]], i64 0, i64 0
119 // CHECK-NEXT:  store ptr [[A0]],
120 // CHECK-NEXT:  [[A00:%.*]] = getelementptr inbounds [2 x ptr], ptr [[A0]], i64 0, i64 0
121 // CHECK-NEXT:  store ptr [[A00]],
122 // CHECK-NEXT:  [[T0:%.*]] = invoke noundef ptr @_Z12test5_helperj(i32 noundef 0)
123 // CHECK:       store ptr [[T0]], ptr [[A00]], align
124 // CHECK-NEXT:  [[A01:%.*]] = getelementptr inbounds ptr, ptr [[A00]], i64 1
125 // CHECK-NEXT:  store ptr [[A01]],
126 // CHECK-NEXT:  [[T0:%.*]] = invoke noundef ptr @_Z12test5_helperj(i32 noundef 1)
127 // CHECK:       store ptr [[T0]], ptr [[A01]], align
128 // CHECK-NEXT:  [[A1:%.*]] = getelementptr inbounds [2 x ptr], ptr [[A0]], i64 1
129 // CHECK-NEXT:  store ptr [[A1]],
130 // CHECK-NEXT:  [[A10:%.*]] = getelementptr inbounds [2 x ptr], ptr [[A1]], i64 0, i64 0
131 // CHECK-NEXT:  store ptr [[A10]],
132 // CHECK-NEXT:  [[T0:%.*]] = invoke noundef ptr @_Z12test5_helperj(i32 noundef 2)
133 // CHECK:       store ptr [[T0]], ptr [[A10]], align
134 // CHECK-NEXT:  [[A11:%.*]] = getelementptr inbounds ptr, ptr [[A10]], i64 1
135 // CHECK-NEXT:  store ptr [[A11]],
136 // CHECK-NEXT:  [[T0:%.*]] = invoke noundef ptr @_Z12test5_helperj(i32 noundef 3)
137 // CHECK:       store ptr [[T0]], ptr [[A11]], align
139 // CHECK: attributes [[NUW]] = { nounwind }