1// RUN: %clang_cc1 -fcxx-exceptions -fexceptions -Wno-unreachable-code -Werror -triple x86_64-linux-gnu -emit-llvm -o - %s | FileCheck %s
2
3int val = 42;
4int& test1() {
5  return throw val, val;
6}
7
8int test2() {
9  return val ? throw val : val;
10}
11
12// rdar://problem/8608801
13void test3() {
14  throw false;
15}
16
17// PR10582
18int test4() {
19  return 1 ? throw val : val;
20}
21
22// PR15923
23int 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
47int 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
71namespace 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
84// CHECK-LABEL: define void @_Z5test7b(
85void test7(bool cond) {
86  // CHECK: br i1
87  //
88  // x.true:
89  // CHECK: call void @__cxa_throw(
90  // CHECK-NEXT: unreachable
91  //
92  // x.false:
93  // CHECK: br label
94  //
95  // end:
96  // CHECK: ret void
97  cond ? throw test7 : val;
98}
99
100// CHECK-LABEL: define dereferenceable(4) i32* @_Z5test8b(
101int &test8(bool cond) {
102  // CHECK: br i1
103  //
104  // x.true:
105  // CHECK: br label
106  //
107  // x.false:
108  // CHECK: call void @__cxa_throw(
109  // CHECK-NEXT: unreachable
110  //
111  // end:
112  // CHECK: ret i32* @val
113  return cond ? val : ((throw "foo"));
114}
115