1// RUN: %clang_cc1 -fobjc-arc -fobjc-runtime-has-weak -fblocks -triple x86_64-apple-darwin10.0.0 -emit-llvm -o - %s | FileCheck %s -check-prefix=CHECK -check-prefix=UNOPT 2// RUN: %clang_cc1 -fobjc-arc -fobjc-runtime-has-weak -fblocks -triple x86_64-apple-darwin10.0.0 -emit-llvm -o - %s -O -disable-llvm-optzns | FileCheck %s -check-prefix=CHECK -check-prefix=OPT 3 4typedef __strong id strong_id; 5typedef __weak id weak_id; 6 7// CHECK-LABEL: define void @_Z8test_newP11objc_object 8void test_new(id invalue) { 9 // CHECK: [[INVALUEADDR:%.*]] = alloca i8* 10 // UNOPT-NEXT: store i8* null, i8** [[INVALUEADDR]] 11 // UNOPT-NEXT: call void @objc_storeStrong(i8** [[INVALUEADDR]], i8* [[INVALUE:%.*]]) 12 // OPT-NEXT: [[T0:%.*]] = call i8* @objc_retain(i8* [[INVALUE:%.*]]) 13 // OPT-NEXT: store i8* [[T0]], i8** [[INVALUEADDR]] 14 15 // CHECK: call i8* @_Znwm 16 // CHECK-NEXT: {{bitcast i8\*.*to i8\*\*}} 17 // CHECK-NEXT: store i8* null, i8** 18 new strong_id; 19 // CHECK: call i8* @_Znwm 20 // CHECK-NEXT: {{bitcast i8\*.*to i8\*\*}} 21 // UNOPT-NEXT: store i8* null, i8** 22 // OPT-NEXT: call i8* @objc_initWeak(i8** {{.*}}, i8* null) 23 new weak_id; 24 25 // CHECK: call i8* @_Znwm 26 // CHECK-NEXT: {{bitcast i8\*.*to i8\*\*}} 27 // CHECK-NEXT: store i8* null, i8** 28 new __strong id; 29 // CHECK: call i8* @_Znwm 30 // CHECK-NEXT: {{bitcast i8\*.*to i8\*\*}} 31 // UNOPT-NEXT: store i8* null, i8** 32 // OPT-NEXT: call i8* @objc_initWeak(i8** {{.*}}, i8* null) 33 new __weak id; 34 35 // CHECK: call i8* @_Znwm 36 // CHECK: call i8* @objc_retain 37 // CHECK: store i8* 38 new __strong id(invalue); 39 40 // CHECK: call i8* @_Znwm 41 // CHECK: call i8* @objc_initWeak 42 new __weak id(invalue); 43 44 // UNOPT: call void @objc_storeStrong 45 // OPT: call void @objc_release 46 // CHECK: ret void 47} 48 49// CHECK-LABEL: define void @_Z14test_array_new 50void test_array_new() { 51 // CHECK: call i8* @_Znam 52 // CHECK: store i64 17, i64* 53 // CHECK: call void @llvm.memset.p0i8.i64 54 new strong_id[17]; 55 56 // CHECK: call i8* @_Znam 57 // CHECK: store i64 17, i64* 58 // CHECK: call void @llvm.memset.p0i8.i64 59 new weak_id[17]; 60 // CHECK: ret void 61} 62 63// CHECK-LABEL: define void @_Z11test_deletePU8__strongP11objc_objectPU6__weakS0_ 64void test_delete(__strong id *sptr, __weak id *wptr) { 65 // CHECK: br i1 66 // UNOPT: call void @objc_storeStrong(i8** {{.*}}, i8* null) 67 // OPT: load i8*, i8** 68 // OPT-NEXT: call void @objc_release 69 // CHECK: call void @_ZdlPv 70 delete sptr; 71 72 // CHECK: call void @objc_destroyWeak 73 // CHECK: call void @_ZdlPv 74 delete wptr; 75 76 // CHECK: ret void 77} 78 79// CHECK-LABEL: define void @_Z17test_array_deletePU8__strongP11objc_objectPU6__weakS0_ 80void test_array_delete(__strong id *sptr, __weak id *wptr) { 81 // CHECK: icmp eq i8** [[BEGIN:%.*]], null 82 // CHECK: [[LEN:%.*]] = load i64, i64* {{%.*}} 83 // CHECK: [[END:%.*]] = getelementptr inbounds i8*, i8** [[BEGIN]], i64 [[LEN]] 84 // CHECK-NEXT: icmp eq i8** [[BEGIN]], [[END]] 85 // CHECK: [[PAST:%.*]] = phi i8** [ [[END]], {{%.*}} ], [ [[CUR:%.*]], 86 // CHECK-NEXT: [[CUR]] = getelementptr inbounds i8*, i8** [[PAST]], i64 -1 87 // UNOPT-NEXT: call void @objc_storeStrong(i8** [[CUR]], i8* null) 88 // OPT-NEXT: [[T0:%.*]] = load i8*, i8** [[CUR]] 89 // OPT-NEXT: objc_release(i8* [[T0]]) 90 // CHECK-NEXT: icmp eq i8** [[CUR]], [[BEGIN]] 91 // CHECK: call void @_ZdaPv 92 delete [] sptr; 93 94 // CHECK: icmp eq i8** [[BEGIN:%.*]], null 95 // CHECK: [[LEN:%.*]] = load i64, i64* {{%.*}} 96 // CHECK: [[END:%.*]] = getelementptr inbounds i8*, i8** [[BEGIN]], i64 [[LEN]] 97 // CHECK-NEXT: icmp eq i8** [[BEGIN]], [[END]] 98 // CHECK: [[PAST:%.*]] = phi i8** [ [[END]], {{%.*}} ], [ [[CUR:%.*]], 99 // CHECK-NEXT: [[CUR]] = getelementptr inbounds i8*, i8** [[PAST]], i64 -1 100 // CHECK-NEXT: call void @objc_destroyWeak(i8** [[CUR]]) 101 // CHECK-NEXT: icmp eq i8** [[CUR]], [[BEGIN]] 102 // CHECK: call void @_ZdaPv 103 delete [] wptr; 104} 105