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
3 
4 // A destructor may be marked noreturn and should still influence the CFG.
5 void pr6884_abort() __attribute__((noreturn));
6 
7 struct pr6884_abort_struct {
pr6884_abort_structpr6884_abort_struct8   pr6884_abort_struct() {}
~pr6884_abort_structpr6884_abort_struct9   ~pr6884_abort_struct() __attribute__((noreturn)) { pr6884_abort(); }
10 };
11 
~otherother12 struct other { ~other() {} };
13 
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 {
basic(int x)18   int basic(int x) {
19     switch (x) { default: pr6884_abort(); }
20   }
f1(int x)21   int f1(int x) {
22     switch (x) default: pr6884_abort_struct();
23   }
f2(int x)24   int f2(int x) {
25     switch (x) { default: pr6884_abort_struct(); }
26   }
f2_positive(int x)27   int f2_positive(int x) {
28     switch (x) { default: ; }
29   } // expected-warning {{non-void function does not return a value}}
f3(int x)30   int f3(int x) {
31     switch (x) { default: { pr6884_abort_struct(); } }
32   }
f4(int x)33   int f4(int x) {
34     switch (x) default: L1: L2: case 4: pr6884_abort_struct();
35   }
f5(int x)36   int f5(int x) {
37     switch (x) default: L1: { L2: case 4: pr6884_abort_struct(); }
38   }
f6(int x)39   int f6(int x) {
40     switch (x) default: L1: L2: case 4: { pr6884_abort_struct(); }
41   }
42 
43   // FIXME: detect noreturn destructors triggered by calls to delete.
f7(int x)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;
48     }
49   } // expected-warning {{non-void function does not return a value}}
50 
51   // Test that these constructs work even when extraneous blocks are created
52   // before and after the switch due to implicit destructors.
g1(int x)53   int g1(int x) {
54     other o;
55     switch (x) default: pr6884_abort_struct();
56   }
g2(int x)57   int g2(int x) {
58     other o;
59     switch (x) { default: pr6884_abort_struct(); }
60   }
g2_positive(int x)61   int g2_positive(int x) {
62     other o;
63     switch (x) { default: ; }
64   } // expected-warning {{non-void function does not return a value}}
g3(int x)65   int g3(int x) {
66     other o;
67     switch (x) { default: { pr6884_abort_struct(); } }
68   }
g4(int x)69   int g4(int x) {
70     other o;
71     switch (x) default: L1: L2: case 4: pr6884_abort_struct();
72   }
g5(int x)73   int g5(int x) {
74     other o;
75     switch (x) default: L1: { L2: case 4: pr6884_abort_struct(); }
76   }
g6(int x)77   int g6(int x) {
78     other o;
79     switch (x) default: L1: L2: case 4: { pr6884_abort_struct(); }
80   }
81 
82   // Test that these constructs work even with variables carrying the no-return
83   // destructor instead of temporaries.
h1(int x)84   int h1(int x) {
85     other o;
86     switch (x) default: pr6884_abort_struct a;
87   }
h2(int x)88   int h2(int x) {
89     other o;
90     switch (x) { default: pr6884_abort_struct a; }
91   }
h3(int x)92   int h3(int x) {
93     other o;
94     switch (x) { default: { pr6884_abort_struct a; } }
95   }
h4(int x)96   int h4(int x) {
97     other o;
98     switch (x) default: L1: L2: case 4: pr6884_abort_struct a;
99   }
h5(int x)100   int h5(int x) {
101     other o;
102     switch (x) default: L1: { L2: case 4: pr6884_abort_struct a; }
103   }
h6(int x)104   int h6(int x) {
105     other o;
106     switch (x) default: L1: L2: case 4: { pr6884_abort_struct a; }
107   }
108 }
109 
110 // PR9380
111 struct PR9380 {
112   ~PR9380();
113 };
114 struct PR9380_B : public PR9380 {
115   PR9380_B( const PR9380& str );
116 };
test_PR9380(const PR9380 & aKey)117 void test_PR9380(const PR9380& aKey) {
118   const PR9380& flatKey = PR9380_B(aKey);
119 }
120 
121 // Array of objects with destructors.  This is purely a coverage test case.
test_array()122 void test_array() {
123   PR9380 a[2];
124 }
125 
126 // Test classes wrapped in typedefs.  This is purely a coverage test case
127 // for CFGImplictDtor::getDestructorDecl().
test_typedefs()128 void test_typedefs() {
129   typedef PR9380 PR9380_Ty;
130   PR9380_Ty test;
131   PR9380_Ty test2[20];
132 }
133 
134 // PR9412 - Handle CFG traversal with null successors.
135 enum PR9412_MatchType { PR9412_Exact };
136 
PR9412_t()137 template <PR9412_MatchType type> int PR9412_t() {
138   switch (type) {
139     case PR9412_Exact:
140     default:
141         break;
142   }
143 } // expected-warning {{non-void function does not return a value}}
144 
PR9412_f()145 void PR9412_f() {
146     PR9412_t<PR9412_Exact>(); // expected-note {{in instantiation of function template specialization 'PR9412_t<PR9412_Exact>' requested here}}
147 }
148 
149 struct NoReturn {
150   ~NoReturn() __attribute__((noreturn));
151   operator bool() const;
152 };
153 struct Return {
154   ~Return();
155   operator bool() const;
156 };
157 
testTernaryUnconditionalNoreturn()158 int testTernaryUnconditionalNoreturn() {
159   true ? NoReturn() : NoReturn();
160 }
161 
testTernaryStaticallyConditionalNoretrunOnTrue()162 int testTernaryStaticallyConditionalNoretrunOnTrue() {
163   true ? NoReturn() : Return();
164 }
165 
testTernaryStaticallyConditionalRetrunOnTrue()166 int testTernaryStaticallyConditionalRetrunOnTrue() {
167   true ? Return() : NoReturn();
168 } // expected-warning {{non-void function does not return a value}}
169 
testTernaryStaticallyConditionalNoretrunOnFalse()170 int testTernaryStaticallyConditionalNoretrunOnFalse() {
171   false ? Return() : NoReturn();
172 }
173 
testTernaryStaticallyConditionalRetrunOnFalse()174 int testTernaryStaticallyConditionalRetrunOnFalse() {
175   false ? NoReturn() : Return();
176 } // expected-warning {{non-void function does not return a value}}
177 
testTernaryConditionalNoreturnTrueBranch(bool 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}}
181 
testTernaryConditionalNoreturnFalseBranch(bool value)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}}
185 
testConditionallyExecutedComplexTernaryTrueBranch(bool value)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}}
189 
testConditionallyExecutedComplexTernaryFalseBranch(bool value)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}}
193 
testStaticallyExecutedLogicalOrBranch()194 int testStaticallyExecutedLogicalOrBranch() {
195   false || NoReturn();
196 }
197 
testStaticallyExecutedLogicalAndBranch()198 int testStaticallyExecutedLogicalAndBranch() {
199   true && NoReturn();
200 }
201 
testStaticallySkippedLogicalOrBranch()202 int testStaticallySkippedLogicalOrBranch() {
203   true || NoReturn();
204 } // expected-warning {{non-void function does not return a value}}
205 
testStaticallySkppedLogicalAndBranch()206 int testStaticallySkppedLogicalAndBranch() {
207   false && NoReturn();
208 } // expected-warning {{non-void function does not return a value}}
209 
testConditionallyExecutedComplexLogicalBranch(bool 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}}
213 
testConditionallyExecutedComplexLogicalBranch2(bool value)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}}
217 
testConditionallyExecutedComplexLogicalBranch3(bool value)218 int testConditionallyExecutedComplexLogicalBranch3(bool value) {
219   (false && (Return() || true)) || (true && NoReturn());
220 }
221 
testConditionallyExecutedComplexLogicalBranch4(bool value)222 int testConditionallyExecutedComplexLogicalBranch4(bool value) {
223   false || ((Return() || true) && (true && NoReturn()));
224 }
225 
226 #if __cplusplus >= 201103L
227 namespace LambdaVsTemporaryDtor {
228   struct Y { ~Y(); };
XLambdaVsTemporaryDtor::X229   struct X { template<typename T> X(T, Y = Y()) {} };
230 
231   struct Fatal { ~Fatal() __attribute__((noreturn)); };
232   struct FatalCopy { FatalCopy(); FatalCopy(const FatalCopy&, Fatal F = Fatal()); };
233 
234   void foo();
235 
bar()236   int bar() {
237     X work([](){ Fatal(); });
238     foo();
239   } // expected-warning {{non-void function does not return a value}}
240 
baz()241   int baz() {
242     FatalCopy fc;
243     X work([fc](){});
244     foo();
245   } // ok, initialization of lambda does not return
246 }
247 #endif
248 
249 // Ensure that function-try-blocks also check for return values properly.
functionTryBlock1(int s)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}}
254 
functionTryBlock2(int s)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}}
259 
functionTryBlock3(int s)260 int functionTryBlock3(int s) try {
261   return 0;
262 } catch (...) {
263   return 0;
264 } // ok, both paths return.
265