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. 6 7void test0_helper(void); 8void test0(void) { 9 @try { 10 test0_helper(); 11 } @catch (Ety *e) { 12 } 13} 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]] 22 23void test1_helper(void); 24void test1(void) { 25 @try { 26 test1_helper(); 27 } @catch (__weak Ety *e) { 28 } 29} 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]] 37 38void test2_helper(void); 39void test2(void) { 40 try { 41 test2_helper(); 42 } catch (Ety *e) { 43 } 44} 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]] 53 54void test3_helper(void); 55void test3(void) { 56 try { 57 test3_helper(); 58 } catch (Ety * __weak e) { 59 } 60} 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]] 68 69namespace test4 { 70 struct A { 71 id single; 72 id array[2][3]; 73 74 A(); 75 }; 76 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 nuw [[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 nuw [[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 105} 106 107__attribute__((ns_returns_retained)) id test5_helper(unsigned); 108void test5(void) { 109 id array[][2] = { 110 test5_helper(0), 111 test5_helper(1), 112 test5_helper(2), 113 test5_helper(3) 114 }; 115} 116// CHECK-LABEL: define{{.*}} void @_Z5test5v() 117// CHECK: [[ARRAY:%.*]] = alloca [2 x [2 x ptr]], align 118// CHECK: store ptr [[ARRAY]], 119// CHECK-NEXT: store ptr [[ARRAY]], 120// CHECK-NEXT: [[T0:%.*]] = invoke noundef ptr @_Z12test5_helperj(i32 noundef 0) 121// CHECK: store ptr [[T0]], ptr [[ARRAY]], align 122// CHECK-NEXT: [[A01:%.*]] = getelementptr inbounds ptr, ptr [[ARRAY]], i64 1 123// CHECK-NEXT: store ptr [[A01]], 124// CHECK-NEXT: [[T0:%.*]] = invoke noundef ptr @_Z12test5_helperj(i32 noundef 1) 125// CHECK: store ptr [[T0]], ptr [[A01]], align 126// CHECK-NEXT: [[A1:%.*]] = getelementptr inbounds [2 x ptr], ptr [[ARRAY]], i64 1 127// CHECK-NEXT: store ptr [[A1]], 128// CHECK-NEXT: store ptr [[A1]], 129// CHECK-NEXT: [[T0:%.*]] = invoke noundef ptr @_Z12test5_helperj(i32 noundef 2) 130// CHECK: store ptr [[T0]], ptr [[A1]], align 131// CHECK-NEXT: [[A11:%.*]] = getelementptr inbounds ptr, ptr [[A1]], i64 1 132// CHECK-NEXT: store ptr [[A11]], 133// CHECK-NEXT: [[T0:%.*]] = invoke noundef ptr @_Z12test5_helperj(i32 noundef 3) 134// CHECK: store ptr [[T0]], ptr [[A11]], align 135 136// CHECK: attributes [[NUW]] = { nounwind } 137