1 // RUN: %clang_cc1 -no-opaque-pointers -fcxx-exceptions -fexceptions -triple x86_64-apple-macosx10.13.99 -std=c++11 -emit-llvm -o - %s | FileCheck --check-prefix=CHECK --check-prefix=UNALIGNED %s 2 // RUN: %clang_cc1 -no-opaque-pointers -fcxx-exceptions -fexceptions -triple x86_64-apple-macosx10.14 -std=c++11 -emit-llvm -o - %s | FileCheck --check-prefix=CHECK --check-prefix=ALIGNED %s 3 4 struct test1_D { 5 double d; 6 } d1; 7 8 void test1() { 9 throw d1; 10 } 11 12 // CHECK-LABEL: 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 // UNALIGNED-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 [[EXN2]], i8* align 8 bitcast ([[DSTAR]] @d1 to i8*), i64 8, i1 false) 17 // ALIGNED-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 16 [[EXN2]], i8* align 8 bitcast ([[DSTAR]] @d1 to i8*), i64 8, i1 false) 18 // CHECK-NEXT: call void @__cxa_throw(i8* [[EXNOBJ]], i8* bitcast ({ i8*, i8* }* @_ZTI7test1_D to i8*), i8* null) [[NR:#[0-9]+]] 19 // CHECK-NEXT: unreachable 20 21 22 struct test2_D { 23 test2_D(const test2_D&o); 24 test2_D(); 25 virtual void bar() { } 26 int i; int j; 27 } d2; 28 29 void test2() { 30 throw d2; 31 } 32 33 // CHECK-LABEL: define{{.*}} void @_Z5test2v() 34 // CHECK: [[EXNVAR:%.*]] = alloca i8* 35 // CHECK-NEXT: [[SELECTORVAR:%.*]] = 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]] noundef nonnull align {{[0-9]+}} dereferenceable({{[0-9]+}}) @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) [[NR]] 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-LABEL: 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) [[NR]] 60 // CHECK-NEXT: unreachable 61 62 63 void test4() { 64 throw; 65 } 66 67 // CHECK-LABEL: define{{.*}} void @_Z5test4v() 68 // CHECK: call void @__cxa_rethrow() [[NR]] 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-LABEL: 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*)) [[NR]] 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-LABEL: define{{.*}} i32 @_ZN5test73fooEv() 106 // CHECK-SAME: personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) 107 int foo() { 108 // CHECK: [[CAUGHTEXNVAR:%.*]] = alloca i8* 109 // CHECK-NEXT: [[SELECTORVAR:%.*]] = alloca i32 110 // CHECK-NEXT: [[INTCATCHVAR:%.*]] = 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: [[CAUGHTVAL:%.*]] = landingpad { i8*, i32 } 121 // CHECK-NEXT: catch i8* bitcast (i8** @_ZTIi to i8*) 122 // CHECK-NEXT: catch i8* null 123 // CHECK-NEXT: [[CAUGHTEXN:%.*]] = extractvalue { i8*, i32 } [[CAUGHTVAL]], 0 124 // CHECK-NEXT: store i8* [[CAUGHTEXN]], i8** [[CAUGHTEXNVAR]] 125 // CHECK-NEXT: [[SELECTOR:%.*]] = extractvalue { i8*, i32 } [[CAUGHTVAL]], 1 126 // CHECK-NEXT: store i32 [[SELECTOR]], i32* [[SELECTORVAR]] 127 // CHECK-NEXT: br label 128 // CHECK: [[SELECTOR:%.*]] = load i32, i32* [[SELECTORVAR]] 129 // CHECK-NEXT: [[T0:%.*]] = call i32 @llvm.eh.typeid.for(i8* bitcast (i8** @_ZTIi to i8*)) 130 // CHECK-NEXT: icmp eq i32 [[SELECTOR]], [[T0]] 131 // CHECK-NEXT: br i1 132 // CHECK: [[T0:%.*]] = load i8*, i8** [[CAUGHTEXNVAR]] 133 // CHECK-NEXT: [[T1:%.*]] = call i8* @__cxa_begin_catch(i8* [[T0]]) 134 // CHECK-NEXT: [[T2:%.*]] = bitcast i8* [[T1]] to i32* 135 // CHECK-NEXT: [[T3:%.*]] = load i32, i32* [[T2]] 136 // CHECK-NEXT: store i32 [[T3]], i32* {{%.*}}, align 4 137 // CHECK-NEXT: invoke void @__cxa_rethrow 138 catch (int) { 139 throw; 140 } 141 } 142 // CHECK: [[CAUGHTVAL:%.*]] = landingpad { i8*, i32 } 143 // CHECK-NEXT: catch i8* null 144 // CHECK-NEXT: [[CAUGHTEXN:%.*]] = extractvalue { i8*, i32 } [[CAUGHTVAL]], 0 145 // CHECK-NEXT: store i8* [[CAUGHTEXN]], i8** [[CAUGHTEXNVAR]] 146 // CHECK-NEXT: [[SELECTOR:%.*]] = extractvalue { i8*, i32 } [[CAUGHTVAL]], 1 147 // CHECK-NEXT: store i32 [[SELECTOR]], i32* [[SELECTORVAR]] 148 // CHECK-NEXT: call void @__cxa_end_catch() 149 // CHECK-NEXT: br label 150 // CHECK: load i8*, i8** [[CAUGHTEXNVAR]] 151 // CHECK-NEXT: call i8* @__cxa_begin_catch 152 // CHECK-NEXT: call void @__cxa_end_catch 153 catch (...) { 154 } 155 // CHECK: ret i32 0 156 return 0; 157 } 158 } 159 160 // Ordering of destructors in a catch handler. 161 namespace test8 { 162 struct A { A(const A&); ~A(); }; 163 void bar(); 164 165 // CHECK-LABEL: define{{.*}} void @_ZN5test83fooEv() 166 void foo() { 167 try { 168 // CHECK: invoke void @_ZN5test83barEv() 169 bar(); 170 } catch (A a) { 171 // CHECK: call i8* @__cxa_get_exception_ptr 172 // CHECK-NEXT: bitcast 173 // CHECK-NEXT: invoke void @_ZN5test81AC1ERKS0_( 174 // CHECK: call i8* @__cxa_begin_catch 175 // CHECK-NEXT: call void @_ZN5test81AD1Ev( 176 // CHECK: call void @__cxa_end_catch() 177 // CHECK: ret void 178 } 179 } 180 } 181 182 // Constructor function-try-block must rethrow on fallthrough. 183 // rdar://problem/7696603 184 namespace test9 { 185 void opaque(); 186 187 struct A { A(); }; 188 189 190 // CHECK-LABEL: define{{.*}} void @_ZN5test91AC2Ev(%"struct.test9::A"* {{[^,]*}} %this) unnamed_addr 191 // CHECK-SAME: personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) 192 A::A() try { 193 // CHECK: invoke void @_ZN5test96opaqueEv() 194 opaque(); 195 } catch (int x) { 196 // CHECK: landingpad { i8*, i32 } 197 // CHECK-NEXT: catch i8* bitcast (i8** @_ZTIi to i8*) 198 199 // CHECK: call i8* @__cxa_begin_catch 200 // CHECK: invoke void @_ZN5test96opaqueEv() 201 // CHECK: invoke void @__cxa_rethrow() 202 203 // CHECK-LABEL: define{{.*}} void @_ZN5test91AC1Ev(%"struct.test9::A"* {{[^,]*}} %this) unnamed_addr 204 // CHECK: call void @_ZN5test91AC2Ev 205 // CHECK-NEXT: ret void 206 opaque(); 207 } 208 } 209 210 // __cxa_end_catch can throw for some kinds of caught exceptions. 211 namespace test10 { 212 void opaque(); 213 214 struct A { ~A(); }; 215 struct B { int x; }; 216 217 // CHECK-LABEL: define{{.*}} void @_ZN6test103fooEv() 218 void foo() { 219 A a; // force a cleanup context 220 221 try { 222 // CHECK: invoke void @_ZN6test106opaqueEv() 223 opaque(); 224 } catch (int i) { 225 // CHECK: call i8* @__cxa_begin_catch 226 // CHECK-NEXT: bitcast 227 // CHECK-NEXT: load i32, i32* 228 // CHECK-NEXT: store i32 229 // CHECK-NEXT: call void @__cxa_end_catch() [[NUW:#[0-9]+]] 230 } catch (B a) { 231 // CHECK: call i8* @__cxa_begin_catch 232 // CHECK-NEXT: bitcast 233 // CHECK-NEXT: bitcast 234 // CHECK-NEXT: bitcast 235 // CHECK-NEXT: call void @llvm.memcpy 236 // CHECK-NEXT: invoke void @__cxa_end_catch() 237 } catch (...) { 238 // CHECK: call i8* @__cxa_begin_catch 239 // CHECK-NEXT: invoke void @__cxa_end_catch() 240 } 241 242 // CHECK: call void @_ZN6test101AD1Ev( 243 } 244 } 245 246 // __cxa_begin_catch returns pointers by value, even when catching by reference 247 // <rdar://problem/8212123> 248 namespace test11 { 249 void opaque(); 250 251 // CHECK-LABEL: define{{.*}} void @_ZN6test113fooEv() 252 void foo() { 253 try { 254 // CHECK: invoke void @_ZN6test116opaqueEv() 255 opaque(); 256 } catch (int**&p) { 257 // CHECK: [[EXN:%.*]] = load i8*, i8** 258 // CHECK-NEXT: call i8* @__cxa_begin_catch(i8* [[EXN]]) [[NUW]] 259 // CHECK-NEXT: [[ADJ1:%.*]] = getelementptr i8, i8* [[EXN]], i32 32 260 // CHECK-NEXT: [[ADJ2:%.*]] = bitcast i8* [[ADJ1]] to i32*** 261 // CHECK-NEXT: store i32*** [[ADJ2]], i32**** [[P:%.*]] 262 // CHECK-NEXT: call void @__cxa_end_catch() [[NUW]] 263 } 264 } 265 266 struct A {}; 267 268 // CHECK-LABEL: define{{.*}} void @_ZN6test113barEv() 269 void bar() { 270 try { 271 // CHECK: [[EXNSLOT:%.*]] = alloca i8* 272 // CHECK-NEXT: [[SELECTORSLOT:%.*]] = alloca i32 273 // CHECK-NEXT: [[P:%.*]] = alloca [[A:%.*]]**, 274 // CHECK-NEXT: [[TMP:%.*]] = alloca [[A]]* 275 // CHECK-NEXT: invoke void @_ZN6test116opaqueEv() 276 opaque(); 277 } catch (A*&p) { 278 // CHECK: [[EXN:%.*]] = load i8*, i8** [[EXNSLOT]] 279 // CHECK-NEXT: [[ADJ1:%.*]] = call i8* @__cxa_begin_catch(i8* [[EXN]]) [[NUW]] 280 // CHECK-NEXT: [[ADJ2:%.*]] = bitcast i8* [[ADJ1]] to [[A]]* 281 // CHECK-NEXT: store [[A]]* [[ADJ2]], [[A]]** [[TMP]] 282 // CHECK-NEXT: store [[A]]** [[TMP]], [[A]]*** [[P]] 283 // CHECK-NEXT: call void @__cxa_end_catch() [[NUW]] 284 } 285 } 286 } 287 288 // PR7686 289 namespace test12 { 290 struct A { ~A() noexcept(false); }; 291 bool opaque(const A&); 292 293 // CHECK-LABEL: define{{.*}} void @_ZN6test124testEv() 294 void test() { 295 // CHECK: [[X:%.*]] = alloca [[A:%.*]], 296 // CHECK: [[EHCLEANUPDEST:%.*]] = alloca i32 297 // CHECK: [[Y:%.*]] = alloca [[A]] 298 // CHECK: [[Z:%.*]] = alloca [[A]] 299 // CHECK: [[CLEANUPDEST:%.*]] = alloca i32 300 301 A x; 302 // CHECK: invoke noundef zeroext i1 @_ZN6test126opaqueERKNS_1AE( 303 if (opaque(x)) { 304 A y; 305 A z; 306 307 // CHECK: invoke void @_ZN6test121AD1Ev([[A]]* {{[^,]*}} [[Z]]) 308 // CHECK: invoke void @_ZN6test121AD1Ev([[A]]* {{[^,]*}} [[Y]]) 309 // CHECK-NOT: switch 310 goto success; 311 } 312 313 success: 314 bool _ = true; 315 316 // CHECK: call void @_ZN6test121AD1Ev([[A]]* {{[^,]*}} [[X]]) 317 // CHECK-NEXT: ret void 318 } 319 } 320 321 // Reduced from some TableGen code that was causing a self-host crash. 322 namespace test13 { 323 struct A { ~A(); }; 324 325 void test0(int x) { 326 try { 327 switch (x) { 328 case 0: 329 break; 330 case 1:{ 331 A a; 332 break; 333 } 334 default: 335 return; 336 } 337 return; 338 } catch (int x) { 339 } 340 return; 341 } 342 343 void test1(int x) { 344 A y; 345 try { 346 switch (x) { 347 default: break; 348 } 349 } catch (int x) {} 350 } 351 } 352 353 // rdar://problem/8231514 354 namespace test14 { 355 struct A { ~A(); }; 356 struct B { ~B(); }; 357 358 B b(); 359 void opaque(); 360 361 void foo() { 362 A a; 363 try { 364 B str = b(); 365 opaque(); 366 } catch (int x) { 367 } 368 } 369 } 370 371 // rdar://problem/8231514 372 // JumpDests shouldn't get confused by scopes that aren't normal cleanups. 373 namespace test15 { 374 struct A { ~A(); }; 375 376 bool opaque(int); 377 378 // CHECK-LABEL: define{{.*}} void @_ZN6test153fooEv() 379 void foo() { 380 A a; 381 382 try { 383 // CHECK: [[X:%.*]] = alloca i32 384 // CHECK: store i32 10, i32* [[X]] 385 // CHECK-NEXT: br label 386 // -> while.cond 387 int x = 10; 388 389 while (true) { 390 // CHECK: load i32, i32* [[X]] 391 // CHECK-NEXT: [[COND:%.*]] = invoke noundef zeroext i1 @_ZN6test156opaqueEi 392 // CHECK: br i1 [[COND]] 393 if (opaque(x)) 394 // CHECK: br label 395 break; 396 397 // CHECK: br label 398 } 399 // CHECK: br label 400 } catch (int x) { } 401 402 // CHECK: call void @_ZN6test151AD1Ev 403 } 404 } 405 406 namespace test16 { 407 struct A { A(); ~A() noexcept(false); }; 408 struct B { int x; B(const A &); ~B() noexcept(false); }; 409 void foo(); 410 bool cond(); 411 412 // CHECK-LABEL: define{{.*}} void @_ZN6test163barEv() 413 void bar() { 414 // CHECK: [[EXN_SAVE:%.*]] = alloca i8* 415 // CHECK-NEXT: [[EXN_ACTIVE:%.*]] = alloca i1 416 // CHECK-NEXT: [[TEMP:%.*]] = alloca [[A:%.*]], 417 // CHECK-NEXT: [[EXNSLOT:%.*]] = alloca i8* 418 // CHECK-NEXT: [[SELECTORSLOT:%.*]] = alloca i32 419 // CHECK-NEXT: [[TEMP_ACTIVE:%.*]] = alloca i1 420 421 cond() ? throw B(A()) : foo(); 422 423 // CHECK-NEXT: [[COND:%.*]] = call noundef zeroext i1 @_ZN6test164condEv() 424 // CHECK-NEXT: store i1 false, i1* [[EXN_ACTIVE]] 425 // CHECK-NEXT: store i1 false, i1* [[TEMP_ACTIVE]] 426 // CHECK-NEXT: br i1 [[COND]], 427 428 // CHECK: [[EXN:%.*]] = call i8* @__cxa_allocate_exception(i64 4) 429 // CHECK-NEXT: store i8* [[EXN]], i8** [[EXN_SAVE]] 430 // CHECK-NEXT: store i1 true, i1* [[EXN_ACTIVE]] 431 // CHECK-NEXT: [[T0:%.*]] = bitcast i8* [[EXN]] to [[B:%.*]]* 432 // CHECK-NEXT: invoke void @_ZN6test161AC1Ev([[A]]* {{[^,]*}} [[TEMP]]) 433 // CHECK: store i1 true, i1* [[TEMP_ACTIVE]] 434 // CHECK-NEXT: invoke void @_ZN6test161BC1ERKNS_1AE([[B]]* {{[^,]*}} [[T0]], [[A]]* noundef nonnull align {{[0-9]+}} dereferenceable({{[0-9]+}}) [[TEMP]]) 435 // CHECK: store i1 false, i1* [[EXN_ACTIVE]] 436 // CHECK-NEXT: invoke void @__cxa_throw(i8* [[EXN]], 437 438 // CHECK: invoke void @_ZN6test163fooEv() 439 // CHECK: br label 440 441 // CHECK: invoke void @_ZN6test161AD1Ev([[A]]* {{[^,]*}} [[TEMP]]) 442 // CHECK: ret void 443 444 // CHECK: [[T0:%.*]] = load i1, i1* [[EXN_ACTIVE]] 445 // CHECK-NEXT: br i1 [[T0]] 446 // CHECK: [[T1:%.*]] = load i8*, i8** [[EXN_SAVE]] 447 // CHECK-NEXT: call void @__cxa_free_exception(i8* [[T1]]) 448 // CHECK-NEXT: br label 449 } 450 } 451 452 namespace test17 { 453 class BaseException { 454 private: 455 int a[4]; 456 public: 457 BaseException() {}; 458 }; 459 460 class DerivedException: public BaseException { 461 }; 462 463 int foo() { 464 throw DerivedException(); 465 // The alignment passed to memset is 16 on Darwin. 466 467 // CHECK: [[T0:%.*]] = call i8* @__cxa_allocate_exception(i64 16) 468 // CHECK-NEXT: [[T1:%.*]] = bitcast i8* [[T0]] to %"class.test17::DerivedException"* 469 // CHECK-NEXT: [[T2:%.*]] = bitcast %"class.test17::DerivedException"* [[T1]] to i8* 470 // UNALIGNED-NEXT: call void @llvm.memset.p0i8.i64(i8* align 8 [[T2]], i8 0, i64 16, i1 false) 471 // ALIGNED-NEXT: call void @llvm.memset.p0i8.i64(i8* align 16 [[T2]], i8 0, i64 16, i1 false) 472 } 473 } 474 475 // CHECK: attributes [[NUW]] = { nounwind } 476 // CHECK: attributes [[NR]] = { noreturn } 477