1 | // RUN: %clang_cc1 -std=c++11 -triple %itanium_abi_triple -fexceptions -fcxx-exceptions -emit-llvm -o - %s | FileCheck %s |
2 | |
3 | struct A { |
4 | ~A(); |
5 | }; |
6 | |
7 | struct B { |
8 | ~B() throw(int); |
9 | }; |
10 | |
11 | struct C { |
12 | B b; |
13 | ~C() {} |
14 | }; |
15 | |
16 | struct D { |
17 | ~D() noexcept(false); |
18 | }; |
19 | |
20 | struct E { |
21 | D d; |
22 | ~E() {} |
23 | }; |
24 | |
25 | void foo() { |
26 | A a; |
27 | C c; |
28 | E e; |
29 | // CHECK: invoke {{.*}} @_ZN1ED1Ev |
30 | // CHECK: invoke {{.*}} @_ZN1CD1Ev |
31 | // CHECK: call {{.*}} @_ZN1AD1Ev |
32 | } |
33 | |
34 | struct F { |
35 | D d; |
36 | ~F(); |
37 | }; |
38 | F::~F() noexcept(false) {} |
39 | |
40 | struct G { |
41 | D d; |
42 | ~G(); |
43 | }; |
44 | G::~G() {} |
45 | |
46 | struct H { |
47 | B b; |
48 | ~H() throw(int); |
49 | }; |
50 | H::~H() throw(int) {} |
51 | |
52 | struct I { |
53 | B b; |
54 | ~I(); |
55 | }; |
56 | I::~I() {} |
57 | |
58 | // Template variants. |
59 | |
60 | template <typename T> |
61 | struct TA { |
62 | ~TA(); |
63 | }; |
64 | |
65 | template <typename T> |
66 | struct TB { |
67 | ~TB() throw(int); |
68 | }; |
69 | |
70 | template <typename T> |
71 | struct TC { |
72 | TB<T> b; |
73 | ~TC() {} |
74 | }; |
75 | |
76 | template <typename T> |
77 | struct TD { |
78 | ~TD() noexcept(false); |
79 | }; |
80 | |
81 | template <typename T> |
82 | struct TE { |
83 | TD<T> d; |
84 | ~TE() {} |
85 | }; |
86 | |
87 | void tfoo() { |
88 | TA<int> a; |
89 | TC<int> c; |
90 | TE<int> e; |
91 | // CHECK: invoke {{.*}} @_ZN2TEIiED1Ev |
92 | // CHECK: invoke {{.*}} @_ZN2TCIiED1Ev |
93 | // CHECK: call {{.*}} @_ZN2TAIiED1Ev |
94 | } |
95 | |
96 | template <typename T> |
97 | struct TF { |
98 | TD<T> d; |
99 | ~TF(); |
100 | }; |
101 | template <typename T> |
102 | TF<T>::~TF() noexcept(false) {} |
103 | |
104 | template <typename T> |
105 | struct TG { |
106 | TD<T> d; |
107 | ~TG(); |
108 | }; |
109 | template <typename T> |
110 | TG<T>::~TG() {} |
111 | |
112 | template <typename T> |
113 | struct TH { |
114 | TB<T> b; |
115 | ~TH(); |
116 | }; |
117 | template <typename T> |
118 | TH<T>::~TH() {} |
119 | |
120 | void tinst() { |
121 | TF<int> f; |
122 | TG<int> g; |
123 | TH<int> h; |
124 | } |
125 | // CHECK: define linkonce_odr {{.*}} @_ZN2THIiED1Ev |
126 | // CHECK: _ZTIi |
127 | // CHECK: __cxa_call_unexpected |
128 | |
129 | struct VX |
130 | { virtual ~VX() {} }; |
131 | |
132 | struct VY : VX |
133 | { virtual ~VY() {} }; |
134 | |
135 | template<typename T> |
136 | struct TVY : VX |
137 | { virtual ~TVY() {} }; |
138 | |
139 | |
140 | struct VA { |
141 | B b; |
142 | virtual ~VA() {} |
143 | }; |
144 | |
145 | struct VB : VA |
146 | { virtual ~VB() {} }; |
147 | |
148 | template<typename T> |
149 | struct TVB : VA |
150 | { virtual ~TVB() {} }; |
151 | |
152 | void tinst2() { |
153 | TVY<int> tvy; |
154 | TVB<int> tvb; |
155 | } |
156 | |
157 | template <typename T> |
158 | struct Sw { |
159 | T t; |
160 | ~Sw() {} |
161 | }; |
162 | |
163 | void tsw() { |
164 | Sw<int> swi; |
165 | Sw<B> swb; |
166 | } |
167 | // CHECK-NOT: define linkonce_odr {{.*}} @_ZN2SwI1BED1Ev({{.*}} # |
168 | // CHECK: define linkonce_odr {{.*}} @_ZN2SwI1BED1Ev({{.*}} |
169 | // CHECK: _ZTIi |
170 | // CHECK: __cxa_call_unexpected |
171 | // CHECK: define linkonce_odr {{.*}} @_ZN2SwIiED1Ev({{.*}} [[ATTRGRP:#[0-9]+]] |
172 | |
173 | template <typename T> |
174 | struct TVC : VX |
175 | { virtual ~TVC(); }; |
176 | template <typename T> |
177 | TVC<T>::~TVC() {} |
178 | |
179 | // CHECK: attributes [[ATTRGRP]] = { noinline nounwind{{.*}} } |
180 | |