318 lines · cpp
1// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -emit-llvm -o - %s | FileCheck %s2void *f();3 4template <typename T> T* g() {5 if (T* t = f())6 return t;7 8 return 0;9}10 11void h() {12 void *a = g<void>();13}14 15struct X {16 X();17 X(const X&);18 ~X();19 operator bool();20};21 22struct Y {23 Y();24 ~Y();25};26 27X getX();28 29// CHECK-LABEL: define{{.*}} void @_Z11if_destructi(30void if_destruct(int z) {31 // Verify that the condition variable is destroyed at the end of the32 // "if" statement.33 // CHECK: call void @_ZN1XC1Ev34 // CHECK: call noundef zeroext i1 @_ZN1XcvbEv35 if (X x = X()) {36 // CHECK: store i32 1837 z = 18;38 }39 // CHECK: call void @_ZN1XD1Ev40 // CHECK: store i32 1741 z = 17;42 43 // CHECK: call void @_ZN1XC1Ev44 if (X x = X())45 Y y;46 // CHECK: br47 // CHECK: call void @_ZN1YC1Ev48 // CHECK: call void @_ZN1YD1Ev49 // CHECK: br50 // CHECK: call void @_ZN1XD1Ev51 52 // CHECK: call void @_Z4getXv53 // CHECK: call noundef zeroext i1 @_ZN1XcvbEv54 // CHECK: call void @_ZN1XD1Ev55 // CHECK: br56 if (getX()) { }57 58 // CHECK: ret59}60 61struct ConvertibleToInt {62 ConvertibleToInt();63 ~ConvertibleToInt();64 operator int();65};66 67ConvertibleToInt getConvToInt();68 69void switch_destruct(int z) {70 // CHECK: call void @_ZN16ConvertibleToIntC1Ev71 switch (ConvertibleToInt conv = ConvertibleToInt()) {72 case 0:73 break;74 75 default:76 // CHECK: store i32 1977 z = 19;78 break;79 }80 // CHECK: call void @_ZN16ConvertibleToIntD1Ev81 // CHECK: store i32 2082 z = 20;83 84 // CHECK: call void @_Z12getConvToIntv85 // CHECK: call noundef i32 @_ZN16ConvertibleToIntcviEv86 // CHECK: call void @_ZN16ConvertibleToIntD1Ev87 switch(getConvToInt()) {88 case 0:89 break;90 }91 // CHECK: store i32 2792 z = 27;93 // CHECK: ret94}95 96int foo();97 98// CHECK-LABEL: define{{.*}} void @_Z14while_destructi99void while_destruct(int z) {100 // CHECK: [[Z:%.*]] = alloca i32101 // CHECK: [[CLEANUPDEST:%.*]] = alloca i32102 while (X x = X()) {103 // CHECK: call void @_ZN1XC1Ev104 // CHECK-NEXT: [[COND:%.*]] = call noundef zeroext i1 @_ZN1XcvbEv105 // CHECK-NEXT: br i1 [[COND]]106 107 // Loop-exit staging block.108 // CHECK: store i32 3, ptr [[CLEANUPDEST]]109 // CHECK-NEXT: br110 111 // While body.112 // CHECK: store i32 21, ptr [[Z]]113 // CHECK: store i32 0, ptr [[CLEANUPDEST]]114 // CHECK-NEXT: br115 z = 21;116 117 // Cleanup.118 // CHECK: call void @_ZN1XD1Ev119 // CHECK-NEXT: [[DEST:%.*]] = load i32, ptr [[CLEANUPDEST]]120 // CHECK-NEXT: switch i32 [[DEST]]121 }122 123 // CHECK: store i32 22, ptr [[Z]]124 z = 22;125 126 // CHECK: call void @_Z4getXv127 // CHECK-NEXT: call noundef zeroext i1 @_ZN1XcvbEv128 // CHECK-NEXT: call void @_ZN1XD1Ev129 // CHECK-NEXT: br130 while(getX()) { }131 132 // CHECK: store i32 25, ptr [[Z]]133 z = 25;134 135 // CHECK: ret136}137 138// CHECK-LABEL: define{{.*}} void @_Z12for_destructi(139void for_destruct(int z) {140 // CHECK: [[Z:%.*]] = alloca i32141 // CHECK: [[CLEANUPDEST:%.*]] = alloca i32142 // CHECK: [[I:%.*]] = alloca i32143 // CHECK: call void @_ZN1YC1Ev144 // CHECK-NEXT: br145 // -> %for.cond146 147 for(Y y = Y(); X x = X(); ++z) {148 // %for.cond: The loop condition.149 // CHECK: call void @_ZN1XC1Ev150 // CHECK-NEXT: [[COND:%.*]] = call noundef zeroext i1 @_ZN1XcvbEv(151 // CHECK-NEXT: br i1 [[COND]]152 // -> %for.body, %for.cond.cleanup153 154 // %for.cond.cleanup: Exit cleanup staging.155 // CHECK: store i32 2, ptr [[CLEANUPDEST]]156 // CHECK-NEXT: br157 // -> %cleanup158 159 // %for.body:160 // CHECK: store i32 23, ptr [[Z]]161 // CHECK-NEXT: br162 // -> %for.inc163 z = 23;164 165 // %for.inc:166 // CHECK: [[TMP:%.*]] = load i32, ptr [[Z]]167 // CHECK-NEXT: [[INC:%.*]] = add nsw i32 [[TMP]], 1168 // CHECK-NEXT: store i32 [[INC]], ptr [[Z]]169 // CHECK-NEXT: store i32 0, ptr [[CLEANUPDEST]]170 // CHECK-NEXT: br171 // -> %cleanup172 173 // %cleanup: Destroys X.174 // CHECK: call void @_ZN1XD1Ev175 // CHECK-NEXT: [[YDESTTMP:%.*]] = load i32, ptr [[CLEANUPDEST]]176 // CHECK-NEXT: switch i32 [[YDESTTMP]]177 // 0 -> %cleanup.cont, default -> %cleanup1178 179 // %cleanup.cont: (eliminable)180 // CHECK: br181 // -> %for.cond182 183 // %cleanup1: Destroys Y.184 // CHECK: call void @_ZN1YD1Ev(185 // CHECK-NEXT: br186 // -> %for.end187 }188 189 // %for.end:190 // CHECK: store i32 24191 z = 24;192 193 // CHECK-NEXT: store i32 0, ptr [[I]]194 // CHECK-NEXT: br195 // -> %for.cond6196 197 // %for.cond6:198 // CHECK: call void @_Z4getXv199 // CHECK-NEXT: call noundef zeroext i1 @_ZN1XcvbEv200 // CHECK-NEXT: call void @_ZN1XD1Ev201 // CHECK-NEXT: br202 // -> %for.body10, %for.end16203 204 // %for.body10:205 // CHECK: br206 // -> %for.inc11207 208 // %for.inc11:209 // CHECK: call void @_Z4getXv210 // CHECK-NEXT: load i32, ptr [[I]]211 // CHECK-NEXT: add212 // CHECK-NEXT: store213 // CHECK-NEXT: call void @_ZN1XD1Ev214 // CHECK-NEXT: br215 // -> %for.cond6216 int i = 0;217 for(; getX(); getX(), ++i) { }218 219 // %for.end16220 // CHECK: store i32 26221 z = 26;222 223 // CHECK-NEXT: ret void224}225 226void do_destruct(int z) {227 // CHECK-LABEL: define{{.*}} void @_Z11do_destruct228 do {229 // CHECK: store i32 77230 z = 77;231 // CHECK: call void @_Z4getXv232 // CHECK: call noundef zeroext i1 @_ZN1XcvbEv233 // CHECK: call void @_ZN1XD1Ev234 // CHECK: br235 } while (getX());236 // CHECK: store i32 99237 z = 99;238 // CHECK: ret239}240 241int f(X); 242 243template<typename T>244int instantiated(T x) { 245 int result;246 247 // CHECK: call void @_ZN1XC1ERKS_248 // CHECK: call noundef i32 @_Z1f1X249 // CHECK: call void @_ZN1XD1Ev250 // CHECK: br251 // CHECK: store i32 2252 // CHECK: br253 // CHECK: store i32 3254 if (f(x)) { result = 2; } else { result = 3; }255 256 // CHECK: call void @_ZN1XC1ERKS_257 // CHECK: call noundef i32 @_Z1f1X258 // CHECK: call void @_ZN1XD1Ev259 // CHECK: br260 // CHECK: store i32 4261 // CHECK: br262 while (f(x)) { result = 4; }263 264 // CHECK: call void @_ZN1XC1ERKS_265 // CHECK: call noundef i32 @_Z1f1X266 // CHECK: call void @_ZN1XD1Ev267 // CHECK: br268 // CHECK: store i32 6269 // CHECK: br270 // CHECK: call void @_ZN1XC1ERKS_271 // CHECK: call noundef i32 @_Z1f1X272 // CHECK: store i32 5273 // CHECK: call void @_ZN1XD1Ev274 // CHECK: br275 for (; f(x); f(x), result = 5) {276 result = 6;277 }278 279 // CHECK: call void @_ZN1XC1ERKS_280 // CHECK: call noundef i32 @_Z1f1X281 // CHECK: call void @_ZN1XD1Ev282 // CHECK: switch i32283 // CHECK: store i32 7284 // CHECK: store i32 8285 switch (f(x)) {286 case 0: 287 result = 7;288 break;289 290 case 1:291 result = 8;292 }293 294 // CHECK: store i32 9295 // CHECK: br296 // CHECK: call void @_ZN1XC1ERKS_297 // CHECK: call noundef i32 @_Z1f1X298 // CHECK: call void @_ZN1XD1Ev299 // CHECK: br300 do {301 result = 9;302 } while (f(x));303 304 // CHECK: store i32 10305 // CHECK: call void @_ZN1XC1ERKS_306 // CHECK: call noundef zeroext i1 @_ZN1XcvbEv307 // CHECK: call void @_ZN1XD1Ev308 // CHECK: br309 do {310 result = 10;311 } while (X(x));312 313 // CHECK: ret i32314 return result;315}316 317template int instantiated(X);318