1 // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py 2 // RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -std=c++11 -emit-llvm -o - %s | FileCheck %s 3 4 struct A { 5 A(); 6 A(const A&); 7 ~A(); 8 }; 9 10 struct B { 11 B(); 12 B(const B&); 13 ~B(); 14 }; 15 16 struct C { 17 C(); 18 C(const C&); 19 ~C(); 20 }; 21 22 struct D { 23 D(); 24 D(const D&); 25 ~D(); 26 27 B *begin(); 28 B *end(); 29 }; 30 31 B *begin(C&); 32 B *end(C&); 33 34 extern B array[5]; 35 36 // CHECK-LABEL: @_Z9for_arrayv( 37 // CHECK-NEXT: entry: 38 // CHECK-NEXT: [[A:%.*]] = alloca [[STRUCT_A:%.*]], align 1 39 // CHECK-NEXT: [[__RANGE1:%.*]] = alloca ptr, align 8 40 // CHECK-NEXT: [[__BEGIN1:%.*]] = alloca ptr, align 8 41 // CHECK-NEXT: [[__END1:%.*]] = alloca ptr, align 8 42 // CHECK-NEXT: [[B:%.*]] = alloca [[STRUCT_B:%.*]], align 1 43 // CHECK-NEXT: call void @_ZN1AC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[A]]) 44 // CHECK-NEXT: store ptr @array, ptr [[__RANGE1]], align 8 45 // CHECK-NEXT: store ptr @array, ptr [[__BEGIN1]], align 8 46 // CHECK-NEXT: store ptr getelementptr inbounds ([[STRUCT_B]], ptr @array, i64 5), ptr [[__END1]], align 8 47 // CHECK-NEXT: br label [[FOR_COND:%.*]] 48 // CHECK: for.cond: 49 // CHECK-NEXT: [[TMP0:%.*]] = load ptr, ptr [[__BEGIN1]], align 8 50 // CHECK-NEXT: [[TMP1:%.*]] = load ptr, ptr [[__END1]], align 8 51 // CHECK-NEXT: [[CMP:%.*]] = icmp ne ptr [[TMP0]], [[TMP1]] 52 // CHECK-NEXT: br i1 [[CMP]], label [[FOR_BODY:%.*]], label [[FOR_END:%.*]] 53 // CHECK: for.body: 54 // CHECK-NEXT: [[TMP2:%.*]] = load ptr, ptr [[__BEGIN1]], align 8 55 // CHECK-NEXT: call void @_ZN1BC1ERKS_(ptr noundef nonnull align 1 dereferenceable(1) [[B]], ptr noundef nonnull align 1 dereferenceable(1) [[TMP2]]) 56 // CHECK-NEXT: call void @_ZN1BD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[B]]) #[[ATTR3:[0-9]+]] 57 // CHECK-NEXT: br label [[FOR_INC:%.*]] 58 // CHECK: for.inc: 59 // CHECK-NEXT: [[TMP3:%.*]] = load ptr, ptr [[__BEGIN1]], align 8 60 // CHECK-NEXT: [[INCDEC_PTR:%.*]] = getelementptr inbounds nuw [[STRUCT_B]], ptr [[TMP3]], i32 1 61 // CHECK-NEXT: store ptr [[INCDEC_PTR]], ptr [[__BEGIN1]], align 8 62 // CHECK-NEXT: br label [[FOR_COND]] 63 // CHECK: for.end: 64 // CHECK-NEXT: call void @_ZN1AD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[A]]) #[[ATTR3]] 65 // CHECK-NEXT: ret void 66 // 67 void for_array() { 68 A a; 69 for (B b : array) { 70 } 71 } 72 73 // CHECK-LABEL: @_Z9for_rangev( 74 // CHECK-NEXT: entry: 75 // CHECK-NEXT: [[A:%.*]] = alloca [[STRUCT_A:%.*]], align 1 76 // CHECK-NEXT: [[__RANGE1:%.*]] = alloca ptr, align 8 77 // CHECK-NEXT: [[REF_TMP:%.*]] = alloca [[STRUCT_C:%.*]], align 1 78 // CHECK-NEXT: [[__BEGIN1:%.*]] = alloca ptr, align 8 79 // CHECK-NEXT: [[__END1:%.*]] = alloca ptr, align 8 80 // CHECK-NEXT: [[B:%.*]] = alloca [[STRUCT_B:%.*]], align 1 81 // CHECK-NEXT: call void @_ZN1AC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[A]]) 82 // CHECK-NEXT: call void @_ZN1CC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[REF_TMP]]) 83 // CHECK-NEXT: store ptr [[REF_TMP]], ptr [[__RANGE1]], align 8 84 // CHECK-NEXT: [[TMP0:%.*]] = load ptr, ptr [[__RANGE1]], align 8 85 // CHECK-NEXT: [[CALL:%.*]] = call noundef ptr @_Z5beginR1C(ptr noundef nonnull align 1 dereferenceable(1) [[TMP0]]) 86 // CHECK-NEXT: store ptr [[CALL]], ptr [[__BEGIN1]], align 8 87 // CHECK-NEXT: [[TMP1:%.*]] = load ptr, ptr [[__RANGE1]], align 8 88 // CHECK-NEXT: [[CALL1:%.*]] = call noundef ptr @_Z3endR1C(ptr noundef nonnull align 1 dereferenceable(1) [[TMP1]]) 89 // CHECK-NEXT: store ptr [[CALL1]], ptr [[__END1]], align 8 90 // CHECK-NEXT: br label [[FOR_COND:%.*]] 91 // CHECK: for.cond: 92 // CHECK-NEXT: [[TMP2:%.*]] = load ptr, ptr [[__BEGIN1]], align 8 93 // CHECK-NEXT: [[TMP3:%.*]] = load ptr, ptr [[__END1]], align 8 94 // CHECK-NEXT: [[CMP:%.*]] = icmp ne ptr [[TMP2]], [[TMP3]] 95 // CHECK-NEXT: br i1 [[CMP]], label [[FOR_BODY:%.*]], label [[FOR_COND_CLEANUP:%.*]] 96 // CHECK: for.cond.cleanup: 97 // CHECK-NEXT: call void @_ZN1CD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[REF_TMP]]) #[[ATTR3]] 98 // CHECK-NEXT: br label [[FOR_END:%.*]] 99 // CHECK: for.body: 100 // CHECK-NEXT: [[TMP4:%.*]] = load ptr, ptr [[__BEGIN1]], align 8 101 // CHECK-NEXT: call void @_ZN1BC1ERKS_(ptr noundef nonnull align 1 dereferenceable(1) [[B]], ptr noundef nonnull align 1 dereferenceable(1) [[TMP4]]) 102 // CHECK-NEXT: call void @_ZN1BD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[B]]) #[[ATTR3]] 103 // CHECK-NEXT: br label [[FOR_INC:%.*]] 104 // CHECK: for.inc: 105 // CHECK-NEXT: [[TMP5:%.*]] = load ptr, ptr [[__BEGIN1]], align 8 106 // CHECK-NEXT: [[INCDEC_PTR:%.*]] = getelementptr inbounds nuw [[STRUCT_B]], ptr [[TMP5]], i32 1 107 // CHECK-NEXT: store ptr [[INCDEC_PTR]], ptr [[__BEGIN1]], align 8 108 // CHECK-NEXT: br label [[FOR_COND]] 109 // CHECK: for.end: 110 // CHECK-NEXT: call void @_ZN1AD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[A]]) #[[ATTR3]] 111 // CHECK-NEXT: ret void 112 // 113 void for_range() { 114 A a; 115 for (B b : C()) { 116 } 117 } 118 119 // CHECK-LABEL: @_Z16for_member_rangev( 120 // CHECK-NEXT: entry: 121 // CHECK-NEXT: [[A:%.*]] = alloca [[STRUCT_A:%.*]], align 1 122 // CHECK-NEXT: [[__RANGE1:%.*]] = alloca ptr, align 8 123 // CHECK-NEXT: [[REF_TMP:%.*]] = alloca [[STRUCT_D:%.*]], align 1 124 // CHECK-NEXT: [[__BEGIN1:%.*]] = alloca ptr, align 8 125 // CHECK-NEXT: [[__END1:%.*]] = alloca ptr, align 8 126 // CHECK-NEXT: [[B:%.*]] = alloca [[STRUCT_B:%.*]], align 1 127 // CHECK-NEXT: call void @_ZN1AC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[A]]) 128 // CHECK-NEXT: call void @_ZN1DC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[REF_TMP]]) 129 // CHECK-NEXT: store ptr [[REF_TMP]], ptr [[__RANGE1]], align 8 130 // CHECK-NEXT: [[TMP0:%.*]] = load ptr, ptr [[__RANGE1]], align 8 131 // CHECK-NEXT: [[CALL:%.*]] = call noundef ptr @_ZN1D5beginEv(ptr noundef nonnull align 1 dereferenceable(1) [[TMP0]]) 132 // CHECK-NEXT: store ptr [[CALL]], ptr [[__BEGIN1]], align 8 133 // CHECK-NEXT: [[TMP1:%.*]] = load ptr, ptr [[__RANGE1]], align 8 134 // CHECK-NEXT: [[CALL1:%.*]] = call noundef ptr @_ZN1D3endEv(ptr noundef nonnull align 1 dereferenceable(1) [[TMP1]]) 135 // CHECK-NEXT: store ptr [[CALL1]], ptr [[__END1]], align 8 136 // CHECK-NEXT: br label [[FOR_COND:%.*]] 137 // CHECK: for.cond: 138 // CHECK-NEXT: [[TMP2:%.*]] = load ptr, ptr [[__BEGIN1]], align 8 139 // CHECK-NEXT: [[TMP3:%.*]] = load ptr, ptr [[__END1]], align 8 140 // CHECK-NEXT: [[CMP:%.*]] = icmp ne ptr [[TMP2]], [[TMP3]] 141 // CHECK-NEXT: br i1 [[CMP]], label [[FOR_BODY:%.*]], label [[FOR_COND_CLEANUP:%.*]] 142 // CHECK: for.cond.cleanup: 143 // CHECK-NEXT: call void @_ZN1DD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[REF_TMP]]) #[[ATTR3]] 144 // CHECK-NEXT: br label [[FOR_END:%.*]] 145 // CHECK: for.body: 146 // CHECK-NEXT: [[TMP4:%.*]] = load ptr, ptr [[__BEGIN1]], align 8 147 // CHECK-NEXT: call void @_ZN1BC1ERKS_(ptr noundef nonnull align 1 dereferenceable(1) [[B]], ptr noundef nonnull align 1 dereferenceable(1) [[TMP4]]) 148 // CHECK-NEXT: call void @_ZN1BD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[B]]) #[[ATTR3]] 149 // CHECK-NEXT: br label [[FOR_INC:%.*]] 150 // CHECK: for.inc: 151 // CHECK-NEXT: [[TMP5:%.*]] = load ptr, ptr [[__BEGIN1]], align 8 152 // CHECK-NEXT: [[INCDEC_PTR:%.*]] = getelementptr inbounds nuw [[STRUCT_B]], ptr [[TMP5]], i32 1 153 // CHECK-NEXT: store ptr [[INCDEC_PTR]], ptr [[__BEGIN1]], align 8 154 // CHECK-NEXT: br label [[FOR_COND]] 155 // CHECK: for.end: 156 // CHECK-NEXT: call void @_ZN1AD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[A]]) #[[ATTR3]] 157 // CHECK-NEXT: ret void 158 // 159 void for_member_range() { 160 A a; 161 for (B b : D()) { 162 } 163 } 164