1 /*
2  * Cppcheck - A tool for static C/C++ code analysis
3  * Copyright (C) 2007-2021 Cppcheck team.
4  *
5  * This program is free software: you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation, either version 3 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
17  */
18 
19 
20 #include "checkautovariables.h"
21 #include "settings.h"
22 #include "testsuite.h"
23 #include "tokenize.h"
24 
25 
26 class TestAutoVariables : public TestFixture {
27 public:
TestAutoVariables()28     TestAutoVariables() : TestFixture("TestAutoVariables") {}
29 
30 private:
31     Settings settings;
32 
check(const char code[],bool inconclusive=false,const char * filename="test.cpp")33     void check(const char code[], bool inconclusive = false, const char* filename = "test.cpp") {
34         // Clear the error buffer..
35         errout.str("");
36 
37         settings.certainty.setEnabled(Certainty::inconclusive, inconclusive);
38 
39         // Tokenize..
40         Tokenizer tokenizer(&settings, this);
41         std::istringstream istr(code);
42         tokenizer.tokenize(istr, filename);
43 
44         CheckAutoVariables checkAutoVariables;
45         checkAutoVariables.runChecks(&tokenizer, &settings, this);
46     }
47 
run()48     void run() OVERRIDE {
49         settings.severity.enable(Severity::warning);
50         settings.severity.enable(Severity::style);
51         LOAD_LIB_2(settings.library, "std.cfg");
52         LOAD_LIB_2(settings.library, "qt.cfg");
53 
54         TEST_CASE(testautovar1);
55         TEST_CASE(testautovar2);
56         TEST_CASE(testautovar3); // ticket #2925
57         TEST_CASE(testautovar4); // ticket #2928
58         TEST_CASE(testautovar5); // ticket #2926
59         TEST_CASE(testautovar6); // ticket #2931
60         TEST_CASE(testautovar7); // ticket #3066
61         TEST_CASE(testautovar8);
62         TEST_CASE(testautovar9);
63         TEST_CASE(testautovar10); // ticket #2930 - void f(char *p) { p = '\0'; }
64         TEST_CASE(testautovar11); // ticket #4641 - fp, assign local struct member address to function parameter
65         TEST_CASE(testautovar12); // ticket #5024 - crash
66         TEST_CASE(testautovar13); // ticket #5537 - crash
67         TEST_CASE(testautovar14); // ticket #4776 - assignment of function parameter, goto
68         TEST_CASE(testautovar15); // ticket #6538
69         TEST_CASE(testautovar16); // ticket #8114
70         TEST_CASE(testautovar_array1);
71         TEST_CASE(testautovar_array2);
72         TEST_CASE(testautovar_normal); // "normal" token list that does not remove casts etc
73         TEST_CASE(testautovar_ptrptr); // ticket #6956
74         TEST_CASE(testautovar_return1);
75         TEST_CASE(testautovar_return2);
76         TEST_CASE(testautovar_return3);
77         TEST_CASE(testautovar_return4);
78         TEST_CASE(testautovar_extern);
79         TEST_CASE(testautovar_reassigned);
80         TEST_CASE(testinvaliddealloc);
81         TEST_CASE(testinvaliddealloc_C);
82         TEST_CASE(testassign1);  // Ticket #1819
83         TEST_CASE(testassign2);  // Ticket #2765
84 
85         TEST_CASE(assignAddressOfLocalArrayToGlobalPointer);
86         TEST_CASE(assignAddressOfLocalVariableToGlobalPointer);
87         TEST_CASE(assignAddressOfLocalVariableToMemberVariable);
88 
89         TEST_CASE(returnLocalVariable1);
90         TEST_CASE(returnLocalVariable2);
91         TEST_CASE(returnLocalVariable3); // &x[0]
92         TEST_CASE(returnLocalVariable4); // x+y
93         TEST_CASE(returnLocalVariable5); // cast
94         TEST_CASE(returnLocalVariable6); // valueflow
95 
96         // return reference..
97         TEST_CASE(returnReference1);
98         TEST_CASE(returnReference2);
99         TEST_CASE(returnReference3);
100         TEST_CASE(returnReference4);
101         TEST_CASE(returnReference5);
102         TEST_CASE(returnReference6);
103         TEST_CASE(returnReference7);
104         TEST_CASE(returnReference8);
105         TEST_CASE(returnReference9);
106         TEST_CASE(returnReference10);
107         TEST_CASE(returnReference11);
108         TEST_CASE(returnReference12);
109         TEST_CASE(returnReference13);
110         TEST_CASE(returnReference14);
111         TEST_CASE(returnReference15); // #9432
112         TEST_CASE(returnReference16); // #9433
113         TEST_CASE(returnReference16); // #9433
114         TEST_CASE(returnReference17); // #9461
115         TEST_CASE(returnReference18); // #9482
116         TEST_CASE(returnReference19); // #9597
117         TEST_CASE(returnReference20); // #9536
118         TEST_CASE(returnReference21); // #9530
119         TEST_CASE(returnReference22);
120         TEST_CASE(returnReference23);
121         TEST_CASE(returnReferenceFunction);
122         TEST_CASE(returnReferenceContainer);
123         TEST_CASE(returnReferenceLiteral);
124         TEST_CASE(returnReferenceCalculation);
125         TEST_CASE(returnReferenceLambda);
126         TEST_CASE(returnReferenceInnerScope);
127         TEST_CASE(returnReferenceRecursive);
128         TEST_CASE(extendedLifetime);
129 
130         TEST_CASE(danglingReference);
131         TEST_CASE(danglingTempReference);
132 
133         // global namespace
134         TEST_CASE(testglobalnamespace);
135 
136         TEST_CASE(returnParameterAddress);
137 
138         TEST_CASE(testconstructor); // ticket #5478 - crash
139 
140         TEST_CASE(variableIsUsedInScope); // ticket #5599 crash in variableIsUsedInScope()
141 
142         TEST_CASE(danglingLifetimeLambda);
143         TEST_CASE(danglingLifetimeContainer);
144         TEST_CASE(danglingLifetime);
145         TEST_CASE(danglingLifetimeFunction);
146         TEST_CASE(danglingLifetimeAggegrateConstructor);
147         TEST_CASE(danglingLifetimeInitList);
148         TEST_CASE(danglingLifetimeImplicitConversion);
149         TEST_CASE(danglingTemporaryLifetime);
150         TEST_CASE(invalidLifetime);
151         TEST_CASE(deadPointer);
152         TEST_CASE(splitNamespaceAuto); // crash #10473
153     }
154 
155 
156 
testautovar1()157     void testautovar1() {
158         check("void func1(int **res)\n"
159               "{\n"
160               "    int num = 2;\n"
161               "    *res = &num;\n"
162               "}");
163         ASSERT_EQUALS("[test.cpp:4]: (error) Address of local auto-variable assigned to a function parameter.\n", errout.str());
164 
165         check("void func1(int **res)\n"
166               "{\n"
167               "    int num = 2;\n"
168               "    res = &num;\n"
169               "}");
170         ASSERT_EQUALS("[test.cpp:4]: (warning) Assignment of function parameter has no effect outside the function. Did you forget dereferencing it?\n", errout.str());
171 
172         check("void func1(int **res)\n"
173               "{\n"
174               "    int num = 2;\n"
175               "    foo.res = &num;\n"
176               "}");
177         ASSERT_EQUALS("", errout.str());
178     }
179 
testautovar2()180     void testautovar2() {
181         check("class Fred {\n"
182               "    void func1(int **res);\n"
183               "}\n"
184               "void Fred::func1(int **res)\n"
185               "{\n"
186               "    int num = 2;\n"
187               "    *res = &num;\n"
188               "}");
189         ASSERT_EQUALS("[test.cpp:7]: (error) Address of local auto-variable assigned to a function parameter.\n", errout.str());
190 
191         check("class Fred {\n"
192               "    void func1(int **res);\n"
193               "}\n"
194               "void Fred::func1(int **res)\n"
195               "{\n"
196               "    int num = 2;\n"
197               "    res = &num;\n"
198               "}");
199         ASSERT_EQUALS("[test.cpp:7]: (warning) Assignment of function parameter has no effect outside the function. Did you forget dereferencing it?\n", errout.str());
200 
201         check("class Fred {\n"
202               "    void func1(int **res);\n"
203               "}\n"
204               "void Fred::func1(int **res)\n"
205               "{\n"
206               "    int num = 2;\n"
207               "    foo.res = &num;\n"
208               "}");
209         ASSERT_EQUALS("", errout.str());
210     }
211 
testautovar3()212     void testautovar3() { // ticket #2925
213         check("void foo(int **p)\n"
214               "{\n"
215               "    int x[100];\n"
216               "    *p = x;\n"
217               "}");
218         ASSERT_EQUALS("[test.cpp:4]: (error) Address of local auto-variable assigned to a function parameter.\n", errout.str());
219     }
220 
testautovar4()221     void testautovar4() { // ticket #2928
222         check("void foo(int **p)\n"
223               "{\n"
224               "    static int x[100];\n"
225               "    *p = x;\n"
226               "}");
227         ASSERT_EQUALS("", errout.str());
228     }
229 
testautovar5()230     void testautovar5() { // ticket #2926
231         check("void foo(struct AB *ab)\n"
232               "{\n"
233               "    char a;\n"
234               "    ab->a = &a;\n"
235               "}");
236         ASSERT_EQUALS("[test.cpp:4]: (error) Address of local auto-variable assigned to a function parameter.\n", errout.str());
237     }
238 
testautovar6()239     void testautovar6() { // ticket #2931
240         check("void foo(struct X *x)\n"
241               "{\n"
242               "    char a[10];\n"
243               "    x->str = a;\n"
244               "}", false);
245         ASSERT_EQUALS("", errout.str());
246 
247         check("void foo(struct X *x)\n"
248               "{\n"
249               "    char a[10];\n"
250               "    x->str = a;\n"
251               "}", true);
252         ASSERT_EQUALS("[test.cpp:4]: (error, inconclusive) Address of local auto-variable assigned to a function parameter.\n", errout.str());
253     }
254 
testautovar7()255     void testautovar7() { // ticket #3066
256         check("struct txt_scrollpane_s * TXT_NewScrollPane(struct txt_widget_s * target)\n"
257               "{\n"
258               "    struct txt_scrollpane_s * scrollpane;\n"
259               "    target->parent = &scrollpane->widget;\n"
260               "    return scrollpane;\n"
261               "}", false);
262         ASSERT_EQUALS("", errout.str());
263     }
264 
testautovar8()265     void testautovar8() {
266         check("void foo(int*& p) {\n"
267               "    int i = 0;\n"
268               "    p = &i;\n"
269               "}", false);
270         ASSERT_EQUALS("[test.cpp:3]: (error) Address of local auto-variable assigned to a function parameter.\n", errout.str());
271 
272         check("void foo(std::string& s) {\n"
273               "    s = foo;\n"
274               "}", false);
275         ASSERT_EQUALS("", errout.str());
276     }
277 
testautovar9()278     void testautovar9() {
279         check("struct FN {int i;};\n"
280               "struct FP {FN* f};\n"
281               "void foo(int*& p, FN* p_fp) {\n"
282               "    FN fn;\n"
283               "    FP fp;\n"
284               "    p = &fn.i;\n"
285               "}", false);
286         ASSERT_EQUALS("[test.cpp:6]: (error) Address of local auto-variable assigned to a function parameter.\n", errout.str());
287 
288         check("struct FN {int i;};\n"
289               "struct FP {FN* f};\n"
290               "void foo(int*& p, FN* p_fp) {\n"
291               "    FN fn;\n"
292               "    FP fp;\n"
293               "    p = &p_fp->i;\n"
294               "}", false);
295         ASSERT_EQUALS("", errout.str());
296 
297         check("struct FN {int i;};\n"
298               "struct FP {FN* f};\n"
299               "void foo(int*& p, FN* p_fp) {\n"
300               "    FN fn;\n"
301               "    FP fp;\n"
302               "    p = &fp.f->i;\n"
303               "}", false);
304         ASSERT_EQUALS("", errout.str());
305     }
306 
testautovar10()307     void testautovar10() { // #2930 - assignment of function parameter
308         check("void foo(char* p) {\n"
309               "    p = 0;\n"
310               "}");
311         ASSERT_EQUALS("[test.cpp:2]: (warning) Assignment of function parameter has no effect outside the function. Did you forget dereferencing it?\n", errout.str());
312 
313         check("void foo(int b) {\n"
314               "    b = foo(b);\n"
315               "}");
316         ASSERT_EQUALS("[test.cpp:2]: (style) Assignment of function parameter has no effect outside the function.\n", errout.str());
317 
318         check("void foo(int b) {\n"
319               "    b += 1;\n"
320               "}");
321         ASSERT_EQUALS("[test.cpp:2]: (style) Assignment of function parameter has no effect outside the function.\n", errout.str());
322 
323         check("void foo(std::string s) {\n"
324               "    s = foo(b);\n"
325               "}");
326         ASSERT_EQUALS("[test.cpp:2]: (style) Assignment of function parameter has no effect outside the function.\n", errout.str());
327 
328         check("void foo(char* p) {\n" // don't warn for self assignment, there is another warning for this
329               "  p = p;\n"
330               "}");
331         ASSERT_EQUALS("", errout.str());
332 
333         check("void foo(char* p) {\n"
334               "    if (!p) p = buf;\n"
335               "    *p = 0;\n"
336               "}");
337         ASSERT_EQUALS("", errout.str());
338 
339         check("void foo(char* p) {\n"
340               "    if (!p) p = buf;\n"
341               "    do_something(p);\n"
342               "}");
343         ASSERT_EQUALS("", errout.str());
344 
345         check("void foo(char* p) {\n"
346               "    while (!p) p = buf;\n"
347               "}");
348         ASSERT_EQUALS("", errout.str());
349 
350         check("void foo(char* p) {\n"
351               "    p = 0;\n"
352               "    asm(\"somecmd\");\n"
353               "}");
354         ASSERT_EQUALS("", errout.str());
355 
356         check("void foo(Foo* p) {\n"
357               "    p = 0;\n"
358               "}");
359         ASSERT_EQUALS("[test.cpp:2]: (warning) Assignment of function parameter has no effect outside the function. Did you forget dereferencing it?\n", errout.str());
360 
361         check("class Foo {};\n"
362               "void foo(Foo p) {\n"
363               "    p = 0;\n"
364               "}");
365         ASSERT_EQUALS("[test.cpp:3]: (style) Assignment of function parameter has no effect outside the function.\n", errout.str());
366 
367         check("void foo(Foo p) {\n"
368               "    p = 0;\n"
369               "}");
370         ASSERT_EQUALS("", errout.str());
371 
372         check("void foo(int& p) {\n"
373               "    p = 0;\n"
374               "}");
375         ASSERT_EQUALS("", errout.str());
376 
377         check("double foo(double d) {\n" // #5005
378               "    int i = d;\n"
379               "    d = i;\n"
380               "    return d;"
381               "}",false);
382         ASSERT_EQUALS("", errout.str());
383 
384         check("void foo(int* ptr) {\n" // #4793
385               "    ptr++;\n"
386               "}");
387         ASSERT_EQUALS("[test.cpp:2]: (warning) Assignment of function parameter has no effect outside the function. Did you forget dereferencing it?\n", errout.str());
388 
389         check("void foo(int* ptr) {\n" // #3177
390               "    --ptr;\n"
391               "}");
392         ASSERT_EQUALS("[test.cpp:2]: (warning) Assignment of function parameter has no effect outside the function. Did you forget dereferencing it?\n", errout.str());
393 
394         check("void foo(struct S* const x) {\n" // #7839
395               "    ++x->n;\n"
396               "}");
397         ASSERT_EQUALS("", errout.str());
398     }
399 
testautovar11()400     void testautovar11() { // #4641 - fp, assign local struct member address to function parameter
401         check("struct A {\n"
402               "    char (*data)[10];\n"
403               "};\n"
404               "void foo(char** p) {\n"
405               "    struct A a = bar();\n"
406               "    *p = &(*a.data)[0];\n"
407               "}");
408         ASSERT_EQUALS("", errout.str());
409 
410         check("struct A {\n"
411               "    char data[10];\n"
412               "};\n"
413               "void foo(char** p) {\n"
414               "    struct A a = bar();\n"
415               "    *p = &a.data[0];\n"
416               "}");
417         ASSERT_EQUALS("[test.cpp:6]: (error) Address of local auto-variable assigned to a function parameter.\n", errout.str());
418 
419         check("void f(char **out) {\n"
420               "  struct S *p = glob;\n"
421               "  *out = &p->data;\n"
422               "}");
423         ASSERT_EQUALS("", errout.str());
424 
425         // #4998
426         check("void f(s8**out) {\n"
427               "  s8 *p;\n"  // <- p is pointer => no error
428               "  *out = &p[1];\n"
429               "}");
430         ASSERT_EQUALS("", errout.str());
431 
432         check("void f(s8**out) {\n"
433               "  s8 p[10];\n"  // <- p is array => error
434               "  *out = &p[1];\n"
435               "}");
436         ASSERT_EQUALS("[test.cpp:3]: (error) Address of local auto-variable assigned to a function parameter.\n", errout.str());
437     }
438 
testautovar12()439     void testautovar12() { // Ticket #5024, #5050 - Crash on invalid input
440         ASSERT_THROW(check("void f(int* a) { a = }"), InternalError);
441         check("struct custom_type { custom_type(int) {} };\n"
442               "void func(int) {}\n"
443               "int var;\n"
444               "void init() { func(var); }\n"
445               "UNKNOWN_MACRO_EXPANDING_TO_SIGNATURE { custom_type a(var); }");
446     }
447 
testautovar13()448     void testautovar13() { // Ticket #5537
449         check("class FileManager {\n"
450               "  FileManager() : UniqueRealDirs(*new UniqueDirContainer())\n"
451               "  {}\n"
452               "  ~FileManager() {\n"
453               "    delete &UniqueRealDirs;\n"
454               "   }\n"
455               "};");
456     }
457 
testautovar14()458     void testautovar14() { // Ticket #4776
459         check("void f(int x) {\n"
460               "label:"
461               "  if (x>0) {\n"
462               "    x = x >> 1;\n"
463               "    goto label;\n"
464               "  }\n"
465               "}");
466         ASSERT_EQUALS("", errout.str());
467     }
468 
testautovar15()469     void testautovar15() { // Ticket #6538
470         check("static const float4  darkOutline(0.05f, 0.05f, 0.05f, 0.95f);\n"
471               "static const float darkLuminosity = 0.05 +\n"
472               "                                    0.0722f * math::powf(darkOutline[2], 2.2);\n"
473               "const float4* ChooseOutlineColor(const float4& textColor)  {\n"
474               "    const float lumdiff = something;\n"
475               "    if (lumdiff > 5.0f)\n"
476               "        return &darkOutline;\n"
477               "    return 0;\n"
478               "}", false);
479         ASSERT_EQUALS("", errout.str());
480     }
481 
testautovar16()482     void testautovar16() { // Ticket #8114
483         check("void f(const void* ptr, bool* result) {\n"
484               "  int dummy;\n"
485               "  *result = (&dummy < ptr);\n"
486               "}");
487         ASSERT_EQUALS("", errout.str());
488     }
489 
testautovar_array1()490     void testautovar_array1() {
491         check("void func1(int* arr[2])\n"
492               "{\n"
493               "    int num=2;"
494               "    arr[0]=&num;\n"
495               "}");
496         ASSERT_EQUALS("[test.cpp:3]: (error) Address of local auto-variable assigned to a function parameter.\n", errout.str());
497     }
498 
testautovar_array2()499     void testautovar_array2() {
500         check("class Fred {\n"
501               "    void func1(int* arr[2]);\n"
502               "}\n"
503               "void Fred::func1(int* arr[2])\n"
504               "{\n"
505               "    int num=2;"
506               "    arr[0]=&num;\n"
507               "}");
508         ASSERT_EQUALS("[test.cpp:6]: (error) Address of local auto-variable assigned to a function parameter.\n", errout.str());
509     }
510 
testautovar_normal()511     void testautovar_normal() {
512         check("void f(XmDestinationCallbackStruct *ds)\n"
513               "{\n"
514               "    XPoint DropPoint;\n"
515               "    ds->location_data = (XtPointer *)&DropPoint;\n"
516               "}");
517         ASSERT_EQUALS("[test.cpp:4]: (error) Address of local auto-variable assigned to a function parameter.\n", errout.str());
518     }
519 
testautovar_ptrptr()520     void testautovar_ptrptr() { // #6596
521         check("void remove_duplicate_matches (char **matches) {\n"
522               "  char dead_slot;\n"
523               "  matches[0] = (char *)&dead_slot;\n"
524               "}");
525         ASSERT_EQUALS("[test.cpp:3]: (error) Address of local auto-variable assigned to a function parameter.\n", errout.str());
526     }
527 
testautovar_return1()528     void testautovar_return1() {
529         check("int* func1()\n"
530               "{\n"
531               "    int num=2;"
532               "    return &num;"
533               "}");
534         ASSERT_EQUALS("[test.cpp:3] -> [test.cpp:3] -> [test.cpp:3]: (error) Returning pointer to local variable 'num' that will be invalid when returning.\n", errout.str());
535     }
536 
testautovar_return2()537     void testautovar_return2() {
538         check("class Fred {\n"
539               "    int* func1();\n"
540               "}\n"
541               "int* Fred::func1()\n"
542               "{\n"
543               "    int num=2;"
544               "    return &num;"
545               "}");
546         ASSERT_EQUALS("[test.cpp:6] -> [test.cpp:6] -> [test.cpp:6]: (error) Returning pointer to local variable 'num' that will be invalid when returning.\n", errout.str());
547     }
548 
testautovar_return3()549     void testautovar_return3() {
550         // #2975 - FP
551         check("void** f()\n"
552               "{\n"
553               "    void *&value = tls[id];"
554               "    return &value;"
555               "}");
556         ASSERT_EQUALS("", errout.str());
557     }
558 
testautovar_return4()559     void testautovar_return4() {
560         // #8058 - FP ignore return in lambda
561         check("void foo() {\n"
562               "  int cond2;\n"
563               "  dostuff([&cond2]() { return &cond2; });\n"
564               "}");
565         ASSERT_EQUALS("", errout.str());
566     }
567 
testautovar_extern()568     void testautovar_extern() {
569         check("struct foo *f()\n"
570               "{\n"
571               "    extern struct foo f;\n"
572               "    return &f;\n"
573               "}");
574         ASSERT_EQUALS("", errout.str());
575     }
576 
testautovar_reassigned()577     void testautovar_reassigned() {
578         check("void foo(cb* pcb) {\n"
579               "  int root0;\n"
580               "  pcb->root0 = &root0;\n"
581               "  dostuff(pcb);\n"
582               "  pcb->root0 = 0;\n"
583               "}");
584         ASSERT_EQUALS("", errout.str());
585 
586         check("void foo(cb* pcb) {\n"
587               "  int root0;\n"
588               "  pcb->root0 = &root0;\n"
589               "  dostuff(pcb);\n"
590               "  if (condition) return;\n" // <- not reassigned => error
591               "  pcb->root0 = 0;\n"
592               "}");
593         ASSERT_EQUALS("[test.cpp:3]: (error) Address of local auto-variable assigned to a function parameter.\n", errout.str());
594 
595         check("void foo(cb* pcb) {\n"
596               "  int root0;\n"
597               "  pcb->root0 = &root0;\n"
598               "  dostuff(pcb);\n"
599               "  if (condition)\n"
600               "    pcb->root0 = 0;\n"  // <- conditional reassign => error
601               "}");
602         ASSERT_EQUALS("[test.cpp:3]: (error) Address of local auto-variable assigned to a function parameter.\n", errout.str());
603     }
604 
testinvaliddealloc()605     void testinvaliddealloc() {
606         check("void func1() {\n"
607               "    char tmp1[256];\n"
608               "    free(tmp1);\n"
609               "    char tmp2[256];\n"
610               "    delete tmp2;\n"
611               "    char tmp3[256];\n"
612               "    delete tmp3;\n"
613               "    char tmp4[256];\n"
614               "    delete[] (tmp4);\n"
615               "    char tmp5[256];\n"
616               "    delete[] tmp5;\n"
617               "}");
618         ASSERT_EQUALS("[test.cpp:3]: (error) Deallocation of an auto-variable results in undefined behaviour.\n"
619                       "[test.cpp:5]: (error) Deallocation of an auto-variable results in undefined behaviour.\n"
620                       "[test.cpp:7]: (error) Deallocation of an auto-variable results in undefined behaviour.\n"
621                       "[test.cpp:9]: (error) Deallocation of an auto-variable results in undefined behaviour.\n"
622                       "[test.cpp:11]: (error) Deallocation of an auto-variable results in undefined behaviour.\n", errout.str());
623 
624         check("void func1() {\n"
625               "    char* tmp1[256];\n"
626               "    init(tmp1);\n"
627               "    delete tmp1[34];\n"
628               "}");
629         ASSERT_EQUALS("", errout.str());
630 
631         check("void func1() {\n"
632               "    static char tmp1[256];\n"
633               "    char *p = tmp1;\n"
634               "    free(p);\n"
635               "}");
636         ASSERT_EQUALS("[test.cpp:4]: (error) Deallocation of an static variable (tmp1) results in undefined behaviour.\n", errout.str());
637 
638         check("char tmp1[256];\n"
639               "void func1() {\n"
640               "    char *p; if (x) p = tmp1;\n"
641               "    free(p);\n"
642               "}");
643         ASSERT_EQUALS("[test.cpp:4]: (error) Deallocation of an global variable (tmp1) results in undefined behaviour.\n", errout.str());
644 
645         check("void f()\n"
646               "{\n"
647               "    char psz_title[10];\n"
648               "    {\n"
649               "        char *psz_title = 0;\n"
650               "        abc(0, psz_title);\n"
651               "        free(psz_title);\n"
652               "    }\n"
653               "}");
654         ASSERT_EQUALS("", errout.str());
655 
656         // #2298 new check: passing stack-address to free()
657         check("int main() {\n"
658               "   int *p = malloc(4);\n"
659               "   free(&p);\n"
660               "   return 0;\n"
661               "}");
662         ASSERT_EQUALS("[test.cpp:3]: (error) Deallocation of an auto-variable results in undefined behaviour.\n", errout.str());
663         check("int main() {\n"
664               "   int i;\n"
665               "   free(&i);\n"
666               "   return 0;\n"
667               "}");
668         ASSERT_EQUALS("[test.cpp:3]: (error) Deallocation of an auto-variable results in undefined behaviour.\n", errout.str());
669 
670         // #5732
671         check("int main() {\n"
672               "   long (*pKoeff)[256] = new long[9][256];\n"
673               "   delete[] pKoeff;\n"
674               "}");
675         ASSERT_EQUALS("", errout.str());
676 
677         check("int main() {\n"
678               "   long *pKoeff[256];\n"
679               "   delete[] pKoeff;\n"
680               "}");
681         ASSERT_EQUALS("[test.cpp:3]: (error) Deallocation of an auto-variable results in undefined behaviour.\n", errout.str());
682 
683         check("int main() {\n"
684               "   long *pKoeff[256];\n"
685               "   free (pKoeff);\n"
686               "}");
687         ASSERT_EQUALS("[test.cpp:3]: (error) Deallocation of an auto-variable results in undefined behaviour.\n", errout.str());
688 
689         check("void foo() {\n"
690               "   const intPtr& intref = Getter();\n"
691               "   delete intref;\n"
692               "}");
693         ASSERT_EQUALS("", errout.str());
694 
695         check("void test() {\n"
696               "   MyObj& obj = *new MyObj;\n"
697               "   delete &obj;\n"
698               "}");
699         ASSERT_EQUALS("", errout.str());
700 
701         // #6506
702         check("struct F {\n"
703               "  void free(void*) {}\n"
704               "};\n"
705               "void foo() {\n"
706               "  char c1[1];\n"
707               "  F().free(c1);\n"
708               "  char *c2 = 0;\n"
709               "  F().free(&c2);\n"
710               "}");
711         ASSERT_EQUALS("", errout.str());
712 
713         check("class foo {\n"
714               "  void free(void* );\n"
715               "  void someMethod() {\n"
716               "    char **dst_copy = NULL;\n"
717               "    free(&dst_copy);\n"
718               "  }\n"
719               "};");
720         ASSERT_EQUALS("", errout.str());
721 
722         // #6551
723         check("bool foo( ) {\n"
724               "  SwTxtFld * pTxtFld = GetFldTxtAttrAt();\n"
725               "  delete static_cast<SwFmtFld*>(&pTxtFld->GetAttr());\n"
726               "}");
727         ASSERT_EQUALS("", errout.str());
728 
729         // #8910
730         check("void f() {\n"
731               "    char stack[512];\n"
732               "    RGNDATA *data;\n"
733               "    if (data_size > sizeof (stack)) data = malloc (data_size);\n"
734               "    else data = (RGNDATA *)stack;\n"
735               "    if ((char *)data != stack) free (data);\n"
736               "}");
737         ASSERT_EQUALS("", errout.str());
738 
739         // #8923
740         check("void f(char **args1, char *args2[]) {\n"
741               "    free((char **)args1);\n"
742               "    free((char **)args2);\n"
743               "}");
744         ASSERT_EQUALS("", errout.str());
745     }
746 
testinvaliddealloc_C()747     void testinvaliddealloc_C() {
748         // #5691
749         check("void svn_repos_dir_delta2() {\n"
750               "  struct context c;\n"
751               "      SVN_ERR(delete(&c, root_baton, src_entry, pool));\n"
752               "}\n", false, "test.c");
753         ASSERT_EQUALS("", errout.str());
754     }
755 
testassign1()756     void testassign1() { // Ticket #1819
757         check("void f(EventPtr *eventP, ActionPtr **actionsP) {\n"
758               "    EventPtr event = *eventP;\n"
759               "    *actionsP = &event->actions;\n"
760               "}");
761         ASSERT_EQUALS("", errout.str());
762     }
763 
testassign2()764     void testassign2() { // Ticket #2765
765         check("static void function(unsigned long **datap) {\n"
766               "    struct my_s *mr = global_structure_pointer;\n"
767               "    *datap = &mr->value;\n"
768               "}");
769         ASSERT_EQUALS("", errout.str());
770     }
771 
assignAddressOfLocalArrayToGlobalPointer()772     void assignAddressOfLocalArrayToGlobalPointer() {
773         check("int *p;\n"
774               "void f() {\n"
775               "  int x[10];\n"
776               "  p = x;\n"
777               "}");
778         ASSERT_EQUALS("[test.cpp:4] -> [test.cpp:3] -> [test.cpp:4]: (error) Non-local variable 'p' will use pointer to local variable 'x'.\n", errout.str());
779 
780         check("int *p;\n"
781               "void f() {\n"
782               "  int x[10];\n"
783               "  p = x;\n"
784               "  p = 0;\n"
785               "}");
786         ASSERT_EQUALS("", errout.str());
787     }
788 
assignAddressOfLocalVariableToGlobalPointer()789     void assignAddressOfLocalVariableToGlobalPointer() {
790         check("int *p;\n"
791               "void f() {\n"
792               "  int x;\n"
793               "  p = &x;\n"
794               "}");
795         ASSERT_EQUALS("[test.cpp:4] -> [test.cpp:3] -> [test.cpp:4]: (error) Non-local variable 'p' will use pointer to local variable 'x'.\n", errout.str());
796 
797         check("int *p;\n"
798               "void f() {\n"
799               "  int x;\n"
800               "  p = &x;\n"
801               "  p = 0;\n"
802               "}");
803         ASSERT_EQUALS("", errout.str());
804     }
805 
assignAddressOfLocalVariableToMemberVariable()806     void assignAddressOfLocalVariableToMemberVariable() {
807         check("struct A {\n"
808               "  void f() {\n"
809               "    int x;\n"
810               "    ptr = &x;\n"
811               "  }\n"
812               "  int *ptr;\n"
813               "};");
814         ASSERT_EQUALS("[test.cpp:4] -> [test.cpp:3] -> [test.cpp:4]: (error) Non-local variable 'ptr' will use pointer to local variable 'x'.\n", errout.str());
815 
816         check("struct A {\n"
817               "  void f() {\n"
818               "    int x;\n"
819               "    ptr = &x;\n"
820               "    ptr = 0;\n"
821               "  }\n"
822               "  int *ptr;\n"
823               "};");
824         ASSERT_EQUALS("", errout.str());
825     }
826 
returnLocalVariable1()827     void returnLocalVariable1() {
828         check("char *foo()\n"
829               "{\n"
830               "    char str[100] = {0};\n"
831               "    return str;\n"
832               "}");
833         ASSERT_EQUALS(
834             "[test.cpp:4] -> [test.cpp:3] -> [test.cpp:4]: (error) Returning pointer to local variable 'str' that will be invalid when returning.\n",
835             errout.str());
836 
837         check("char *foo()\n" // use ValueFlow
838               "{\n"
839               "    char str[100] = {0};\n"
840               "    char *p = str;\n"
841               "    return p;\n"
842               "}");
843         ASSERT_EQUALS(
844             "[test.cpp:4] -> [test.cpp:3] -> [test.cpp:5]: (error) Returning pointer to local variable 'str' that will be invalid when returning.\n",
845             errout.str());
846 
847         check("class Fred {\n"
848               "    char *foo();\n"
849               "};\n"
850               "char *Fred::foo()\n"
851               "{\n"
852               "    char str[100] = {0};\n"
853               "    return str;\n"
854               "}");
855         ASSERT_EQUALS(
856             "[test.cpp:7] -> [test.cpp:6] -> [test.cpp:7]: (error) Returning pointer to local variable 'str' that will be invalid when returning.\n",
857             errout.str());
858 
859         check("char * format_reg(char *outbuffer_start) {\n"
860               "    return outbuffer_start;\n"
861               "}\n"
862               "void print_with_operands() {\n"
863               "    char temp[42];\n"
864               "    char *tp = temp;\n"
865               "    tp = format_reg(tp);\n"
866               "}");
867         ASSERT_EQUALS("", errout.str());
868     }
869 
returnLocalVariable2()870     void returnLocalVariable2() {
871         check("std::string foo()\n"
872               "{\n"
873               "    char str[100] = {0};\n"
874               "    return str;\n"
875               "}");
876         ASSERT_EQUALS("", errout.str());
877 
878         check("class Fred {\n"
879               "    std::string foo();\n"
880               "};\n"
881               "std::string Fred::foo()\n"
882               "{\n"
883               "    char str[100] = {0};\n"
884               "    return str;\n"
885               "}");
886         ASSERT_EQUALS("", errout.str());
887     }
888 
889 
returnLocalVariable3()890     void returnLocalVariable3() { // &x[..]
891         // #3030
892         check("char *foo() {\n"
893               "    char q[] = \"AAAAAAAAAAAA\";\n"
894               "    return &q[1];\n"
895               "}");
896         ASSERT_EQUALS("[test.cpp:3] -> [test.cpp:2] -> [test.cpp:3]: (error) Returning pointer to local variable 'q' that will be invalid when returning.\n", errout.str());
897 
898         check("char *foo()\n"
899               "{\n"
900               "    static char q[] = \"AAAAAAAAAAAA\";\n"
901               "    return &q[1];\n"
902               "}");
903         ASSERT_EQUALS("", errout.str());
904 
905         check("char *foo()\n"
906               "{\n"
907               "char q[] = \"AAAAAAAAAAAA\";\n"
908               "char *p;\n"
909               "p = &q[1];\n"
910               "return p;\n"
911               "}");
912         ASSERT_EQUALS("[test.cpp:5] -> [test.cpp:3] -> [test.cpp:6]: (error) Returning pointer to local variable 'q' that will be invalid when returning.\n", errout.str());
913     }
914 
returnLocalVariable4()915     void returnLocalVariable4() { // x+y
916         check("char *foo() {\n"
917               "    char x[10] = {0};\n"
918               "    return x+5;\n"
919               "}");
920         ASSERT_EQUALS(
921             "[test.cpp:3] -> [test.cpp:2] -> [test.cpp:3]: (error) Returning pointer to local variable 'x' that will be invalid when returning.\n",
922             errout.str());
923 
924         check("char *foo(int y) {\n"
925               "    char x[10] = {0};\n"
926               "    return (x+8)-y;\n"
927               "}");
928         ASSERT_EQUALS(
929             "[test.cpp:3] -> [test.cpp:2] -> [test.cpp:3]: (error) Returning pointer to local variable 'x' that will be invalid when returning.\n",
930             errout.str());
931     }
932 
returnLocalVariable5()933     void returnLocalVariable5() { // cast
934         check("char *foo() {\n"
935               "    int x[10] = {0};\n"
936               "    return (char *)x;\n"
937               "}");
938         ASSERT_EQUALS(
939             "[test.cpp:3] -> [test.cpp:2] -> [test.cpp:3]: (error) Returning pointer to local variable 'x' that will be invalid when returning.\n",
940             errout.str());
941     }
942 
returnLocalVariable6()943     void returnLocalVariable6() { // valueflow
944         check("int *foo() {\n"
945               "    int x = 123;\n"
946               "    int p = &x;\n"
947               "    return p;\n"
948               "}");
949         ASSERT_EQUALS("[test.cpp:3] -> [test.cpp:2] -> [test.cpp:4]: (error) Returning object that points to local variable 'x' that will be invalid when returning.\n", errout.str());
950     }
951 
returnReference1()952     void returnReference1() {
953         check("int &foo()\n"
954               "{\n"
955               "    int s = 0;\n"
956               "    int& x = s;\n"
957               "    return x;\n"
958               "}");
959         ASSERT_EQUALS("[test.cpp:4] -> [test.cpp:5]: (error) Reference to local variable returned.\n", errout.str());
960 
961         check("std::string &foo()\n"
962               "{\n"
963               "    std::string s;\n"
964               "    return s;\n"
965               "}");
966         ASSERT_EQUALS("[test.cpp:4]: (error) Reference to local variable returned.\n", errout.str());
967 
968         check("std::vector<int> &foo()\n"
969               "{\n"
970               "    std::vector<int> v;\n"
971               "    return v;\n"
972               "}");
973         ASSERT_EQUALS("[test.cpp:4]: (error) Reference to local variable returned.\n", errout.str());
974 
975         check("std::vector<int> &foo()\n"
976               "{\n"
977               "    static std::vector<int> v;\n"
978               "    return v;\n"
979               "}");
980         ASSERT_EQUALS("", errout.str());
981 
982         check("std::vector<int> &foo()\n"
983               "{\n"
984               "    thread_local std::vector<int> v;\n"
985               "    return v;\n"
986               "}");
987         ASSERT_EQUALS("", errout.str());
988 
989         check("std::string hello()\n"
990               "{\n"
991               "     return \"hello\";\n"
992               "}\n"
993               "\n"
994               "std::string &f()\n"
995               "{\n"
996               "    return hello();\n"
997               "}");
998         ASSERT_EQUALS("[test.cpp:8]: (error) Reference to temporary returned.\n", errout.str());
999 
1000         // make sure scope is used in function lookup
1001         check("class Fred {\n"
1002               "    std::string hello() {\n"
1003               "        return std::string();\n"
1004               "    }\n"
1005               "};\n"
1006               "std::string &f() {\n"
1007               "    return hello();\n"
1008               "}");
1009         ASSERT_EQUALS("", errout.str());
1010 
1011         check("std::string hello() {\n"
1012               "     return std::string();\n"
1013               "}\n"
1014               "\n"
1015               "std::string &f() {\n"
1016               "    return hello();\n"
1017               "}");
1018         ASSERT_EQUALS("[test.cpp:6]: (error) Reference to temporary returned.\n", errout.str());
1019 
1020         check("std::string hello() {\n"
1021               "     return \"foo\";\n"
1022               "}\n"
1023               "\n"
1024               "std::string &f() {\n"
1025               "    return hello().substr(1);\n"
1026               "}");
1027         ASSERT_EQUALS("[test.cpp:6]: (error) Reference to temporary returned.\n", errout.str());
1028 
1029         check("class Foo;\n"
1030               "Foo hello() {\n"
1031               "     return Foo();\n"
1032               "}\n"
1033               "\n"
1034               "Foo& f() {\n"
1035               "    return hello();\n"
1036               "}");
1037         ASSERT_EQUALS("[test.cpp:7]: (error) Reference to temporary returned.\n", errout.str());
1038 
1039         // make sure function overloads are handled properly
1040         check("class Foo;\n"
1041               "Foo & hello(bool) {\n"
1042               "     static Foo foo;\n"
1043               "     return foo;\n"
1044               "}\n"
1045               "Foo hello() {\n"
1046               "     return Foo();\n"
1047               "}\n"
1048               "\n"
1049               "Foo& f() {\n"
1050               "    return hello(true);\n"
1051               "}");
1052         ASSERT_EQUALS("", errout.str());
1053 
1054         check("Foo hello() {\n"
1055               "     return Foo();\n"
1056               "}\n"
1057               "\n"
1058               "Foo& f() {\n" // Unknown type - might be a reference
1059               "    return hello();\n"
1060               "}");
1061         ASSERT_EQUALS("", errout.str());
1062     }
1063 
returnReference2()1064     void returnReference2() {
1065         check("class Fred {\n"
1066               "    std::string &foo();\n"
1067               "}\n"
1068               "std::string &Fred::foo()\n"
1069               "{\n"
1070               "    std::string s;\n"
1071               "    return s;\n"
1072               "}");
1073         ASSERT_EQUALS("[test.cpp:7]: (error) Reference to local variable returned.\n", errout.str());
1074 
1075         check("class Fred {\n"
1076               "    std::vector<int> &foo();\n"
1077               "};\n"
1078               "std::vector<int> &Fred::foo()\n"
1079               "{\n"
1080               "    std::vector<int> v;\n"
1081               "    return v;\n"
1082               "}");
1083         ASSERT_EQUALS("[test.cpp:7]: (error) Reference to local variable returned.\n", errout.str());
1084 
1085         check("class Fred {\n"
1086               "    std::vector<int> &foo();\n"
1087               "};\n"
1088               "std::vector<int> &Fred::foo()\n"
1089               "{\n"
1090               "    static std::vector<int> v;\n"
1091               "    return v;\n"
1092               "}");
1093         ASSERT_EQUALS("", errout.str());
1094 
1095         check("class Fred {\n"
1096               "    std::string &f();\n"
1097               "};\n"
1098               "std::string hello()\n"
1099               "{\n"
1100               "     return \"hello\";\n"
1101               "}\n"
1102               "std::string &Fred::f()\n"
1103               "{\n"
1104               "    return hello();\n"
1105               "}");
1106         ASSERT_EQUALS("[test.cpp:10]: (error) Reference to temporary returned.\n", errout.str());
1107 
1108         check("class Fred {\n"
1109               "    std::string hello();\n"
1110               "    std::string &f();\n"
1111               "};\n"
1112               "std::string Fred::hello()\n"
1113               "{\n"
1114               "     return \"hello\";\n"
1115               "}\n"
1116               "std::string &Fred::f()\n"
1117               "{\n"
1118               "    return hello();\n"
1119               "}");
1120         ASSERT_EQUALS("[test.cpp:11]: (error) Reference to temporary returned.\n", errout.str());
1121 
1122         check("class Bar;\n"
1123               "Bar foo() {\n"
1124               "     return something;\n"
1125               "}\n"
1126               "Bar& bar() {\n"
1127               "    return foo();\n"
1128               "}");
1129         ASSERT_EQUALS("[test.cpp:6]: (error) Reference to temporary returned.\n", errout.str());
1130 
1131         check("std::map<int, string> foo() {\n"
1132               "     return something;\n"
1133               "}\n"
1134               "std::map<int, string>& bar() {\n"
1135               "    return foo();\n"
1136               "}");
1137         ASSERT_EQUALS("[test.cpp:5]: (error) Reference to temporary returned.\n", errout.str());
1138 
1139         check("Bar foo() {\n"
1140               "     return something;\n"
1141               "}\n"
1142               "Bar& bar() {\n" // Unknown type - might be a typedef to a reference type
1143               "    return foo();\n"
1144               "}");
1145         ASSERT_EQUALS("", errout.str());
1146         // Don't crash with function in unknown scope (#4076)
1147         check("X& a::Bar() {}"
1148               "X& foo() {"
1149               "    return Bar();"
1150               "}");
1151     }
1152 
returnReference3()1153     void returnReference3() {
1154         check("double & f(double & rd) {\n"
1155               "    double ret = getValue();\n"
1156               "    rd = ret;\n"
1157               "    return rd;\n"
1158               "}", false);
1159         ASSERT_EQUALS("", errout.str());
1160     }
1161 
1162     // Returning reference to global variable
returnReference4()1163     void returnReference4() {
1164         check("double a;\n"
1165               "double & f() {\n"
1166               "    return a;\n"
1167               "}");
1168         ASSERT_EQUALS("", errout.str());
1169     }
1170 
returnReference5()1171     void returnReference5() {
1172         check("struct A {\n"
1173               "    int i;\n"
1174               "};\n"
1175 
1176               "struct B {\n"
1177               "    A a;\n"
1178               "};\n"
1179 
1180               "struct C {\n"
1181               "    B *b;\n"
1182               "    const A& a() const {\n"
1183               "        const B *pb = b;\n"
1184               "        const A &ra = pb->a;\n"
1185               "        return ra;\n"
1186               "    }\n"
1187               "};");
1188         ASSERT_EQUALS("", errout.str());
1189     }
1190 
returnReference6()1191     void returnReference6() {
1192         check("Fred & create() {\n"
1193               "    Fred &fred(*new Fred);\n"
1194               "    return fred;\n"
1195               "}");
1196         ASSERT_EQUALS("", errout.str());
1197     }
1198 
returnReference7()1199     void returnReference7() {  // 3791 - false positive for overloaded function
1200         check("std::string a();\n"
1201               "std::string &a(int);\n"
1202               "std::string &b() {\n"
1203               "    return a(12);\n"
1204               "}");
1205         ASSERT_EQUALS("", errout.str());
1206 
1207         check("std::string &a(int);\n"
1208               "std::string a();\n"
1209               "std::string &b() {\n"
1210               "    return a(12);\n"
1211               "}");
1212         ASSERT_EQUALS("", errout.str());
1213     }
1214 
returnReference8()1215     void returnReference8() {
1216         check("int& f(std::vector<int> &v) {\n"
1217               "    std::vector<int>::iterator it = v.begin();\n"
1218               "    int& value = *it;\n"
1219               "    return value;\n"
1220               "}");
1221         ASSERT_EQUALS("", errout.str());
1222     }
1223 
returnReference9()1224     void returnReference9() {
1225         check("int& f(bool b, int& x, int& y) {\n"
1226               "    return b ? x : y;\n"
1227               "}");
1228         ASSERT_EQUALS("", errout.str());
1229     }
1230 
returnReference10()1231     void returnReference10() {
1232         check("class A { int f() const; };\n"
1233               "int& g() {\n"
1234               "    A a;\n"
1235               "    return a.f();\n"
1236               "}");
1237         ASSERT_EQUALS("[test.cpp:4]: (error) Reference to temporary returned.\n", errout.str());
1238 
1239         check("class A { int& f() const; };\n"
1240               "int& g() {\n"
1241               "    A a;\n"
1242               "    return a.f();\n"
1243               "}");
1244         ASSERT_EQUALS("", errout.str());
1245     }
1246 
returnReference11()1247     void returnReference11() {
1248         check("class A { static int f(); };\n"
1249               "int& g() {\n"
1250               "    return A::f();\n"
1251               "}");
1252         ASSERT_EQUALS("[test.cpp:3]: (error) Reference to temporary returned.\n", errout.str());
1253 
1254         check("class A { static int& f(); };\n"
1255               "int& g() {\n"
1256               "    return A::f();\n"
1257               "}");
1258         ASSERT_EQUALS("", errout.str());
1259 
1260         check("namespace A { int& f(); }\n"
1261               "int& g() {\n"
1262               "    return A::f();\n"
1263               "}");
1264         ASSERT_EQUALS("", errout.str());
1265     }
1266 
returnReference12()1267     void returnReference12() {
1268         check("class A { static int& f(); };\n"
1269               "auto g() {\n"
1270               "    return &A::f;\n"
1271               "}");
1272         ASSERT_EQUALS("", errout.str());
1273 
1274         check("class A { static int& f(); };\n"
1275               "auto g() {\n"
1276               "    auto x = &A::f;\n"
1277               "    return x;\n"
1278               "}");
1279         ASSERT_EQUALS("", errout.str());
1280     }
1281 
returnReference13()1282     void returnReference13() {
1283         check("std::vector<int> v;\n"
1284               "void* vp = &v;\n"
1285               "int& foo(size_t i) {\n"
1286               "    return ((std::vector<int>*)vp)->at(i);\n"
1287               "}");
1288         ASSERT_EQUALS("", errout.str());
1289 
1290         check("std::vector<int> v;\n"
1291               "void* vp = &v;\n"
1292               "int& foo(size_t i) {\n"
1293               "    return static_cast<std::vector<int>*>(vp)->at(i);\n"
1294               "}");
1295         ASSERT_EQUALS("", errout.str());
1296     }
1297 
returnReference14()1298     void returnReference14() {
1299         check("struct C { void* m; };\n"
1300               "struct A { void* &f(); };\n"
1301               "C* g() {\n"
1302               "    static C c;\n"
1303               "    return &c;\n"
1304               "}\n"
1305               "void* &A::f() {\n"
1306               "    return g()->m;\n"
1307               "}");
1308         ASSERT_EQUALS("", errout.str());
1309     }
1310 
returnReference15()1311     void returnReference15() {
1312         check("template <class T>\n"
1313               "const int& f() {\n"
1314               "    static int s;\n"
1315               "    return s;\n"
1316               "}\n"
1317               "template <class T>\n"
1318               "const int& f(const T&) {\n"
1319               "    return f<T>();\n"
1320               "}");
1321         ASSERT_EQUALS("", errout.str());
1322 
1323         check("template <class T>\n"
1324               "int g();\n"
1325               "template <class T>\n"
1326               "const int& f(const T&) {\n"
1327               "    return g<T>();\n"
1328               "}");
1329         TODO_ASSERT_EQUALS("error", "", errout.str());
1330     }
1331 
returnReference16()1332     void returnReference16() {
1333         check("int& f(std::tuple<int>& x) {\n"
1334               "    return std::get<0>(x);\n"
1335               "}");
1336         ASSERT_EQUALS("", errout.str());
1337 
1338         check("int& f(int x) {\n"
1339               "    return std::get<0>(std::make_tuple(x));\n"
1340               "}");
1341         TODO_ASSERT_EQUALS("error", "", errout.str());
1342     }
1343 
returnReference17()1344     void returnReference17() {
1345         check("auto g() -> int&;\n"
1346               "int& f() {\n"
1347               "    return g();\n"
1348               "}");
1349         ASSERT_EQUALS("", errout.str());
1350     }
1351 
returnReference18()1352     void returnReference18() {
1353         check("template<class T>\n"
1354               "auto f(T& x) -> decltype(x);\n"
1355               "int& g(int* x) {\n"
1356               "    return f(*x);\n"
1357               "}");
1358         ASSERT_EQUALS("", errout.str());
1359     }
1360 
1361     // #9597
returnReference19()1362     void returnReference19() {
1363         check("struct C : B {\n"
1364               "    const B &f() const { return (const B &)*this; }\n"
1365               "}");
1366         ASSERT_EQUALS("", errout.str());
1367     }
1368 
1369     // #9536
returnReference20()1370     void returnReference20() {
1371         check("struct a {\n"
1372               "    int& operator()() const;\n"
1373               "};\n"
1374               "int& b() {\n"
1375               "    return a()();\n"
1376               "}");
1377         ASSERT_EQUALS("", errout.str());
1378 
1379         check("auto a() {\n"
1380               "    return []() -> int& {\n"
1381               "        static int b;\n"
1382               "        return b;\n"
1383               "    };\n"
1384               "}\n"
1385               "const int& c() {\n"
1386               "    return a()();\n"
1387               "}");
1388         ASSERT_EQUALS("", errout.str());
1389 
1390         check("std::function<int&()> a();\n"
1391               "int& b() {\n"
1392               "    return a()();\n"
1393               "}");
1394         ASSERT_EQUALS("", errout.str());
1395 
1396         // #9889
1397         check("int f(std::vector<std::function<int&()>>& v, int i) {\n"
1398               "    auto& j = v[i]();\n"
1399               "    return j;\n"
1400               "}\n");
1401         ASSERT_EQUALS("", errout.str());
1402     }
1403 
1404     // #9530
returnReference21()1405     void returnReference21() {
1406         check("int& f(int& x) {\n"
1407               "    return {x};\n"
1408               "}\n");
1409         ASSERT_EQUALS("", errout.str());
1410     }
1411 
returnReference22()1412     void returnReference22() {
1413         check("int& f() {\n"
1414               "    std::unique_ptr<int> p = std::make_unique<int>(1);\n"
1415               "    return *p;\n"
1416               "}\n");
1417         ASSERT_EQUALS("[test.cpp:3]: (error) Reference to local variable returned.\n", errout.str());
1418 
1419         check("void g(const std::unique_ptr<int>&);\n"
1420               "int& f() {\n"
1421               "    std::unique_ptr<int> p = std::make_unique<int>(1);\n"
1422               "    g(p);\n"
1423               "    return *p;\n"
1424               "}\n");
1425         ASSERT_EQUALS("[test.cpp:5]: (error) Reference to local variable returned.\n", errout.str());
1426 
1427         check("void g(std::shared_ptr<int>);\n"
1428               "int& f() {\n"
1429               "    std::shared_ptr<int> p = std::make_shared<int>(1);\n"
1430               "    g(p);\n"
1431               "    return *p;\n"
1432               "}\n");
1433         ASSERT_EQUALS("", errout.str());
1434 
1435         check("std::shared_ptr<int> g();\n"
1436               "int& f() {\n"
1437               "    return *g();\n"
1438               "}\n");
1439         ASSERT_EQUALS("", errout.str());
1440 
1441         check("std::unique_ptr<int> g();\n"
1442               "int& f() {\n"
1443               "    return *g();\n"
1444               "}\n");
1445         ASSERT_EQUALS("[test.cpp:3]: (error) Reference to temporary returned.\n", errout.str());
1446 
1447         check("struct A { int x; };\n"
1448               "int& f() {\n"
1449               "    std::unique_ptr<A> p = std::make_unique<A>();\n"
1450               "    return p->x;\n"
1451               "}\n");
1452         ASSERT_EQUALS("[test.cpp:4]: (error) Reference to local variable returned.\n", errout.str());
1453     }
1454 
returnReference23()1455     void returnReference23() {
1456         check("const std::vector<int> * g();\n"
1457               "const std::vector<int>& f() {\n"
1458               "    return *g();\n"
1459               "}\n");
1460         ASSERT_EQUALS("", errout.str());
1461     }
1462 
returnReferenceFunction()1463     void returnReferenceFunction() {
1464         check("int& f(int& a) {\n"
1465               "    return a;\n"
1466               "}\n"
1467               "int& hello() {\n"
1468               "    int x = 0;\n"
1469               "    return f(x);\n"
1470               "}");
1471         ASSERT_EQUALS(
1472             "[test.cpp:1] -> [test.cpp:2] -> [test.cpp:6] -> [test.cpp:6]: (error) Reference to local variable returned.\n",
1473             errout.str());
1474 
1475         check("int& f(int& a) {\n"
1476               "    return a;\n"
1477               "}\n"
1478               "int* hello() {\n"
1479               "    int x = 0;\n"
1480               "    return &f(x);\n"
1481               "}");
1482         ASSERT_EQUALS(
1483             "[test.cpp:1] -> [test.cpp:2] -> [test.cpp:6] -> [test.cpp:6] -> [test.cpp:5] -> [test.cpp:6]: (error) Returning pointer to local variable 'x' that will be invalid when returning.\n",
1484             errout.str());
1485 
1486         check("int* f(int * x) {\n"
1487               "    return x;\n"
1488               "}\n"
1489               "int * g(int x) {\n"
1490               "    return f(&x);\n"
1491               "}");
1492         ASSERT_EQUALS("[test.cpp:5] -> [test.cpp:5] -> [test.cpp:4] -> [test.cpp:5]: (error) Returning pointer to local variable 'x' that will be invalid when returning.\n", errout.str());
1493 
1494         check("int* f(int * x) {\n"
1495               "    x = nullptr;\n"
1496               "    return x;\n"
1497               "}\n"
1498               "int * g(int x) {\n"
1499               "    return f(&x);\n"
1500               "}");
1501         ASSERT_EQUALS("", errout.str());
1502 
1503         check("int f(int& a) {\n"
1504               "    return a;\n"
1505               "}\n"
1506               "int& hello() {\n"
1507               "    int x = 0;\n"
1508               "    return f(x);\n"
1509               "}");
1510         ASSERT_EQUALS("[test.cpp:6]: (error) Reference to temporary returned.\n", errout.str());
1511 
1512         check("int& f(int a) {\n"
1513               "    return a;\n"
1514               "}\n"
1515               "int& hello() {\n"
1516               "    int x = 0;\n"
1517               "    return f(x);\n"
1518               "}");
1519         ASSERT_EQUALS("[test.cpp:2]: (error) Reference to local variable returned.\n", errout.str());
1520 
1521         check("int f(int a) {\n"
1522               "    return a;\n"
1523               "}\n"
1524               "int& hello() {\n"
1525               "    int x = 0;\n"
1526               "    return f(x);\n"
1527               "}");
1528         ASSERT_EQUALS("[test.cpp:6]: (error) Reference to temporary returned.\n", errout.str());
1529 
1530         check("template<class T>\n"
1531               "int& f(int& x, T y) {\n"
1532               "    x += y;\n"
1533               "    return x;\n"
1534               "}");
1535         ASSERT_EQUALS("", errout.str());
1536     }
1537 
returnReferenceContainer()1538     void returnReferenceContainer() {
1539         check("auto& f() {\n"
1540               "    std::vector<int> x;\n"
1541               "    return x[0];\n"
1542               "}");
1543         ASSERT_EQUALS("[test.cpp:3]: (error) Reference to local variable returned.\n", errout.str());
1544 
1545         check("auto& f() {\n"
1546               "    std::vector<int> x;\n"
1547               "    return x.front();\n"
1548               "}");
1549         ASSERT_EQUALS("[test.cpp:3] -> [test.cpp:3]: (error) Reference to local variable returned.\n", errout.str());
1550 
1551         check("std::vector<int> g();\n"
1552               "auto& f() {\n"
1553               "    return g().front();\n"
1554               "}");
1555         ASSERT_EQUALS("[test.cpp:3] -> [test.cpp:3]: (error) Reference to temporary returned.\n", errout.str());
1556 
1557         check("auto& f() {\n"
1558               "    return std::vector<int>{1}.front();\n"
1559               "}");
1560         ASSERT_EQUALS("[test.cpp:2] -> [test.cpp:2]: (error) Reference to temporary returned.\n", errout.str());
1561 
1562         check("struct A { int foo; };\n"
1563               "int& f(std::vector<A> v) {\n"
1564               "    auto it = v.begin();\n"
1565               "    return it->foo;\n"
1566               "}");
1567         ASSERT_EQUALS("[test.cpp:3] -> [test.cpp:4]: (error) Reference to local variable returned.\n", errout.str());
1568 
1569         check("template <class T, class K, class V>\n"
1570               "const V& get_default(const T& t, const K& k, const V& v) {\n"
1571               "    auto it = t.find(k);\n"
1572               "    if (it == t.end()) return v;\n"
1573               "    return it->second;\n"
1574               "}\n"
1575               "const int& bar(const std::unordered_map<int, int>& m, int k) {\n"
1576               "    auto x = 0;\n"
1577               "    return get_default(m, k, x);\n"
1578               "}\n",
1579               true);
1580         ASSERT_EQUALS(
1581             "[test.cpp:2] -> [test.cpp:4] -> [test.cpp:9] -> [test.cpp:9]: (error, inconclusive) Reference to local variable returned.\n",
1582             errout.str());
1583 
1584         check("template <class T, class K, class V>\n"
1585               "const V& get_default(const T& t, const K& k, const V& v) {\n"
1586               "    auto it = t.find(k);\n"
1587               "    if (it == t.end()) return v;\n"
1588               "    return it->second;\n"
1589               "}\n"
1590               "const int& bar(const std::unordered_map<int, int>& m, int k) {\n"
1591               "    return get_default(m, k, 0);\n"
1592               "}\n",
1593               true);
1594         ASSERT_EQUALS(
1595             "[test.cpp:2] -> [test.cpp:4] -> [test.cpp:8] -> [test.cpp:8]: (error, inconclusive) Reference to temporary returned.\n",
1596             errout.str());
1597 
1598         check("struct A { int foo; };\n"
1599               "int& f(std::vector<A>& v) {\n"
1600               "    auto it = v.begin();\n"
1601               "    return it->foo;\n"
1602               "}");
1603         ASSERT_EQUALS("", errout.str());
1604     }
1605 
returnReferenceLiteral()1606     void returnReferenceLiteral() {
1607         check("const std::string &a() {\n"
1608               "    return \"foo\";\n"
1609               "}");
1610         ASSERT_EQUALS("[test.cpp:2]: (error) Reference to temporary returned.\n", errout.str());
1611 
1612         check("const std::string a() {\n"
1613               "    return \"foo\";\n"
1614               "}");
1615         ASSERT_EQUALS("", errout.str());
1616 
1617         check("const std::string& f(const std::string& x) { return x; }\n"
1618               "const std::string &a() {\n"
1619               "    return f(\"foo\");\n"
1620               "}");
1621         ASSERT_EQUALS(
1622             "[test.cpp:1] -> [test.cpp:1] -> [test.cpp:3] -> [test.cpp:3]: (error) Reference to temporary returned.\n",
1623             errout.str());
1624 
1625         check("const char * f(const char * x) { return x; }\n"
1626               "const std::string &a() {\n"
1627               "    return f(\"foo\");\n"
1628               "}");
1629         ASSERT_EQUALS("[test.cpp:3]: (error) Reference to temporary returned.\n", errout.str());
1630     }
1631 
returnReferenceCalculation()1632     void returnReferenceCalculation() {
1633         check("const std::string &a(const std::string& str) {\n"
1634               "    return \"foo\" + str;\n"
1635               "}");
1636         ASSERT_EQUALS("[test.cpp:2]: (error) Reference to temporary returned.\n", errout.str());
1637 
1638         check("int& operator<<(int out, int path) {\n"
1639               "    return out << path;\n"
1640               "}");
1641         ASSERT_EQUALS("[test.cpp:2]: (error) Reference to temporary returned.\n", errout.str());
1642 
1643         check("std::ostream& operator<<(std::ostream& out, const std::string& path) {\n"
1644               "    return out << path;\n"
1645               "}");
1646         ASSERT_EQUALS("", errout.str());
1647 
1648         check("std::ostream& operator<<(std::ostream* out, const std::string& path) {\n"
1649               "    return *out << path;\n"
1650               "}");
1651         ASSERT_EQUALS("", errout.str());
1652 
1653         check("Unknown1& operator<<(Unknown1 out, Unknown2 path) {\n"
1654               "    return out << path;\n"
1655               "}");
1656         ASSERT_EQUALS("", errout.str());
1657 
1658         check("int& a(int b) {\n"
1659               "    return 2*(b+1);\n"
1660               "}");
1661         ASSERT_EQUALS("[test.cpp:2]: (error) Reference to temporary returned.\n", errout.str());
1662 
1663         check("const std::string &a(const std::string& str) {\n"
1664               "    return str;\n"
1665               "}");
1666         ASSERT_EQUALS("", errout.str());
1667 
1668         check("const std::string &a(int bar) {\n"
1669               "    return foo(bar + 1);\n"
1670               "}");
1671         ASSERT_EQUALS("", errout.str());
1672 
1673         check("const std::string a(const std::string& str) {\n"
1674               "    return \"foo\" + str;\n"
1675               "}");
1676         ASSERT_EQUALS("", errout.str());
1677 
1678         check("int& incValue(int& value) {\n"
1679               "    return ++value;\n"
1680               "}");
1681         ASSERT_EQUALS("", errout.str());
1682     }
1683 
returnReferenceLambda()1684     void returnReferenceLambda() {
1685         // #6787
1686         check("const Item& foo(const Container& items) const {\n"
1687               "    return bar(items.begin(), items.end(),\n"
1688               "    [](const Item& lhs, const Item& rhs) {\n"
1689               "        return false;\n"
1690               "    });\n"
1691               "}");
1692         ASSERT_EQUALS("", errout.str());
1693 
1694         // #5844
1695         check("map<string,string> const &getVariableTable() {\n"
1696               "static map<string,string> const s_var = []{\n"
1697               "    map<string,string> var;\n"
1698               "    return var;\n"
1699               "  }();\n"
1700               "return s_var;\n"
1701               "}");
1702         ASSERT_EQUALS("", errout.str());
1703 
1704         // #7583
1705         check("Command& foo() {\n"
1706               "  return f([]() -> int { return 1; });\n"
1707               "}");
1708         ASSERT_EQUALS("", errout.str());
1709     }
1710 
returnReferenceInnerScope()1711     void returnReferenceInnerScope() {
1712         // #6951
1713         check("const Callback& make() {\n"
1714               "    struct _Wrapper {\n"
1715               "        static ulong call(void* o, const void* f, const void*[]) {\n"
1716               "            return 1;\n"
1717               "        }\n"
1718               "    };\n"
1719               "    return _make(_Wrapper::call, pmf);\n"
1720               "}");
1721         ASSERT_EQUALS("", errout.str());
1722     }
1723 
returnReferenceRecursive()1724     void returnReferenceRecursive() {
1725         check("int& f() { return f(); }");
1726         ASSERT_EQUALS("", errout.str());
1727 
1728         check("int& g(int& i) { return i; }\n"
1729               "int& f() { return g(f()); }");
1730         ASSERT_EQUALS("", errout.str());
1731     }
1732 
extendedLifetime()1733     void extendedLifetime() {
1734         check("void g(int*);\n"
1735               "int h();\n"
1736               "auto f() {\n"
1737               "    const int& x = h();\n"
1738               "    return [&] { return x; };\n"
1739               "}");
1740         ASSERT_EQUALS("[test.cpp:4] -> [test.cpp:5] -> [test.cpp:4] -> [test.cpp:5]: (error) Returning lambda that captures local variable 'x' that will be invalid when returning.\n", errout.str());
1741 
1742         check("void g(int*);\n"
1743               "int h();\n"
1744               "int* f() {\n"
1745               "    const int& x = h();\n"
1746               "    return &x;\n"
1747               "}");
1748         ASSERT_EQUALS("[test.cpp:4] -> [test.cpp:5] -> [test.cpp:4] -> [test.cpp:5]: (error) Returning pointer to local variable 'x' that will be invalid when returning.\n", errout.str());
1749 
1750         check("void g(int*);\n"
1751               "int h();\n"
1752               "void f() {\n"
1753               "    int& x = h();\n"
1754               "    g(&x);\n"
1755               "}");
1756         ASSERT_EQUALS("[test.cpp:4] -> [test.cpp:5] -> [test.cpp:5]: (error) Using pointer to temporary.\n"
1757                       "[test.cpp:4] -> [test.cpp:5]: (error) Using reference to dangling temporary.\n", errout.str());
1758 
1759         check("void g(int*);\n"
1760               "int h();\n"
1761               "void f() {\n"
1762               "    const int& x = h();\n"
1763               "    g(&x);\n"
1764               "}");
1765         ASSERT_EQUALS("", errout.str());
1766 
1767         check("struct Data {\n"
1768               "    std::string path;\n"
1769               "};\n"
1770               "const char* foo() {\n"
1771               "    const Data& data = getData();\n"
1772               "    return data.path.c_str();\n"
1773               "}");
1774         ASSERT_EQUALS("", errout.str());
1775     }
1776 
danglingReference()1777     void danglingReference() {
1778         check("int f( int k )\n"
1779               "{\n"
1780               "    static int &r = k;\n"
1781               "    return r;\n"
1782               "}");
1783         ASSERT_EQUALS("[test.cpp:3] -> [test.cpp:3]: (error) Non-local reference variable 'r' to local variable 'k'\n",
1784                       errout.str());
1785 
1786         check("int &f( int & k )\n"
1787               "{\n"
1788               "    static int &r = k;\n"
1789               "    return r;\n"
1790               "}");
1791         ASSERT_EQUALS("", errout.str());
1792     }
1793 
danglingTempReference()1794     void danglingTempReference() {
1795         check("const std::string& g(const std::string& str_cref) {\n"
1796               "    return str_cref;\n"
1797               "}\n"
1798               "void f() {\n"
1799               "    const auto& str_cref2 = g(std::string(\"hello\"));\n"
1800               "    std::cout << str_cref2 << std::endl;\n"
1801               "}\n");
1802         ASSERT_EQUALS("[test.cpp:5] -> [test.cpp:1] -> [test.cpp:2] -> [test.cpp:5] -> [test.cpp:6]: (error) Using reference to dangling temporary.\n", errout.str());
1803 
1804         // Lifetime extended
1805         check("std::string g(const std::string& str_cref) {\n"
1806               "    return str_cref;\n"
1807               "}\n"
1808               "void f() {\n"
1809               "    const auto& str_cref2 = g(std::string(\"hello\"));\n"
1810               "    std::cout << str_cref2 << std::endl;\n"
1811               "}\n");
1812         ASSERT_EQUALS("", errout.str());
1813 
1814         check("char f() {\n"
1815               "    char c = 0;\n"
1816               "    char&& cr = std::move(c);\n"
1817               "    return cr;\n"
1818               "}\n");
1819         ASSERT_EQUALS("", errout.str());
1820 
1821         // #9987
1822         check("void g(std::vector<int>);\n"
1823               "void f() {\n"
1824               "    std::vector<int>&& v = {};\n"
1825               "    g(std::move(v));\n"
1826               "}\n");
1827         ASSERT_EQUALS("", errout.str());
1828 
1829         check("void g(std::vector<int>);\n"
1830               "std::vector<int> h();\n"
1831               "void f() {\n"
1832               "    std::vector<int>&& v = h();\n"
1833               "    g(std::move(v));\n"
1834               "}\n");
1835         ASSERT_EQUALS("", errout.str());
1836     }
1837 
testglobalnamespace()1838     void testglobalnamespace() {
1839         check("class SharedPtrHolder\n"
1840               "{\n"
1841               "   ::std::tr1::shared_ptr<int> pNum;\n"
1842               "public:\n"
1843               "   void SetNum(const ::std::tr1::shared_ptr<int> & apNum)\n"
1844               "   {\n"
1845               "      pNum = apNum;\n"
1846               "   }\n"
1847               "}");
1848 
1849         ASSERT_EQUALS("", errout.str());
1850     }
1851 
returnParameterAddress()1852     void returnParameterAddress() {
1853         check("int* foo(int y)\n"
1854               "{\n"
1855               "  return &y;\n"
1856               "}");
1857 
1858         ASSERT_EQUALS("[test.cpp:3] -> [test.cpp:1] -> [test.cpp:3]: (error) Returning pointer to local variable 'y' that will be invalid when returning.\n", errout.str());
1859 
1860         check("int ** foo(int * y)\n"
1861               "{\n"
1862               "  return &y;\n"
1863               "}");
1864 
1865         ASSERT_EQUALS("[test.cpp:3] -> [test.cpp:1] -> [test.cpp:3]: (error) Returning pointer to local variable 'y' that will be invalid when returning.\n", errout.str());
1866 
1867         check("const int * foo(const int & y)\n"
1868               "{\n"
1869               "  return &y;\n"
1870               "}");
1871 
1872         ASSERT_EQUALS("", errout.str());
1873 
1874         check("int * foo(int * y)\n"
1875               "{\n"
1876               "  return y;\n"
1877               "}");
1878 
1879         ASSERT_EQUALS("", errout.str());
1880 
1881         check("struct s { void *p; };\n"
1882               "extern struct s* f(void);\n"
1883               "void g(void **q)\n"
1884               "{\n"
1885               "    struct s *r = f();\n"
1886               "    *q = &r->p;\n"
1887               "}");
1888 
1889         ASSERT_EQUALS("", errout.str());
1890     }
1891 
testconstructor()1892     void testconstructor() { // Ticket #5478 - crash while checking a constructor
1893         check("class const_tree_iterator {\n"
1894               "  const_tree_iterator(bool (*_incream)(node_type*&)) {}\n"
1895               "  const_tree_iterator& parent() {\n"
1896               "    return const_tree_iterator(foo);\n"
1897               "  }\n"
1898               "};");
1899     }
1900 
variableIsUsedInScope()1901     void variableIsUsedInScope() {
1902         check("void removed_cb (GList *uids) {\n"
1903               "for (; uids; uids = uids->next) {\n"
1904               "}\n"
1905               "}\n"
1906               "void opened_cb () {\n"
1907               "	g_signal_connect (G_CALLBACK (removed_cb));\n"
1908               "}");
1909     }
1910 
danglingLifetimeLambda()1911     void danglingLifetimeLambda() {
1912         check("auto f() {\n"
1913               "    int a = 1;\n"
1914               "    auto l = [&](){ return a; };\n"
1915               "    return l;\n"
1916               "}");
1917         ASSERT_EQUALS("[test.cpp:3] -> [test.cpp:2] -> [test.cpp:4]: (error) Returning lambda that captures local variable 'a' that will be invalid when returning.\n", errout.str());
1918 
1919         check("auto f() {\n"
1920               "    int a = 1;\n"
1921               "    return [&](){ return a; };\n"
1922               "}");
1923         ASSERT_EQUALS("[test.cpp:3] -> [test.cpp:2] -> [test.cpp:3]: (error) Returning lambda that captures local variable 'a' that will be invalid when returning.\n", errout.str());
1924 
1925         check("auto f(int a) {\n"
1926               "    return [&](){ return a; };\n"
1927               "}");
1928         ASSERT_EQUALS("[test.cpp:2] -> [test.cpp:1] -> [test.cpp:2]: (error) Returning lambda that captures local variable 'a' that will be invalid when returning.\n", errout.str());
1929 
1930         check("auto f(int a) {\n"
1931               "    auto p = &a;\n"
1932               "    return [=](){ return p; };\n"
1933               "}");
1934         ASSERT_EQUALS("[test.cpp:2] -> [test.cpp:3] -> [test.cpp:1] -> [test.cpp:3]: (error) Returning lambda that captures local variable 'a' that will be invalid when returning.\n", errout.str());
1935 
1936         check("auto g(int& a) {\n"
1937               "    int p = a;\n"
1938               "    return [&](){ return p; };\n"
1939               "}");
1940         ASSERT_EQUALS("[test.cpp:3] -> [test.cpp:2] -> [test.cpp:3]: (error) Returning lambda that captures local variable 'p' that will be invalid when returning.\n", errout.str());
1941 
1942         check("auto f() {\n"
1943               "    return [=](){\n"
1944               "        int a = 1;\n"
1945               "        return [&](){ return a; };\n"
1946               "    };\n"
1947               "}");
1948         ASSERT_EQUALS("[test.cpp:4] -> [test.cpp:3] -> [test.cpp:4]: (error) Returning lambda that captures local variable 'a' that will be invalid when returning.\n", errout.str());
1949 
1950         check("auto f(int b) {\n"
1951               "    return [=](int a){\n"
1952               "        a += b;\n"
1953               "        return [&](){ return a; };\n"
1954               "    };\n"
1955               "}");
1956         ASSERT_EQUALS("[test.cpp:4] -> [test.cpp:2] -> [test.cpp:4]: (error) Returning lambda that captures local variable 'a' that will be invalid when returning.\n", errout.str());
1957 
1958         check("auto g(int& a) {\n"
1959               "    return [&](){ return a; };\n"
1960               "}");
1961         ASSERT_EQUALS("", errout.str());
1962 
1963         check("auto g(int a) {\n"
1964               "    auto p = a;\n"
1965               "    return [=](){ return p; };\n"
1966               "}");
1967         ASSERT_EQUALS("", errout.str());
1968 
1969         check("auto g(int& a) {\n"
1970               "    auto p = a;\n"
1971               "    return [=](){ return p; };\n"
1972               "}");
1973         ASSERT_EQUALS("", errout.str());
1974 
1975         check("auto g(int& a) {\n"
1976               "    int& p = a;\n"
1977               "    return [&](){ return p; };\n"
1978               "}");
1979         ASSERT_EQUALS("", errout.str());
1980 
1981         check("template<class F>\n"
1982               "void g(F);\n"
1983               "auto f() {\n"
1984               "    int x;\n"
1985               "    return g([&]() { return x; });\n"
1986               "}");
1987         ASSERT_EQUALS("", errout.str());
1988 
1989         check("auto f() {\n"
1990               "    int i = 0;\n"
1991               "    return [&i] {};\n"
1992               "}\n");
1993         ASSERT_EQUALS("[test.cpp:3] -> [test.cpp:2] -> [test.cpp:3]: (error) Returning lambda that captures local variable 'i' that will be invalid when returning.\n", errout.str());
1994 
1995         check("auto f() {\n"
1996               "    int i = 0;\n"
1997               "    return [i] {};\n"
1998               "}\n");
1999         ASSERT_EQUALS("", errout.str());
2000 
2001         check("auto f() {\n"
2002               "    int i = 0;\n"
2003               "    return [=, &i] {};\n"
2004               "}\n");
2005         ASSERT_EQUALS("[test.cpp:3] -> [test.cpp:2] -> [test.cpp:3]: (error) Returning lambda that captures local variable 'i' that will be invalid when returning.\n", errout.str());
2006 
2007         check("auto f() {\n"
2008               "    int i = 0;\n"
2009               "    int j = 0;\n"
2010               "    return [=, &i] { return j; };\n"
2011               "}\n");
2012         ASSERT_EQUALS("[test.cpp:4] -> [test.cpp:2] -> [test.cpp:4]: (error) Returning lambda that captures local variable 'i' that will be invalid when returning.\n", errout.str());
2013 
2014         check("auto f() {\n"
2015               "    int i = 0;\n"
2016               "    return [&, i] {};\n"
2017               "}\n");
2018         ASSERT_EQUALS("", errout.str());
2019 
2020         check("auto f() {\n"
2021               "    int i = 0;\n"
2022               "    int j = 0;\n"
2023               "    return [&, i] { return j; };\n"
2024               "}\n");
2025         ASSERT_EQUALS("[test.cpp:4] -> [test.cpp:3] -> [test.cpp:4]: (error) Returning lambda that captures local variable 'j' that will be invalid when returning.\n", errout.str());
2026 
2027         check("auto f(int& i) {\n"
2028               "    int j = 0;\n"
2029               "    return [=, &i] { return j; };\n"
2030               "}\n");
2031         ASSERT_EQUALS("", errout.str());
2032 
2033         check("void f(int*);\n"
2034               "auto g(int y) {\n"
2035               "    int x = y;\n"
2036               "    return [=] {\n"
2037               "        g(&x);\n"
2038               "    };\n"
2039               "}\n");
2040         ASSERT_EQUALS("", errout.str());
2041 
2042         check("struct A {\n"
2043               "    int x;\n"
2044               "};\n"
2045               "auto f() {\n"
2046               "    A a;\n"
2047               "    return [=] {\n"
2048               "        const A* ap = &a;\n"
2049               "        ap->x;\n"
2050               "    };\n"
2051               "}\n");
2052         ASSERT_EQUALS("", errout.str());
2053     }
2054 
danglingLifetimeContainer()2055     void danglingLifetimeContainer() {
2056         check("auto f(const std::vector<int>& x) {\n"
2057               "    auto it = x.begin();\n"
2058               "    return it;\n"
2059               "}");
2060         ASSERT_EQUALS("", errout.str());
2061 
2062         check("auto f() {\n"
2063               "    std::vector<int> x;\n"
2064               "    auto it = x.begin();\n"
2065               "    return it;\n"
2066               "}");
2067         ASSERT_EQUALS("[test.cpp:3] -> [test.cpp:2] -> [test.cpp:4]: (error) Returning iterator to local container 'x' that will be invalid when returning.\n", errout.str());
2068 
2069         check("auto f() {\n"
2070               "    std::vector<int> x;\n"
2071               "    auto p = x.data();\n"
2072               "    return p;\n"
2073               "}");
2074         ASSERT_EQUALS(
2075             "[test.cpp:3] -> [test.cpp:2] -> [test.cpp:4]: (error) Returning pointer to local variable 'x' that will be invalid when returning.\n",
2076             errout.str());
2077 
2078         check("auto f() {\n"
2079               "    std::vector<int> x;\n"
2080               "    auto p = &x[0];\n"
2081               "    return p;\n"
2082               "}");
2083         ASSERT_EQUALS(
2084             "[test.cpp:3] -> [test.cpp:2] -> [test.cpp:4]: (error) Returning pointer to local variable 'x' that will be invalid when returning.\n",
2085             errout.str());
2086 
2087         check("struct A { int foo; };\n"
2088               "int* f(std::vector<A> v) {\n"
2089               "    auto it = v.begin();\n"
2090               "    return &it->foo;\n"
2091               "}");
2092         ASSERT_EQUALS(
2093             "[test.cpp:3] -> [test.cpp:4] -> [test.cpp:2] -> [test.cpp:4]: (error) Returning object that points to local variable 'v' that will be invalid when returning.\n",
2094             errout.str());
2095 
2096         check("auto f(std::vector<int> x) {\n"
2097               "    auto it = x.begin();\n"
2098               "    return it;\n"
2099               "}");
2100         ASSERT_EQUALS("[test.cpp:2] -> [test.cpp:1] -> [test.cpp:3]: (error) Returning iterator to local container 'x' that will be invalid when returning.\n", errout.str());
2101 
2102         check("auto f() {\n"
2103               "    std::vector<int> x;\n"
2104               "    auto it = x.begin();\n"
2105               "    return std::next(it);\n"
2106               "}");
2107         ASSERT_EQUALS(
2108             "[test.cpp:3] -> [test.cpp:4] -> [test.cpp:2] -> [test.cpp:4]: (error) Returning object that points to local variable 'x' that will be invalid when returning.\n",
2109             errout.str());
2110 
2111         check("auto f() {\n"
2112               "    std::vector<int> x;\n"
2113               "    auto it = x.begin();\n"
2114               "    return it + 1;\n"
2115               "}");
2116         ASSERT_EQUALS(
2117             "[test.cpp:3] -> [test.cpp:2] -> [test.cpp:4]: (error) Returning iterator to local container 'x' that will be invalid when returning.\n",
2118             errout.str());
2119 
2120         check("auto f() {\n"
2121               "    std::vector<int> x;\n"
2122               "    auto it = x.begin();\n"
2123               "    return std::next(it + 1);\n"
2124               "}");
2125         ASSERT_EQUALS(
2126             "[test.cpp:3] -> [test.cpp:4] -> [test.cpp:2] -> [test.cpp:4]: (error) Returning object that points to local variable 'x' that will be invalid when returning.\n",
2127             errout.str());
2128 
2129         check("std::vector<int*> f() {\n"
2130               "    int i = 0;\n"
2131               "    std::vector<int*> v;\n"
2132               "    v.push_back(&i);\n"
2133               "    return v;\n"
2134               "}");
2135         ASSERT_EQUALS(
2136             "[test.cpp:4] -> [test.cpp:4] -> [test.cpp:2] -> [test.cpp:5]: (error) Returning object that points to local variable 'i' that will be invalid when returning.\n",
2137             errout.str());
2138 
2139         check("std::vector<int*> f() {\n"
2140               "    std::vector<int*> r;\n"
2141               "    int i = 0;\n"
2142               "    std::vector<int*> v;\n"
2143               "    v.push_back(&i);\n"
2144               "    r.assign(v.begin(), v.end());\n"
2145               "    return r;\n"
2146               "}");
2147         ASSERT_EQUALS(
2148             "[test.cpp:5] -> [test.cpp:5] -> [test.cpp:5] -> [test.cpp:3] -> [test.cpp:7]: (error) Returning object that points to local variable 'i' that will be invalid when returning.\n",
2149             errout.str());
2150 
2151         check("struct A {\n"
2152               "    std::vector<int*> v;\n"
2153               "    void f() {\n"
2154               "        int i;\n"
2155               "        v.push_back(&i);\n"
2156               "    }\n"
2157               "};");
2158         ASSERT_EQUALS(
2159             "[test.cpp:5] -> [test.cpp:5] -> [test.cpp:4] -> [test.cpp:5]: (error) Non-local variable 'v' will use object that points to local variable 'i'.\n",
2160             errout.str());
2161 
2162         check("struct A {\n"
2163               "    std::vector<int*> v;\n"
2164               "    void f() {\n"
2165               "        int i;\n"
2166               "        int * p = &i;\n"
2167               "        v.push_back(p);\n"
2168               "    }\n"
2169               "};");
2170         ASSERT_EQUALS(
2171             "[test.cpp:5] -> [test.cpp:6] -> [test.cpp:4] -> [test.cpp:6]: (error) Non-local variable 'v' will use object that points to local variable 'i'.\n",
2172             errout.str());
2173 
2174         check("struct A {\n"
2175               "    std::vector<int*> m;\n"
2176               "    void f() {\n"
2177               "        int x;\n"
2178               "        std::vector<int*> v;\n"
2179               "        v.push_back(&x);\n"
2180               "        m.insert(m.end(), v.begin(), v.end());\n"
2181               "    }\n"
2182               "};");
2183         ASSERT_EQUALS(
2184             "[test.cpp:6] -> [test.cpp:6] -> [test.cpp:6] -> [test.cpp:4] -> [test.cpp:7]: (error) Non-local variable 'm' will use object that points to local variable 'x'.\n",
2185             errout.str());
2186 
2187         check("std::vector<int>::iterator f(std::vector<int> v) {\n"
2188               "    for(auto it = v.begin();it != v.end();it++) {\n"
2189               "        return it;\n"
2190               "    }\n"
2191               "    return {};\n"
2192               "}");
2193         ASSERT_EQUALS(
2194             "[test.cpp:2] -> [test.cpp:1] -> [test.cpp:3]: (error) Returning iterator to local container 'v' that will be invalid when returning.\n",
2195             errout.str());
2196 
2197         check("const char * f() {\n"
2198               "   std::string ba(\"hello\");\n"
2199               "   return ba.c_str();\n"
2200               "}");
2201         ASSERT_EQUALS(
2202             "[test.cpp:3] -> [test.cpp:2] -> [test.cpp:3]: (error) Returning pointer to local variable 'ba' that will be invalid when returning.\n",
2203             errout.str());
2204 
2205         check("template <class T, class K, class V>\n"
2206               "const V* get_default(const T& t, const K& k, const V* v) {\n"
2207               "    auto it = t.find(k);\n"
2208               "    if (it == t.end()) return v;\n"
2209               "    return &it->second;\n"
2210               "}\n"
2211               "const int* bar(const std::unordered_map<int, int>& m, int k) {\n"
2212               "    auto x = 0;\n"
2213               "    return get_default(m, k, &x);\n"
2214               "}\n",
2215               true);
2216         ASSERT_EQUALS(
2217             "[test.cpp:9] -> [test.cpp:9] -> [test.cpp:8] -> [test.cpp:9]: (error, inconclusive) Returning pointer to local variable 'x' that will be invalid when returning.\n",
2218             errout.str());
2219 
2220         check("std::vector<int> g();\n"
2221               "auto f() {\n"
2222               "    return g().begin();\n"
2223               "}");
2224         TODO_ASSERT_EQUALS(
2225             "[test.cpp:3] -> [test.cpp:3]: (error) Returning iterator that will be invalid when returning.\n",
2226             "",
2227             errout.str());
2228 
2229         check("std::vector<int> f();\n"
2230               "auto f() {\n"
2231               "    auto it = g().begin();\n"
2232               "    return it;\n"
2233               "}");
2234         TODO_ASSERT_EQUALS("error", "", errout.str());
2235 
2236         check("std::vector<int> f();\n"
2237               "int& f() {\n"
2238               "    return *g().begin();\n"
2239               "}");
2240         TODO_ASSERT_EQUALS("error", "", errout.str());
2241 
2242         check("struct A {\n"
2243               "    std::vector<std::string> v;\n"
2244               "    void f() {\n"
2245               "        char s[3];\n"
2246               "        v.push_back(s);\n"
2247               "    }\n"
2248               "};");
2249         ASSERT_EQUALS("", errout.str());
2250 
2251         check("std::vector<std::string> f() {\n"
2252               "    const char * s = \"hello\";\n"
2253               "    std::vector<std::string> v;\n"
2254               "    v.push_back(s);\n"
2255               "    return v;\n"
2256               "}");
2257         ASSERT_EQUALS("", errout.str());
2258 
2259         check("auto f() {\n"
2260               "  static std::vector<int> x;\n"
2261               "  return x.begin();\n"
2262               "}");
2263         ASSERT_EQUALS("", errout.str());
2264 
2265         check("std::string g() {\n"
2266               "    std::vector<char> v;\n"
2267               "    return v.data();\n"
2268               "}");
2269         ASSERT_EQUALS("", errout.str());
2270 
2271         check("std::vector<int>::iterator f(std::vector<int>* v) {\n"
2272               "    return v->begin();\n"
2273               "}");
2274         ASSERT_EQUALS("", errout.str());
2275 
2276         check("std::vector<int>::iterator f(std::vector<int>* v) {\n"
2277               "    std::vector<int>* v = new std::vector<int>();\n"
2278               "    return v->begin();\n"
2279               "}");
2280         ASSERT_EQUALS("", errout.str());
2281 
2282         check("int f(std::vector<int> v) {\n"
2283               "    return *v.begin();\n"
2284               "}");
2285         ASSERT_EQUALS("", errout.str());
2286 
2287         check("int f(std::vector<int> v) {\n"
2288               "    return v.end() - v.begin();\n"
2289               "}");
2290         ASSERT_EQUALS("", errout.str());
2291 
2292         check("auto g() {\n"
2293               "    std::vector<char> v;\n"
2294               "    return {v, [v]() { return v.data(); }};\n"
2295               "}");
2296         ASSERT_EQUALS("", errout.str());
2297 
2298         check("template<class F>\n"
2299               "void g(F);\n"
2300               "auto f() {\n"
2301               "    std::vector<char> v;\n"
2302               "    return g([&]() { return v.data(); });\n"
2303               "}");
2304         ASSERT_EQUALS("", errout.str());
2305 
2306         check("std::vector<int> g();\n"
2307               "struct A {\n"
2308               "    std::vector<int> m;\n"
2309               "    void f() {\n"
2310               "        std::vector<int> v = g();\n"
2311               "        m.insert(m.end(), v.begin(), v.end());\n"
2312               "    }\n"
2313               "};");
2314         ASSERT_EQUALS("", errout.str());
2315 
2316         check("void f(bool b) {\n"
2317               "    std::vector<int> v = {1};\n"
2318               "    if (b) {\n"
2319               "        int a[] = {0};\n"
2320               "        v.insert(a, a+1);\n"
2321               "    }\n"
2322               "    return v.back() == 0;\n"
2323               "}");
2324         ASSERT_EQUALS("", errout.str());
2325 
2326         check("class A {\n"
2327               "    int f( P p ) {\n"
2328               "        std::vector< S > maps;\n"
2329               "        m2.insert( m1.begin(), m1.end() );\n"
2330               "    }\n"
2331               "    struct B {};\n"
2332               "    std::map< S, B > m1;\n"
2333               "    std::map< S, B > m2;\n"
2334               "};");
2335         ASSERT_EQUALS("", errout.str());
2336 
2337         check("struct A {\n"
2338               "    std::vector<int*> v;\n"
2339               "    int x;\n"
2340               "    void f() {\n"
2341               "        v.push_back(&x);\n"
2342               "    }\n"
2343               "};");
2344         ASSERT_EQUALS("", errout.str());
2345 
2346         check("size_t f(const std::string& x) {\n"
2347               "    std::string y = \"x\";\n"
2348               "    return y.find(x);\n"
2349               "}");
2350         ASSERT_EQUALS("", errout.str());
2351 
2352         check("std::string* f();\n"
2353               "const char* g() {\n"
2354               "    std::string* var = f();\n"
2355               "    return var->c_str();\n"
2356               "}");
2357         ASSERT_EQUALS("", errout.str());
2358 
2359         check("std::string f() {\n"
2360               "    std::vector<char> data{};\n"
2361               "    data.push_back('a');\n"
2362               "    return std::string{ data.data(), data.size() };\n"
2363               "}");
2364         ASSERT_EQUALS("", errout.str());
2365 
2366         check("std::vector<char*> f() {\n"
2367               "    char a = 0;\n"
2368               "    return std::vector<char*>{&a};\n"
2369               "}");
2370         ASSERT_EQUALS("[test.cpp:3] -> [test.cpp:3] -> [test.cpp:2] -> [test.cpp:3]: (error) Returning object that points to local variable 'a' that will be invalid when returning.\n", errout.str());
2371 
2372         check("std::vector<int>* g();\n"
2373               "int& f() {\n"
2374               "    auto* p = g();\n"
2375               "    return p->front();\n"
2376               "}\n");
2377         ASSERT_EQUALS("", errout.str());
2378 
2379         check("std::vector<std::vector<int>> g();\n"
2380               "void f() {\n"
2381               "    for(auto& x:g())\n"
2382               "        std::sort(x.begin(), x.end());\n"
2383               "}\n");
2384         ASSERT_EQUALS("", errout.str());
2385 
2386         check("struct A {\n"
2387               "    std::vector<int*> v;\n"
2388               "    void add(int* i) {\n"
2389               "        v.push_back(i);\n"
2390               "    }\n"
2391               "    void f() {\n"
2392               "        int i = 0;\n"
2393               "        add(&i);\n"
2394               "    }\n"
2395               "};\n");
2396         ASSERT_EQUALS(
2397             "[test.cpp:8] -> [test.cpp:8] -> [test.cpp:4] -> [test.cpp:7] -> [test.cpp:4]: (error) Non-local variable 'v' will use object that points to local variable 'i'.\n",
2398             errout.str());
2399 
2400         check("struct A {\n"
2401               "    std::vector<int*> v;\n"
2402               "    void add(int* i) {\n"
2403               "        v.push_back(i);\n"
2404               "    }\n"
2405               "};\n"
2406               "void f() {\n"
2407               "    A a;\n"
2408               "    int i = 0;\n"
2409               "    a.add(&i);\n"
2410               "}\n");
2411         ASSERT_EQUALS("", errout.str());
2412 
2413         check("struct A {\n"
2414               "    std::vector<int*> v;\n"
2415               "    void add(int* i) {\n"
2416               "        v.push_back(i);\n"
2417               "    }\n"
2418               "    void f() {\n"
2419               "        A a;\n"
2420               "        int i = 0;\n"
2421               "        a.add(&i);\n"
2422               "    }\n"
2423               "};\n");
2424         ASSERT_EQUALS("", errout.str());
2425 
2426         check("int f() {\n"
2427               "    int i;\n"
2428               "    {\n"
2429               "        std::vector<int> vec;\n"
2430               "        const auto iter = vec.begin();\n"
2431               "        i = (int)(iter - vec.begin());\n"
2432               "    }\n"
2433               "    return i;\n"
2434               "}\n");
2435         ASSERT_EQUALS("", errout.str());
2436 
2437         check("int* get(std::vector<int>& container) {\n"
2438               "    Sequence seq(container);\n"
2439               "    for (auto& r : seq) {\n"
2440               "        return &r;\n"
2441               "    }\n"
2442               "    return &*seq.begin();\n"
2443               "}\n");
2444         ASSERT_EQUALS("", errout.str());
2445     }
2446 
danglingLifetime()2447     void danglingLifetime() {
2448         check("auto f() {\n"
2449               "    std::vector<int> a;\n"
2450               "    auto it = a.begin();\n"
2451               "    return [=](){ return it; };\n"
2452               "}");
2453         ASSERT_EQUALS("[test.cpp:3] -> [test.cpp:4] -> [test.cpp:2] -> [test.cpp:4]: (error) Returning lambda that captures local variable 'a' that will be invalid when returning.\n", errout.str());
2454 
2455         check("auto f(std::vector<int> a) {\n"
2456               "    auto it = a.begin();\n"
2457               "    return [=](){ return it; };\n"
2458               "}");
2459         ASSERT_EQUALS("[test.cpp:2] -> [test.cpp:3] -> [test.cpp:1] -> [test.cpp:3]: (error) Returning lambda that captures local variable 'a' that will be invalid when returning.\n", errout.str());
2460 
2461         check("struct e {};\n"
2462               "e * j() {\n"
2463               "    e c[20];\n"
2464               "    return c;\n"
2465               "}");
2466         ASSERT_EQUALS(
2467             "[test.cpp:4] -> [test.cpp:3] -> [test.cpp:4]: (error) Returning pointer to local variable 'c' that will be invalid when returning.\n",
2468             errout.str());
2469 
2470         check("auto f(std::vector<int>& a) {\n"
2471               "    auto it = a.begin();\n"
2472               "    return [=](){ return it; };\n"
2473               "}");
2474         ASSERT_EQUALS("", errout.str());
2475 
2476         check("int * f(int a[]) {\n"
2477               "    return a;\n"
2478               "}");
2479         ASSERT_EQUALS("", errout.str());
2480 
2481         check("void f() {\n"
2482               "    struct b {\n"
2483               "        uint32_t f[6];\n"
2484               "    } d;\n"
2485               "    uint32_t *a = d.f;\n"
2486               "}");
2487         ASSERT_EQUALS("", errout.str());
2488 
2489         // Don't decay std::array
2490         check("std::array<char, 1> f() {\n"
2491               "    std::array<char, 1> x;\n"
2492               "    return x;\n"
2493               "}");
2494         ASSERT_EQUALS("", errout.str());
2495 
2496         // Make sure we don't hang
2497         check("struct A;\n"
2498               "void f() {\n"
2499               "    using T = A[3];\n"
2500               "    A &&a = T{1, 2, 3}[1];\n"
2501               "}");
2502         ASSERT_EQUALS("", errout.str());
2503 
2504         // Make sure we don't hang
2505         check("struct A;\n"
2506               "void f() {\n"
2507               "    using T = A[3];\n"
2508               "    A &&a = T{1, 2, 3}[1]();\n"
2509               "}");
2510         ASSERT_EQUALS("", errout.str());
2511 
2512         // Make sure we don't hang
2513         check("struct A;\n"
2514               "void f() {\n"
2515               "    using T = A[3];\n"
2516               "    A &&a = T{1, 2, 3}[1];\n"
2517               "}");
2518         ASSERT_EQUALS("", errout.str());
2519 
2520         // Make sure we don't hang
2521         check("struct A;\n"
2522               "void f() {\n"
2523               "    using T = A[3];\n"
2524               "    A &&a = T{1, 2, 3}[1]();\n"
2525               "}");
2526         ASSERT_EQUALS("", errout.str());
2527 
2528         // Crash #8872
2529         check("struct a {\n"
2530               "  void operator()(b c) override {\n"
2531               "    d(c, [&] { c->e });\n"
2532               "  }\n"
2533               "};");
2534         ASSERT_EQUALS("", errout.str());
2535 
2536         check("struct a {\n"
2537               "  void operator()(b c) override {\n"
2538               "    d(c, [=] { c->e });\n"
2539               "  }\n"
2540               "};");
2541         ASSERT_EQUALS("", errout.str());
2542 
2543         check("struct a {\n"
2544               "    a(char* b) {}\n"
2545               "};\n"
2546               "a f() {\n"
2547               "    char c[20];\n"
2548               "    return c;\n"
2549               "}");
2550         ASSERT_EQUALS("", errout.str());
2551 
2552         check("struct a {\n"
2553               "    a(char* b) {}\n"
2554               "};\n"
2555               "a g() {\n"
2556               "    char c[20];\n"
2557               "    a d = c;\n"
2558               "    return d;\n"
2559               "}");
2560         ASSERT_EQUALS("", errout.str());
2561 
2562         check("void f() {\n"
2563               "    struct a {\n"
2564               "        std::vector<int> v;\n"
2565               "        auto g() { return v.end(); }\n"
2566               "    };\n"
2567               "}");
2568         ASSERT_EQUALS("", errout.str());
2569 
2570         check("int * f(std::vector<int>& v) {\n"
2571               "    for(int & x : v)\n"
2572               "        return &x;\n"
2573               "    return nullptr;\n"
2574               "}");
2575         ASSERT_EQUALS("", errout.str());
2576 
2577         // #9275
2578         check("struct S {\n"
2579               "   void f();\n"
2580               "   std::string m;\n"
2581               "}\n"
2582               "void S::f() {\n"
2583               "    char buf[1024];\n"
2584               "    const char* msg = buf;\n"
2585               "    m = msg;\n"
2586               "}");
2587         ASSERT_EQUALS("", errout.str());
2588 
2589         // #9201
2590         check("int* f() {\n"
2591               "    struct a { int m; };\n"
2592               "    static a b{0};\n"
2593               "    return &b.m;\n"
2594               "}");
2595         ASSERT_EQUALS("", errout.str());
2596 
2597         // #9453
2598         check("int *ptr;\n"
2599               "void foo(int arr[]) {\n"
2600               "    ptr = &arr[2];\n"
2601               "}");
2602         ASSERT_EQUALS("", errout.str());
2603 
2604         // #9639
2605         check("struct Fred {\n"
2606               "    std::string s;\n"
2607               "};\n"
2608               "const Fred &getFred();\n"
2609               "const char * f() {\n"
2610               "  const Fred &fred = getFred();\n"
2611               "  return fred.s.c_str();\n"
2612               "}");
2613         ASSERT_EQUALS("", errout.str());
2614 
2615         // #9534
2616         check("struct A {\n"
2617               "    int* x;\n"
2618               "};\n"
2619               "int* f(int i, std::vector<A>& v) {\n"
2620               "    A& y = v[i];\n"
2621               "    return &y.x[i];\n"
2622               "}");
2623         ASSERT_EQUALS("", errout.str());
2624 
2625         // #9712
2626         check("std::string f(const char *str) {\n"
2627               "    char value[256];\n"
2628               "    return value;\n"
2629               "}");
2630         ASSERT_EQUALS("", errout.str());
2631 
2632         // #9770
2633         check("class C {\n"
2634               "  std::string f(const char*);\n"
2635               "};\n"
2636               "std::string C::f(const char*) {\n"
2637               "  const char data[] = \"x\";\n"
2638               "  return data;\n"
2639               "}\n");
2640         ASSERT_EQUALS("", errout.str());
2641 
2642         // #9899
2643         check("struct A {\n"
2644               "    std::vector<int> v;\n"
2645               "    void f(std::vector<int> w) {\n"
2646               "        v = std::move(w);\n"
2647               "    }\n"
2648               "    void g(std::vector<int> w) {\n"
2649               "        f(std::move(w));\n"
2650               "    }\n"
2651               "};\n");
2652         ASSERT_EQUALS("", errout.str());
2653 
2654         //Make sure we can still take the address of a reference without warning
2655         check("int* foo() {\n"
2656               "  int& x = getX();\n"
2657               "  return &x;\n"
2658               "}\n");
2659         ASSERT_EQUALS("", errout.str());
2660         check("struct C {\n"
2661               "  int* m_x;\n"
2662               "  void foo() {\n"
2663               "    const int& x = getX();\n"
2664               "    m_x = &x;\n"
2665               "  }\n"
2666               "}\n");
2667         ASSERT_EQUALS("", errout.str());
2668 
2669         // #10090
2670         check("struct a {\n"
2671               "    int b{};\n"
2672               "};\n"
2673               "struct c {\n"
2674               "    int* c{};\n"
2675               "    a* d{};\n"
2676               "};\n"
2677               "a* f();\n"
2678               "c g() {\n"
2679               "    c e;\n"
2680               "    e.d = f();\n"
2681               "    if (e.d)\n"
2682               "        e.c = &e.d->b;\n"
2683               "    return e;\n"
2684               "}\n");
2685         ASSERT_EQUALS("", errout.str());
2686 
2687         // #10214
2688         check("struct A {\n"
2689               "  std::string key;\n"
2690               "  const char *value;\n"
2691               "};\n"
2692               "const char *f(const std::string &key, const std::vector<A> &lookup) {\n"
2693               "  const auto &entry =\n"
2694               "      std::find_if(lookup.begin(), lookup.end(),\n"
2695               "                   [key](const auto &v) { return v.key == key; });\n"
2696               "  return (entry == lookup.end()) ? \"\" : entry->value;\n"
2697               "}\n");
2698         ASSERT_EQUALS("", errout.str());
2699 
2700         // #9811
2701         check("struct Base {\n"
2702               "    virtual auto get() -> int & = 0;\n"
2703               "};\n"
2704               "struct A : public Base {\n"
2705               "    int z = 42;\n"
2706               "    auto get() -> int & override { return z; }\n"
2707               "    auto getMore() -> int & { return get(); }\n"
2708               "};\n");
2709         ASSERT_EQUALS("", errout.str());
2710     }
2711 
danglingLifetimeFunction()2712     void danglingLifetimeFunction() {
2713         check("auto f() {\n"
2714               "    int a;\n"
2715               "    return std::ref(a);\n"
2716               "}");
2717         ASSERT_EQUALS(
2718             "[test.cpp:3] -> [test.cpp:2] -> [test.cpp:3]: (error) Returning object that points to local variable 'a' that will be invalid when returning.\n",
2719             errout.str());
2720 
2721         check("auto f() {\n"
2722               "    int a;\n"
2723               "    return std::make_tuple(std::ref(a));\n"
2724               "}");
2725         ASSERT_EQUALS(
2726             "[test.cpp:3] -> [test.cpp:3] -> [test.cpp:2] -> [test.cpp:3]: (error) Returning object that points to local variable 'a' that will be invalid when returning.\n",
2727             errout.str());
2728 
2729         check("template<class T>\n"
2730               "auto by_value(T x) {\n"
2731               "    return [=] { return x; };\n"
2732               "}\n"
2733               "auto g() {\n"
2734               "    std::vector<int> v;\n"
2735               "    return by_value(v.begin());\n"
2736               "}");
2737         ASSERT_EQUALS(
2738             "[test.cpp:7] -> [test.cpp:7] -> [test.cpp:3] -> [test.cpp:3] -> [test.cpp:6] -> [test.cpp:7]: (error) Returning object that points to local variable 'v' that will be invalid when returning.\n",
2739             errout.str());
2740 
2741         check("template<class T>\n"
2742               "auto by_value(const T& x) {\n"
2743               "    return [=] { return x; };\n"
2744               "}\n"
2745               "auto g() {\n"
2746               "    std::vector<int> v;\n"
2747               "    return by_value(v.begin());\n"
2748               "}\n");
2749         ASSERT_EQUALS(
2750             "[test.cpp:7] -> [test.cpp:7] -> [test.cpp:3] -> [test.cpp:3] -> [test.cpp:2] -> [test.cpp:6] -> [test.cpp:7]: (error) Returning object that points to local variable 'v' that will be invalid when returning.\n",
2751             errout.str());
2752 
2753         check("auto by_ref(int& x) {\n"
2754               "    return [&] { return x; };\n"
2755               "}\n"
2756               "auto f() {\n"
2757               "    int i = 0;\n"
2758               "    return by_ref(i);\n"
2759               "}");
2760         ASSERT_EQUALS(
2761             "[test.cpp:2] -> [test.cpp:1] -> [test.cpp:2] -> [test.cpp:6] -> [test.cpp:5] -> [test.cpp:6]: (error) Returning object that points to local variable 'i' that will be invalid when returning.\n",
2762             errout.str());
2763 
2764         check("auto by_ref(const int& x) {\n"
2765               "    return [=] { return x; };\n"
2766               "}\n"
2767               "auto f() {\n"
2768               "    int i = 0;\n"
2769               "    return by_ref(i);\n"
2770               "}\n");
2771         ASSERT_EQUALS("", errout.str());
2772 
2773         check("auto f(int x) {\n"
2774               "    int a;\n"
2775               "    std::tie(a) = x;\n"
2776               "    return a;\n"
2777               "}");
2778         ASSERT_EQUALS("", errout.str());
2779 
2780         check("std::pair<std::string, std::string>\n"
2781               "str_pair(std::string const & a, std::string const & b) {\n"
2782               "    return std::make_pair(a, b);\n"
2783               "}\n"
2784               "std::vector<std::pair<std::string, std::string> > create_parameters() {\n"
2785               "    std::vector<std::pair<std::string, std::string> > par;\n"
2786               "    par.push_back(str_pair(\"param1\", \"prop_a\"));\n"
2787               "    par.push_back(str_pair(\"param2\", \"prop_b\"));\n"
2788               "    par.push_back(str_pair(\"param3\", \"prop_c\"));\n"
2789               "    return par;\n"
2790               "}\n");
2791         ASSERT_EQUALS("", errout.str());
2792     }
2793 
danglingLifetimeAggegrateConstructor()2794     void danglingLifetimeAggegrateConstructor() {
2795         check("struct A {\n"
2796               "    const int& x;\n"
2797               "    int y;\n"
2798               "};\n"
2799               "A f() {\n"
2800               "    int i = 0;\n"
2801               "    return A{i, i};\n"
2802               "}");
2803         ASSERT_EQUALS(
2804             "[test.cpp:7] -> [test.cpp:6] -> [test.cpp:7]: (error) Returning object that points to local variable 'i' that will be invalid when returning.\n",
2805             errout.str());
2806 
2807         check("struct A {\n"
2808               "    const int& x;\n"
2809               "    int y;\n"
2810               "};\n"
2811               "A f() {\n"
2812               "    int i = 0;\n"
2813               "    return {i, i};\n"
2814               "}");
2815         ASSERT_EQUALS(
2816             "[test.cpp:7] -> [test.cpp:6] -> [test.cpp:7]: (error) Returning object that points to local variable 'i' that will be invalid when returning.\n",
2817             errout.str());
2818 
2819         check("struct A {\n"
2820               "    const int& x;\n"
2821               "    int y;\n"
2822               "};\n"
2823               "A f() {\n"
2824               "    int i = 0;\n"
2825               "    A r{i, i};\n"
2826               "    return r;\n"
2827               "}");
2828         ASSERT_EQUALS(
2829             "[test.cpp:7] -> [test.cpp:6] -> [test.cpp:8]: (error) Returning object that points to local variable 'i' that will be invalid when returning.\n",
2830             errout.str());
2831 
2832         check("struct A {\n"
2833               "    const int& x;\n"
2834               "    int y;\n"
2835               "};\n"
2836               "A f() {\n"
2837               "    int i = 0;\n"
2838               "    A r = {i, i};\n"
2839               "    return r;\n"
2840               "}");
2841         ASSERT_EQUALS(
2842             "[test.cpp:7] -> [test.cpp:6] -> [test.cpp:8]: (error) Returning object that points to local variable 'i' that will be invalid when returning.\n",
2843             errout.str());
2844 
2845         check("struct A {\n"
2846               "    const int& x;\n"
2847               "    int y;\n"
2848               "};\n"
2849               "A f(int& x) {\n"
2850               "    int i = 0;\n"
2851               "    return A{i, x};\n"
2852               "}");
2853         ASSERT_EQUALS(
2854             "[test.cpp:7] -> [test.cpp:6] -> [test.cpp:7]: (error) Returning object that points to local variable 'i' that will be invalid when returning.\n",
2855             errout.str());
2856 
2857         check("struct A {\n"
2858               "    const int& x;\n"
2859               "    int y;\n"
2860               "};\n"
2861               "A f(int& x) {\n"
2862               "    int i = 0;\n"
2863               "    return A{x, i};\n"
2864               "}");
2865         ASSERT_EQUALS("", errout.str());
2866 
2867         check("struct A {\n"
2868               "    const int& x;\n"
2869               "    int y;\n"
2870               "};\n"
2871               "A f(int& x) {\n"
2872               "    return A{x, x};\n"
2873               "}");
2874         ASSERT_EQUALS("", errout.str());
2875 
2876         check("struct A { int i; const int& j; };\n"
2877               "A f(int& x) {\n"
2878               "    int y = 0;\n"
2879               "    return A{y, x};\n"
2880               "}");
2881         ASSERT_EQUALS("", errout.str());
2882     }
2883 
danglingLifetimeInitList()2884     void danglingLifetimeInitList() {
2885         check("std::vector<int*> f() {\n"
2886               "    int i = 0;\n"
2887               "    std::vector<int*> v = {&i, &i};\n"
2888               "    return v;\n"
2889               "}");
2890         ASSERT_EQUALS(
2891             "[test.cpp:3] -> [test.cpp:3] -> [test.cpp:2] -> [test.cpp:4]: (error) Returning object that points to local variable 'i' that will be invalid when returning.\n",
2892             errout.str());
2893 
2894         // TODO: Ast is missing for this case
2895         check("std::vector<int*> f() {\n"
2896               "    int i = 0;\n"
2897               "    std::vector<int*> v{&i, &i};\n"
2898               "    return v;\n"
2899               "}");
2900         TODO_ASSERT_EQUALS(
2901             "[test.cpp:3] -> [test.cpp:3] -> [test.cpp:2] -> [test.cpp:4]: (error) Returning object that points to local variable 'i' that will be invalid when returning.\n",
2902             "",
2903             errout.str());
2904 
2905         check("std::vector<int*> f() {\n"
2906               "    int i = 0;\n"
2907               "    return {&i, &i};\n"
2908               "}");
2909         ASSERT_EQUALS(
2910             "[test.cpp:3] -> [test.cpp:3] -> [test.cpp:2] -> [test.cpp:3]: (error) Returning object that points to local variable 'i' that will be invalid when returning.\n",
2911             errout.str());
2912 
2913         check("std::vector<int*> f(int& x) {\n"
2914               "    return {&x, &x};\n"
2915               "}");
2916         ASSERT_EQUALS("", errout.str());
2917 
2918         check("std::vector<std::string> f() {\n"
2919               "    std::set<std::string> x;\n"
2920               "    x.insert(\"1\");\n"
2921               "    x.insert(\"2\");\n"
2922               "    return { x.begin(), x.end() };\n"
2923               "}");
2924         ASSERT_EQUALS("", errout.str());
2925     }
2926 
danglingLifetimeImplicitConversion()2927     void danglingLifetimeImplicitConversion() {
2928         check("struct A { A(const char *a); };\n"
2929               "A f() {\n"
2930               "   std::string ba(\"hello\");\n"
2931               "   return ba.c_str();\n"
2932               "}");
2933         ASSERT_EQUALS("", errout.str());
2934 
2935         check("struct A { A(const char *a); };\n"
2936               "A f() {\n"
2937               "   std::string ba(\"hello\");\n"
2938               "   A bp = ba.c_str();\n"
2939               "   return bp;\n"
2940               "}");
2941         ASSERT_EQUALS("", errout.str());
2942 
2943         check("struct A { A(const char *a); };\n"
2944               "std::vector<A> f() {\n"
2945               "   std::string ba(\"hello\");\n"
2946               "   std::vector<A> v;\n"
2947               "   v.push_back(ba.c_str());\n"
2948               "   return v;\n"
2949               "}");
2950         ASSERT_EQUALS("", errout.str());
2951 
2952         check("std::string f(const std::string& x) {\n"
2953               "  const char c[] = \"\";\n"
2954               "  if (!x.empty())\n"
2955               "    return x + c;\n"
2956               "  return \"\";\n"
2957               "}");
2958         ASSERT_EQUALS("", errout.str());
2959 
2960         check("std::string f(const std::string& x) {\n"
2961               "  const char c[] = \"123\";\n"
2962               "  if (!x.empty())\n"
2963               "    return c + 1;\n"
2964               "  return \"\";\n"
2965               "}");
2966         ASSERT_EQUALS("", errout.str());
2967     }
2968 
danglingTemporaryLifetime()2969     void danglingTemporaryLifetime() {
2970         check("const int& g(const int& x) {\n"
2971               "    return x;\n"
2972               "}\n"
2973               "void f(int& i) {\n"
2974               "    int* x = &g(0);\n"
2975               "    i += *x;\n"
2976               "}");
2977         ASSERT_EQUALS(
2978             "[test.cpp:1] -> [test.cpp:2] -> [test.cpp:5] -> [test.cpp:5] -> [test.cpp:6]: (error) Using pointer to temporary.\n",
2979             errout.str());
2980 
2981         check("QString f() {\n"
2982               "    QString a(\"dummyValue\");\n"
2983               "    const char* b = a.toStdString().c_str();\n"
2984               "    QString c = b;\n"
2985               "    return c;\n"
2986               "}");
2987         ASSERT_EQUALS(
2988             "[test.cpp:3] -> [test.cpp:4]: (error) Using pointer to temporary.\n",
2989             errout.str());
2990 
2991         check("auto f(std::string s) {\n"
2992               "    const char *x = s.substr(1,2).c_str();\n"
2993               "    auto i = s.substr(4,5).begin();\n"
2994               "    return *i;\n"
2995               "}");
2996         ASSERT_EQUALS(
2997             "[test.cpp:3] -> [test.cpp:4]: (error) Using iterator to temporary.\n",
2998             errout.str());
2999 
3000         check("std::string f() {\n"
3001               "    std::stringstream tmp;\n"
3002               "    const std::string &str = tmp.str();\n"
3003               "    return std::string(str.c_str(), 1);\n"
3004               "}");
3005         ASSERT_EQUALS("", errout.str());
3006 
3007         check("int get_value();\n"
3008               "const int &get_reference1() {\n"
3009               "  const int &x = get_value();\n"
3010               "  return x;\n"
3011               "}\n");
3012         ASSERT_EQUALS("[test.cpp:3] -> [test.cpp:4]: (error) Reference to temporary returned.\n", errout.str());
3013 
3014         check("int get_value();\n"
3015               "const int &get_reference2() {\n"
3016               "  const int &x1 = get_value();\n"
3017               "  const int &x2 = x1;\n"
3018               "  return x2;\n"
3019               "}\n");
3020         ASSERT_EQUALS("[test.cpp:4] -> [test.cpp:3] -> [test.cpp:5]: (error) Reference to temporary returned.\n",
3021                       errout.str());
3022 
3023         check("const std::string& getState() {\n"
3024               "    static const std::string& state = \"\";\n"
3025               "    return state;\n"
3026               "}\n");
3027         ASSERT_EQUALS("", errout.str());
3028 
3029         check("struct var {\n"
3030               "    void fun();\n"
3031               "}x;\n"
3032               "var* T(const char*) {\n"
3033               "    return &x;\n"
3034               "}\n"
3035               "std::string GetTemp();\n"
3036               "void f() {\n"
3037               "    auto a = T(GetTemp().c_str());\n"
3038               "    a->fun();\n"
3039               "}\n");
3040         ASSERT_EQUALS("", errout.str());
3041     }
3042 
invalidLifetime()3043     void invalidLifetime() {
3044         check("void foo(int a) {\n"
3045               "    std::function<void()> f;\n"
3046               "    if (a > 0) {\n"
3047               "        int b = a + 1;\n"
3048               "        f = [&]{ return b; };\n"
3049               "    }\n"
3050               "    f();\n"
3051               "}");
3052         ASSERT_EQUALS("[test.cpp:5] -> [test.cpp:4] -> [test.cpp:7]: (error) Using lambda that captures local variable 'b' that is out of scope.\n", errout.str());
3053 
3054         check("void f(bool b)  {\n"
3055               "  int* x;\n"
3056               "  if(b) {\n"
3057               "    int y[6] = {0,1,2,3,4,5};\n"
3058               "    x = y;\n"
3059               "  }\n"
3060               "  x[3];\n"
3061               "}");
3062         ASSERT_EQUALS(
3063             "[test.cpp:5] -> [test.cpp:4] -> [test.cpp:7]: (error) Using pointer to local variable 'y' that is out of scope.\n",
3064             errout.str());
3065 
3066         check("void foo(int a) {\n"
3067               "    std::function<void()> f;\n"
3068               "    if (a > 0) {\n"
3069               "        int b = a + 1;\n"
3070               "        f = [&]{ return b; };\n"
3071               "        f();\n"
3072               "    }\n"
3073               "}");
3074         ASSERT_EQUALS("", errout.str());
3075 
3076         check("struct a {\n"
3077               "  b();\n"
3078               "  std::list<int> c;\n"
3079               "};\n"
3080               "void a::b() {\n"
3081               "  c.end()\n"
3082               "}");
3083         ASSERT_EQUALS("", errout.str());
3084 
3085         check("void b(char f[], char c[]) {\n"
3086               "  std::string d(c); {\n"
3087               "    std::string e;\n"
3088               "    b(f, e.c_str())\n"
3089               "  }\n"
3090               "}");
3091         ASSERT_EQUALS("", errout.str());
3092 
3093         check("void f(bool b) {\n"
3094               "    std::string s;\n"
3095               "    if(b) {\n"
3096               "        char buf[3];\n"
3097               "        s = buf;\n"
3098               "    }\n"
3099               "    std::cout << s;\n"
3100               "}");
3101         ASSERT_EQUALS("", errout.str());
3102 
3103         check("int &a[];\n"
3104               "void b(){int *c = a};");
3105         ASSERT_EQUALS("", errout.str());
3106 
3107         check("struct A {\n"
3108               "    int x;\n"
3109               "};\n"
3110               "struct B {\n"
3111               "    std::function<void()> x;\n"
3112               "    void f() {\n"
3113               "        this->x = [&] {\n"
3114               "            B y;\n"
3115               "            return y.x;\n"
3116               "        };\n"
3117               "    }\n"
3118               "};");
3119         ASSERT_EQUALS("", errout.str());
3120     }
3121 
deadPointer()3122     void deadPointer() {
3123         check("void f() {\n"
3124               "  int *p = p1;\n"
3125               "  if (cond) {\n"
3126               "    int x;\n"
3127               "    p = &x;\n"
3128               "  }\n"
3129               "  *p = 0;\n"
3130               "}");
3131         ASSERT_EQUALS("[test.cpp:5] -> [test.cpp:4] -> [test.cpp:7]: (error) Using pointer to local variable 'x' that is out of scope.\n", errout.str());
3132 
3133         // FP: don't warn in subfunction
3134         check("void f(struct KEY *key) {\n"
3135               "  key->x = 0;\n"
3136               "}\n"
3137               "\n"
3138               "int main() {\n"
3139               "  struct KEY *tmp = 0;\n"
3140               "  struct KEY k;\n"
3141               "\n"
3142               "  if (condition) {\n"
3143               "    tmp = &k;\n"
3144               "  } else {\n"
3145               "  }\n"
3146               "  f(tmp);\n"
3147               "}");
3148         ASSERT_EQUALS("", errout.str());
3149 
3150         // Don't warn about references (#6399)
3151         check("void f() {\n"
3152               "    wxAuiToolBarItem* former_hover = NULL;\n"
3153               "    for (i = 0, count = m_items.GetCount(); i < count; ++i) {\n"
3154               "        wxAuiToolBarItem& item = m_items.Item(i);\n"
3155               "        former_hover = &item;\n"
3156               "    }\n"
3157               "    if (former_hover != pitem)\n"
3158               "        dosth();\n"
3159               "}");
3160         ASSERT_EQUALS("", errout.str());
3161 
3162         check("void f() {\n"
3163               "    wxAuiToolBarItem* former_hover = NULL;\n"
3164               "    for (i = 0, count = m_items.GetCount(); i < count; ++i) {\n"
3165               "        wxAuiToolBarItem item = m_items.Item(i);\n"
3166               "        former_hover = &item;\n"
3167               "    }\n"
3168               "    if (former_hover != pitem)\n"
3169               "        dosth();\n"
3170               "}");
3171         ASSERT_EQUALS("[test.cpp:5] -> [test.cpp:4] -> [test.cpp:7]: (error) Using pointer to local variable 'item' that is out of scope.\n", errout.str());
3172 
3173         // #6575
3174         check("void trp_deliver_signal()  {\n"
3175               "    union {\n"
3176               "        Uint32 theData[25];\n"
3177               "        EventReport repData;\n"
3178               "    };\n"
3179               "    EventReport * rep = &repData;\n"
3180               "    rep->setEventType(NDB_LE_Connected);\n"
3181               "}");
3182         ASSERT_EQUALS("", errout.str());
3183 
3184         // #8785
3185         check("int f(bool a, bool b) {\n"
3186               "    int *iPtr = 0;\n"
3187               "    if(b) {\n"
3188               "        int x = 42;\n"
3189               "        iPtr = &x;\n"
3190               "    }\n"
3191               "    if(b && a)\n"
3192               "        return *iPtr;\n"
3193               "    return 0;\n"
3194               "}");
3195         ASSERT_EQUALS("[test.cpp:5] -> [test.cpp:4] -> [test.cpp:8]: (error) Using pointer to local variable 'x' that is out of scope.\n", errout.str());
3196     }
3197 
splitNamespaceAuto()3198     void splitNamespaceAuto() { // #10473
3199         check("namespace ns\n"
3200               "{\n"
3201               "    auto var{ 0 };\n"
3202               "}\n"
3203               "namespace ns\n"
3204               "{\n"
3205               "    int i;\n"
3206               "}\n");
3207         ASSERT_EQUALS("", errout.str());
3208     }
3209 
3210 };
3211 
3212 REGISTER_TEST(TestAutoVariables)
3213