228 lines · plain
1// RUN: %clang_cc1 -std=c++11 -fobjc-arc -fblocks -triple x86_64-apple-darwin10.0.0 -fobjc-runtime-has-weak -emit-llvm -o - %s | FileCheck %s2 3struct ObjCMember {4 id member;5};6 7struct ObjCArrayMember {8 id member[2][3];9};10 11struct ObjCBlockMember {12 int (^bp)(int);13};14 15// CHECK: %[[STRUCT_CONTAINSWEAK:.*]] = type { %[[STRUCT_WEAK:.*]] }16// CHECK: %[[STRUCT_WEAK]] = type { ptr }17 18// The Weak object that is passed is destructed in this constructor.19 20// CHECK: define{{.*}} void @_ZN12ContainsWeakC2E4Weak(21// CHECK: call void @_ZN4WeakC1ERKS_(22// CHECK: call void @_ZN4WeakD1Ev(23 24// Check that the Weak object passed to this constructor is not destructed after25// the delegate constructor is called.26 27// CHECK: define{{.*}} void @_ZN12ContainsWeakC1E4Weak(28// CHECK: call void @_ZN12ContainsWeakC2E4Weak(29// CHECK-NEXT: ret void30 31struct Weak {32 Weak(id);33 __weak id x;34};35 36struct ContainsWeak {37 ContainsWeak(Weak);38 Weak w;39};40 41ContainsWeak::ContainsWeak(Weak a) : w(a) {}42 43// The Weak object that is passed is destructed in this constructor.44 45// CHECK: define{{.*}} void @_ZN4BaseC2E4Weak(46// CHECK: call void @_ZN4WeakD1Ev(47// CHECK: ret void48 49// Check that the Weak object passed to this constructor is not destructed after50// the delegate constructor is called.51 52// CHECK: define linkonce_odr void @_ZN7DerivedCI14BaseE4Weak(53// CHECK: call void @_ZN7DerivedCI24BaseE4Weak(54// CHECK-NEXT: ret void55 56struct Base {57 Base(Weak);58};59 60Base::Base(Weak a) {}61 62struct Derived : Base {63 using Base::Base;64};65 66Derived d(Weak(0));67 68// CHECK-LABEL: define{{.*}} void @_Z42test_ObjCMember_default_construct_destructv(69void test_ObjCMember_default_construct_destruct() {70 // CHECK: call void @_ZN10ObjCMemberC1Ev71 // CHECK: call void @_ZN10ObjCMemberD1Ev72 ObjCMember m1;73}74 75// CHECK-LABEL: define{{.*}} void @_Z39test_ObjCMember_copy_construct_destruct10ObjCMember76void test_ObjCMember_copy_construct_destruct(ObjCMember m1) {77 // CHECK: call void @_ZN10ObjCMemberC1ERKS_78 // CHECK: call void @_ZN10ObjCMemberD1Ev79 ObjCMember m2 = m1;80 // CHECK: ret void81}82 83// CHECK-LABEL: define{{.*}} void @_Z27test_ObjCMember_copy_assign10ObjCMemberS_84void test_ObjCMember_copy_assign(ObjCMember m1, ObjCMember m2) {85 // CHECK: {{call.*_ZN10ObjCMemberaSERKS_}}86 m1 = m2;87 // CHECK-NEXT: call void @_ZN10ObjCMemberD1Ev(88 // CHECK-NEXT: call void @_ZN10ObjCMemberD1Ev(89 // CHECK-NEXT: ret void90}91 92// Implicitly-generated copy assignment operator for ObjCMember93// CHECK: {{define linkonce_odr.*@_ZN10ObjCMemberaSERKS_}}94// CHECK: call void @llvm.objc.storeStrong95// CHECK: ret96 97// CHECK-LABEL: define{{.*}} void @_Z47test_ObjCArrayMember_default_construct_destructv98void test_ObjCArrayMember_default_construct_destruct() {99 // CHECK: call void @_ZN15ObjCArrayMemberC1Ev100 ObjCArrayMember m1;101 // CHECK: call void @_ZN15ObjCArrayMemberD1Ev102 // CHECK: ret void103}104 105// CHECK-LABEL: define{{.*}} void @_Z44test_ObjCArrayMember_copy_construct_destruct15ObjCArrayMember106void test_ObjCArrayMember_copy_construct_destruct(ObjCArrayMember m1) {107 // CHECK: call void @_ZN15ObjCArrayMemberC1ERKS_108 ObjCArrayMember m2 = m1;109 // CHECK: call void @_ZN15ObjCArrayMemberD1Ev110 // CHECK: ret void111}112 113void test_ObjCArrayMember_copy_assign(ObjCArrayMember m1, ObjCArrayMember m2) {114 // CHECK: {{call.*@_ZN15ObjCArrayMemberaSERKS_}}115 m1 = m2;116 // CHECK-NEXT: call void @_ZN15ObjCArrayMemberD1Ev(117 // CHECK-NEXT: call void @_ZN15ObjCArrayMemberD1Ev(118 // CHECK-NEXT: ret void119}120 121// Implicitly-generated copy assignment operator for ObjCArrayMember122// CHECK: {{define linkonce_odr.*@_ZN15ObjCArrayMemberaSERKS_}}123// CHECK: call void @llvm.objc.storeStrong124// CHECK-NEXT: br label125// CHECK: ret126 127// CHECK-LABEL: define{{.*}} void @_Z47test_ObjCBlockMember_default_construct_destructv128void test_ObjCBlockMember_default_construct_destruct() {129 // CHECK: call void @_ZN15ObjCBlockMemberC1Ev130 ObjCBlockMember m;131 // CHECK-NEXT: call void @_ZN15ObjCBlockMemberD1Ev132 // CHECK-NEXT: ret void133}134 135// CHECK-LABEL: define{{.*}} void @_Z44test_ObjCBlockMember_copy_construct_destruct15ObjCBlockMember136void test_ObjCBlockMember_copy_construct_destruct(ObjCBlockMember m1) {137 // CHECK: call void @_ZN15ObjCBlockMemberC1ERKS_138 ObjCBlockMember m2 = m1;139 // CHECK-NEXT: call void @_ZN15ObjCBlockMemberD1Ev(140 // CHECK-NEXT: call void @_ZN15ObjCBlockMemberD1Ev(141 // CHECK-NEXT: ret void142}143 144// CHECK-LABEL: define{{.*}} void @_Z32test_ObjCBlockMember_copy_assign15ObjCBlockMemberS_145void test_ObjCBlockMember_copy_assign(ObjCBlockMember m1, ObjCBlockMember m2) {146 // CHECK: {{call.*_ZN15ObjCBlockMemberaSERKS_}}147 m1 = m2;148 // CHECK-NEXT: call void @_ZN15ObjCBlockMemberD1Ev(149 // CHECK-NEXT: call void @_ZN15ObjCBlockMemberD1Ev(150 // CHECK-NEXT: ret void151}152 153// Implicitly-generated copy assignment operator for ObjCBlockMember154// CHECK: define linkonce_odr noundef nonnull align {{[0-9]+}} dereferenceable({{[0-9]+}}) ptr @_ZN15ObjCBlockMemberaSERKS_(155// CHECK: [[T0:%.*]] = getelementptr inbounds nuw [[T:%.*]], ptr {{%.*}}, i32 0, i32 0156// CHECK-NEXT: [[T1:%.*]] = load ptr, ptr [[T0]], align 8157// CHECK-NEXT: [[T3:%.*]] = call ptr @llvm.objc.retainBlock(ptr [[T1]])158// CHECK-NEXT: [[T5:%.*]] = getelementptr inbounds nuw [[T]], ptr {{%.*}}, i32 0, i32 0159// CHECK-NEXT: [[T6:%.*]] = load ptr, ptr [[T5]], align 8160// CHECK-NEXT: store ptr [[T3]], ptr [[T5]]161// CHECK-NEXT: call void @llvm.objc.release(ptr [[T6]])162// CHECK-NEXT: ret163 164// Check that the Weak object passed to this constructor is not destructed after165// the delegate constructor is called.166 167// CHECK: define linkonce_odr void @_ZN7DerivedCI24BaseE4Weak(168// CHECK: call void @_ZN4BaseC2E4Weak(169// CHECK-NEXT: ret void170 171// Implicitly-generated default constructor for ObjCMember172// CHECK-LABEL: define linkonce_odr void @_ZN10ObjCMemberC2Ev173// CHECK-NOT: objc_release174// CHECK: store ptr null175// CHECK-NEXT: ret void176 177// Implicitly-generated destructor for ObjCMember178// CHECK-LABEL: define linkonce_odr void @_ZN10ObjCMemberD2Ev179// CHECK: call void @llvm.objc.storeStrong180// CHECK: ret void181 182// Implicitly-generated copy constructor for ObjCMember183// CHECK-LABEL: define linkonce_odr void @_ZN10ObjCMemberC2ERKS_184// CHECK-NOT: objc_release185// CHECK: call ptr @llvm.objc.retain186// CHECK-NEXT: store ptr187// CHECK-NEXT: ret void188 189// Implicitly-generated default constructor for ObjCArrayMember190// CHECK-LABEL: define linkonce_odr void @_ZN15ObjCArrayMemberC2Ev191// CHECK: call void @llvm.memset.p0.i64192// CHECK: ret193 194// Implicitly-generated destructor for ObjCArrayMember195// CHECK-LABEL: define linkonce_odr void @_ZN15ObjCArrayMemberD2Ev196// CHECK: [[BEGIN:%.*]] = getelementptr inbounds [2 x [3 x ptr]], ptr197// CHECK-NEXT: [[END:%.*]] = getelementptr inbounds ptr, ptr [[BEGIN]], i64 6198// CHECK-NEXT: br label199// CHECK: [[PAST:%.*]] = phi ptr [ [[END]], {{%.*}} ], [ [[CUR:%.*]], {{%.*}} ]200// CHECK-NEXT: [[CUR]] = getelementptr inbounds ptr, ptr [[PAST]], i64 -1201// CHECK-NEXT: call void @llvm.objc.storeStrong(ptr [[CUR]], ptr null)202// CHECK-NEXT: [[T1:%.*]] = icmp eq ptr [[CUR]], [[BEGIN]]203// CHECK-NEXT: br i1 [[T1]],204// CHECK: ret void205 206// Implicitly-generated copy constructor for ObjCArrayMember207// CHECK-LABEL: define linkonce_odr void @_ZN15ObjCArrayMemberC2ERKS_208// CHECK: call ptr @llvm.objc.retain209// CHECK-NEXT: store ptr210// CHECK: br i1211// CHECK: ret212 213// Implicitly-generated default constructor for ObjCBlockMember214// CHECK-LABEL: define linkonce_odr void @_ZN15ObjCBlockMemberC2Ev215// CHECK: store {{.*}} null,216// CHECK-NEXT: ret void217 218// Implicitly-generated destructor for ObjCBlockMember219// CHECK-LABEL: define linkonce_odr void @_ZN15ObjCBlockMemberD2Ev220// CHECK: call void @llvm.objc.storeStrong(ptr221// CHECK: ret222 223// Implicitly-generated copy constructor for ObjCBlockMember224// CHECK-LABEL: define linkonce_odr void @_ZN15ObjCBlockMemberC2ERKS_225// CHECK: call ptr @llvm.objc.retainBlock226// CHECK: ret227 228