1 // RUN: %clang_cc1 -fcxx-exceptions -fexceptions -Wno-unreachable-code -Werror -triple x86_64-linux-gnu -emit-llvm -o - %s | FileCheck %s
2 
3 int val = 42;
test1()4 int& test1() {
5   return throw val, val;
6 }
7 
test2()8 int test2() {
9   return val ? throw val : val;
10 }
11 
12 // rdar://problem/8608801
test3()13 void test3() {
14   throw false;
15 }
16 
17 // PR10582
test4()18 int test4() {
19   return 1 ? throw val : val;
20 }
21 
22 // PR15923
test5(bool x,bool y,int z)23 int test5(bool x, bool y, int z) {
24   return (x ? throw 1 : y) ? z : throw 2;
25 }
26 // CHECK-LABEL: define{{.*}} i32 @_Z5test5bbi(
27 // CHECK: br i1
28 //
29 // x.true:
30 // CHECK: call void @__cxa_throw(
31 // CHECK-NEXT: unreachable
32 //
33 // x.false:
34 // CHECK: br i1
35 //
36 // y.true:
37 // CHECK: load i32, i32*
38 // CHECK: br label
39 //
40 // y.false:
41 // CHECK: call void @__cxa_throw(
42 // CHECK-NEXT: unreachable
43 //
44 // end:
45 // CHECK: ret i32
46 
test6(bool x,bool y,int z)47 int test6(bool x, bool y, int z) {
48   return (x ? throw 1 : y) ? z : (throw 2);
49 }
50 // CHECK-LABEL: define{{.*}} i32 @_Z5test6bbi(
51 // CHECK: br i1
52 //
53 // x.true:
54 // CHECK: call void @__cxa_throw(
55 // CHECK-NEXT: unreachable
56 //
57 // x.false:
58 // CHECK: br i1
59 //
60 // y.true:
61 // CHECK: load i32, i32*
62 // CHECK: br label
63 //
64 // y.false:
65 // CHECK: call void @__cxa_throw(
66 // CHECK-NEXT: unreachable
67 //
68 // end:
69 // CHECK: ret i32
70 
71 namespace DR1560 {
72   struct A {
73     ~A();
74   };
75   extern bool b;
76   A get();
77   // CHECK-LABEL: @_ZN6DR15601bE
78   const A &r = b ? get() : throw 0;
79   // CHECK-NOT: call {{.*}}@_ZN6DR15601AD1Ev
80   // CHECK: call {{.*}} @__cxa_atexit({{.*}} @_ZN6DR15601AD1Ev {{.*}} @_ZGRN6DR15601rE
81   // CHECK-NOT: call {{.*}}@_ZN6DR15601AD1Ev
82 
83   // PR28184
conditional_throw()84   void conditional_throw() {
85     int a;
86     (true ? throw 0 : a) = 0; // CHECK: call void @__cxa_throw({{.*}})
87   }
88 }
89 
90 // CHECK-LABEL: define{{.*}} void @_Z5test7b(
test7(bool cond)91 void test7(bool cond) {
92   // CHECK: br i1
93   //
94   // x.true:
95   // CHECK: call void @__cxa_throw(
96   // CHECK-NEXT: unreachable
97   //
98   // x.false:
99   // CHECK: br label
100   //
101   // end:
102   // CHECK: ret void
103   cond ? throw test7 : val;
104 }
105 
106 // CHECK-LABEL: define{{.*}} nonnull align 4 dereferenceable(4) i32* @_Z5test8b(
test8(bool cond)107 int &test8(bool cond) {
108   // CHECK: br i1
109   //
110   // x.true:
111   // CHECK: br label
112   //
113   // x.false:
114   // CHECK: call void @__cxa_throw(
115   // CHECK-NEXT: unreachable
116   //
117   // end:
118   // CHECK: ret i32* @val
119   return cond ? val : ((throw "foo"));
120 }
121