1 // RUN: %clang_cc1 -fcxx-exceptions -fexceptions -triple x86_64-apple-darwin -std=c++0x -emit-llvm %s -o %t.ll 2 // RUN: FileCheck --input-file=%t.ll %s 3 4 struct test1_D { 5 double d; 6 } d1; 7 8 void test1() { 9 throw d1; 10 } 11 12 // CHECK: define void @_Z5test1v() 13 // CHECK: [[EXNOBJ:%.*]] = call i8* @__cxa_allocate_exception(i64 8) 14 // CHECK-NEXT: [[EXN:%.*]] = bitcast i8* [[EXNOBJ]] to [[DSTAR:%[^*]*\*]] 15 // CHECK-NEXT: [[EXN2:%.*]] = bitcast [[DSTAR]] [[EXN]] to i8* 16 // CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* [[EXN2]], i8* bitcast ([[DSTAR]] @d1 to i8*), i64 8, i32 8, i1 false) 17 // CHECK-NEXT: call void @__cxa_throw(i8* [[EXNOBJ]], i8* bitcast ({ i8*, i8* }* @_ZTI7test1_D to i8*), i8* null) noreturn 18 // CHECK-NEXT: unreachable 19 20 21 struct test2_D { 22 test2_D(const test2_D&o); 23 test2_D(); 24 virtual void bar() { } 25 int i; int j; 26 } d2; 27 28 void test2() { 29 throw d2; 30 } 31 32 // CHECK: define void @_Z5test2v() 33 // CHECK: [[EXNVAR:%.*]] = alloca i8* 34 // CHECK-NEXT: [[SELECTORVAR:%.*]] = alloca i32 35 // CHECK-NEXT: [[CLEANUPDESTVAR:%.*]] = alloca i32 36 // CHECK-NEXT: [[EXNOBJ:%.*]] = call i8* @__cxa_allocate_exception(i64 16) 37 // CHECK-NEXT: [[EXN:%.*]] = bitcast i8* [[EXNOBJ]] to [[DSTAR:%[^*]*\*]] 38 // CHECK-NEXT: invoke void @_ZN7test2_DC1ERKS_([[DSTAR]] [[EXN]], [[DSTAR]] @d2) 39 // CHECK-NEXT: to label %[[CONT:.*]] unwind label %{{.*}} 40 // : [[CONT]]: (can't check this in Release-Asserts builds) 41 // CHECK: call void @__cxa_throw(i8* [[EXNOBJ]], i8* bitcast ({{.*}}* @_ZTI7test2_D to i8*), i8* null) noreturn 42 // CHECK-NEXT: unreachable 43 44 45 struct test3_D { 46 test3_D() { } 47 test3_D(volatile test3_D&o); 48 virtual void bar(); 49 }; 50 51 void test3() { 52 throw (volatile test3_D *)0; 53 } 54 55 // CHECK: define void @_Z5test3v() 56 // CHECK: [[EXNOBJ:%.*]] = call i8* @__cxa_allocate_exception(i64 8) 57 // CHECK-NEXT: [[EXN:%.*]] = bitcast i8* [[EXNOBJ]] to [[D:%[^*]+]]** 58 // CHECK-NEXT: store [[D]]* null, [[D]]** [[EXN]] 59 // CHECK-NEXT: call void @__cxa_throw(i8* [[EXNOBJ]], i8* bitcast ({ i8*, i8*, i32, i8* }* @_ZTIPV7test3_D to i8*), i8* null) noreturn 60 // CHECK-NEXT: unreachable 61 62 63 void test4() { 64 throw; 65 } 66 67 // CHECK: define void @_Z5test4v() 68 // CHECK: call void @__cxa_rethrow() noreturn 69 // CHECK-NEXT: unreachable 70 71 72 // rdar://problem/7696549 73 namespace test5 { 74 struct A { 75 A(); 76 A(const A&); 77 ~A(); 78 }; 79 80 void test() { 81 try { throw A(); } catch (A &x) {} 82 } 83 // CHECK: define void @_ZN5test54testEv() 84 // CHECK: [[EXNOBJ:%.*]] = call i8* @__cxa_allocate_exception(i64 1) 85 // CHECK: [[EXNCAST:%.*]] = bitcast i8* [[EXNOBJ]] to [[A:%[^*]*]]* 86 // CHECK-NEXT: invoke void @_ZN5test51AC1Ev([[A]]* [[EXNCAST]]) 87 // CHECK: invoke void @__cxa_throw(i8* [[EXNOBJ]], i8* bitcast ({{.*}}* @_ZTIN5test51AE to i8*), i8* bitcast (void ([[A]]*)* @_ZN5test51AD1Ev to i8*)) noreturn 88 // CHECK-NEXT: to label {{%.*}} unwind label %[[HANDLER:[^ ]*]] 89 // : [[HANDLER]]: (can't check this in Release-Asserts builds) 90 // CHECK: {{%.*}} = call i32 @llvm.eh.typeid.for(i8* bitcast ({{.*}}* @_ZTIN5test51AE to i8*)) 91 } 92 93 namespace test6 { 94 template <class T> struct allocator { 95 ~allocator() throw() { } 96 }; 97 98 void foo() { 99 allocator<int> a; 100 } 101 } 102 103 // PR7127 104 namespace test7 { 105 // CHECK: define i32 @_ZN5test73fooEv() 106 int foo() { 107 // CHECK: [[CAUGHTEXNVAR:%.*]] = alloca i8* 108 // CHECK-NEXT: [[SELECTORVAR:%.*]] = alloca i32 109 // CHECK-NEXT: [[INTCATCHVAR:%.*]] = alloca i32 110 // CHECK-NEXT: [[EHCLEANUPDESTVAR:%.*]] = alloca i32 111 try { 112 try { 113 // CHECK-NEXT: [[EXNALLOC:%.*]] = call i8* @__cxa_allocate_exception 114 // CHECK-NEXT: bitcast i8* [[EXNALLOC]] to i32* 115 // CHECK-NEXT: store i32 1, i32* 116 // CHECK-NEXT: invoke void @__cxa_throw(i8* [[EXNALLOC]], i8* bitcast (i8** @_ZTIi to i8*), i8* null 117 throw 1; 118 } 119 120 // CHECK: [[CAUGHTEXN:%.*]] = call i8* @llvm.eh.exception() 121 // CHECK-NEXT: store i8* [[CAUGHTEXN]], i8** [[CAUGHTEXNVAR]] 122 // CHECK-NEXT: [[SELECTOR:%.*]] = call i32 (i8*, i8*, ...)* @llvm.eh.selector(i8* [[CAUGHTEXN]], i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*), i8* bitcast (i8** @_ZTIi to i8*), i8* null) 123 // CHECK-NEXT: store i32 [[SELECTOR]], i32* [[SELECTORVAR]] 124 // CHECK-NEXT: call i32 @llvm.eh.typeid.for(i8* bitcast (i8** @_ZTIi to i8*)) 125 // CHECK-NEXT: icmp eq 126 // CHECK-NEXT: br i1 127 // CHECK: load i8** [[CAUGHTEXNVAR]] 128 // CHECK-NEXT: call i8* @__cxa_begin_catch 129 // CHECK: invoke void @__cxa_rethrow 130 catch (int) { 131 throw; 132 } 133 } 134 // CHECK: [[CAUGHTEXN:%.*]] = call i8* @llvm.eh.exception() 135 // CHECK-NEXT: store i8* [[CAUGHTEXN]], i8** [[CAUGHTEXNVAR]] 136 // CHECK-NEXT: [[SELECTOR:%.*]] = call i32 (i8*, i8*, ...)* @llvm.eh.selector(i8* [[CAUGHTEXN]], i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*), i8* null) 137 // CHECK-NEXT: store i32 [[SELECTOR]], i32* [[SELECTORVAR]] 138 // CHECK-NEXT: store i32 1, i32* [[EHCLEANUPDESTVAR]] 139 // CHECK-NEXT: call void @__cxa_end_catch() 140 // CHECK-NEXT: br label 141 // CHECK: load i8** [[CAUGHTEXNVAR]] 142 // CHECK-NEXT: call i8* @__cxa_begin_catch 143 // CHECK-NEXT: call void @__cxa_end_catch 144 catch (...) { 145 } 146 // CHECK: ret i32 0 147 return 0; 148 } 149 } 150 151 // Ordering of destructors in a catch handler. 152 namespace test8 { 153 struct A { A(const A&); ~A(); }; 154 void bar(); 155 156 // CHECK: define void @_ZN5test83fooEv() 157 void foo() { 158 try { 159 // CHECK: invoke void @_ZN5test83barEv() 160 bar(); 161 } catch (A a) { 162 // CHECK: call i8* @__cxa_get_exception_ptr 163 // CHECK-NEXT: bitcast 164 // CHECK-NEXT: invoke void @_ZN5test81AC1ERKS0_( 165 // CHECK: call i8* @__cxa_begin_catch 166 // CHECK-NEXT: call void @_ZN5test81AD1Ev( 167 // CHECK: call void @__cxa_end_catch() 168 // CHECK: ret void 169 } 170 } 171 } 172 173 // Constructor function-try-block must rethrow on fallthrough. 174 // rdar://problem/7696603 175 namespace test9 { 176 void opaque(); 177 178 struct A { A(); }; 179 180 // CHECK: define void @_ZN5test91AC1Ev(%"struct.test9::A"* %this) unnamed_addr 181 // CHECK: call void @_ZN5test91AC2Ev 182 // CHECK-NEXT: ret void 183 184 // CHECK: define void @_ZN5test91AC2Ev(%"struct.test9::A"* %this) unnamed_addr 185 A::A() try { 186 // CHECK: invoke void @_ZN5test96opaqueEv() 187 opaque(); 188 } catch (int x) { 189 // CHECK: call i8* @__cxa_begin_catch 190 // CHECK: invoke void @_ZN5test96opaqueEv() 191 // CHECK: invoke void @__cxa_rethrow() 192 opaque(); 193 } 194 195 // landing pad from first call to invoke 196 // CHECK: call i8* @llvm.eh.exception 197 // CHECK: call i32 (i8*, i8*, ...)* @llvm.eh.selector(i8* {{.*}}, i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*), i8* bitcast (i8** @_ZTIi to i8*)) 198 } 199 200 // __cxa_end_catch can throw for some kinds of caught exceptions. 201 namespace test10 { 202 void opaque(); 203 204 struct A { ~A(); }; 205 struct B { int x; }; 206 207 // CHECK: define void @_ZN6test103fooEv() 208 void foo() { 209 A a; // force a cleanup context 210 211 try { 212 // CHECK: invoke void @_ZN6test106opaqueEv() 213 opaque(); 214 } catch (int i) { 215 // CHECK: call i8* @__cxa_begin_catch 216 // CHECK-NEXT: bitcast 217 // CHECK-NEXT: load i32* 218 // CHECK-NEXT: store i32 219 // CHECK-NEXT: call void @__cxa_end_catch() nounwind 220 } catch (B a) { 221 // CHECK: call i8* @__cxa_begin_catch 222 // CHECK-NEXT: bitcast 223 // CHECK-NEXT: bitcast 224 // CHECK-NEXT: bitcast 225 // CHECK-NEXT: call void @llvm.memcpy 226 // CHECK-NEXT: invoke void @__cxa_end_catch() 227 } catch (...) { 228 // CHECK: call i8* @__cxa_begin_catch 229 // CHECK-NEXT: invoke void @__cxa_end_catch() 230 } 231 232 // CHECK: call void @_ZN6test101AD1Ev( 233 } 234 } 235 236 // __cxa_begin_catch returns pointers by value, even when catching by reference 237 // <rdar://problem/8212123> 238 namespace test11 { 239 void opaque(); 240 241 // CHECK: define void @_ZN6test113fooEv() 242 void foo() { 243 try { 244 // CHECK: invoke void @_ZN6test116opaqueEv() 245 opaque(); 246 } catch (int**&p) { 247 // CHECK: [[EXN:%.*]] = load i8** 248 // CHECK-NEXT: call i8* @__cxa_begin_catch(i8* [[EXN]]) nounwind 249 // CHECK-NEXT: [[ADJ1:%.*]] = getelementptr i8* [[EXN]], i32 32 250 // CHECK-NEXT: [[ADJ2:%.*]] = bitcast i8* [[ADJ1]] to i32*** 251 // CHECK-NEXT: store i32*** [[ADJ2]], i32**** [[P:%.*]] 252 // CHECK-NEXT: call void @__cxa_end_catch() nounwind 253 } 254 } 255 256 struct A {}; 257 258 // CHECK: define void @_ZN6test113barEv() 259 void bar() { 260 try { 261 // CHECK: [[EXNSLOT:%.*]] = alloca i8* 262 // CHECK-NEXT: [[SELECTORSLOT:%.*]] = alloca i32 263 // CHECK-NEXT: [[P:%.*]] = alloca [[A:%.*]]**, 264 // CHECK-NEXT: [[TMP:%.*]] = alloca [[A]]* 265 // CHECK-NEXT: invoke void @_ZN6test116opaqueEv() 266 opaque(); 267 } catch (A*&p) { 268 // CHECK: [[EXN:%.*]] = load i8** [[EXNSLOT]] 269 // CHECK-NEXT: [[ADJ1:%.*]] = call i8* @__cxa_begin_catch(i8* [[EXN]]) nounwind 270 // CHECK-NEXT: [[ADJ2:%.*]] = bitcast i8* [[ADJ1]] to [[A]]* 271 // CHECK-NEXT: store [[A]]* [[ADJ2]], [[A]]** [[TMP]] 272 // CHECK-NEXT: store [[A]]** [[TMP]], [[A]]*** [[P]] 273 // CHECK-NEXT: call void @__cxa_end_catch() nounwind 274 } 275 } 276 } 277 278 // PR7686 279 namespace test12 { 280 struct A { ~A() noexcept(false); }; 281 bool opaque(const A&); 282 283 // CHECK: define void @_ZN6test124testEv() 284 void test() { 285 // CHECK: [[X:%.*]] = alloca [[A:%.*]], 286 // CHECK: [[EHCLEANUPDEST:%.*]] = alloca i32 287 // CHECK: [[Y:%.*]] = alloca [[A]] 288 // CHECK: [[Z:%.*]] = alloca [[A]] 289 // CHECK: [[CLEANUPDEST:%.*]] = alloca i32 290 291 A x; 292 // CHECK: invoke zeroext i1 @_ZN6test126opaqueERKNS_1AE( 293 if (opaque(x)) { 294 A y; 295 A z; 296 297 // CHECK: invoke void @_ZN6test121AD1Ev([[A]]* [[Z]]) 298 // CHECK: invoke void @_ZN6test121AD1Ev([[A]]* [[Y]]) 299 300 // It'd be great if something eliminated this switch. 301 // CHECK: load i32* [[CLEANUPDEST]] 302 // CHECK-NEXT: switch i32 303 goto success; 304 } 305 306 success: 307 bool _ = true; 308 309 // CHECK: call void @_ZN6test121AD1Ev([[A]]* [[X]]) 310 // CHECK-NEXT: ret void 311 } 312 } 313 314 // Reduced from some TableGen code that was causing a self-host crash. 315 namespace test13 { 316 struct A { ~A(); }; 317 318 void test0(int x) { 319 try { 320 switch (x) { 321 case 0: 322 break; 323 case 1:{ 324 A a; 325 break; 326 } 327 default: 328 return; 329 } 330 return; 331 } catch (int x) { 332 } 333 return; 334 } 335 336 void test1(int x) { 337 A y; 338 try { 339 switch (x) { 340 default: break; 341 } 342 } catch (int x) {} 343 } 344 } 345 346 // rdar://problem/8231514 347 namespace test14 { 348 struct A { ~A(); }; 349 struct B { ~B(); }; 350 351 B b(); 352 void opaque(); 353 354 void foo() { 355 A a; 356 try { 357 B str = b(); 358 opaque(); 359 } catch (int x) { 360 } 361 } 362 } 363 364 // rdar://problem/8231514 365 // JumpDests shouldn't get confused by scopes that aren't normal cleanups. 366 namespace test15 { 367 struct A { ~A(); }; 368 369 bool opaque(int); 370 371 // CHECK: define void @_ZN6test153fooEv() 372 void foo() { 373 A a; 374 375 try { 376 // CHECK: [[X:%.*]] = alloca i32 377 // CHECK: store i32 10, i32* [[X]] 378 // CHECK-NEXT: br label 379 // -> while.cond 380 int x = 10; 381 382 while (true) { 383 // CHECK: load i32* [[X]] 384 // CHECK-NEXT: [[COND:%.*]] = invoke zeroext i1 @_ZN6test156opaqueEi 385 // CHECK: br i1 [[COND]] 386 if (opaque(x)) 387 // CHECK: br label 388 break; 389 390 // CHECK: br label 391 } 392 // CHECK: br label 393 } catch (int x) { } 394 395 // CHECK: call void @_ZN6test151AD1Ev 396 } 397 } 398 399 namespace test16 { 400 struct A { A(); ~A() noexcept(false); }; 401 struct B { int x; B(const A &); ~B() noexcept(false); }; 402 void foo(); 403 bool cond(); 404 405 // CHECK: define void @_ZN6test163barEv() 406 void bar() { 407 // CHECK: [[EXN_SAVE:%.*]] = alloca i8* 408 // CHECK-NEXT: [[EXN_ACTIVE:%.*]] = alloca i1 409 // CHECK-NEXT: [[TEMP:%.*]] = alloca [[A:%.*]], 410 // CHECK-NEXT: [[EXNSLOT:%.*]] = alloca i8* 411 // CHECK-NEXT: [[SELECTORSLOT:%.*]] = alloca i32 412 // CHECK-NEXT: [[EHDEST:%.*]] = alloca i32 413 // CHECK-NEXT: [[TEMP_ACTIVE:%.*]] = alloca i1 414 415 cond() ? throw B(A()) : foo(); 416 417 // CHECK-NEXT: [[COND:%.*]] = call zeroext i1 @_ZN6test164condEv() 418 // CHECK-NEXT: store i1 false, i1* [[EXN_ACTIVE]] 419 // CHECK-NEXT: store i1 false, i1* [[TEMP_ACTIVE]] 420 // CHECK-NEXT: br i1 [[COND]], 421 422 // CHECK: [[EXN:%.*]] = call i8* @__cxa_allocate_exception(i64 4) 423 // CHECK-NEXT: store i8* [[EXN]], i8** [[EXN_SAVE]] 424 // CHECK-NEXT: store i1 true, i1* [[EXN_ACTIVE]] 425 // CHECK-NEXT: [[T0:%.*]] = bitcast i8* [[EXN]] to [[B:%.*]]* 426 // CHECK-NEXT: invoke void @_ZN6test161AC1Ev([[A]]* [[TEMP]]) 427 // CHECK: store i1 true, i1* [[TEMP_ACTIVE]] 428 // CHECK-NEXT: invoke void @_ZN6test161BC1ERKNS_1AE([[B]]* [[T0]], [[A]]* [[TEMP]]) 429 // CHECK: store i1 false, i1* [[EXN_ACTIVE]] 430 // CHECK-NEXT: invoke void @__cxa_throw(i8* [[EXN]], 431 432 // CHECK: invoke void @_ZN6test163fooEv() 433 // CHECK: br label 434 435 // CHECK: invoke void @_ZN6test161AD1Ev([[A]]* [[TEMP]]) 436 // CHECK: ret void 437 438 // CHECK: [[T0:%.*]] = load i1* [[EXN_ACTIVE]] 439 // CHECK-NEXT: br i1 [[T0]] 440 // CHECK: [[T1:%.*]] = load i8** [[EXN_SAVE]] 441 // CHECK-NEXT: call void @__cxa_free_exception(i8* [[T1]]) 442 // CHECK-NEXT: br label 443 } 444 } 445