eh.cpp revision 82cd2e5c15aa909ec9613c4228ab69e07f1c6f7a
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 4struct test1_D { 5 double d; 6} d1; 7 8void 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 21struct test2_D { 22 test2_D(const test2_D&o); 23 test2_D(); 24 virtual void bar() { } 25 int i; int j; 26} d2; 27 28void 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 45struct test3_D { 46 test3_D() { } 47 test3_D(volatile test3_D&o); 48 virtual void bar(); 49}; 50 51void 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 63void 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 73namespace 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 93namespace test6 { 94 template <class T> struct allocator { 95 ~allocator() throw() { } 96 }; 97 98 void foo() { 99 allocator<int> a; 100 } 101} 102 103// PR7127 104namespace 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. 152namespace 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 175namespace 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. 201namespace 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> 238namespace 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 279namespace 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 // CHECK-NOT: switch 300 goto success; 301 } 302 303 success: 304 bool _ = true; 305 306 // CHECK: call void @_ZN6test121AD1Ev([[A]]* [[X]]) 307 // CHECK-NEXT: ret void 308 } 309} 310 311// Reduced from some TableGen code that was causing a self-host crash. 312namespace test13 { 313 struct A { ~A(); }; 314 315 void test0(int x) { 316 try { 317 switch (x) { 318 case 0: 319 break; 320 case 1:{ 321 A a; 322 break; 323 } 324 default: 325 return; 326 } 327 return; 328 } catch (int x) { 329 } 330 return; 331 } 332 333 void test1(int x) { 334 A y; 335 try { 336 switch (x) { 337 default: break; 338 } 339 } catch (int x) {} 340 } 341} 342 343// rdar://problem/8231514 344namespace test14 { 345 struct A { ~A(); }; 346 struct B { ~B(); }; 347 348 B b(); 349 void opaque(); 350 351 void foo() { 352 A a; 353 try { 354 B str = b(); 355 opaque(); 356 } catch (int x) { 357 } 358 } 359} 360 361// rdar://problem/8231514 362// JumpDests shouldn't get confused by scopes that aren't normal cleanups. 363namespace test15 { 364 struct A { ~A(); }; 365 366 bool opaque(int); 367 368 // CHECK: define void @_ZN6test153fooEv() 369 void foo() { 370 A a; 371 372 try { 373 // CHECK: [[X:%.*]] = alloca i32 374 // CHECK: store i32 10, i32* [[X]] 375 // CHECK-NEXT: br label 376 // -> while.cond 377 int x = 10; 378 379 while (true) { 380 // CHECK: load i32* [[X]] 381 // CHECK-NEXT: [[COND:%.*]] = invoke zeroext i1 @_ZN6test156opaqueEi 382 // CHECK: br i1 [[COND]] 383 if (opaque(x)) 384 // CHECK: br label 385 break; 386 387 // CHECK: br label 388 } 389 // CHECK: br label 390 } catch (int x) { } 391 392 // CHECK: call void @_ZN6test151AD1Ev 393 } 394} 395 396namespace test16 { 397 struct A { A(); ~A() noexcept(false); }; 398 struct B { int x; B(const A &); ~B() noexcept(false); }; 399 void foo(); 400 bool cond(); 401 402 // CHECK: define void @_ZN6test163barEv() 403 void bar() { 404 // CHECK: [[EXN_SAVE:%.*]] = alloca i8* 405 // CHECK-NEXT: [[EXN_ACTIVE:%.*]] = alloca i1 406 // CHECK-NEXT: [[TEMP:%.*]] = alloca [[A:%.*]], 407 // CHECK-NEXT: [[EXNSLOT:%.*]] = alloca i8* 408 // CHECK-NEXT: [[SELECTORSLOT:%.*]] = alloca i32 409 // CHECK-NEXT: [[EHDEST:%.*]] = alloca i32 410 // CHECK-NEXT: [[TEMP_ACTIVE:%.*]] = alloca i1 411 412 cond() ? throw B(A()) : foo(); 413 414 // CHECK-NEXT: [[COND:%.*]] = call zeroext i1 @_ZN6test164condEv() 415 // CHECK-NEXT: store i1 false, i1* [[EXN_ACTIVE]] 416 // CHECK-NEXT: store i1 false, i1* [[TEMP_ACTIVE]] 417 // CHECK-NEXT: br i1 [[COND]], 418 419 // CHECK: [[EXN:%.*]] = call i8* @__cxa_allocate_exception(i64 4) 420 // CHECK-NEXT: store i8* [[EXN]], i8** [[EXN_SAVE]] 421 // CHECK-NEXT: store i1 true, i1* [[EXN_ACTIVE]] 422 // CHECK-NEXT: [[T0:%.*]] = bitcast i8* [[EXN]] to [[B:%.*]]* 423 // CHECK-NEXT: invoke void @_ZN6test161AC1Ev([[A]]* [[TEMP]]) 424 // CHECK: store i1 true, i1* [[TEMP_ACTIVE]] 425 // CHECK-NEXT: invoke void @_ZN6test161BC1ERKNS_1AE([[B]]* [[T0]], [[A]]* [[TEMP]]) 426 // CHECK: store i1 false, i1* [[EXN_ACTIVE]] 427 // CHECK-NEXT: invoke void @__cxa_throw(i8* [[EXN]], 428 429 // CHECK: invoke void @_ZN6test163fooEv() 430 // CHECK: br label 431 432 // CHECK: invoke void @_ZN6test161AD1Ev([[A]]* [[TEMP]]) 433 // CHECK: ret void 434 435 // CHECK: [[T0:%.*]] = load i1* [[EXN_ACTIVE]] 436 // CHECK-NEXT: br i1 [[T0]] 437 // CHECK: [[T1:%.*]] = load i8** [[EXN_SAVE]] 438 // CHECK-NEXT: call void @__cxa_free_exception(i8* [[T1]]) 439 // CHECK-NEXT: br label 440 } 441} 442