xref: /aosp_15_r20/external/clang/test/CodeGenObjCXX/arc-exceptions.mm (revision 67e74705e28f6214e480b399dd47ea732279e315)
1*67e74705SXin Li// 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*67e74705SXin Li
3*67e74705SXin Li@class Ety;
4*67e74705SXin Li
5*67e74705SXin Li// These first four tests are all PR11732 / rdar://problem/10667070.
6*67e74705SXin Li
7*67e74705SXin Livoid test0_helper(void);
8*67e74705SXin Livoid test0(void) {
9*67e74705SXin Li  @try {
10*67e74705SXin Li    test0_helper();
11*67e74705SXin Li  } @catch (Ety *e) {
12*67e74705SXin Li  }
13*67e74705SXin Li}
14*67e74705SXin Li// CHECK-LABEL: define void @_Z5test0v()
15*67e74705SXin Li// CHECK:      [[E:%.*]] = alloca [[ETY:%.*]]*, align 8
16*67e74705SXin Li// CHECK-NEXT: invoke void @_Z12test0_helperv()
17*67e74705SXin Li// CHECK:      [[T0:%.*]] = call i8* @objc_begin_catch(
18*67e74705SXin Li// CHECK-NEXT: [[T1:%.*]] = bitcast i8* [[T0]] to [[ETY]]*
19*67e74705SXin Li// CHECK-NEXT: [[T2:%.*]] = bitcast [[ETY]]* [[T1]] to i8*
20*67e74705SXin Li// CHECK-NEXT: [[T3:%.*]] = call i8* @objc_retain(i8* [[T2]]) [[NUW:#[0-9]+]]
21*67e74705SXin Li// CHECK-NEXT: [[T4:%.*]] = bitcast i8* [[T3]] to [[ETY]]*
22*67e74705SXin Li// CHECK-NEXT: store [[ETY]]* [[T4]], [[ETY]]** [[E]]
23*67e74705SXin Li// CHECK-NEXT: [[T0:%.*]] = bitcast [[ETY]]** [[E]] to i8**
24*67e74705SXin Li// CHECK-NEXT: call void @objc_storeStrong(i8** [[T0]], i8* null) [[NUW]]
25*67e74705SXin Li// CHECK-NEXT: call void @objc_end_catch() [[NUW]]
26*67e74705SXin Li
27*67e74705SXin Livoid test1_helper(void);
28*67e74705SXin Livoid test1(void) {
29*67e74705SXin Li  @try {
30*67e74705SXin Li    test1_helper();
31*67e74705SXin Li  } @catch (__weak Ety *e) {
32*67e74705SXin Li  }
33*67e74705SXin Li}
34*67e74705SXin Li// CHECK-LABEL: define void @_Z5test1v()
35*67e74705SXin Li// CHECK:      [[E:%.*]] = alloca [[ETY:%.*]]*, align 8
36*67e74705SXin Li// CHECK-NEXT: invoke void @_Z12test1_helperv()
37*67e74705SXin Li// CHECK:      [[T0:%.*]] = call i8* @objc_begin_catch(
38*67e74705SXin Li// CHECK-NEXT: [[T1:%.*]] = bitcast i8* [[T0]] to [[ETY]]*
39*67e74705SXin Li// CHECK-NEXT: [[T2:%.*]] = bitcast [[ETY]]** [[E]] to i8**
40*67e74705SXin Li// CHECK-NEXT: [[T3:%.*]] = bitcast [[ETY]]* [[T1]] to i8*
41*67e74705SXin Li// CHECK-NEXT: call i8* @objc_initWeak(i8** [[T2]], i8* [[T3]]) [[NUW]]
42*67e74705SXin Li// CHECK-NEXT: [[T0:%.*]] = bitcast [[ETY]]** [[E]] to i8**
43*67e74705SXin Li// CHECK-NEXT: call void @objc_destroyWeak(i8** [[T0]]) [[NUW]]
44*67e74705SXin Li// CHECK-NEXT: call void @objc_end_catch() [[NUW]]
45*67e74705SXin Li
46*67e74705SXin Livoid test2_helper(void);
47*67e74705SXin Livoid test2(void) {
48*67e74705SXin Li  try {
49*67e74705SXin Li    test2_helper();
50*67e74705SXin Li  } catch (Ety *e) {
51*67e74705SXin Li  }
52*67e74705SXin Li}
53*67e74705SXin Li// CHECK-LABEL: define void @_Z5test2v()
54*67e74705SXin Li// CHECK:      [[E:%.*]] = alloca [[ETY:%.*]]*, align 8
55*67e74705SXin Li// CHECK-NEXT: invoke void @_Z12test2_helperv()
56*67e74705SXin Li// CHECK:      [[T0:%.*]] = call i8* @__cxa_begin_catch(
57*67e74705SXin Li// CHECK-NEXT: [[T1:%.*]] = bitcast i8* [[T0]] to [[ETY]]*
58*67e74705SXin Li// CHECK-NEXT: [[T2:%.*]] = bitcast [[ETY]]* [[T1]] to i8*
59*67e74705SXin Li// CHECK-NEXT: [[T3:%.*]] = call i8* @objc_retain(i8* [[T2]]) [[NUW]]
60*67e74705SXin Li// CHECK-NEXT: [[T4:%.*]] = bitcast i8* [[T3]] to [[ETY]]*
61*67e74705SXin Li// CHECK-NEXT: store [[ETY]]* [[T4]], [[ETY]]** [[E]]
62*67e74705SXin Li// CHECK-NEXT: [[T0:%.*]] = bitcast [[ETY]]** [[E]] to i8**
63*67e74705SXin Li// CHECK-NEXT: call void @objc_storeStrong(i8** [[T0]], i8* null) [[NUW]]
64*67e74705SXin Li// CHECK-NEXT: call void @__cxa_end_catch() [[NUW]]
65*67e74705SXin Li
66*67e74705SXin Livoid test3_helper(void);
67*67e74705SXin Livoid test3(void) {
68*67e74705SXin Li  try {
69*67e74705SXin Li    test3_helper();
70*67e74705SXin Li  } catch (Ety * __weak e) {
71*67e74705SXin Li  }
72*67e74705SXin Li}
73*67e74705SXin Li// CHECK-LABEL: define void @_Z5test3v()
74*67e74705SXin Li// CHECK:      [[E:%.*]] = alloca [[ETY:%.*]]*, align 8
75*67e74705SXin Li// CHECK-NEXT: invoke void @_Z12test3_helperv()
76*67e74705SXin Li// CHECK:      [[T0:%.*]] = call i8* @__cxa_begin_catch(
77*67e74705SXin Li// CHECK-NEXT: [[T1:%.*]] = bitcast i8* [[T0]] to [[ETY]]*
78*67e74705SXin Li// CHECK-NEXT: [[T2:%.*]] = bitcast [[ETY]]** [[E]] to i8**
79*67e74705SXin Li// CHECK-NEXT: [[T3:%.*]] = bitcast [[ETY]]* [[T1]] to i8*
80*67e74705SXin Li// CHECK-NEXT: call i8* @objc_initWeak(i8** [[T2]], i8* [[T3]]) [[NUW]]
81*67e74705SXin Li// CHECK-NEXT: [[T0:%.*]] = bitcast [[ETY]]** [[E]] to i8**
82*67e74705SXin Li// CHECK-NEXT: call void @objc_destroyWeak(i8** [[T0]]) [[NUW]]
83*67e74705SXin Li// CHECK-NEXT: call void @__cxa_end_catch() [[NUW]]
84*67e74705SXin Li
85*67e74705SXin Linamespace test4 {
86*67e74705SXin Li  struct A {
87*67e74705SXin Li    id single;
88*67e74705SXin Li    id array[2][3];
89*67e74705SXin Li
90*67e74705SXin Li    A();
91*67e74705SXin Li  };
92*67e74705SXin Li
93*67e74705SXin Li  A::A() {
94*67e74705SXin Li    throw 0;
95*67e74705SXin Li  }
96*67e74705SXin Li  // CHECK-LABEL:    define void @_ZN5test41AC2Ev(
97*67e74705SXin Li  // CHECK:      [[THIS:%.*]] = load [[A:%.*]]*, [[A:%.*]]** {{%.*}}
98*67e74705SXin Li  //   Construct single.
99*67e74705SXin Li  // CHECK-NEXT: [[SINGLE:%.*]] = getelementptr inbounds [[A]], [[A]]* [[THIS]], i32 0, i32 0
100*67e74705SXin Li  // CHECK-NEXT: store i8* null, i8** [[SINGLE]], align 8
101*67e74705SXin Li  //   Construct array.
102*67e74705SXin Li  // CHECK-NEXT: [[ARRAY:%.*]] = getelementptr inbounds [[A]], [[A]]* [[THIS]], i32 0, i32 1
103*67e74705SXin Li  // CHECK-NEXT: [[T0:%.*]] = bitcast [2 x [3 x i8*]]* [[ARRAY]] to i8*
104*67e74705SXin Li  // CHECK-NEXT: call void @llvm.memset.p0i8.i64(i8* [[T0]], i8 0, i64 48, i32 8, i1 false)
105*67e74705SXin Li  //   throw 0;
106*67e74705SXin Li  // CHECK:      invoke void @__cxa_throw(
107*67e74705SXin Li  //   Landing pad from throw site:
108*67e74705SXin Li  // CHECK:      landingpad
109*67e74705SXin Li  //     - First, destroy all of array.
110*67e74705SXin Li  // CHECK:      [[ARRAYBEGIN:%.*]] = getelementptr inbounds [2 x [3 x i8*]], [2 x [3 x i8*]]* [[ARRAY]], i32 0, i32 0, i32 0
111*67e74705SXin Li  // CHECK-NEXT: [[ARRAYEND:%.*]] = getelementptr inbounds i8*, i8** [[ARRAYBEGIN]], i64 6
112*67e74705SXin Li  // CHECK-NEXT: br label
113*67e74705SXin Li  // CHECK:      [[AFTER:%.*]] = phi i8** [ [[ARRAYEND]], {{%.*}} ], [ [[ELT:%.*]], {{%.*}} ]
114*67e74705SXin Li  // CHECK-NEXT: [[ELT]] = getelementptr inbounds i8*, i8** [[AFTER]], i64 -1
115*67e74705SXin Li  // CHECK-NEXT: call void @objc_storeStrong(i8** [[ELT]], i8* null) [[NUW]]
116*67e74705SXin Li  // CHECK-NEXT: [[DONE:%.*]] = icmp eq i8** [[ELT]], [[ARRAYBEGIN]]
117*67e74705SXin Li  // CHECK-NEXT: br i1 [[DONE]],
118*67e74705SXin Li  //     - Next, destroy single.
119*67e74705SXin Li  // CHECK:      call void @objc_storeStrong(i8** [[SINGLE]], i8* null) [[NUW]]
120*67e74705SXin Li  // CHECK:      br label
121*67e74705SXin Li  // CHECK:      resume
122*67e74705SXin Li}
123*67e74705SXin Li
124*67e74705SXin Li// rdar://21397946
125*67e74705SXin Li__attribute__((ns_returns_retained)) id test5_helper(unsigned);
126*67e74705SXin Livoid test5(void) {
127*67e74705SXin Li  id array[][2] = {
128*67e74705SXin Li    test5_helper(0),
129*67e74705SXin Li    test5_helper(1),
130*67e74705SXin Li    test5_helper(2),
131*67e74705SXin Li    test5_helper(3)
132*67e74705SXin Li  };
133*67e74705SXin Li}
134*67e74705SXin Li// CHECK-LABEL: define void @_Z5test5v()
135*67e74705SXin Li// CHECK:       [[ARRAY:%.*]] = alloca [2 x [2 x i8*]], align
136*67e74705SXin Li// CHECK:       [[A0:%.*]] = getelementptr inbounds [2 x [2 x i8*]], [2 x [2 x i8*]]* [[ARRAY]], i64 0, i64 0
137*67e74705SXin Li// CHECK-NEXT:  store [2 x i8*]* [[A0]],
138*67e74705SXin Li// CHECK-NEXT:  [[A00:%.*]] = getelementptr inbounds [2 x i8*], [2 x i8*]* [[A0]], i64 0, i64 0
139*67e74705SXin Li// CHECK-NEXT:  store i8** [[A00]],
140*67e74705SXin Li// CHECK-NEXT:  [[T0:%.*]] = invoke i8* @_Z12test5_helperj(i32 0)
141*67e74705SXin Li// CHECK:       store i8* [[T0]], i8** [[A00]], align
142*67e74705SXin Li// CHECK-NEXT:  [[A01:%.*]] = getelementptr inbounds i8*, i8** [[A00]], i64 1
143*67e74705SXin Li// CHECK-NEXT:  store i8** [[A01]],
144*67e74705SXin Li// CHECK-NEXT:  [[T0:%.*]] = invoke i8* @_Z12test5_helperj(i32 1)
145*67e74705SXin Li// CHECK:       store i8* [[T0]], i8** [[A01]], align
146*67e74705SXin Li// CHECK-NEXT:  [[A1:%.*]] = getelementptr inbounds [2 x i8*], [2 x i8*]* [[A0]], i64 1
147*67e74705SXin Li// CHECK-NEXT:  store [2 x i8*]* [[A1]],
148*67e74705SXin Li// CHECK-NEXT:  [[A10:%.*]] = getelementptr inbounds [2 x i8*], [2 x i8*]* [[A1]], i64 0, i64 0
149*67e74705SXin Li// CHECK-NEXT:  store i8** [[A10]],
150*67e74705SXin Li// CHECK-NEXT:  [[T0:%.*]] = invoke i8* @_Z12test5_helperj(i32 2)
151*67e74705SXin Li// CHECK:       store i8* [[T0]], i8** [[A10]], align
152*67e74705SXin Li// CHECK-NEXT:  [[A11:%.*]] = getelementptr inbounds i8*, i8** [[A10]], i64 1
153*67e74705SXin Li// CHECK-NEXT:  store i8** [[A11]],
154*67e74705SXin Li// CHECK-NEXT:  [[T0:%.*]] = invoke i8* @_Z12test5_helperj(i32 3)
155*67e74705SXin Li// CHECK:       store i8* [[T0]], i8** [[A11]], align
156*67e74705SXin Li
157*67e74705SXin Li// CHECK: attributes [[NUW]] = { nounwind }
158