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
{
19 switch (x
) { default: pr6884_abort(); }
22 switch (x
) default: pr6884_abort_struct();
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}}
31 switch (x
) { default: { pr6884_abort_struct(); } }
34 switch (x
) default: L1
: L2
: case 4: pr6884_abort_struct();
37 switch (x
) default: L1
: { L2
: case 4: pr6884_abort_struct(); }
40 switch (x
) default: L1
: L2
: case 4: { pr6884_abort_struct(); }
43 // FIXME: detect noreturn destructors triggered by calls to delete.
45 switch (x
) default: L1
: L2
: case 4: {
46 pr6884_abort_struct
*p
= new pr6884_abort_struct();
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.
55 switch (x
) default: pr6884_abort_struct();
59 switch (x
) { default: pr6884_abort_struct(); }
61 int g2_positive(int x
) {
63 switch (x
) { default: ; }
64 } // expected-warning {{non-void function does not return a value}}
67 switch (x
) { default: { pr6884_abort_struct(); } }
71 switch (x
) default: L1
: L2
: case 4: pr6884_abort_struct();
75 switch (x
) default: L1
: { L2
: case 4: pr6884_abort_struct(); }
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.
86 switch (x
) default: pr6884_abort_struct a
;
90 switch (x
) { default: pr6884_abort_struct a
; }
94 switch (x
) { default: { pr6884_abort_struct a
; } }
98 switch (x
) default: L1
: L2
: case 4: pr6884_abort_struct a
;
102 switch (x
) default: L1
: { L2
: case 4: pr6884_abort_struct a
; }
106 switch (x
) default: L1
: L2
: case 4: { pr6884_abort_struct a
; }
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.
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
;
134 // PR9412 - Handle CFG traversal with null successors.
135 enum PR9412_MatchType
{ PR9412_Exact
};
137 template <PR9412_MatchType type
> int PR9412_t() {
143 } // expected-warning {{non-void function does not return a value}}
146 PR9412_t
<PR9412_Exact
>(); // expected-note {{in instantiation of function template specialization 'PR9412_t<PR9412_Exact>' requested here}}
150 ~NoReturn() __attribute__((noreturn
));
151 operator bool() const;
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() {
198 int testStaticallyExecutedLogicalAndBranch() {
202 int testStaticallySkippedLogicalOrBranch() {
204 } // expected-warning {{non-void function does not return a value}}
206 int testStaticallySkppedLogicalAndBranch() {
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
{
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()); };
237 X
work([](){ Fatal(); });
239 } // expected-warning {{non-void function does not return a value}}
245 } // ok, initialization of lambda does not return
249 // Ensure that function-try-blocks also check for return values properly.
250 int functionTryBlock1(int s
) try {
253 } // expected-warning {{non-void function does not return a value in all control paths}}
255 int functionTryBlock2(int s
) try {
258 } // expected-warning {{non-void function does not return a value in all control paths}}
260 int functionTryBlock3(int s
) try {
264 } // ok, both paths return.