[clang] Handle __declspec() attributes in using
[llvm-project.git] / clang / test / SemaCXX / return-noreturn.cpp
blobb88e5a519d1bb0691387bd588eba1a453c1667f0
1 // RUN: %clang_cc1 %s -fsyntax-only -fcxx-exceptions -verify -Wreturn-type -Wmissing-noreturn -Wno-unreachable-code -Wno-covered-switch-default
2 // RUN: %clang_cc1 %s -fsyntax-only -fcxx-exceptions -std=c++11 -verify -Wreturn-type -Wmissing-noreturn -Wno-unreachable-code -Wno-covered-switch-default
4 // A destructor may be marked noreturn and should still influence the CFG.
5 void pr6884_abort() __attribute__((noreturn));
7 struct pr6884_abort_struct {
8 pr6884_abort_struct() {}
9 ~pr6884_abort_struct() __attribute__((noreturn)) { pr6884_abort(); }
12 struct other { ~other() {} };
14 // Ensure that destructors from objects are properly modeled in the CFG despite
15 // the presence of switches, case statements, labels, and blocks. These tests
16 // try to cover bugs reported in both PR6884 and PR10063.
17 namespace abort_struct_complex_cfgs {
18 int basic(int x) {
19 switch (x) { default: pr6884_abort(); }
21 int f1(int x) {
22 switch (x) default: pr6884_abort_struct();
24 int f2(int x) {
25 switch (x) { default: pr6884_abort_struct(); }
27 int f2_positive(int x) {
28 switch (x) { default: ; }
29 } // expected-warning {{non-void function does not return a value}}
30 int f3(int x) {
31 switch (x) { default: { pr6884_abort_struct(); } }
33 int f4(int x) {
34 switch (x) default: L1: L2: case 4: pr6884_abort_struct();
36 int f5(int x) {
37 switch (x) default: L1: { L2: case 4: pr6884_abort_struct(); }
39 int f6(int x) {
40 switch (x) default: L1: L2: case 4: { pr6884_abort_struct(); }
43 // FIXME: detect noreturn destructors triggered by calls to delete.
44 int f7(int x) {
45 switch (x) default: L1: L2: case 4: {
46 pr6884_abort_struct *p = new pr6884_abort_struct();
47 delete p;
49 } // expected-warning {{non-void function does not return a value}}
51 // Test that these constructs work even when extraneous blocks are created
52 // before and after the switch due to implicit destructors.
53 int g1(int x) {
54 other o;
55 switch (x) default: pr6884_abort_struct();
57 int g2(int x) {
58 other o;
59 switch (x) { default: pr6884_abort_struct(); }
61 int g2_positive(int x) {
62 other o;
63 switch (x) { default: ; }
64 } // expected-warning {{non-void function does not return a value}}
65 int g3(int x) {
66 other o;
67 switch (x) { default: { pr6884_abort_struct(); } }
69 int g4(int x) {
70 other o;
71 switch (x) default: L1: L2: case 4: pr6884_abort_struct();
73 int g5(int x) {
74 other o;
75 switch (x) default: L1: { L2: case 4: pr6884_abort_struct(); }
77 int g6(int x) {
78 other o;
79 switch (x) default: L1: L2: case 4: { pr6884_abort_struct(); }
82 // Test that these constructs work even with variables carrying the no-return
83 // destructor instead of temporaries.
84 int h1(int x) {
85 other o;
86 switch (x) default: pr6884_abort_struct a;
88 int h2(int x) {
89 other o;
90 switch (x) { default: pr6884_abort_struct a; }
92 int h3(int x) {
93 other o;
94 switch (x) { default: { pr6884_abort_struct a; } }
96 int h4(int x) {
97 other o;
98 switch (x) default: L1: L2: case 4: pr6884_abort_struct a;
100 int h5(int x) {
101 other o;
102 switch (x) default: L1: { L2: case 4: pr6884_abort_struct a; }
104 int h6(int x) {
105 other o;
106 switch (x) default: L1: L2: case 4: { pr6884_abort_struct a; }
110 // PR9380
111 struct PR9380 {
112 ~PR9380();
114 struct PR9380_B : public PR9380 {
115 PR9380_B( const PR9380& str );
117 void test_PR9380(const PR9380& aKey) {
118 const PR9380& flatKey = PR9380_B(aKey);
121 // Array of objects with destructors. This is purely a coverage test case.
122 void test_array() {
123 PR9380 a[2];
126 // Test classes wrapped in typedefs. This is purely a coverage test case
127 // for CFGImplictDtor::getDestructorDecl().
128 void test_typedefs() {
129 typedef PR9380 PR9380_Ty;
130 PR9380_Ty test;
131 PR9380_Ty test2[20];
134 // PR9412 - Handle CFG traversal with null successors.
135 enum PR9412_MatchType { PR9412_Exact };
137 template <PR9412_MatchType type> int PR9412_t() {
138 switch (type) {
139 case PR9412_Exact:
140 default:
141 break;
143 } // expected-warning {{non-void function does not return a value}}
145 void PR9412_f() {
146 PR9412_t<PR9412_Exact>(); // expected-note {{in instantiation of function template specialization 'PR9412_t<PR9412_Exact>' requested here}}
149 struct NoReturn {
150 ~NoReturn() __attribute__((noreturn));
151 operator bool() const;
153 struct Return {
154 ~Return();
155 operator bool() const;
158 int testTernaryUnconditionalNoreturn() {
159 true ? NoReturn() : NoReturn();
162 int testTernaryStaticallyConditionalNoretrunOnTrue() {
163 true ? NoReturn() : Return();
166 int testTernaryStaticallyConditionalRetrunOnTrue() {
167 true ? Return() : NoReturn();
168 } // expected-warning {{non-void function does not return a value}}
170 int testTernaryStaticallyConditionalNoretrunOnFalse() {
171 false ? Return() : NoReturn();
174 int testTernaryStaticallyConditionalRetrunOnFalse() {
175 false ? NoReturn() : Return();
176 } // expected-warning {{non-void function does not return a value}}
178 int testTernaryConditionalNoreturnTrueBranch(bool value) {
179 value ? (NoReturn() || NoReturn()) : Return();
180 } // expected-warning {{non-void function does not return a value in all control paths}}
182 int testTernaryConditionalNoreturnFalseBranch(bool value) {
183 value ? Return() : (NoReturn() || NoReturn());
184 } // expected-warning {{non-void function does not return a value in all control paths}}
186 int testConditionallyExecutedComplexTernaryTrueBranch(bool value) {
187 value || (true ? NoReturn() : true);
188 } // expected-warning {{non-void function does not return a value in all control paths}}
190 int testConditionallyExecutedComplexTernaryFalseBranch(bool value) {
191 value || (false ? true : NoReturn());
192 } // expected-warning {{non-void function does not return a value in all control paths}}
194 int testStaticallyExecutedLogicalOrBranch() {
195 false || NoReturn();
198 int testStaticallyExecutedLogicalAndBranch() {
199 true && NoReturn();
202 int testStaticallySkippedLogicalOrBranch() {
203 true || NoReturn();
204 } // expected-warning {{non-void function does not return a value}}
206 int testStaticallySkppedLogicalAndBranch() {
207 false && NoReturn();
208 } // expected-warning {{non-void function does not return a value}}
210 int testConditionallyExecutedComplexLogicalBranch(bool value) {
211 value || (true && NoReturn());
212 } // expected-warning {{non-void function does not return a value in all control paths}}
214 int testConditionallyExecutedComplexLogicalBranch2(bool value) {
215 (true && value) || (true && NoReturn());
216 } // expected-warning {{non-void function does not return a value in all control paths}}
218 int testConditionallyExecutedComplexLogicalBranch3(bool value) {
219 (false && (Return() || true)) || (true && NoReturn());
222 int testConditionallyExecutedComplexLogicalBranch4(bool value) {
223 false || ((Return() || true) && (true && NoReturn()));
226 #if __cplusplus >= 201103L
227 namespace LambdaVsTemporaryDtor {
228 struct Y { ~Y(); };
229 struct X { template<typename T> X(T, Y = Y()) {} };
231 struct Fatal { ~Fatal() __attribute__((noreturn)); };
232 struct FatalCopy { FatalCopy(); FatalCopy(const FatalCopy&, Fatal F = Fatal()); };
234 void foo();
236 int bar() {
237 X work([](){ Fatal(); });
238 foo();
239 } // expected-warning {{non-void function does not return a value}}
241 int baz() {
242 FatalCopy fc;
243 X work([fc](){});
244 foo();
245 } // ok, initialization of lambda does not return
247 #endif
249 // Ensure that function-try-blocks also check for return values properly.
250 int functionTryBlock1(int s) try {
251 return 0;
252 } catch (...) {
253 } // expected-warning {{non-void function does not return a value in all control paths}}
255 int functionTryBlock2(int s) try {
256 } catch (...) {
257 return 0;
258 } // expected-warning {{non-void function does not return a value in all control paths}}
260 int functionTryBlock3(int s) try {
261 return 0;
262 } catch (...) {
263 return 0;
264 } // ok, both paths return.