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 #include "checkuninitvar.h"
20 #include "library.h"
21 #include "settings.h"
22 #include "testsuite.h"
23 #include "tokenize.h"
24 
25 #include <sstream>
26 #include <string>
27 
28 struct InternalError;
29 
30 
31 class TestUninitVar : public TestFixture {
32 public:
TestUninitVar()33     TestUninitVar() : TestFixture("TestUninitVar") {}
34 
35 private:
36     Settings settings;
37 
run()38     void run() OVERRIDE {
39         LOAD_LIB_2(settings.library, "std.cfg");
40 
41         TEST_CASE(uninitvar1);
42         TEST_CASE(uninitvar_warn_once); // only write 1 warning at a time
43         TEST_CASE(uninitvar_decl);      // handling various types in C and C++ files
44         TEST_CASE(uninitvar_bitop);     // using uninitialized operand in bit operation
45         TEST_CASE(uninitvar_alloc);     // data is allocated but not initialized
46         TEST_CASE(uninitvar_arrays);    // arrays
47         TEST_CASE(uninitvar_class);     // class/struct
48         TEST_CASE(uninitvar_enum);      // enum variables
49         TEST_CASE(uninitvar_if);        // handling if
50         TEST_CASE(uninitvar_loops);     // handling for/while
51         TEST_CASE(uninitvar_switch);    // handling switch
52         TEST_CASE(uninitvar_references); // references
53         TEST_CASE(uninitvar_return);    // return
54         TEST_CASE(uninitvar_assign);    // = {..}
55         TEST_CASE(uninitvar_strncpy);   // strncpy doesn't always null-terminate
56         TEST_CASE(func_uninit_var);     // analyse function calls for: 'int a(int x) { return x+x; }'
57         TEST_CASE(func_uninit_pointer); // analyse function calls for: 'void a(int *p) { *p = 0; }'
58         TEST_CASE(uninitvar_typeof);    // typeof
59         TEST_CASE(uninitvar_ignore);    // ignore cast, *&x, ..
60         TEST_CASE(uninitvar2);
61         TEST_CASE(uninitvar3);          // #3844
62         TEST_CASE(uninitvar4);          // #3869 (reference)
63         TEST_CASE(uninitvar5);          // #3861
64         TEST_CASE(uninitvar2_func);     // function calls
65         TEST_CASE(uninitvar2_value);    // value flow
66         TEST_CASE(uninitStructMember);  // struct members
67         TEST_CASE(uninitvar2_while);
68         TEST_CASE(uninitvar2_4494);      // #4494
69         TEST_CASE(uninitvar2_malloc);    // malloc returns uninitialized data
70         TEST_CASE(uninitvar8); // ticket #6230
71         TEST_CASE(uninitvar9); // ticket #6424
72         TEST_CASE(uninitvar10); // ticket #9467
73         TEST_CASE(uninitvar11); // ticket #9123
74         TEST_CASE(uninitvar12); // #10218 - stream read
75         TEST_CASE(uninitvar13); // #9772
76         TEST_CASE(uninitvar_unconditionalTry);
77         TEST_CASE(uninitvar_funcptr); // #6404
78         TEST_CASE(uninitvar_operator); // #6680
79         TEST_CASE(uninitvar_ternaryexpression); // #4683
80         TEST_CASE(uninitvar_pointertoarray);
81         TEST_CASE(uninitvar_cpp11ArrayInit); // #7010
82         TEST_CASE(uninitvar_rangeBasedFor); // #7078
83         TEST_CASE(uninitvar_static); // #8734
84         TEST_CASE(checkExpr);
85         TEST_CASE(trac_4871);
86         TEST_CASE(syntax_error); // Ticket #5073
87         TEST_CASE(trac_5970);
88         TEST_CASE(valueFlowUninit);
89         TEST_CASE(uninitvar_ipa);
90         TEST_CASE(uninitvar_memberfunction);
91         TEST_CASE(uninitvar_nonmember); // crash in ycmd test
92 
93         TEST_CASE(isVariableUsageDeref); // *p
94 
95         // whole program analysis
96         TEST_CASE(ctu);
97     }
98 
checkUninitVar(const char code[],const char fname[]="test.cpp",bool debugwarnings=false)99     void checkUninitVar(const char code[], const char fname[] = "test.cpp", bool debugwarnings = false) {
100         // Clear the error buffer..
101         errout.str("");
102 
103         // Tokenize..
104         settings.debugwarnings = debugwarnings;
105         Tokenizer tokenizer(&settings, this);
106         std::istringstream istr(code);
107         tokenizer.tokenize(istr, fname);
108 
109         // Check for redundant code..
110         CheckUninitVar checkuninitvar(&tokenizer, &settings, this);
111         checkuninitvar.check();
112 
113         settings.debugwarnings = false;
114         settings.certainty.enable(Certainty::experimental);
115     }
116 
uninitvar1()117     void uninitvar1() {
118         // extracttests.start: int b; int c;
119 
120         // Ticket #2207 - False negative
121         checkUninitVar("void foo() {\n"
122                        "    int a;\n"
123                        "    b = c - a;\n"
124                        "}");
125         ASSERT_EQUALS("[test.cpp:3]: (error) Uninitialized variable: a\n", errout.str());
126 
127         checkUninitVar("void foo() {\n"
128                        "    int a;\n"
129                        "    b = a - c;\n"
130                        "}");
131         ASSERT_EQUALS("[test.cpp:3]: (error) Uninitialized variable: a\n", errout.str());
132 
133         // Ticket #6455 - some compilers allow const variables to be uninitialized
134         // extracttests.disable
135         checkUninitVar("void foo() {\n"
136                        "    const int a;\n"
137                        "    b = c - a;\n"
138                        "}");
139         ASSERT_EQUALS("[test.cpp:3]: (error) Uninitialized variable: a\n", errout.str());
140         // extracttests.enable
141 
142         checkUninitVar("void foo() {\n"
143                        "    int *p;\n"
144                        "    realloc(p,10);\n"
145                        "}");
146         ASSERT_EQUALS("[test.cpp:3]: (error) Uninitialized variable: p\n", errout.str());
147 
148         checkUninitVar("void foo() {\n" // #5240
149                        "    char *p = malloc(100);\n"
150                        "    char *tmp = realloc(p,1000);\n"
151                        "    if (!tmp) free(p);\n"
152                        "}");
153         ASSERT_EQUALS("", errout.str());
154 
155         checkUninitVar("void foo() {\n"
156                        "    int *p = NULL;\n"
157                        "    realloc(p,10);\n"
158                        "}");
159         ASSERT_EQUALS("", errout.str());
160 
161         // dereferencing uninitialized pointer..
162         // extracttests.start: struct Foo { void abcd(); };
163         checkUninitVar("static void foo()\n"
164                        "{\n"
165                        "    Foo *p;\n"
166                        "    p->abcd();\n"
167                        "}");
168         ASSERT_EQUALS("[test.cpp:4]: (error) Uninitialized variable: p\n", errout.str());
169 
170         // extracttests.start: template<class T> struct Foo { void abcd(); };
171         checkUninitVar("static void foo()\n"
172                        "{\n"
173                        "    Foo<int> *p;\n"
174                        "    p->abcd();\n"
175                        "}");
176         ASSERT_EQUALS("[test.cpp:4]: (error) Uninitialized variable: p\n", errout.str());
177 
178         // extracttests.start: struct Foo { void* a; };
179         checkUninitVar("void f(Foo *p)\n"
180                        "{\n"
181                        "    int a;\n"
182                        "    p->a = malloc(4 * a);\n"
183                        "}");
184         ASSERT_EQUALS("[test.cpp:4]: (error) Uninitialized variable: a\n", errout.str());
185 
186         checkUninitVar("static void foo()\n"
187                        "{\n"
188                        "    int *p;\n"
189                        "    delete p;\n"
190                        "}");
191         ASSERT_EQUALS("[test.cpp:4]: (error) Uninitialized variable: p\n", errout.str());
192 
193         checkUninitVar("static void foo()\n"
194                        "{\n"
195                        "    int *p;\n"
196                        "    delete [] p;\n"
197                        "}");
198         ASSERT_EQUALS("[test.cpp:4]: (error) Uninitialized variable: p\n", errout.str());
199 
200         checkUninitVar("static void foo()\n"
201                        "{\n"
202                        "    int *p;\n"
203                        "    *p = 135;\n"
204                        "}");
205         ASSERT_EQUALS("[test.cpp:4]: (error) Uninitialized variable: p\n", errout.str());
206 
207         checkUninitVar("static void foo()\n"
208                        "{\n"
209                        "    int *p;\n"
210                        "    p[0] = 135;\n"
211                        "}");
212         ASSERT_EQUALS("[test.cpp:4]: (error) Uninitialized variable: p\n", errout.str());
213 
214         checkUninitVar("static void foo()\n"
215                        "{\n"
216                        "    int *x;\n"
217                        "    int y = *x;\n"
218                        "}");
219         ASSERT_EQUALS("[test.cpp:4]: (error) Uninitialized variable: x\n", errout.str());
220 
221         checkUninitVar("static void foo()\n"
222                        "{\n"
223                        "    int *x;\n"
224                        "    int &y(*x);\n"
225                        "}");
226         ASSERT_EQUALS("[test.cpp:4]: (error) Uninitialized variable: x\n", errout.str());
227 
228         checkUninitVar("void foo()\n"
229                        "{\n"
230                        "    int x;\n"
231                        "    int *y = &x;\n"
232                        "}");
233         ASSERT_EQUALS("", errout.str());
234 
235         checkUninitVar("void foo()\n"
236                        "{\n"
237                        "    int *x;\n"
238                        "    int *&y = x;\n"
239                        "}");
240         ASSERT_EQUALS("", errout.str());
241 
242         checkUninitVar("void foo()\n"
243                        "{\n"
244                        "    int x = xyz::x;\n"
245                        "}");
246         ASSERT_EQUALS("", errout.str());
247 
248         checkUninitVar("void f()\n"
249                        "{\n"
250                        "    int a;\n"
251                        "    a = 5 + a;\n"
252                        "}");
253         ASSERT_EQUALS("[test.cpp:4]: (error) Uninitialized variable: a\n", errout.str());
254 
255         checkUninitVar("void f()\n"
256                        "{\n"
257                        "    int a;\n"
258                        "    a++;\n"
259                        "}");
260         ASSERT_EQUALS("[test.cpp:4]: (error) Uninitialized variable: a\n", errout.str());
261 
262         checkUninitVar("void f()\n"
263                        "{\n"
264                        "    extern int a;\n"
265                        "    a++;\n"
266                        "}");
267         ASSERT_EQUALS("", errout.str());
268 
269         // extracttests.start: void bar(int);
270         checkUninitVar("void f()\n"
271                        "{\n"
272                        "    int a;\n"
273                        "    bar(4 * a);\n"
274                        "}");
275         ASSERT_EQUALS("[test.cpp:4]: (error) Uninitialized variable: a\n", errout.str());
276 
277         checkUninitVar("static void foo()\n"
278                        "{\n"
279                        "    int i;\n"
280                        "    if (i);\n"
281                        "}");
282         ASSERT_EQUALS("[test.cpp:4]: (error) Uninitialized variable: i\n", errout.str());
283 
284         checkUninitVar("static void foo()\n"
285                        "{\n"
286                        "    int i;\n"
287                        "    for (int x = 0; i < 10; x++);\n"
288                        "}");
289         ASSERT_EQUALS("[test.cpp:4]: (error) Uninitialized variable: i\n", errout.str());
290 
291         checkUninitVar("static void foo()\n"
292                        "{\n"
293                        "    int i;\n"
294                        "    for (int x = 0; x < 10; i++);\n"
295                        "}");
296         ASSERT_EQUALS("[test.cpp:4]: (error) Uninitialized variable: i\n", errout.str());
297 
298         checkUninitVar("static void foo(int x)\n"
299                        "{\n"
300                        "    int i;\n"
301                        "    if (x)\n"
302                        "        i = 0;\n"
303                        "    i++;\n"
304                        "}");
305         ASSERT_EQUALS("[test.cpp:6]: (error) Uninitialized variable: i\n", errout.str());
306 
307         checkUninitVar("static void foo()\n"
308                        "{\n"
309                        "    int ar[10];\n"
310                        "    int i;\n"
311                        "    ar[i] = 0;\n"
312                        "}");
313         ASSERT_EQUALS("[test.cpp:5]: (error) Uninitialized variable: i\n", errout.str());
314 
315         checkUninitVar("static void foo()\n"
316                        "{\n"
317                        "    int x, y;\n"
318                        "    x = (y = 10);\n"
319                        "    int z = y * 2;\n"
320                        "}", "test.cpp", false);
321         ASSERT_EQUALS("", errout.str());
322 
323         checkUninitVar("static void foo() {\n"
324                        "    int x, y;\n"
325                        "    x = ((y) = 10);\n"
326                        "}");
327         ASSERT_EQUALS("", errout.str());
328 
329         // Ticket #3597
330         checkUninitVar("void f() {\n"
331                        "    int a;\n"
332                        "    int b = 1;\n"
333                        "    (b += a) = 1;\n"
334                        "}");
335         ASSERT_EQUALS("[test.cpp:4]: (error) Uninitialized variable: a\n", errout.str());
336 
337         checkUninitVar("int f() {\n"
338                        "    int a,b,c;\n"
339                        "    a = b = c;\n"
340                        "}", "test.cpp", /*debugwarnings=*/ false);
341         ASSERT_EQUALS("[test.cpp:3]: (error) Uninitialized variable: c\n", errout.str());
342 
343         checkUninitVar("static void foo()\n"
344                        "{\n"
345                        "    Foo p;\n"
346                        "    p.abcd();\n"
347                        "}");
348         ASSERT_EQUALS("", errout.str());
349 
350         checkUninitVar("static void foo()\n"
351                        "{\n"
352                        "    Foo p;\n"
353                        "    int x = p.abcd();\n"
354                        "}");
355         ASSERT_EQUALS("", errout.str());
356 
357         // Unknown types
358         // extracttests.disable
359         {
360             checkUninitVar("void a()\n"
361                            "{\n"
362                            "    A ret;\n"
363                            "    return ret;\n"
364                            "}");
365             ASSERT_EQUALS("", errout.str());
366 
367             checkUninitVar("void a()\n"
368                            "{\n"
369                            "    A ret;\n"
370                            "    return ret;\n"
371                            "}\n",
372                            "test.c");
373             ASSERT_EQUALS("[test.c:4]: (error) Uninitialized variable: ret\n", errout.str());
374         }
375         // extracttests.enable
376 
377         // #3916 - avoid false positive
378         checkUninitVar("void f(float x) {\n"
379                        "  union lf { long l; float f; } u_lf;\n"
380                        "  float hx = (u_lf.f = (x), u_lf.l);\n"
381                        "}",
382                        "test.c", false);
383         ASSERT_EQUALS("", errout.str());
384 
385         checkUninitVar("void a()\n"
386                        "{\n"
387                        "    int x[10];\n"
388                        "    int *y = x;\n"
389                        "}");
390         ASSERT_EQUALS("", errout.str());
391 
392         checkUninitVar("void a()\n"
393                        "{\n"
394                        "    int x;\n"
395                        "    int *y = &x;\n"
396                        "    *y = 0;\n"
397                        "    x++;\n"
398                        "}", "test.cpp", false);
399         ASSERT_EQUALS("", errout.str());
400 
401         checkUninitVar("void a()\n"
402                        "{\n"
403                        "    char x[10], y[10];\n"
404                        "    char *z = x;\n"
405                        "    memset(z, 0, sizeof(x));\n"
406                        "    memcpy(y, x, sizeof(x));\n"
407                        "}", "test.cpp", false);
408         ASSERT_EQUALS("", errout.str());
409 
410         // Handling >> and <<
411         {
412             checkUninitVar("int a() {\n"
413                            "    int ret;\n"
414                            "    std::cin >> ret;\n"
415                            "    ret++;\n"
416                            "}");
417             ASSERT_EQUALS("", errout.str());
418 
419             checkUninitVar("void f(int b) {\n"
420                            "    int a;\n"
421                            "    std::cin >> b >> a;\n"
422                            "    return a;"
423                            "}");
424             ASSERT_EQUALS("", errout.str());
425 
426             checkUninitVar("void f() {\n"
427                            "    int ret[2];\n"
428                            "    std::cin >> ret[0];\n"
429                            "}");
430             ASSERT_EQUALS("", errout.str());
431 
432             checkUninitVar("void f(int i) {\n"
433                            "    int a;\n"
434                            "    i >> a;\n"
435                            "}");
436             ASSERT_EQUALS("[test.cpp:3]: (error) Uninitialized variable: a\n", errout.str());
437 
438             checkUninitVar("int a() {\n"
439                            "    int ret;\n"
440                            "    int a = value >> ret;\n"
441                            "}\n",
442                            "test.c");
443             ASSERT_EQUALS("[test.c:3]: (error) Uninitialized variable: ret\n", errout.str());
444 
445             checkUninitVar("void foo() {\n"   // #3707
446                            "    Node node;\n"
447                            "    int x;\n"
448                            "    node[\"abcd\"] >> x;\n"
449                            "}");
450             ASSERT_EQUALS("", errout.str());
451 
452             checkUninitVar("int a(FArchive &arc) {\n"   // #3060 (initialization through operator<<)
453                            "    int *p;\n"
454                            "    arc << p;\n" // <- TODO initialization?
455                            "    return *p;\n"
456                            "}");
457             ASSERT_EQUALS("[test.cpp:3]: (error) Uninitialized variable: p\n", errout.str());
458 
459             checkUninitVar("void a() {\n"
460                            "    int ret;\n"
461                            "    a = value << ret;\n"
462                            "}\n",
463                            "test.c");
464             ASSERT_EQUALS("[test.c:3]: (error) Uninitialized variable: ret\n", errout.str());
465 
466             // #4320 says this is a FP. << is overloaded.
467             checkUninitVar("int f() {\n"
468                            "    int a;\n"
469                            "    a << 1;\n"  // <- TODO initialization?
470                            "    return a;\n"
471                            "}");
472             ASSERT_EQUALS("[test.cpp:3]: (error) Uninitialized variable: a\n", errout.str());
473 
474             // #4673
475             checkUninitVar("void f() {\n"
476                            "    int a;\n"
477                            "    std::cout << a;\n"
478                            "}");
479             ASSERT_EQUALS("[test.cpp:3]: (error) Uninitialized variable: a\n", errout.str());
480 
481             checkUninitVar("void f(std::ostringstream& os) {\n"
482                            "    int a;\n"
483                            "    os << a;\n"
484                            "}");
485             ASSERT_EQUALS("[test.cpp:3]: (error) Uninitialized variable: a\n", errout.str());
486 
487             checkUninitVar("void f() {\n"
488                            "    int a;\n"
489                            "    std::cout << 1 << a;\n"
490                            "}");
491             ASSERT_EQUALS("[test.cpp:3]: (error) Uninitialized variable: a\n", errout.str());
492 
493             checkUninitVar("void f(std::ostringstream& os) {\n"
494                            "    int a;\n"
495                            "    os << 1 << a;\n"
496                            "}");
497             ASSERT_EQUALS("[test.cpp:3]: (error) Uninitialized variable: a\n", errout.str());
498 
499             {
500                 // #9422
501                 checkUninitVar("void f() {\n"
502                                "  char *p = new char[10];\n"
503                                "  std::cout << (void *)p << 1;\n"
504                                "}");
505                 ASSERT_EQUALS("", errout.str());
506 
507                 checkUninitVar("void f() {\n"
508                                "  char p[10];\n"
509                                "  std::cout << (void *)p << 1;\n"
510                                "}");
511                 ASSERT_EQUALS("", errout.str());
512 
513                 checkUninitVar("void f() {\n"
514                                "  char *p = new char[10];\n"
515                                "  std::cout << p << 1;\n"
516                                "}");
517                 ASSERT_EQUALS("[test.cpp:3]: (error) Memory is allocated but not initialized: p\n", errout.str());
518 
519                 checkUninitVar("void f() {\n"
520                                "  char p[10];\n"
521                                "  std::cout << p << 1;\n"
522                                "}");
523                 ASSERT_EQUALS("[test.cpp:3]: (error) Uninitialized variable: p\n", errout.str());
524 
525                 checkUninitVar("void f() {\n"
526                                "  char p[10];\n"
527                                "  std::cout << *p << 1;\n"
528                                "}");
529                 ASSERT_EQUALS("[test.cpp:3]: (error) Uninitialized variable: p\n", errout.str());
530             }
531         }
532 
533         // #8494 : Overloaded & operator
534         checkUninitVar("void f() {\n"
535                        "  int x;\n"
536                        "  a & x;\n"
537                        "}");
538         ASSERT_EQUALS("", errout.str());
539 
540         checkUninitVar("void f(int a) {\n"
541                        "  int x;\n"
542                        "  a & x;\n"
543                        "}");
544         ASSERT_EQUALS("[test.cpp:3]: (error) Uninitialized variable: x\n", errout.str());
545 
546         checkUninitVar("void f() {\n"
547                        "  int a,b,c;\n"
548                        "  ar & a & b & c;\n"
549                        "}");
550         ASSERT_EQUALS("", errout.str());
551 
552         checkUninitVar("void a() {\n"   // asm
553                        "    int x;\n"
554                        "    asm();\n"
555                        "    x++;\n"
556                        "}");
557         ASSERT_EQUALS("", errout.str());
558 
559         checkUninitVar("void a()\n"
560                        "{\n"
561                        "    int x[10];\n"
562                        "    struct xyz xyz1 = { .x = x };\n"
563                        "}");
564         ASSERT_EQUALS("", errout.str());
565 
566         checkUninitVar("void a()\n"
567                        "{\n"
568                        "    struct S *s;\n"
569                        "    s->x = 0;\n"
570                        "}");
571         ASSERT_EQUALS("[test.cpp:4]: (error) Uninitialized variable: s\n", errout.str());
572 
573         checkUninitVar("void foo()\n"
574                        "{\n"
575                        "   char *buf = malloc(100);\n"
576                        "   struct ABC *abc = buf;\n"
577                        "}");
578         ASSERT_EQUALS("", errout.str());
579 
580         checkUninitVar("class Fred {\n"
581                        "public:\n"
582                        "    FILE *f;\n"
583                        "    ~Fred();\n"
584                        "}\n"
585                        "Fred::~Fred()\n"
586                        "{\n"
587                        "    fclose(f);\n"
588                        "}");
589         ASSERT_EQUALS("", errout.str());
590 
591         checkUninitVar("void f()\n"
592                        "{\n"
593                        "    int c;\n"
594                        "    ab(sizeof(xyz), &c);\n"
595                        "    if (c);\n"
596                        "}");
597         ASSERT_EQUALS("", errout.str());
598 
599         checkUninitVar("void f()\n"
600                        "{\n"
601                        "    int c;\n"
602                        "    a = (f2(&c));\n"
603                        "    c++;\n"
604                        "}");
605         ASSERT_EQUALS("", errout.str());
606 
607         checkUninitVar("void f(int a)\n"
608                        "{\n"
609                        "    if (a) {\n"
610                        "        char *p;\n"
611                        "        *p = 0;\n"
612                        "    }\n"
613                        "}");
614         ASSERT_EQUALS("[test.cpp:5]: (error) Uninitialized variable: p\n", errout.str());
615 
616         // +=
617         checkUninitVar("void f()\n"
618                        "{\n"
619                        "    int c;\n"
620                        "    c += 2;\n"
621                        "}");
622         ASSERT_EQUALS("[test.cpp:4]: (error) Uninitialized variable: c\n", errout.str());
623 
624         checkUninitVar("void f()\n"
625                        "{\n"
626                        "    int a[10];\n"
627                        "    a[0] = 10 - a[1];\n"
628                        "}");
629         ASSERT_EQUALS("[test.cpp:4]: (error) Uninitialized variable: a[1]\n", errout.str());
630 
631         // goto/setjmp/longjmp..
632         checkUninitVar("void foo(int x)\n"
633                        "{\n"
634                        "    long b;\n"
635                        "    if (g()) {\n"
636                        "        b =2;\n"
637                        "        goto found;\n"
638                        "    }\n"
639                        "\n"
640                        "    return;\n"
641                        "\n"
642                        "found:\n"
643                        "    int a = b;\n"
644                        "}", "test.cpp", false);
645         ASSERT_EQUALS("", errout.str());
646 
647         checkUninitVar("int foo()\n"
648                        "{\n"
649                        "    jmp_buf env;\n"
650                        "    int a;\n"
651                        "    int val = setjmp(env);\n"
652                        "    if(val)\n"
653                        "        return a;\n"
654                        "    a = 1;\n"
655                        "    longjmp(env, 1);\n"
656                        "}");
657         ASSERT_EQUALS("", errout.str());
658 
659         // macro_for..
660         checkUninitVar("int foo()\n"
661                        "{\n"
662                        "  int retval;\n"
663                        "  if (condition) {\n"
664                        "    for12(1,2) { }\n"
665                        "    retval = 1;\n"
666                        "  }\n"
667                        "  else\n"
668                        "    retval = 2;\n"
669                        "  return retval;\n"
670                        "}");
671         ASSERT_EQUALS("", errout.str());
672 
673         checkUninitVar("int foo()\n"
674                        "{\n"
675                        "    int i;\n"
676                        "    goto exit;\n"
677                        "    i++;\n"
678                        "exit:\n"
679                        "}", "test.cpp", false);
680         ASSERT_EQUALS("", errout.str());
681 
682         checkUninitVar("int foo() {\n"
683                        "    int x,y=0;\n"
684                        "again:\n"
685                        "    if (y) return x;\n"
686                        "    x = a;\n"
687                        "    y = 1;\n"
688                        "    goto again;\n"
689                        "}", "test.c", false);
690         ASSERT_EQUALS("", errout.str());
691 
692         // Ticket #3873 (false positive)
693         checkUninitVar("MachineLoopRange *MachineLoopRanges::getLoopRange(const MachineLoop *Loop) {\n"
694                        "  MachineLoopRange *&Range = Cache[Loop];\n"
695                        "  if (!Range)\n"
696                        "    Range = new MachineLoopRange(Loop, Allocator, *Indexes);\n"
697                        "  return Range;\n"
698                        "}");
699         ASSERT_EQUALS("", errout.str());
700 
701         // #4040 - False positive
702         checkUninitVar("int f(int x)  {\n"
703                        "    int iter;\n"
704                        "    {\n"
705                        "        union\n"
706                        "        {\n"
707                        "            int asInt;\n"
708                        "            double asDouble;\n"
709                        "        };\n"
710                        "\n"
711                        "        iter = x;\n"
712                        "    }\n"
713                        "    return 1 + iter;\n"
714                        "}", "test.cpp", false);
715         ASSERT_EQUALS("", errout.str());
716 
717         // C++11 style initialization
718         checkUninitVar("int f() {\n"
719                        "    int i = 0;\n"
720                        "    int j{ i };\n"
721                        "    return j;\n"
722                        "}");
723         ASSERT_EQUALS("", errout.str());
724 
725         // Ticket #5646
726         checkUninitVar("float foo() {\n"
727                        "  float source[2] = {3.1, 3.1};\n"
728                        "  float (*sink)[2] = &source;\n"
729                        "  return (*sink)[0];\n"
730                        "}");
731         ASSERT_EQUALS("", errout.str());
732 
733         // Ticket #9296
734         checkUninitVar("void f(void)\n"
735                        "{\n"
736                        "    int x;\n"
737                        "    int z = (x) & ~__round_mask(1, 1);\n"
738                        "}");
739         ASSERT_EQUALS("[test.cpp:4]: (error) Uninitialized variable: x\n", errout.str());
740 
741         checkUninitVar("void f(void)\n"
742                        "{\n"
743                        "    int x;\n"
744                        "    int z = (x) | ~__round_mask(1, 1);\n"
745                        "}");
746         ASSERT_EQUALS("[test.cpp:4]: (error) Uninitialized variable: x\n", errout.str());
747 
748         checkUninitVar("int __round_mask(int, int);\n"
749                        "void f(void)\n"
750                        "{\n"
751                        "    int x;\n"
752                        "    int* z = &x;\n"
753                        "}");
754         ASSERT_EQUALS("", errout.str());
755     }
756 
uninitvar_warn_once()757     void uninitvar_warn_once() {
758         // extracttests.start: int a; int b;
759 
760         checkUninitVar("void f() {\n"
761                        "  int x;\n"
762                        "  a = x;\n"
763                        "  b = x;\n"
764                        "}");
765         ASSERT_EQUALS("[test.cpp:3]: (error) Uninitialized variable: x\n", errout.str());
766     }
767 
768     // Handling of unknown types. Assume they are POD in C.
uninitvar_decl()769     void uninitvar_decl() {
770         const char code[] = "void f() {\n"
771                             "    dfs a;\n"
772                             "    return a;\n"
773                             "}";
774 
775         // Assume dfs is a non POD type if file is C++
776         checkUninitVar(code, "test.cpp");
777         ASSERT_EQUALS("", errout.str());
778 
779         // Assume dfs is a POD type if file is C
780         checkUninitVar(code, "test.c");
781         ASSERT_EQUALS("[test.c:3]: (error) Uninitialized variable: a\n", errout.str());
782 
783         const char code2[] = "struct AB { int a,b; };\n"
784                              "void f() {\n"
785                              "    struct AB ab;\n"
786                              "    return ab;\n"
787                              "}";
788         checkUninitVar(code2, "test.cpp");
789         ASSERT_EQUALS("[test.cpp:4]: (error) Uninitialized struct member: ab.a\n"
790                       "[test.cpp:4]: (error) Uninitialized struct member: ab.b\n", errout.str());
791         checkUninitVar(code2, "test.c");
792         ASSERT_EQUALS("[test.c:4]: (error) Uninitialized variable: ab\n", errout.str());
793 
794         // Ticket #3890 - False positive for std::map
795         checkUninitVar("void f() {\n"
796                        "    std::map<int,bool> x;\n"
797                        "    return x;\n"
798                        "}");
799         ASSERT_EQUALS("", errout.str());
800 
801         // Ticket #3906 - False positive for std::vector pointer
802         checkUninitVar("void f() {\n"
803                        "    std::vector<int> *x = NULL;\n"
804                        "    return x;\n"
805                        "}", "test.cpp", false);
806         ASSERT_EQUALS("", errout.str());
807 
808         // Ticket #6701 - Variable name is a POD type according to cfg
809         const char xmldata[] = "<?xml version=\"1.0\"?>\n"
810                                "<def format=\"1\">"
811                                "  <podtype name=\"_tm\"/>"
812                                "</def>";
813         settings.library.loadxmldata(xmldata, sizeof(xmldata));
814         checkUninitVar("void f() {\n"
815                        "  Fred _tm;\n"
816                        "  _tm.dostuff();\n"
817                        "}");
818         ASSERT_EQUALS("", errout.str());
819 
820         // Ticket #7822 - Array type
821         checkUninitVar("A *f() {\n"
822                        "    A a,b;\n"
823                        "    b[0] = 0;"
824                        "    return a;\n"
825                        "}", "test.c", false);
826         ASSERT_EQUALS("", errout.str());
827     }
828 
uninitvar3()829     void uninitvar3() { // #3844
830         // avoid false positive
831         checkUninitVar("namespace std _GLIBCXX_VISIBILITY(default)\n"
832                        "{\n"
833                        "_GLIBCXX_BEGIN_NAMESPACE_CONTAINER\n"
834                        "    typedef unsigned long _Bit_type;\n"
835                        "    struct _Bit_reference\n"
836                        "    {\n"
837                        "        _Bit_type * _M_p;\n"
838                        "        _Bit_type _M_mask;\n"
839                        "        _Bit_reference(_Bit_type * __x, _Bit_type __y)\n"
840                        "         : _M_p(__x), _M_mask(__y) { }\n"
841                        "    };\n"
842                        "}");
843         ASSERT_EQUALS("", errout.str());
844     }
845 
uninitvar_bitop()846     void uninitvar_bitop() {
847         // extracttests.start: int a; int c;
848 
849         checkUninitVar("void foo() {\n"
850                        "    int b;\n"
851                        "    c = a | b;\n"
852                        "}");
853         ASSERT_EQUALS("[test.cpp:3]: (error) Uninitialized variable: b\n", errout.str());
854 
855         checkUninitVar("void foo() {\n"
856                        "    int b;\n"
857                        "    c = b | a;\n"
858                        "}");
859         ASSERT_EQUALS("[test.cpp:3]: (error) Uninitialized variable: b\n", errout.str());
860     }
861 
862     // if..
uninitvar_if()863     void uninitvar_if() {
864         // extracttests.start: struct Foo { void abcd(); };
865         checkUninitVar("static void foo(int x)\n"
866                        "{\n"
867                        "    Foo *p;\n"
868                        "    if (x)\n"
869                        "        p = new Foo;\n"
870                        "    p->abcd();\n"
871                        "}");
872         ASSERT_EQUALS("[test.cpp:6]: (error) Uninitialized variable: p\n", errout.str());
873 
874         checkUninitVar("static void foo(int x)\n"
875                        "{\n"
876                        "    int a;\n"
877                        "    if (x==1);\n"
878                        "    if (x==2);\n"
879                        "    x = a;\n"
880                        "}");
881         ASSERT_EQUALS("[test.cpp:6]: (error) Uninitialized variable: a\n", errout.str());
882 
883         checkUninitVar("int foo() {\n"
884                        "    int i;\n"
885                        "    if (1)\n"
886                        "        i = 11;\n"
887                        "    return i;\n"
888                        "}");
889         ASSERT_EQUALS("", errout.str());
890 
891         checkUninitVar("int bar(int x) {\n"
892                        "    int n;\n"
893                        "    if ( x == 23)\n"
894                        "      n = 1;\n"
895                        "    else if ( x == 11 )\n"
896                        "      n = 2;\n"
897                        "    return n;\n"
898                        "}");
899         TODO_ASSERT_EQUALS("error", "", errout.str());
900 
901         checkUninitVar("int foo()\n"
902                        "{\n"
903                        "    int i;\n"
904                        "    if (x)\n"
905                        "        i = 22;\n"
906                        "    else\n"
907                        "        i = 33;\n"
908                        "    return i;\n"
909                        "}");
910         ASSERT_EQUALS("", errout.str());
911 
912         checkUninitVar("int foo(int x)\n" // #5503
913                        "{\n"
914                        "    int i;\n"
915                        "    if (x < 2)\n"
916                        "        i = 22;\n"
917                        "    else if (x >= 2)\n" // condition is always true
918                        "        i = 33;\n"
919                        "    return i;\n"
920                        "}");
921         ASSERT_EQUALS("", errout.str());
922 
923         checkUninitVar("int foo()\n"
924                        "{\n"
925                        "    int i;\n"
926                        "    if (x)\n"
927                        "        i = 22;\n"
928                        "    else\n"
929                        "    {\n"
930                        "        char *y = {0};\n"
931                        "        i = 33;\n"
932                        "    }\n"
933                        "    return i;\n"
934                        "}");
935         ASSERT_EQUALS("", errout.str());
936 
937         checkUninitVar("int foo()\n"
938                        "{\n"
939                        "    int i;\n"
940                        "    if (x)\n"
941                        "    {\n"
942                        "        struct abc abc1 = (struct abc) { .a=0, .b=0, .c=0 };\n"
943                        "        i = 22;\n"
944                        "    }\n"
945                        "    else\n"
946                        "    {\n"
947                        "        i = 33;\n"
948                        "    }\n"
949                        "    return i;\n"
950                        "}", "test.cpp", false);
951         ASSERT_EQUALS("", errout.str());
952 
953         checkUninitVar("static void foo(int x)\n"
954                        "{\n"
955                        "    Foo *p;\n"
956                        "    if (x)\n"
957                        "        p = new Foo;\n"
958                        "    if (x)\n"
959                        "        p->abcd();\n"
960                        "}");
961         ASSERT_EQUALS("", errout.str());
962 
963         checkUninitVar("void foo(int a)\n"
964                        "{\n"
965                        "    int n;\n"
966                        "    int condition;\n"
967                        "    if(a == 1) {\n"
968                        "        n=0;\n"
969                        "        condition=0;\n"
970                        "    }\n"
971                        "    else {\n"
972                        "        n=1;\n"
973                        "    }\n"
974                        "\n"
975                        "    if( n == 0) {\n"
976                        "        a=condition;\n"
977                        "    }\n"
978                        "}");
979         ASSERT_EQUALS("", errout.str());
980 
981         checkUninitVar("void f()\n"
982                        "{\n"
983                        "    C *c;\n"
984                        "    if (fun(&c));\n"
985                        "    c->Release();\n"
986                        "}");
987         ASSERT_EQUALS("", errout.str());
988 
989         checkUninitVar("void f() {\n"
990                        "    C c;\n"
991                        "    if (fun(&c.d));\n"
992                        "    return c;\n"
993                        "}");
994         ASSERT_EQUALS("", errout.str());
995 
996         checkUninitVar("void f() {\n"
997                        "   char a[10];\n"
998                        "   if (a[0] = x){}\n"
999                        "}");
1000         ASSERT_EQUALS("", errout.str());
1001 
1002         checkUninitVar("int foo(int x)\n"
1003                        "{\n"
1004                        "    int i;\n"
1005                        "    if (one())\n"
1006                        "        i = 1;\n"
1007                        "    else\n"
1008                        "        return 3;\n"
1009                        "    return i;\n"
1010                        "}");
1011         ASSERT_EQUALS("", errout.str());
1012 
1013         // Ticket #2207 - False positive
1014         checkUninitVar("void foo(int x) {\n"
1015                        "    int a;\n"
1016                        "    if (x)\n"
1017                        "        a = 1;\n"
1018                        "    if (!x)\n"
1019                        "        return;\n"
1020                        "    b = (c - a);\n"
1021                        "}");
1022         ASSERT_EQUALS("", errout.str());
1023 
1024         checkUninitVar("int foo()\n"
1025                        "{\n"
1026                        "    int ret;\n"
1027                        "    if (one())\n"
1028                        "        ret = 1;\n"
1029                        "    else\n"
1030                        "        throw 3;\n"
1031                        "    return ret;\n"
1032                        "}");
1033         ASSERT_EQUALS("", errout.str());
1034 
1035         checkUninitVar("int f(int a)\n"
1036                        "{\n"
1037                        "    int ret;\n"
1038                        "    if (a == 1)\n"
1039                        "        ret = 1;\n"
1040                        "    else\n"
1041                        "        XYZ ret = 2;\n"  // XYZ may be an unexpanded macro so bailout the checking of "ret".
1042                        "    return ret;\n"
1043                        "}");
1044         ASSERT_EQUALS("[test.cpp:8]: (error) Uninitialized variable: ret\n", errout.str());
1045 
1046         checkUninitVar("int f(int a, int b)\n"
1047                        "{\n"
1048                        "   int x;\n"
1049                        "   if (a)\n"
1050                        "      x = a;\n"
1051                        "   else {\n"
1052                        "      do { } while (f2());\n"
1053                        "      x = b;\n"
1054                        "   }\n"
1055                        "   return x;\n"
1056                        "}");
1057         ASSERT_EQUALS("", errout.str());
1058 
1059         checkUninitVar("void foo(long verbose,bool bFlag)\n"
1060                        "{\n"
1061                        "  double t;\n"
1062                        "  if (bFlag)\n"
1063                        "  {\n"
1064                        "    if (verbose)\n"
1065                        "      t = 1;\n"
1066                        "    if (verbose)\n"
1067                        "      std::cout << (12-t);\n"
1068                        "  }\n"
1069                        "}");
1070         ASSERT_EQUALS("", errout.str());
1071 
1072         checkUninitVar("int test(int cond1, int cond2) {\n"
1073                        "  int foo;\n"
1074                        "  if (cond1 || cond2) {\n"
1075                        "     if (cond2)\n"
1076                        "        foo = 0;\n"
1077                        "  }\n"
1078                        "  if (cond2) {\n"
1079                        "    int t = foo*foo;\n"
1080                        "  }\n"
1081                        "}");
1082         ASSERT_EQUALS("", errout.str());
1083 
1084         checkUninitVar("void foo(int *pix) {\n"
1085                        "    int dest_x;\n"
1086                        "    {\n"
1087                        "        if (pix)\n"
1088                        "            dest_x = 123;\n"
1089                        "    }\n"
1090                        "    if (pix)\n"
1091                        "        a = dest_x;\n" // <- not uninitialized
1092                        "}");
1093         ASSERT_EQUALS("", errout.str());
1094 
1095         // ? :
1096         checkUninitVar("static void foo(int v) {\n"
1097                        "    int x;\n"
1098                        "    x = v <= 0 ? -1 : x;\n"
1099                        "}");
1100         ASSERT_EQUALS("[test.cpp:3]: (error) Uninitialized variable: x\n", errout.str());
1101 
1102         checkUninitVar("void foo()\n"
1103                        "{\n"
1104                        "    const char *msgid1, *msgid2;\n"
1105                        "    int ret = bar(&msgid1);\n"
1106                        "    if (ret > 0) {\n"
1107                        "        ret = bar(&msgid2);\n"
1108                        "    }\n"
1109                        "    ret = ret <= 0 ? -1 :\n"
1110                        "          strcmp(msgid1, msgid2) == 0;\n"
1111                        "}");
1112         ASSERT_EQUALS("", errout.str());
1113 
1114         checkUninitVar("void foo(int a, int b)\n"
1115                        "{\n"
1116                        "    int x; x = (a<b) ? 1 : 0;\n"
1117                        "    int y = y;\n"
1118                        "}");
1119         ASSERT_EQUALS("[test.cpp:4]: (error) Uninitialized variable: y\n", errout.str());
1120 
1121         checkUninitVar("void foo() {\n" // pidgin-2.11.0/finch/libgnt/gnttree.c
1122                        "  int x = (x = bar()) ? x : 0;\n"
1123                        "}");
1124         ASSERT_EQUALS("", errout.str());
1125 
1126         // ; { .. }
1127         checkUninitVar("int foo()\n"
1128                        "{\n"
1129                        "  int retval;\n"
1130                        "  if (condition) {\n"
1131                        "    { }\n"
1132                        "    retval = 1; }\n"
1133                        "  else\n"
1134                        "    retval = 2;\n"
1135                        "  return retval;\n"
1136                        "}");
1137         ASSERT_EQUALS("", errout.str());
1138 
1139         checkUninitVar("void foo()\n"
1140                        "{\n"
1141                        "  {\n"
1142                        "    for (int i = 0; i < 10; ++i)\n"
1143                        "    { }\n"
1144                        "  }\n"
1145                        "\n"
1146                        "  { }\n"
1147                        "}");
1148         ASSERT_EQUALS("", errout.str());
1149 
1150         // ({ .. })
1151         checkUninitVar("void f() {\n"
1152                        "    int x;\n"
1153                        "    if (abc) { x = 123; }\n"
1154                        "    else { a = ({b=c;}); x = 456; }\n"
1155                        "    ++x;\n"
1156                        "}");
1157         ASSERT_EQUALS("", errout.str());
1158 
1159         // Ticket #3098 - False negative uninitialized variable
1160         checkUninitVar("void f()\n"
1161                        "{\n"
1162                        "    char *c1,*c2;\n"
1163                        "    if(strcoll(c1,c2))\n"
1164                        "    {\n"
1165                        "    }\n"
1166                        "}");
1167         ASSERT_EQUALS("[test.cpp:4]: (error) Uninitialized variable: c1\n"
1168                       "[test.cpp:4]: (error) Uninitialized variable: c2\n", errout.str());
1169 
1170         checkUninitVar("void f(char *c1, char *c2)\n"
1171                        "{\n"
1172                        "    if(strcoll(c1,c2))\n"
1173                        "    {\n"
1174                        "    }\n"
1175                        "}");
1176         ASSERT_EQUALS("", errout.str());
1177 
1178         checkUninitVar("void f()\n"
1179                        "{\n"
1180                        "    char *c1;\n"
1181                        "    c1=strcpy(c1,\"test\");\n"
1182                        "}");
1183         ASSERT_EQUALS("[test.cpp:4]: (error) Uninitialized variable: c1\n", errout.str());
1184 
1185         checkUninitVar("void f(char *c1)\n"
1186                        "{\n"
1187                        "    c1=strcpy(c1,\"test\");\n"
1188                        "}");
1189         ASSERT_EQUALS("", errout.str());
1190 
1191         checkUninitVar("void f() {\n"
1192                        "  X var;\n"
1193                        "  memset(var, 0, sizeof(var));\n"
1194                        "}", "test.c");
1195         ASSERT_EQUALS("", errout.str());
1196     }
1197 
1198 
1199     // handling for/while loops..
uninitvar_loops()1200     void uninitvar_loops() {
1201         // for..
1202         // extracttests.start: void b(int);
1203         checkUninitVar("void f()\n"
1204                        "{\n"
1205                        "    for (int i = 0; i < 4; ++i) {\n"
1206                        "        int a;\n"
1207                        "        b(4*a);\n"
1208                        "    }"
1209                        "}");
1210         ASSERT_EQUALS("[test.cpp:5]: (error) Uninitialized variable: a\n", errout.str());
1211 
1212         checkUninitVar("void f() {\n"
1213                        "    int k;\n"
1214                        "    for (int i = 0; i < 4; ++i) {\n"
1215                        "        k = k + 2;\n"
1216                        "    }\n"
1217                        "}");
1218         ASSERT_EQUALS("[test.cpp:4]: (error) Uninitialized variable: k\n", errout.str());
1219 
1220         checkUninitVar("void f() {\n"
1221                        "    gchar sel[10];\n"
1222                        "    for (int i = 0; i < 4; ++i) {\n"
1223                        "        int sz = sizeof(sel);\n"
1224                        "    }\n"
1225                        "}");
1226         ASSERT_EQUALS("", errout.str());
1227 
1228         checkUninitVar("enum ABCD { A, B, C, D };\n"
1229                        "\n"
1230                        "static void f(char *str ) {\n"
1231                        "    enum ABCD i;\n"
1232                        "    for (i = 0; i < D; i++) {\n"
1233                        "        str[i] = 0;\n"
1234                        "    }\n"
1235                        "}");
1236         ASSERT_EQUALS("", errout.str());
1237 
1238         checkUninitVar("void x() {\n"
1239                        "    do  {\n"
1240                        "        Token * tok;\n"
1241                        "        for (tok = a; tok; tok = tok->next())\n"
1242                        "        {\n"
1243                        "        }\n"
1244                        "    } while (tok2);\n"
1245                        "}");
1246         ASSERT_EQUALS("", errout.str());
1247 
1248         checkUninitVar("void foo(void) {\n"
1249                        "    int a = 0;\n"
1250                        "    int x;\n"
1251                        "\n"
1252                        "    for (;;) {\n"
1253                        "        if (!a || 12 < x) {\n" // <- x is not uninitialized
1254                        "            a = 1;\n"
1255                        "            x = 2;\n"
1256                        "        }\n"
1257                        "    }\n"
1258                        "}");
1259         ASSERT_EQUALS("", errout.str());
1260 
1261         checkUninitVar("void foo(void) {\n"
1262                        "    int a = 0;\n"
1263                        "    int x;\n"
1264                        "\n"
1265                        "    for (;;) {\n"
1266                        "        if (!a || 12 < x) {\n" // <- x is uninitialized
1267                        "            a = 1;\n"
1268                        "        }\n"
1269                        "    }\n"
1270                        "}");
1271         ASSERT_EQUALS("[test.cpp:6]: (error) Uninitialized variable: x\n", errout.str());
1272 
1273         checkUninitVar("void foo(int n) {\n"
1274                        "  int one[10];\n"
1275                        "  for (int rank = 0; rank < n; ++rank) {\n"
1276                        "    for (int i=0;i<rank;i++)\n"
1277                        "      f = one[i];\n"
1278                        "    one[rank] = -1;\n"
1279                        "  }\n"
1280                        "}");
1281         ASSERT_EQUALS("", errout.str());
1282 
1283         // Ticket #2226: C++0x loop
1284         checkUninitVar("void f() {\n"
1285                        "    container c;\n"
1286                        "    for (iterator it : c) {\n"
1287                        "    }\n"
1288                        "}");
1289         ASSERT_EQUALS("", errout.str());
1290 
1291         // Ticket #2345: False positive in sub-condition in if inside a loop
1292         checkUninitVar("void f(int x) {\n"
1293                        "    const PoolItem* pItem;\n"
1294                        "    while (x > 0) {\n"
1295                        "        if (GetItem(&pItem) && (*pItem != rPool))\n"
1296                        "        { }\n"
1297                        "        x--;\n"
1298                        "    }\n"
1299                        "}");
1300         ASSERT_EQUALS("", errout.str());
1301         // extracttests.start: struct PoolItem { bool operator!=(const PoolItem&) const; };
1302         checkUninitVar("void f(int x, const PoolItem& rPool) {\n"
1303                        "    const PoolItem* pItem;\n"
1304                        "    while (x > 0) {\n"
1305                        "        if (*pItem != rPool)\n"
1306                        "        { }\n"
1307                        "        x--;\n"
1308                        "    }\n"
1309                        "}");
1310         ASSERT_EQUALS("[test.cpp:4]: (error) Uninitialized variable: pItem\n", errout.str());
1311 
1312         // #2231 - conditional initialization in loop..
1313         checkUninitVar("int foo(char *a) {\n"
1314                        "    int x;\n"
1315                        "\n"
1316                        "    for (int i = 0; i < 10; ++i) {\n"
1317                        "        if (a[i] == 'x') {\n"
1318                        "            x = i;\n"
1319                        "            break;\n"
1320                        "        }\n"
1321                        "    }\n"
1322                        "\n"
1323                        "    return x;\n"
1324                        "}");
1325         TODO_ASSERT_EQUALS("[test.cpp:11]: (error) Uninitialized variable: x\n", "", errout.str());
1326 
1327         // Ticket #2796
1328         checkUninitVar("void foo() {\n"
1329                        "    while (true) {\n"
1330                        "        int x;\n"
1331                        "        if (y) x = 0;\n"
1332                        "        else break;\n"
1333                        "        return x;\n"   // <- x is initialized
1334                        "    }\n"
1335                        "}");
1336         ASSERT_EQUALS("", errout.str());
1337 
1338         // Assignment in for. Ticket #3287
1339         checkUninitVar("int foo(char* in, bool b) {\n"
1340                        "    char* c;\n"
1341                        "    if (b) for (c = in; *c == 0; ++c) {}\n"
1342                        "    else c = in + strlen(in) - 1;\n"
1343                        "    *c = 0;\n"
1344                        "}");
1345         ASSERT_EQUALS("", errout.str());
1346 
1347         // #10273 - assignment in conditional code
1348         // extracttests.start: extern const int PORT_LEARN_DISABLE;
1349         checkUninitVar("void foo() {\n"
1350                        "    int learn;\n"
1351                        "    for (int index = 0; index < 10; index++) {\n"
1352                        "        if (!(learn & PORT_LEARN_DISABLE))\n"
1353                        "            learn = 123;\n"
1354                        "    }\n"
1355                        "}");
1356         ASSERT_EQUALS("[test.cpp:4]: (error) Uninitialized variable: learn\n", errout.str());
1357 
1358         // extracttests.start: struct Entry { Entry *next; }; Entry *buckets[10];
1359         checkUninitVar("void foo() {\n"
1360                        "  Entry *entry, *nextEntry;\n"
1361                        "  for(int i = 0; i < 10; i++) {\n"
1362                        "    for(entry = buckets[i]; entry != NULL; entry = nextEntry) {\n" // <- nextEntry is not uninitialized
1363                        "      nextEntry = entry->next;\n"
1364                        "    }\n"
1365                        "  }\n"
1366                        "}\n");
1367         ASSERT_EQUALS("", errout.str());
1368 
1369         checkUninitVar("void foo() {\n"
1370                        "  Entry *entry, *nextEntry;\n"
1371                        "  for(int i = 0; i < 10; i++) {\n"
1372                        "    for(entry = buckets[i]; entry != NULL; entry = nextEntry) {\n"
1373                        "    }\n"
1374                        "  }\n"
1375                        "}\n");
1376         ASSERT_EQUALS("[test.cpp:4]: (error) Uninitialized variable: nextEntry\n", errout.str());
1377 
1378         checkUninitVar("void f(int x) {\n"
1379                        "    list *f = NULL;\n"
1380                        "    list *l;\n"
1381                        "\n"
1382                        "    while (--x) {\n"
1383                        "        if (!f)\n"
1384                        "            f = c;\n"
1385                        "        else\n"
1386                        "            l->next = c;\n" // <- not uninitialized
1387                        "        l = c;\n"
1388                        "    }\n"
1389                        "}\n");
1390         ASSERT_EQUALS("", errout.str());
1391 
1392         // #6952 - do-while-loop
1393         checkUninitVar("void f(void)\n"
1394                        "{\n"
1395                        "    int* p;\n"
1396                        "    do\n"
1397                        "    {\n"
1398                        "        if (true) {;}\n"
1399                        "        else\n"
1400                        "        {\n"
1401                        "            return;\n"
1402                        "        }\n"
1403                        "        *p = 7;\n" // <<
1404                        "        p = new int(9);\n"
1405                        "    } while (*p != 8);\n"
1406                        "}");
1407         ASSERT_EQUALS("[test.cpp:11]: (error) Uninitialized variable: p\n", errout.str());
1408 
1409         // #6952 - while-loop
1410         checkUninitVar("void f(void)\n"
1411                        "{\n"
1412                        "    int* p;\n"
1413                        "    while (*p != 8) {\n" // <<
1414                        "        *p = 7;\n"
1415                        "        p = new int(9);\n"
1416                        "    }\n"
1417                        "}");
1418         ASSERT_EQUALS("[test.cpp:4]: (error) Uninitialized variable: p\n", errout.str());
1419 
1420         // switch in loop
1421         checkUninitVar("int foo(int *p) {\n"
1422                        "  int x;\n"
1423                        "  while (true) {\n"
1424                        "    switch (*p) {\n"
1425                        "    case 1:\n"
1426                        "        return x;\n"
1427                        "    case 2:\n"
1428                        "        x = 123;\n"
1429                        "        break;\n"
1430                        "    };\n"
1431                        "    ++p\n"
1432                        "  }\n"
1433                        "}");
1434         ASSERT_EQUALS("", errout.str());
1435     }
1436 
1437     // switch..
uninitvar_switch()1438     void uninitvar_switch() {
1439         checkUninitVar("void f(int x)\n"
1440                        "{\n"
1441                        "    short c;\n"
1442                        "    switch(x) {\n"
1443                        "    case 1:\n"
1444                        "        c++;\n"
1445                        "        break;\n"
1446                        "    };\n"
1447                        "}");
1448         TODO_ASSERT_EQUALS("[test.cpp:6]: (error) Uninitialized variable: c\n", "", errout.str());
1449 
1450         checkUninitVar("char * f()\n"
1451                        "{\n"
1452                        "    static char ret[200];\n"
1453                        "    memset(ret, 0, 200);\n"
1454                        "    switch (x)\n"
1455                        "    {\n"
1456                        "        case 1: return ret;\n"
1457                        "        case 2: return ret;\n"
1458                        "    }\n"
1459                        "    return 0;\n"
1460                        "}");
1461         ASSERT_EQUALS("", errout.str());
1462 
1463         checkUninitVar("int foo(const int iVar, unsigned int slot, unsigned int pin)\n"
1464                        "{\n"
1465                        "    int i;\n"
1466                        "    if (iVar == 0)\n"
1467                        "    {\n"
1468                        "        switch (slot)\n"
1469                        "        {\n"
1470                        "            case 4:  return 5;\n"
1471                        "            default: return -1;\n"
1472                        "        }\n"
1473                        "    }\n"
1474                        "    else\n"
1475                        "    {\n"
1476                        "        switch (pin)\n"
1477                        "        {\n"
1478                        "            case 0:   i =  2; break;\n"
1479                        "            default:  i = -1; break;\n"
1480                        "        }\n"
1481                        "    }\n"
1482                        "    return i;\n"
1483                        "}");
1484         ASSERT_EQUALS("", errout.str());
1485 
1486         // #1855 - switch(foo(&x))
1487         checkUninitVar("int a()\n"
1488                        "{\n"
1489                        "    int x;\n"
1490                        "    switch (foo(&x))\n"
1491                        "    {\n"
1492                        "        case 1:\n"
1493                        "            return x;\n"
1494                        "    }\n"
1495                        "}");
1496         ASSERT_EQUALS("", errout.str());
1497 
1498         // #3231 - ({ switch .. })
1499         checkUninitVar("void f() {\n"
1500                        "    int a;\n"
1501                        "    ({\n"
1502                        "    switch(sizeof(int)) {\n"
1503                        "    case 4:\n"
1504                        "    default:\n"
1505                        "        (a)=0;\n"
1506                        "        break;\n"
1507                        "    };\n"
1508                        "    })\n"
1509                        "}", "test.cpp", false);
1510         ASSERT_EQUALS("", errout.str());
1511     }
1512 
1513     // arrays..
uninitvar_arrays()1514     void uninitvar_arrays() {
1515         checkUninitVar("void f()\n"
1516                        "{\n"
1517                        "    char a[10];\n"
1518                        "    a[a[0]] = 0;\n"
1519                        "}");
1520         ASSERT_EQUALS("[test.cpp:4]: (error) Uninitialized variable: a[0]\n", errout.str());
1521 
1522         checkUninitVar("int f()\n"
1523                        "{\n"
1524                        "    char a[10];\n"
1525                        "    *a = '\\0';\n"
1526                        "    int i = strlen(a);\n"
1527                        "}");
1528         ASSERT_EQUALS("", errout.str());
1529 
1530         checkUninitVar("void f()\n"
1531                        "{\n"
1532                        "    char a, b[10];\n"
1533                        "    a = b[0] = 0;\n"
1534                        "}");
1535         ASSERT_EQUALS("", errout.str());
1536 
1537         checkUninitVar("void f()\n"
1538                        "{\n"
1539                        "    char a[10], b[10];\n"
1540                        "    a[0] = b[0] = 0;\n"
1541                        "}");
1542         ASSERT_EQUALS("", errout.str());
1543 
1544         checkUninitVar("void f()\n"
1545                        "{\n"
1546                        "    char a[10], *p;\n"
1547                        "    *(p = a) = 0;\n"
1548                        "}");
1549         ASSERT_EQUALS("", errout.str());
1550 
1551         checkUninitVar("void f() {\n"
1552                        "    char a[10], *p;\n"
1553                        "    p = &(a[10]);\n"
1554                        "}");
1555         ASSERT_EQUALS("", errout.str());
1556 
1557         // array usage in ?: (tests that the isVariableUsed() works)
1558         checkUninitVar("void f() {\n"
1559                        "    char a[10], *p;\n"
1560                        "    p = c?a:0;\n"
1561                        "}");
1562         ASSERT_EQUALS("", errout.str());
1563 
1564         checkUninitVar("void f(int x) {\n"
1565                        "    char a[10], c;\n"
1566                        "    c = *(x?a:0);\n"
1567                        "}");
1568         ASSERT_EQUALS("[test.cpp:3]: (error) Uninitialized variable: a\n", errout.str());
1569 
1570         checkUninitVar("void f() {\n"
1571                        "    char a[10], c;\n"
1572                        "    strcpy(dest, x?a:\"\");\n"
1573                        "}");
1574         TODO_ASSERT_EQUALS("error", "", errout.str());
1575 
1576         checkUninitVar("void f(int x) {\n"
1577                        "  int a[2];\n"
1578                        "  y *= (x ? 1 : 2);\n"
1579                        "}");
1580         ASSERT_EQUALS("", errout.str());
1581 
1582         // passing array to library functions
1583         checkUninitVar("void f()\n"
1584                        "{\n"
1585                        "    char c[50] = \"\";\n"
1586                        "    strcat(c, \"test\");\n"
1587                        "}");
1588         ASSERT_EQUALS("", errout.str());
1589 
1590         checkUninitVar("void f(char *s2) {\n"
1591                        "    char s[20];\n"
1592                        "    strcpy(s2, s);\n"
1593                        "};");
1594         ASSERT_EQUALS("[test.cpp:3]: (error) Uninitialized variable: s\n", errout.str());
1595 
1596         checkUninitVar("void f() {\n"
1597                        "    char s[20];\n"
1598                        "    strcat(s, \"abc\");\n"
1599                        "};");
1600         ASSERT_EQUALS("[test.cpp:3]: (error) Uninitialized variable: s\n", errout.str());
1601 
1602         checkUninitVar("void f() {\n"
1603                        "    char s[20];\n"
1604                        "    strchr(s, ' ');\n"
1605                        "};");
1606         ASSERT_EQUALS("[test.cpp:3]: (error) Uninitialized variable: s\n", errout.str());
1607 
1608         checkUninitVar("void foo()\n"
1609                        "{\n"
1610                        "        int y[2];\n"
1611                        "        int s;\n"
1612                        "        GetField( y + 0, y + 1 );\n"
1613                        "        s = y[0] * y[1];\n"
1614                        "}");
1615         ASSERT_EQUALS("", errout.str());
1616 
1617         checkUninitVar("void foo()\n"
1618                        "{\n"
1619                        "        int a[2];\n"
1620                        "        init(a - 1);\n"
1621                        "        int b = a[0];\n"
1622                        "}");
1623         ASSERT_EQUALS("", errout.str());
1624 
1625         checkUninitVar("void foo()\n"
1626                        "{\n"
1627                        "        Fred a[2];\n"
1628                        "        Fred b = a[0];\n"
1629                        "}");
1630         ASSERT_EQUALS("", errout.str());
1631 
1632         checkUninitVar("void foo() {\n"
1633                        "  char buf[1024];\n"
1634                        "  char *b = (char *) (((uintptr_t) buf + 63) & ~(uintptr_t) 63);\n"
1635                        "}\n");
1636         ASSERT_EQUALS("", errout.str());
1637 
1638         checkUninitVar("void foo() {\n"
1639                        "  char buf[1024];\n"
1640                        "  char x = *(char *) (((uintptr_t) buf + 63) & ~(uintptr_t) 63);\n"
1641                        "}\n");
1642         ASSERT_EQUALS("[test.cpp:3]: (error) Uninitialized variable: buf\n", errout.str());
1643 
1644         // Passing array to function
1645         checkUninitVar("void f(int i);\n"
1646                        "void foo()\n"
1647                        "{\n"
1648                        "    int a[10];\n"
1649                        "    f(a[0]);\n"
1650                        "}");
1651         ASSERT_EQUALS("[test.cpp:5]: (error) Uninitialized variable: a\n", errout.str());
1652 
1653         // Ticket #2320
1654         checkUninitVar("void foo() {\n"
1655                        "        char a[2];\n"
1656                        "        unsigned long b = (unsigned long)(a+2) & ~7;\n"
1657                        "}");
1658         ASSERT_EQUALS("", errout.str());
1659 
1660         checkUninitVar("void f() {\n"   // Ticket #3050
1661                        "    char a[2];\n"
1662                        "    printf(\"%s\", a);\n"
1663                        "}");
1664         TODO_ASSERT_EQUALS("[test.cpp:3]: (error) Uninitialized variable: a\n", "", errout.str());
1665 
1666         checkUninitVar("void f() {\n"   // Ticket #5108 (fp)
1667                        "    const char *a;\n"
1668                        "    printf(\"%s\", a=\"abc\");\n"
1669                        "}");
1670         ASSERT_EQUALS("", errout.str());
1671 
1672         checkUninitVar("void f() {\n"    // Ticket #3497
1673                        "    char header[1];\n"
1674                        "    *((unsigned char*)(header)) = 0xff;\n"
1675                        "    return header[0];\n"
1676                        "}");
1677         ASSERT_EQUALS("", errout.str());
1678 
1679         checkUninitVar("void f() {\n"    // Ticket #3497
1680                        "    char header[1];\n"
1681                        "    *((unsigned char*)((unsigned char *)(header))) = 0xff;\n"
1682                        "    return header[0];\n"
1683                        "}");
1684         ASSERT_EQUALS("", errout.str());
1685 
1686         checkUninitVar("void f() {\n"
1687                        "    ABC abc;\n"
1688                        "    int a[1];\n"
1689                        "\n"
1690                        "    abc.a = a;\n"
1691                        "    init(&abc);\n"
1692                        "    return a[0];\n"
1693                        "}");
1694         ASSERT_EQUALS("", errout.str());
1695 
1696         // ticket #3344
1697         checkUninitVar("void f(){\n"
1698                        "   char *strMsg = \"This is a message\";\n"
1699                        "   char *buffer=(char*)malloc(128*sizeof(char));\n"
1700                        "   strcpy(strMsg,buffer);\n"
1701                        "   free(buffer);\n"
1702                        "}", "test.cpp", false);
1703         ASSERT_EQUALS("[test.cpp:4]: (error) Memory is allocated but not initialized: buffer\n", errout.str());
1704 
1705         checkUninitVar("void f(){\n"
1706                        "   char *strMsg = \"This is a message\";\n"
1707                        "   char *buffer=static_cast<char*>(malloc(128*sizeof(char)));\n"
1708                        "   strcpy(strMsg,buffer);\n"
1709                        "   free(buffer);\n"
1710                        "}", "test.cpp", false);
1711         ASSERT_EQUALS("[test.cpp:4]: (error) Memory is allocated but not initialized: buffer\n", errout.str());
1712 
1713         // #3845
1714         checkUninitVar("int foo() {\n"
1715                        "    int a[1] = {5};\n"
1716                        "    return a[0];\n"
1717                        "}");
1718         ASSERT_EQUALS("", errout.str());
1719 
1720         checkUninitVar("int foo() {\n"
1721                        "    int a[2][2] = {{3,4}, {5,6}};\n"
1722                        "    return a[0][1];\n"
1723                        "}");
1724         ASSERT_EQUALS("", errout.str());
1725 
1726         checkUninitVar("int foo() {\n"
1727                        "    int a[1];\n"
1728                        "    return a[0];\n"
1729                        "}");
1730         ASSERT_EQUALS("[test.cpp:3]: (error) Uninitialized variable: a\n", errout.str());
1731 
1732         checkUninitVar("int foo() {\n"
1733                        "    int a[2][2];\n"
1734                        "    return a[0][1];\n"
1735                        "}");
1736         ASSERT_EQUALS("[test.cpp:3]: (error) Uninitialized variable: a\n", errout.str());
1737 
1738         checkUninitVar("int foo() {\n"
1739                        "    int a[10];\n"
1740                        "    dostuff(a[0]);\n"
1741                        "}");
1742         ASSERT_EQUALS("", errout.str());
1743 
1744         // # 4740
1745         checkUninitVar("void f() {\n"
1746                        "    int *a[2][19];\n"
1747                        "    int **b = a[0];\n"
1748                        "}");
1749         ASSERT_EQUALS("", errout.str());
1750 
1751         // #6869 - FP when passing uninit array to function
1752         checkUninitVar("void bar(PSTR x);\n"
1753                        "void foo() {\n"
1754                        "  char x[10];\n"
1755                        "  bar(x);\n"
1756                        "}");
1757         ASSERT_EQUALS("", errout.str());
1758 
1759         // struct
1760         checkUninitVar("struct Fred { int x; int y; };\n"
1761                        ""
1762                        "void f() {\n"
1763                        "  struct Fred fred[10];\n"
1764                        "  fred[1].x = 0;\n"
1765                        "}", "test.c");
1766         ASSERT_EQUALS("", errout.str());
1767     }
1768 
uninitvar_pointertoarray()1769     void uninitvar_pointertoarray() {
1770         checkUninitVar("void draw_quad(float z)  {\n"
1771                        "    int i;\n"
1772                        "    float (*vertices)[2][4];\n"
1773                        "    vertices[0][0][0] = z;\n"
1774                        "    vertices[0][0][1] = z;\n"
1775                        "    vertices[1][0][0] = z;\n"
1776                        "    vertices[1][0][1] = z;\n"
1777                        "    vertices[2][0][0] = z;\n"
1778                        "    vertices[2][0][1] = z;\n"
1779                        "    vertices[3][0][0] = z;\n"
1780                        "    vertices[3][0][1] = z;\n"
1781                        "    for (i = 0; i < 4; i++) {\n"
1782                        "        vertices[i][0][2] = z;\n"
1783                        "        vertices[i][0][3] = 1.0;\n"
1784                        "        vertices[i][1][0] = 2.0;\n"
1785                        "        vertices[i][1][1] = 3.0;\n"
1786                        "        vertices[i][1][2] = 4.0;\n"
1787                        "        vertices[i][1][3] = 5.0;\n"
1788                        "    }\n"
1789                        "}");
1790         ASSERT_EQUALS("[test.cpp:4]: (error) Uninitialized variable: vertices\n",
1791                       errout.str());
1792     }
1793 
uninitvar_cpp11ArrayInit()1794     void uninitvar_cpp11ArrayInit() { // #7010
1795         checkUninitVar("double foo(bool flag) {\n"
1796                        "    double adIHPoint_local[4][4]{};\n"
1797                        "    function(*adIHPoint_local);\n"
1798                        "}");
1799         ASSERT_EQUALS("", errout.str());
1800     }
1801 
1802     // alloc..
uninitvar_alloc()1803     void uninitvar_alloc() {
1804         checkUninitVar("void f() {\n"
1805                        "    char *s = (char *)malloc(100);\n"
1806                        "    strcat(s, \"abc\");\n"
1807                        "};");
1808         ASSERT_EQUALS("[test.cpp:3]: (error) Memory is allocated but not initialized: s\n", errout.str());
1809 
1810         checkUninitVar("void f()\n"
1811                        "{\n"
1812                        "    char *s1 = new char[10];\n"
1813                        "    char *s2 = new char[strlen(s1)];\n"
1814                        "};");
1815         ASSERT_EQUALS("[test.cpp:4]: (error) Memory is allocated but not initialized: s1\n", errout.str());
1816 
1817         checkUninitVar("void f()\n"
1818                        "{\n"
1819                        "    char *p = (char*)malloc(64);\n"
1820                        "    int x = p[0];\n"
1821                        "}");
1822         ASSERT_EQUALS("[test.cpp:4]: (error) Memory is allocated but not initialized: p\n", errout.str());
1823 
1824         checkUninitVar("void f() {\n"
1825                        "    char *p = (char*)malloc(64);\n"
1826                        "    if (p[0]) { }\n"
1827                        "}");
1828         ASSERT_EQUALS("[test.cpp:3]: (error) Memory is allocated but not initialized: p[0]\n", errout.str());
1829 
1830         checkUninitVar("char f() {\n"
1831                        "    char *p = (char*)malloc(64);\n"
1832                        "    return p[0];\n"
1833                        "}");
1834         ASSERT_EQUALS("[test.cpp:3]: (error) Memory is allocated but not initialized: p\n", errout.str());
1835 
1836         checkUninitVar("void f()\n"
1837                        "{\n"
1838                        "    Fred *fred = new Fred;\n"
1839                        "    fred->foo();\n"
1840                        "}");
1841         ASSERT_EQUALS("", errout.str());
1842 
1843         checkUninitVar("struct Fred { int i; Fred(int, float); };\n"
1844                        "void f() {\n"
1845                        "    Fred *fred = new Fred(1, 2);\n"
1846                        "    fred->foo();\n"
1847                        "}");
1848         ASSERT_EQUALS("", errout.str());
1849 
1850         checkUninitVar("void f()\n"
1851                        "{\n"
1852                        "    Fred *fred = malloc(sizeof(Fred));\n"
1853                        "    x(&fred->f);\n"
1854                        "}");
1855         ASSERT_EQUALS("", errout.str());
1856 
1857         checkUninitVar("void f()\n"
1858                        "{\n"
1859                        "    Fred *fred = malloc(sizeof(Fred));\n"
1860                        "    x(fred->f);\n"
1861                        "}");
1862         ASSERT_EQUALS("", errout.str());
1863 
1864         checkUninitVar("void foo(char *s)\n"
1865                        "{\n"
1866                        "    char *a = malloc(100);\n"
1867                        "    *a = *s;\n"
1868                        "}");
1869         ASSERT_EQUALS("", errout.str());
1870 
1871         checkUninitVar("void foo()\n"
1872                        "{\n"
1873                        "    char *a;\n"
1874                        "    if (a);\n"
1875                        "}");
1876         ASSERT_EQUALS("[test.cpp:4]: (error) Uninitialized variable: a\n", errout.str());
1877 
1878         checkUninitVar("void foo()\n"
1879                        "{\n"
1880                        "    char *a = malloc(100);\n"
1881                        "    if (a);\n"
1882                        "}");
1883         ASSERT_EQUALS("", errout.str());
1884 
1885         checkUninitVar("void foo()\n"
1886                        "{\n"
1887                        "    ABC *abc = malloc(100);\n"
1888                        "    abc->a = 123;\n"
1889                        "}");
1890         ASSERT_EQUALS("", errout.str());
1891 
1892         checkUninitVar("void foo()\n"
1893                        "{\n"
1894                        "    ABC *abc = malloc(100);\n"
1895                        "    abc->a.word = 123;\n"
1896                        "}");
1897         ASSERT_EQUALS("", errout.str());
1898 
1899         checkUninitVar("void foo()\n"
1900                        "{\n"
1901                        "    ABC *abc = malloc(100);\n"
1902                        "    abc->a = 123;\n"
1903                        "    abc->a += 123;\n"
1904                        "}");
1905         ASSERT_EQUALS("", errout.str());
1906 
1907         checkUninitVar("void foo()\n"
1908                        "{\n"
1909                        "    ABC *abc = malloc(100);\n"
1910                        "    free(abc);\n"
1911                        "}");
1912         ASSERT_EQUALS("", errout.str());
1913 
1914         checkUninitVar("void f()\n"
1915                        "{\n"
1916                        "    char *s = (char*)malloc(100);\n"
1917                        "    if (!s)\n"
1918                        "        return;\n"
1919                        "    char c = *s;\n"
1920                        "}");
1921         TODO_ASSERT_EQUALS("[test.cpp:6]: (error) Memory is allocated but not initialized: s\n", "", errout.str());
1922 
1923         // #3708 - false positive when using ptr typedef
1924         checkUninitVar("void f() {\n"
1925                        "    uintptr_t x = malloc(100);\n"
1926                        "    uintptr_t y = x + 10;\n"  // <- not bad usage
1927                        "}");
1928         ASSERT_EQUALS("", errout.str());
1929 
1930         checkUninitVar("void f() {\n"
1931                        "  z_stream strm;\n"
1932                        "  char* buf = malloc(10);\n"
1933                        "  strm.next_out = buf;\n"
1934                        "  deflate(&strm, Z_FINISH);\n"
1935                        "  memcpy(body, buf, 10);\n"
1936                        "}");
1937         ASSERT_EQUALS("", errout.str());
1938 
1939         // #6451 - allocation in subscope
1940         checkUninitVar("struct StgStrm {\n"
1941                        "    StgIo& rIo;\n"
1942                        "    StgStrm(StgIo&);\n"
1943                        "    virtual sal_Int32 Write();\n"
1944                        "};\n"
1945                        "void Tmp2Strm() {\n"
1946                        "    StgStrm* pNewStrm;\n"
1947                        "    if (someflag)\n"
1948                        "        pNewStrm = new StgStrm(rIo);\n"
1949                        "    else\n"
1950                        "        pNewStrm = new StgStrm(rIo);\n"
1951                        "    pNewStrm->Write();\n"
1952                        "}");
1953         ASSERT_EQUALS("", errout.str());
1954 
1955         // #6450 - calling a member function is allowed if memory was allocated by new
1956         checkUninitVar("struct EMFPFont {\n"
1957                        "    bool family;\n"
1958                        "    void Initialize();\n"
1959                        "};\n"
1960                        "void processObjectRecord() {\n"
1961                        "    EMFPFont *font = new EMFPFont();\n"
1962                        "    font->Initialize();\n"
1963                        "}");
1964         ASSERT_EQUALS("", errout.str());
1965 
1966         // #7623 - new can also initialize the memory, don't warn in this case
1967         checkUninitVar("void foo(){\n"
1968                        "    int* p1 = new int(314);\n"
1969                        "    int* p2 = new int();\n"
1970                        "    int* arr = new int[5]();\n"
1971                        "    std::cout << *p1 << *p2 << arr[0];\n"
1972                        "}");
1973         ASSERT_EQUALS("", errout.str());
1974 
1975         // new in C code does not allocate..
1976         checkUninitVar("int main() {\n"
1977                        "    char * pBuf = new(10);\n"
1978                        "    a = *pBuf;\n"
1979                        "}", "test.c");
1980         ASSERT_EQUALS("", errout.str());
1981     }
1982 
1983     // class / struct..
uninitvar_class()1984     void uninitvar_class() {
1985         checkUninitVar("class Fred\n"
1986                        "{\n"
1987                        "    int i;\n"
1988                        "    int a() { return i; }\n"
1989                        "};");
1990         ASSERT_EQUALS("", errout.str());
1991 
1992         checkUninitVar("void f()\n"
1993                        "{\n"
1994                        "    struct Relative {\n"
1995                        "        Surface *surface;\n"
1996                        "        void MoveTo(int x, int y) {\n"
1997                        "            surface->MoveTo();\n"
1998                        "        }\n"
1999                        "    };\n"
2000                        "}");
2001         ASSERT_EQUALS("", errout.str());
2002 
2003         checkUninitVar("void f()\n"
2004                        "{\n"
2005                        "    static const struct ab {\n"
2006                        "        int a,b;\n"
2007                        "        int get_a() { return a; }"
2008                        "    } = { 0, 0 };\n"
2009                        "}", "test.cpp", false);
2010         ASSERT_EQUALS("", errout.str());
2011 
2012         checkUninitVar("void f()\n"
2013                        "{\n"
2014                        "    int i;\n"
2015                        "    {\n"
2016                        "        union ab {\n"
2017                        "            int a,b;\n"
2018                        "        }\n"
2019                        "        i = 0;\n"
2020                        "    }\n"
2021                        "    return i;\n"
2022                        "}", "test.cpp", false);
2023         ASSERT_EQUALS("", errout.str());
2024 
2025         checkUninitVar("void f(int x) {\n"
2026                        "    struct AB ab;\n"
2027                        "    x = ab.x = 12;\n"
2028                        "}");
2029         ASSERT_EQUALS("", errout.str());
2030     }
2031 
2032     // enum..
uninitvar_enum()2033     void uninitvar_enum() {
2034         checkUninitVar("void f()\n"
2035                        "{\n"
2036                        "    enum AB { a, b };\n"
2037                        "    AB ab;\n"
2038                        "    if (ab);\n"
2039                        "}");
2040         ASSERT_EQUALS("[test.cpp:5]: (error) Uninitialized variable: ab\n", errout.str());
2041     }
2042 
2043     // references..
uninitvar_references()2044     void uninitvar_references() {
2045         checkUninitVar("void f()\n"
2046                        "{\n"
2047                        "    int a;\n"
2048                        "    int &b = a;\n"
2049                        "    b = 0;\n"
2050                        "    int x = a;\n"
2051                        "}", "test.cpp", false);
2052         ASSERT_EQUALS("", errout.str());
2053 
2054         checkUninitVar("void f(struct blame_entry *ent)\n"
2055                        "{\n"
2056                        "    struct origin *suspect = ent->suspect;\n"
2057                        "    char hex[41];\n"
2058                        "    strcpy(hex, sha1_to_hex(suspect->commit->object.sha1));\n"
2059                        "}");
2060         ASSERT_EQUALS("", errout.str());
2061 
2062         checkUninitVar("void foo()\n"
2063                        "{\n"
2064                        "    const std::string s(x());\n"
2065                        "    strchr(s.c_str(), ',');\n"
2066                        "}");
2067         ASSERT_EQUALS("", errout.str());
2068 
2069         // #6717
2070         checkUninitVar("void f() {\n"
2071                        "    struct thing { int value; };\n"
2072                        "    thing it;\n"
2073                        "    int& referenced_int = it.value;\n"
2074                        "    referenced_int = 123;\n"
2075                        "}");
2076         ASSERT_EQUALS("", errout.str());
2077     }
2078 
uninitvar_return()2079     void uninitvar_return() {
2080 
2081         checkUninitVar("static int foo() {\n"
2082                        "    int ret;\n"
2083                        "    return ret;\n"
2084                        "}");
2085         ASSERT_EQUALS("[test.cpp:3]: (error) Uninitialized variable: ret\n", errout.str());
2086 
2087         checkUninitVar("static int foo() {\n"
2088                        "    int ret;\n"
2089                        "    return ret+5;\n"
2090                        "}");
2091         ASSERT_EQUALS("[test.cpp:3]: (error) Uninitialized variable: ret\n", errout.str());
2092 
2093         checkUninitVar("static int foo() {\n"
2094                        "    int ret;\n"
2095                        "    return ret = 5;\n"
2096                        "}");
2097         ASSERT_EQUALS("", errout.str());
2098 
2099         {
2100             checkUninitVar("static int foo() {\n"
2101                            "    int ret;\n"
2102                            "    cin >> ret;\n"
2103                            "    return ret;\n"
2104                            "}");
2105             ASSERT_EQUALS("", errout.str());
2106 
2107             checkUninitVar("static int foo() {\n"
2108                            "    int ret;\n"
2109                            "    return cin >> ret;\n"
2110                            "}\n", "test.c");
2111             ASSERT_EQUALS("[test.c:3]: (error) Uninitialized variable: ret\n", errout.str());
2112         }
2113 
2114         // Ticket #6341- False negative
2115         {
2116             checkUninitVar("wchar_t f() { int i; return btowc(i); }");
2117             ASSERT_EQUALS("[test.cpp:1]: (error) Uninitialized variable: i\n", errout.str());
2118 
2119             checkUninitVar("wchar_t f(int i) { return btowc(i); }");
2120             ASSERT_EQUALS("", errout.str());
2121 
2122             // Avoid a potential false positive (#6341)
2123             checkUninitVar(
2124                 "void setvalue(int &x) {\n"
2125                 "  x = 0;\n"
2126                 "  return 123;\n"
2127                 "}\n"
2128                 "int f() {\n"
2129                 "  int x;\n"
2130                 "  return setvalue(x);\n"
2131                 "}");
2132             ASSERT_EQUALS("", errout.str());
2133         }
2134 
2135         // Ticket #5412 - False negative
2136         {
2137             checkUninitVar("void f(bool b) {\n"
2138                            "    double f;\n"
2139                            "    if (b)   {  }\n"
2140                            "    else  {\n"
2141                            "        f = 0.0;\n"
2142                            "    }\n"
2143                            "    printf (\"%f\",f);\n"
2144                            "}");
2145             ASSERT_EQUALS("[test.cpp:7]: (error) Uninitialized variable: f\n", errout.str());
2146 
2147             // Check for potential FP
2148             checkUninitVar("void f(bool b) {\n"
2149                            "    double f;\n"
2150                            "    if (b)   { f = 1.0 }\n"
2151                            "    else  {\n"
2152                            "        f = 0.0;\n"
2153                            "    }\n"
2154                            "    printf (\"%f\",f);\n"
2155                            "}");
2156             ASSERT_EQUALS("", errout.str());
2157         }
2158 
2159         // Ticket #2146 - False negative
2160         checkUninitVar("int f(int x) {\n"
2161                        "    int y;\n"
2162                        "    return x ? 1 : y;\n"
2163                        "}");
2164         ASSERT_EQUALS("[test.cpp:3]: (error) Uninitialized variable: y\n", errout.str());
2165 
2166         // Ticket #3106 - False positive
2167         {
2168             checkUninitVar("int f() {\n"
2169                            "    int i;\n"
2170                            "    return x(&i) ? i : 0;\n"
2171                            "}");
2172             ASSERT_EQUALS("", errout.str());
2173 
2174             checkUninitVar("int f() {\n"
2175                            "    int i;\n"
2176                            "    return x() ? i : 0;\n"
2177                            "}");
2178             ASSERT_EQUALS("[test.cpp:3]: (error) Uninitialized variable: i\n", errout.str());
2179         }
2180     }
2181 
uninitvar_assign()2182     void uninitvar_assign() {  // = { .. }
2183         // #1533
2184         checkUninitVar("char a()\n"
2185                        "{\n"
2186                        "    char key;\n"
2187                        "    struct A msg = { .buf = {&key} };\n"
2188                        "    init(&msg);\n"
2189                        "    key++;\n"
2190                        "}");
2191         ASSERT_EQUALS("", errout.str());
2192 
2193         // Ticket #5660 - False positive
2194         checkUninitVar("int f() {\n"
2195                        "    int result;\n"
2196                        "    int *res[] = {&result};\n"
2197                        "    foo(res);\n"
2198                        "    return result;\n"
2199                        "}");
2200         ASSERT_EQUALS("", errout.str());
2201 
2202         // #6873
2203         checkUninitVar("int f() {\n"
2204                        "    char a[10];\n"
2205                        "    char *b[] = {a};\n"
2206                        "    foo(b);\n"
2207                        "    return atoi(a);\n"
2208                        "}");
2209         ASSERT_EQUALS("", errout.str());
2210 
2211         // = { .. }
2212         checkUninitVar("int f() {\n"
2213                        "    int a;\n"
2214                        "    int *p[] = { &a };\n"
2215                        "    *p[0] = 0;\n"
2216                        "    return a;\n"
2217                        "}");
2218         ASSERT_EQUALS("", errout.str());
2219 
2220     }
2221 
2222     // strncpy doesn't always null-terminate..
uninitvar_strncpy()2223     void uninitvar_strncpy() {
2224         // TODO: Add this checking
2225         // Can it be added without hardcoding?
2226 
2227         checkUninitVar("void f()\n"
2228                        "{\n"
2229                        "    char a[100];\n"
2230                        "    strncpy(a, s, 20);\n"
2231                        "    strncat(a, s, 20);\n"
2232                        "}");
2233         TODO_ASSERT_EQUALS("[test.cpp:5]: (error) Dangerous usage of 'a' (strncpy doesn't always null-terminate it).\n", "", errout.str());
2234 
2235         checkUninitVar("void f()\n"
2236                        "{\n"
2237                        "    char a[100];\n"
2238                        "    strncpy(a, \"hello\", 3);\n"
2239                        "    strncat(a, \"world\", 20);\n"
2240                        "}");
2241         TODO_ASSERT_EQUALS("[test.cpp:5]: (error) Dangerous usage of 'a' (strncpy doesn't always null-terminate it).\n", "", errout.str());
2242 
2243         checkUninitVar("void f()\n"
2244                        "{\n"
2245                        "    char a[100];\n"
2246                        "    strncpy(a, \"hello\", sizeof(a));\n"
2247                        "    strncat(a, \"world\", 20);\n"
2248                        "}", "test.cpp", false);
2249         ASSERT_EQUALS("", errout.str());
2250 
2251         // #3245 - false positive
2252         {
2253             checkUninitVar("void f() {\n"
2254                            "    char a[100];\n"
2255                            "    strncpy(a,p,10);\n"
2256                            "    memcmp(a,q,10);\n"
2257                            "}");
2258             ASSERT_EQUALS("", errout.str());
2259 
2260             checkUninitVar("void f() {\n"
2261                            "    char a[100];\n"
2262                            "    strncpy(a,p,10);\n"
2263                            "    if (memcmp(a,q,10)==0);\n"
2264                            "}");
2265             ASSERT_EQUALS("", errout.str());
2266         }
2267 
2268         // Using strncpy isn't necessarily dangerous usage
2269         checkUninitVar("void f(const char dev[], char *str) {\n"
2270                        "    char buf[10];\n"
2271                        "    strncpy(buf, dev, 10);\n"
2272                        "    strncpy(str, buf, 10);\n"
2273                        "}");
2274         ASSERT_EQUALS("", errout.str());
2275 
2276         checkUninitVar("void f() {\n"
2277                        "  char dst[4];\n"
2278                        "  const char* source = \"You\";\n"
2279                        "  strncpy(dst, source, sizeof(dst));\n"
2280                        "  char value = dst[2];\n"
2281                        "}", "test.cpp", false);
2282         ASSERT_EQUALS("", errout.str());
2283     }
2284 
2285     // valid and invalid use of 'int a(int x) { return x + x; }'
func_uninit_var()2286     void func_uninit_var() {
2287         const std::string funca("int a(int x) { return x + x; }");
2288 
2289         checkUninitVar((funca +
2290                         "void b() {\n"
2291                         "    int x;\n"
2292                         "    a(x);\n"
2293                         "}").c_str());
2294         ASSERT_EQUALS("[test.cpp:3]: (error) Uninitialized variable: x\n", errout.str());
2295 
2296         checkUninitVar((funca +
2297                         "void b() {\n"
2298                         "    int *p;\n"
2299                         "    a(*p);\n"
2300                         "}").c_str());
2301         ASSERT_EQUALS("[test.cpp:3]: (error) Uninitialized variable: p\n", errout.str());
2302     }
2303 
2304 
2305     // valid and invalid use of 'void a(int *p) { *p = 0; }'
func_uninit_pointer()2306     void func_uninit_pointer() {
2307         const std::string funca("void a(int *p) { *p = 0; }");
2308 
2309         // ok - initialized pointer
2310         checkUninitVar((funca +
2311                         "void b() {\n"
2312                         "    int buf[10];\n"
2313                         "    a(buf);\n"
2314                         "}").c_str());
2315         ASSERT_EQUALS("", errout.str());
2316 
2317         // not ok - uninitialized pointer
2318         checkUninitVar((funca +
2319                         "void b() {\n"
2320                         "    int *p;\n"
2321                         "    a(p);\n"
2322                         "}").c_str());
2323         ASSERT_EQUALS("[test.cpp:3]: (error) Uninitialized variable: p\n", errout.str());
2324     }
2325 
uninitvar_typeof()2326     void uninitvar_typeof() {
2327         checkUninitVar("void f() {\n"
2328                        "    struct Fred *fred;\n"
2329                        "    typeof(fred->x);\n"
2330                        "}");
2331         ASSERT_EQUALS("", errout.str());
2332 
2333         checkUninitVar("void f() {\n"
2334                        "    struct SData * s;\n"
2335                        "    ab(typeof(s->status));\n"
2336                        "}");
2337         ASSERT_EQUALS("", errout.str());
2338 
2339         checkUninitVar("void f() {\n"
2340                        "    struct SData * s;\n"
2341                        "    TYPEOF(s->status);\n"
2342                        "}");
2343         TODO_ASSERT_EQUALS("", "[test.cpp:3]: (error) Uninitialized variable: s\n", errout.str());
2344 
2345         checkUninitVar("void f() {\n"
2346                        "    int *n = ({ typeof(*n) z;  (typeof(*n)*)z; })\n"
2347                        "}", "test.cpp", false);
2348         ASSERT_EQUALS("", errout.str());
2349     }
2350 
uninitvar_ignore()2351     void uninitvar_ignore() {
2352         checkUninitVar("void foo() {\n"
2353                        "  int i;\n"
2354                        "  dostuff((int&)i, 0);\n" // <- cast is not use
2355                        "}");
2356         ASSERT_EQUALS("", errout.str());
2357 
2358         checkUninitVar("int foo() {\n"
2359                        "  int i;\n"
2360                        "  return (int&)i + 2;\n"
2361                        "}");
2362         ASSERT_EQUALS("[test.cpp:3]: (error) Uninitialized variable: i\n", errout.str());
2363 
2364         checkUninitVar("void foo() {\n"
2365                        "  int i;\n"
2366                        "  dostuff(*&i, 0);\n" // <- *& is not use
2367                        "}");
2368         ASSERT_EQUALS("", errout.str());
2369 
2370         checkUninitVar("int foo() {\n"
2371                        "  int i;\n"
2372                        "  return *&i;\n"
2373                        "}");
2374         ASSERT_EQUALS("[test.cpp:3]: (error) Uninitialized variable: i\n", errout.str());
2375     }
2376 
uninitvar2()2377     void uninitvar2() {
2378         // using uninit var
2379         checkUninitVar("void f() {\n"
2380                        "    int x;\n"
2381                        "    x++;\n"
2382                        "}");
2383         ASSERT_EQUALS("[test.cpp:3]: (error) Uninitialized variable: x\n", errout.str());
2384 
2385         // extracttests.start: char str[10];
2386         checkUninitVar("void f() {\n"
2387                        "    int x;\n"
2388                        "    str[x] = 0;\n"
2389                        "}");
2390         ASSERT_EQUALS("[test.cpp:3]: (error) Uninitialized variable: x\n", errout.str());
2391 
2392         checkUninitVar("void f() {\n" // #7736
2393                        "    int buf[12];\n"
2394                        "    printf (\"%d\", buf[0] );\n"
2395                        "}");
2396         ASSERT_EQUALS("[test.cpp:3]: (error) Uninitialized variable: buf\n", errout.str());
2397 
2398         checkUninitVar("void f() {\n"
2399                        "    int x;\n"
2400                        "    int y = x & 3;\n"
2401                        "}");
2402         ASSERT_EQUALS("[test.cpp:3]: (error) Uninitialized variable: x\n", errout.str());
2403 
2404         checkUninitVar("void f() {\n"
2405                        "    int x;\n"
2406                        "    int y = 3 & x;\n"
2407                        "}");
2408         ASSERT_EQUALS("[test.cpp:3]: (error) Uninitialized variable: x\n", errout.str());
2409 
2410         checkUninitVar("void f() {\n"
2411                        "    int x;\n"
2412                        "    x = 3 + x;\n"
2413                        "}");
2414         ASSERT_EQUALS("[test.cpp:3]: (error) Uninitialized variable: x\n", errout.str());
2415 
2416         checkUninitVar("void f() {\n"
2417                        "    int x;\n"
2418                        "    x = x;\n"
2419                        "}");
2420         ASSERT_EQUALS("[test.cpp:3]: (error) Uninitialized variable: x\n", errout.str());
2421 
2422         // extracttests.start: struct ABC {int a;};
2423         checkUninitVar("void f() {\n"
2424                        "    struct ABC *abc;\n"
2425                        "    abc->a = 0;\n"
2426                        "}");
2427         ASSERT_EQUALS("[test.cpp:3]: (error) Uninitialized variable: abc\n", errout.str());
2428 
2429         checkUninitVar("int f() {\n"
2430                        "    static int x;\n"
2431                        "    return ++x;\n"
2432                        "}");
2433         ASSERT_EQUALS("", errout.str());
2434 
2435         checkUninitVar("int f() {\n"
2436                        "    extern int x;\n"
2437                        "    return ++x;\n"
2438                        "}");
2439         ASSERT_EQUALS("", errout.str());
2440 
2441         checkUninitVar("void f() {\n"  // #3926 - weird cast.
2442                        "    int x;\n"
2443                        "    *(((char *)&x) + 0) = 0;\n"
2444                        "}", "test.c", false);
2445         ASSERT_EQUALS("", errout.str());
2446 
2447         checkUninitVar("void f() {\n" // #4737 - weird cast.
2448                        "    int x;\n"
2449                        "    do_something(&((char*)&x)[0], 1);\n"
2450                        "}");
2451         ASSERT_EQUALS("", errout.str());
2452 
2453         checkUninitVar("void f() {\n"
2454                        "    int x;\n"
2455                        "    char *p = (char*)&x + 1;\n"
2456                        "}", "test.cpp", false);
2457         ASSERT_EQUALS("", errout.str());
2458 
2459         checkUninitVar("void f() {\n"
2460                        "    int i;\n"
2461                        "    i=f(), i!=2;\n"
2462                        "}");
2463         ASSERT_EQUALS("", errout.str());
2464 
2465         // using uninit var in condition
2466         checkUninitVar("void f(void) {\n"
2467                        "    int x;\n"
2468                        "    if (x) { }\n"
2469                        "}");
2470         ASSERT_EQUALS("[test.cpp:3]: (error) Uninitialized variable: x\n", errout.str());
2471 
2472         checkUninitVar("void f() {\n"
2473                        "    int x;\n"
2474                        "    if (1 == (3 & x)) { }\n"
2475                        "}");
2476         ASSERT_EQUALS("[test.cpp:3]: (error) Uninitialized variable: x\n", errout.str());
2477 
2478         // ?:
2479         checkUninitVar("int f(int *ptr) {\n"
2480                        "    int a;\n"
2481                        "    int *p = ptr ? ptr : &a;\n"
2482                        "}");
2483         ASSERT_EQUALS("", errout.str());
2484 
2485         checkUninitVar("int f(int a) {\n"
2486                        "    int x;\n"
2487                        "    if (a==3) { x=2; }\n"
2488                        "    y = (a==3) ? x : a;\n"
2489                        "}");
2490         ASSERT_EQUALS("", errout.str());
2491 
2492         // = ({ .. })
2493         checkUninitVar("void f() {\n"
2494                        "    int x = ({ 1 + 2; });\n"
2495                        "    int y = 1 + (x ? y : y);\n"
2496                        "}");
2497         ASSERT_EQUALS("[test.cpp:3]: (error) Uninitialized variable: y\n", errout.str());
2498 
2499         // >> => initialization / usage
2500         {
2501             const char code[] = "void f() {\n"
2502                                 "    int x;\n"
2503                                 "    if (i >> x) { }\n"
2504                                 "}";
2505             checkUninitVar(code, "test.cpp");
2506             ASSERT_EQUALS("", errout.str());
2507 
2508             checkUninitVar(code, "test.c");
2509             ASSERT_EQUALS("[test.c:3]: (error) Uninitialized variable: x\n", errout.str());
2510         }
2511 
2512         checkUninitVar("void f() {\n"
2513                        "    int i, i2;\n"
2514                        "    strm >> i >> i2;\n"
2515                        "}");
2516         ASSERT_EQUALS("", errout.str());
2517 
2518         // unconditional initialization
2519         checkUninitVar("int f() {\n"
2520                        "    int ret;\n"
2521                        "    if (a) { ret = 1; }\n"
2522                        "    else { {} ret = 2; }\n"
2523                        "    return ret;\n"
2524                        "}");
2525         ASSERT_EQUALS("", errout.str());
2526 
2527         checkUninitVar("int f() {\n"
2528                        "    int ret;\n"
2529                        "    if (a) { ret = 1; }\n"
2530                        "    else { s=foo(1,{2,3},4); ret = 2; }\n"
2531                        "    return ret;\n"
2532                        "}");
2533         ASSERT_EQUALS("", errout.str());
2534 
2535         // conditional initialization
2536         checkUninitVar("void f() {\n"
2537                        "    int x;\n"
2538                        "    if (y == 1) { x = 1; }\n"
2539                        "    else { if (y == 2) { x = 1; } }\n"
2540                        "    return x;\n"
2541                        "}");
2542         ASSERT_EQUALS("[test.cpp:5]: (error) Uninitialized variable: x\n", errout.str());
2543 
2544         checkUninitVar("void f() {\n"
2545                        "    int x;\n"
2546                        "    if (y == 1) { x = 1; }\n"
2547                        "    else { if (y == 2) { x = 1; } }\n"
2548                        "    if (y == 3) { }\n"   // <- ignore condition
2549                        "    return x;\n"
2550                        "}");
2551         ASSERT_EQUALS("[test.cpp:6]: (error) Uninitialized variable: x\n", errout.str());
2552 
2553         // initialization in condition
2554         checkUninitVar("void f() {\n"
2555                        "    int a;\n"
2556                        "    if (init(&a)) { }\n"
2557                        "    a++;\n"
2558                        "}");
2559         ASSERT_EQUALS("", errout.str());
2560 
2561         // return, break, continue, goto
2562         checkUninitVar("void f() {\n"
2563                        "    int x;\n"
2564                        "    if (y == 1) { return; }\n"
2565                        "    else { x = 1; }\n"
2566                        "    return x;\n"
2567                        "}");
2568         ASSERT_EQUALS("", errout.str());
2569 
2570         checkUninitVar("void f() {\n"
2571                        "    int x;\n"
2572                        "    if (y == 1) { return; }\n"
2573                        "    return x;\n"
2574                        "}");
2575         ASSERT_EQUALS("[test.cpp:4]: (error) Uninitialized variable: x\n", errout.str());
2576 
2577         checkUninitVar("int f(int x) {\n"
2578                        "    int ret;\n"
2579                        "    if (!x) {\n"
2580                        "        ret = -123;\n"
2581                        "        goto out1;\n"
2582                        "    }\n"
2583                        "    return 0;\n"
2584                        "out1:\n"
2585                        "out2:\n"
2586                        "    return ret;\n"
2587                        "}", "test.c");
2588         ASSERT_EQUALS("", errout.str());
2589 
2590         checkUninitVar("void f() {\n"
2591                        "    int i;\n"
2592                        "    if (x) {\n"
2593                        "        i = 1;\n"
2594                        "    } else {\n"
2595                        "        goto out;\n"
2596                        "    }\n"
2597                        "    i++;\n"
2598                        "}");
2599         ASSERT_EQUALS("", errout.str());
2600 
2601         checkUninitVar("int f() {\n"
2602                        "    int i,x;\n"
2603                        "    for (i=0;i<9;++i)\n"
2604                        "        if (foo) break;\n"
2605                        "    return x;\n"
2606                        "}");
2607         ASSERT_EQUALS("[test.cpp:5]: (error) Uninitialized variable: x\n", errout.str());
2608 
2609         checkUninitVar("int f() {\n"
2610                        "    int x;\n"
2611                        "    while (foo)\n"
2612                        "        if (bar) break;\n"
2613                        "    return x;\n"
2614                        "}");
2615         ASSERT_EQUALS("[test.cpp:5]: (error) Uninitialized variable: x\n", errout.str());
2616 
2617         // try/catch : don't warn about exception variable
2618         checkUninitVar("void f() {\n"
2619                        "    try {\n"
2620                        "    } catch (CException* e) {\n"
2621                        "        trace();\n"
2622                        "        e->Delete();\n"
2623                        "    }\n"
2624                        "}");
2625         ASSERT_EQUALS("", errout.str());
2626 
2627         checkUninitVar("void f() {\n" // #5347
2628                        "    try {\n"
2629                        "    } catch (const char* e) {\n"
2630                        "        A a = e;\n"
2631                        "    }\n"
2632                        "}");
2633         ASSERT_EQUALS("", errout.str());
2634 
2635         // exit
2636         checkUninitVar("void f() {\n"
2637                        "    int x;\n"
2638                        "    if (y == 1) { exit(0); }\n"
2639                        "    else { x = 1; }\n"
2640                        "    return x;\n"
2641                        "}");
2642         ASSERT_EQUALS("", errout.str());
2643 
2644         // strange code.. don't crash (#3415)
2645         checkUninitVar("void foo() {\n"
2646                        "    int i;\n"
2647                        "    ({ if (0); });\n"
2648                        "    for_each(i) { }\n"
2649                        "}", "test.c", false);
2650 
2651         // if, if
2652         checkUninitVar("void f(int a) {\n"
2653                        "    int i;\n"
2654                        "    if (a) i = 0;\n"
2655                        "    if (a) i++;\n"
2656                        "}");
2657         ASSERT_EQUALS("", errout.str());
2658 
2659         checkUninitVar("void f() {\n"
2660                        "    int a,b=0;\n"
2661                        "    if (x) {\n"
2662                        "        if (y) {\n"
2663                        "            a = 0;\n"
2664                        "            b = 1;\n"
2665                        "        }\n"
2666                        "    }\n"
2667                        "    if (b) a++;\n"
2668                        "}");
2669         ASSERT_EQUALS("", errout.str());
2670 
2671         checkUninitVar("void f() {\n"
2672                        "    int a=0, b;\n"
2673                        "    if (x) { }\n"
2674                        "    else { if (y==2) { a=1; b=2; } }\n"
2675                        "    if (a) { ++b; }\n"
2676                        "}");
2677         ASSERT_EQUALS("", errout.str());
2678 
2679         checkUninitVar("static void f(int x, int y) {\n"
2680                        "    int a;\n"
2681                        "    if (x == 0) { a = y; }\n"
2682                        "    if (x == 0 && (a == 1)) { }\n"
2683                        "}");
2684         ASSERT_EQUALS("", errout.str());
2685 
2686         checkUninitVar("static void f() {\n"
2687                        "    int a=0, b;\n"
2688                        "    if (something) { a = dostuff(&b); }\n"
2689                        "    if (!a || b) { }\n"
2690                        "}");
2691         ASSERT_EQUALS("", errout.str());
2692 
2693         checkUninitVar("static void f(int x, int y) {\n"
2694                        "    int a;\n"
2695                        "    if (x == 0 && (a == 1)) { }\n"
2696                        "}", "test.cpp", false);
2697         ASSERT_EQUALS("[test.cpp:3]: (error) Uninitialized variable: a\n", errout.str());
2698 
2699         checkUninitVar("void f() {\n"
2700                        "    int a;\n"
2701                        "    if (x) { a = 0; }\n"
2702                        "    if (x) { if (y) { a++; } }\n"
2703                        "}");
2704         ASSERT_EQUALS("", errout.str());
2705 
2706         checkUninitVar("void f() {\n"
2707                        "    int a;\n"
2708                        "    if (x) { a = 0; }\n"
2709                        "    if (x) { if (y) { } else { a++; } }\n"
2710                        "}");
2711         ASSERT_EQUALS("", errout.str());
2712 
2713         checkUninitVar("struct AB { int a; int b; };\n"
2714                        "void f(void) {\n"
2715                        "    struct AB ab;\n"
2716                        "    if (x) ab = getAB();\n"
2717                        "    else ab.a = 0;\n"
2718                        "    if (ab.a == 1) b = ab.b;\n"
2719                        "}", "test.c");
2720         ASSERT_EQUALS("", errout.str());
2721 
2722         checkUninitVar("int f(void) {\n"
2723                        "    int a;\n"
2724                        "    int i;\n"
2725                        "    if (x) { noreturn(); }\n"
2726                        "    else { i = 0; }\n"
2727                        "    if (i==1) { a = 0; }\n"
2728                        "    else { a = 1; }\n"
2729                        "    return a;\n"
2730                        "}");
2731         ASSERT_EQUALS("", errout.str());
2732 
2733         checkUninitVar("int f(int a) {\n" // #4560
2734                        "    int x = 0, y;\n"
2735                        "    if (a) x = 1;\n"
2736                        "    else return 0;\n"
2737                        "    if (x) y = 123;\n" // <- y is always initialized
2738                        "    else {}\n"
2739                        "    return y;\n"
2740                        "}");
2741         ASSERT_EQUALS("", errout.str());
2742 
2743         checkUninitVar("int f(int a) {\n" // #6583
2744                        "    int x;\n"
2745                        "    if (a < 2) exit(1);\n"
2746                        "    else if (a == 2) x = 0;\n"
2747                        "    else exit(2);\n"
2748                        "    return x;\n"
2749                        "}");
2750         ASSERT_EQUALS("", errout.str());
2751 
2752         checkUninitVar("int f(int a) {\n" // #4560
2753                        "    int x = 1, y;\n"
2754                        "    if (a) x = 0;\n"
2755                        "    else return 0;\n"
2756                        "    if (x) {}\n"
2757                        "    else y = 123;\n" // <- y is always initialized
2758                        "    return y;\n"
2759                        "}");
2760         ASSERT_EQUALS("", errout.str());
2761 
2762         checkUninitVar("void f(int x) {\n" // #3948
2763                        "  int value;\n"
2764                        "  if (x !=-1)\n"
2765                        "    value = getvalue();\n"
2766                        "  if (x == -1 || value > 300) {}\n"
2767                        "}");
2768         ASSERT_EQUALS("", errout.str());
2769 
2770         checkUninitVar("enum t_err { ERR_NONE, ERR_BAD_ARGS };\n" // #9649
2771                        "struct box_t { int value; };\n"
2772                        "int init_box(box_t *p, int v);\n"
2773                        "\n"
2774                        "void foo(int ret) {\n"
2775                        "    box_t box2;\n"
2776                        "    if (ret == ERR_NONE)\n"
2777                        "        ret = init_box(&box2, 20);\n"
2778                        "    if (ret == ERR_NONE)\n"
2779                        "        z = x + box2.value;\n"
2780                        "}");
2781         ASSERT_EQUALS("", errout.str());
2782 
2783         checkUninitVar("void f(int x) {\n"
2784                        "  int value;\n"
2785                        "  if (x == 32)\n"
2786                        "    value = getvalue();\n"
2787                        "  if (x == 1)\n"
2788                        "    v = value;\n"
2789                        "}");
2790         ASSERT_EQUALS("[test.cpp:6]: (error) Uninitialized variable: value\n", errout.str());
2791 
2792         checkUninitVar("void f(int x) {\n"
2793                        "  int value;\n"
2794                        "  if (x == 32)\n"
2795                        "    value = getvalue();\n"
2796                        "  if (x == 32) {}\n"
2797                        "  else v = value;\n"
2798                        "}");
2799         ASSERT_EQUALS("[test.cpp:6]: (error) Uninitialized variable: value\n", errout.str());
2800 
2801         checkUninitVar("static int x;" // #4773
2802                        "int f() {\n"
2803                        "    int y;\n"
2804                        "    if (x) g();\n"
2805                        "    if (x) y = 123;\n"
2806                        "    else y = 456;\n"
2807                        "    return y;\n"
2808                        "}");
2809         ASSERT_EQUALS("", errout.str());
2810 
2811         checkUninitVar("static int x;" // #4773
2812                        "int f() {\n"
2813                        "    int y;\n"
2814                        "    if (!x) g();\n"
2815                        "    if (x) y = 123;\n"
2816                        "    else y = 456;\n"
2817                        "    return y;\n"
2818                        "}");
2819         ASSERT_EQUALS("", errout.str());
2820 
2821         checkUninitVar("void f(int a) {\n"
2822                        "  int x;\n"
2823                        "  if (a) x=123;\n"
2824                        "  if (!a) {\n"
2825                        "    if (!a) {}\n"
2826                        "    else if (x) {}\n"
2827                        "  }\n"
2828                        "}");
2829         ASSERT_EQUALS("", errout.str());
2830 
2831         // asm
2832         checkUninitVar("void f() {\n"
2833                        "    int x;\n"
2834                        "    asm();\n"
2835                        "    x++;\n"
2836                        "}");
2837         ASSERT_EQUALS("", errout.str());
2838 
2839         // sizeof / typeof / offsetof / etc
2840         checkUninitVar("void f() {\n"
2841                        "    int i;\n"
2842                        "    sizeof(i+1);\n"
2843                        "}");
2844         ASSERT_EQUALS("", errout.str());
2845 
2846         checkUninitVar("void f() {\n"
2847                        "    int i;\n"
2848                        "    if (100 == sizeof(i+1));\n"
2849                        "}");
2850         ASSERT_EQUALS("", errout.str());
2851 
2852         checkUninitVar("void f() {\n"
2853                        "    struct ABC *abc;\n"
2854                        "    int i = ARRAY_SIZE(abc.a);"
2855                        "}");
2856         // FP ASSERT_EQUALS("", errout.str());
2857 
2858         checkUninitVar("void f() {\n"
2859                        "    int *abc;\n"
2860                        "    typeof(*abc);\n"
2861                        "}");
2862         ASSERT_EQUALS("", errout.str());
2863 
2864         checkUninitVar("void f() {\n"
2865                        "    struct ABC *abc;\n"
2866                        "    return do_something(typeof(*abc));\n"
2867                        "}");
2868         ASSERT_EQUALS("", errout.str());
2869 
2870         checkUninitVar("void f() {\n"
2871                        "    A *a;\n"
2872                        "    a = malloc(sizeof(*a));\n"
2873                        "}");
2874         ASSERT_EQUALS("", errout.str());
2875 
2876         // &
2877         checkUninitVar("void f() {\n"  // #4426 - address of uninitialized variable
2878                        "    int a,b;\n"
2879                        "    if (&a == &b);\n"
2880                        "}");
2881         ASSERT_EQUALS("", errout.str());
2882 
2883         checkUninitVar("void f() {\n"  // #4439 - cast address of uninitialized variable
2884                        "    int a;\n"
2885                        "    x((LPARAM)(RECT*)&a);\n"
2886                        "}");
2887         ASSERT_EQUALS("", errout.str());
2888 
2889         checkUninitVar("int main() {\n"
2890                        "    int done;\n"
2891                        "    dostuff(1, (AuPointer) &done);\n" // <- It is not conclusive if the "&" is a binary or unary operator. Bailout.
2892                        "}");
2893         ASSERT_EQUALS("", errout.str());
2894 
2895         checkUninitVar("void f() {\n" // #4778 - cast address of uninitialized variable
2896                        "    long a;\n"
2897                        "    &a;\n"
2898                        "}");
2899         ASSERT_EQUALS("", errout.str());
2900 
2901         checkUninitVar("void f() {\n" // #4717 - ({})
2902                        "    int a = ({ long b = (long)(123); 2 + b; });\n"
2903                        "}", "test.c");
2904         ASSERT_EQUALS("", errout.str());
2905     }
2906 
2907     // #3869 - reference variable
uninitvar4()2908     void uninitvar4() {
2909         checkUninitVar("void f() {\n"
2910                        "    int buf[10];\n"
2911                        "    int &x = buf[0];\n"
2912                        "    buf[0] = 0;\n"
2913                        "    x++;\n"
2914                        "}");
2915         ASSERT_EQUALS("", errout.str());
2916     }
2917 
2918     // #3861
uninitvar5()2919     void uninitvar5() {
2920         // ensure there is no false positive
2921         checkUninitVar("void f() {\n"
2922                        "    x<char> c;\n"
2923                        "    c << 2345;\n"
2924                        "}");
2925         ASSERT_EQUALS("", errout.str());
2926 
2927         // ensure there is no false negative
2928         checkUninitVar("void f() {\n"
2929                        "    char c;\n"
2930                        "    char a = c << 2;\n"
2931                        "}");
2932         ASSERT_EQUALS("[test.cpp:3]: (error) Uninitialized variable: c\n", errout.str());
2933     }
2934 
uninitvar8()2935     void uninitvar8() {
2936         const char code[] = "struct Fred {\n"
2937                             "    void Sync(dsmp_t& type, int& len, int limit = 123);\n"
2938                             "    void Sync(int& syncpos, dsmp_t& type, int& len, int limit = 123);\n"
2939                             "    void FindSyncPoint();\n"
2940                             "};\n"
2941                             "void Fred::FindSyncPoint() {\n"
2942                             "    dsmp_t type;\n"
2943                             "    int syncpos, len;\n"
2944                             "    Sync(syncpos, type, len);\n"
2945                             "}";
2946         checkUninitVar(code, "test.cpp");
2947         ASSERT_EQUALS("", errout.str());
2948     }
2949 
uninitvar9()2950     void uninitvar9() { // 6424
2951         const char code[] = "namespace Ns { class C; }\n"
2952                             "void f1() { char *p; *p = 0; }\n"
2953                             "class Ns::C* p;\n"
2954                             "void f2() { char *p; *p = 0; }";
2955         checkUninitVar(code, "test.cpp");
2956         ASSERT_EQUALS("[test.cpp:2]: (error) Uninitialized variable: p\n"
2957                       "[test.cpp:4]: (error) Uninitialized variable: p\n", errout.str());
2958     }
2959 
uninitvar10()2960     void uninitvar10() { // 9467
2961         const char code[] = "class Foo {\n"
2962                             "    template <unsigned int i>\n"
2963                             "    bool bar() {\n"
2964                             "        return true;\n"
2965                             "    }\n"
2966                             "};\n"
2967                             "template <>\n"
2968                             "bool Foo::bar<9>() {\n"
2969                             "    return true;\n"
2970                             "}\n"
2971                             "int global() {\n"
2972                             "    int bar = 1;\n"
2973                             "    return bar;\n"
2974                             "}";
2975         checkUninitVar(code, "test.cpp");
2976         ASSERT_EQUALS("", errout.str());
2977     }
2978 
uninitvar11()2979     void uninitvar11() { // 9123
2980         const char code[] = "bool get(int &var);\n"
2981                             "void foo () {\n"
2982                             "    int x;\n"
2983                             "    x = get(x) && x;\n"
2984                             "}";
2985         checkUninitVar(code, "test.cpp");
2986         ASSERT_EQUALS("", errout.str());
2987     }
2988 
uninitvar12()2989     void uninitvar12() { // 10218
2990         const char code[] = "void fp() {\n"
2991                             "  std::stringstream ss;\n"
2992                             "  for (int i; ss >> i;) {}\n"
2993                             "}";
2994         checkUninitVar(code);
2995         ASSERT_EQUALS("", errout.str());
2996     }
2997 
uninitvar13()2998     void uninitvar13() { // #9772 - FP
2999         const char code[] = "int func(void)\n"
3000                             "{ int rez;\n"
3001                             "  struct sccb* ccb;\n"
3002                             " \n"
3003                             "  do\n"
3004                             "  { if ((ccb = calloc(1, sizeof(*ccb))) == NULL)\n"
3005                             "    { rez = 1;\n"
3006                             "      break;\n"
3007                             "    }\n"
3008                             "    rez = 0;\n"
3009                             "  } while (0);\n"
3010                             " \n"
3011                             "  if (rez != 0)\n"
3012                             "    free(ccb);\n"
3013                             " \n"
3014                             "  return rez;\n"
3015                             "}";
3016         checkUninitVar(code);
3017         ASSERT_EQUALS("", errout.str());
3018     }
3019 
uninitvar_unconditionalTry()3020     void uninitvar_unconditionalTry() {
3021         // Unconditional scopes and try{} scopes
3022         checkUninitVar("int f() {\n"
3023                        "    int i;\n"
3024                        "    {\n"
3025                        "        return i;\n"
3026                        "    }\n"
3027                        "}");
3028         ASSERT_EQUALS("[test.cpp:4]: (error) Uninitialized variable: i\n", errout.str());
3029 
3030         checkUninitVar("int f() {\n"
3031                        "    int i;\n"
3032                        "    try {\n"
3033                        "        return i;\n"
3034                        "    } catch(...) {}\n"
3035                        "}");
3036         ASSERT_EQUALS("[test.cpp:4]: (error) Uninitialized variable: i\n", errout.str());
3037     }
3038 
uninitvar_funcptr()3039     void uninitvar_funcptr() {
3040         // extracttests.disable
3041 
3042         checkUninitVar("void getLibraryContainer() {\n"
3043                        "    Reference< XStorageBasedLibraryContainer >(*Factory)(const Reference< XComponentContext >&, const Reference< XStorageBasedDocument >&)\n"
3044                        "        = &DocumentDialogLibraryContainer::create;\n"
3045                        "    rxContainer.set((*Factory)(m_aContext, xDocument));\n"
3046                        "}");
3047         ASSERT_EQUALS("", errout.str());
3048 
3049         checkUninitVar("void foo() {\n"
3050                        "    void* x;\n"
3051                        "    int (*f)(int, int) = x;\n"
3052                        "    dostuff((*f)(a,b));\n"
3053                        "}");
3054         ASSERT_EQUALS("[test.cpp:3]: (error) Uninitialized variable: x\n", errout.str());
3055 
3056         checkUninitVar("void getLibraryContainer() {\n"
3057                        "    Reference< XStorageBasedLibraryContainer >(*Factory)(const Reference< XComponentContext >&, const Reference< XStorageBasedDocument >&);\n"
3058                        "    rxContainer.set((*Factory)(m_aContext, xDocument));\n"
3059                        "}");
3060         ASSERT_EQUALS("[test.cpp:3]: (error) Uninitialized variable: Factory\n", errout.str());
3061 
3062         // extracttests.enable
3063     }
3064 
uninitvar_operator()3065     void uninitvar_operator() { // Ticket #6463, #6680
3066         checkUninitVar("struct Source { Source& operator>>(int& i) { i = 0; return *this; } };\n"
3067                        "struct Sink { int v; };\n"
3068                        "Source foo;\n"
3069                        "void uninit() {\n"
3070                        "  Sink s;\n"
3071                        "  int n = 1 >> s.v;\n" // Not initialized
3072                        "};\n"
3073                        "void notUninit() {\n"
3074                        "  Sink s1;\n"
3075                        "  foo >> s1.v;\n" // Initialized by operator>>
3076                        "  Sink s2;\n"
3077                        "  int n;\n"
3078                        "  foo >> s2.v >> n;\n" // Initialized by operator>>
3079                        "}");
3080         ASSERT_EQUALS("[test.cpp:6]: (error) Uninitialized struct member: s.v\n", errout.str());
3081 
3082         checkUninitVar("struct Fred { int a; };\n"
3083                        "void foo() {\n"
3084                        "  Fred fred;\n"
3085                        "  std::cin >> fred.a;\n"
3086                        "}");
3087         ASSERT_EQUALS("", errout.str());
3088     }
3089 
3090     // Handling of function calls
uninitvar2_func()3091     void uninitvar2_func() {
3092         // non-pointer variable
3093         checkUninitVar("void a(char);\n"  // value => error
3094                        "void b() {\n"
3095                        "    char c;\n"
3096                        "    a(c);\n"
3097                        "}");
3098         ASSERT_EQUALS("[test.cpp:4]: (error) Uninitialized variable: c\n", errout.str());
3099 
3100         checkUninitVar("void a(char c);\n"  // value => error
3101                        "void b() {\n"
3102                        "    char c;\n"
3103                        "    a(c);\n"
3104                        "}");
3105         ASSERT_EQUALS("[test.cpp:4]: (error) Uninitialized variable: c\n", errout.str());
3106 
3107         checkUninitVar("void a(const char c);\n"  // const value => error
3108                        "void b() {\n"
3109                        "    char c;\n"
3110                        "    a(c);\n"
3111                        "}");
3112         ASSERT_EQUALS("[test.cpp:4]: (error) Uninitialized variable: c\n", errout.str());
3113 
3114         checkUninitVar("void a(char *c);\n"  // address => no error
3115                        "void b() {\n"
3116                        "    char c;\n"
3117                        "    a(&c);\n"
3118                        "}");
3119         ASSERT_EQUALS("", errout.str());
3120 
3121         checkUninitVar("void a(pstr s);\n"  // address => no error
3122                        "void b() {\n"
3123                        "    char c;\n"
3124                        "    a(&c);\n"
3125                        "}");
3126         ASSERT_EQUALS("", errout.str());
3127 
3128         checkUninitVar("void a(const char *c);\n"  // const address => data is not changed
3129                        "void b() {\n"
3130                        "    char c;\n"
3131                        "    a(&c);\n"  // <- no warning
3132                        "    c++;\n"  // <- uninitialized variable
3133                        "}");
3134         TODO_ASSERT_EQUALS("[test.cpp:5]: (error) Uninitialized variable: c\n", "", errout.str());
3135 
3136         // pointer variable
3137         checkUninitVar("void a(char c);\n"  // value => error
3138                        "void b() {\n"
3139                        "    char *c;\n"
3140                        "    a(*c);\n"
3141                        "}");
3142         ASSERT_EQUALS("[test.cpp:4]: (error) Uninitialized variable: c\n", errout.str());
3143 
3144 
3145         checkUninitVar("void a(char *c);\n"  // address => error
3146                        "void b() {\n"
3147                        "    char *c;\n"
3148                        "    a(c);\n"
3149                        "}");
3150         ASSERT_EQUALS("[test.cpp:4]: (error) Uninitialized variable: c\n", errout.str());
3151 
3152         checkUninitVar("typedef struct { int a; int b; } AB;\n"
3153                        "void a(AB *ab);\n"
3154                        "void b() {\n"
3155                        "    AB *ab;\n"
3156                        "    a(ab);\n"
3157                        "}");
3158         ASSERT_EQUALS("[test.cpp:5]: (error) Uninitialized variable: ab\n", errout.str());
3159 
3160         checkUninitVar("void a(const char *c);\n"  // const address => error
3161                        "void b() {\n"
3162                        "    char *c;\n"
3163                        "    a(c);\n"
3164                        "}");
3165         ASSERT_EQUALS("[test.cpp:4]: (error) Uninitialized variable: c\n", errout.str());
3166 
3167         checkUninitVar("void a(const char c[]);\n"  // const address => error
3168                        "void b() {\n"
3169                        "    char *c;\n"
3170                        "    a(c);\n"
3171                        "}");
3172         ASSERT_EQUALS("[test.cpp:4]: (error) Uninitialized variable: c\n", errout.str());
3173 
3174         checkUninitVar("void a(char **c);\n"  // address of pointer => no error
3175                        "void b() {\n"
3176                        "    char *c;\n"
3177                        "    a(&c);\n"
3178                        "}");
3179         ASSERT_EQUALS("", errout.str());
3180 
3181         checkUninitVar("void a(char *c);\n"  // address of pointer (suspicious cast to pointer) => no error
3182                        "void b() {\n"
3183                        "    char *c;\n"
3184                        "    a(&c);\n"
3185                        "}");
3186         ASSERT_EQUALS("", errout.str());
3187 
3188         checkUninitVar("void a(const char **c);\n"  // const address of pointer => no error
3189                        "void b() {\n"
3190                        "    const char *c;\n"
3191                        "    a(&c);\n"
3192                        "}");
3193         ASSERT_EQUALS("", errout.str());
3194 
3195         // array
3196         checkUninitVar("int calc(const int *p, int n);\n"
3197                        "void f() {\n"
3198                        "    int x[10];\n"
3199                        "    calc(x,10);\n"
3200                        "}");
3201         TODO_ASSERT_EQUALS("[test.cpp:4]: (error) Uninitialized variable: x\n",
3202                            "", errout.str());
3203 
3204         checkUninitVar("void f() {\n"
3205                        "    int x[10];\n"
3206                        "    int &x0(*x);\n"
3207                        "}");
3208         ASSERT_EQUALS("", errout.str());
3209 
3210         // ....
3211         checkUninitVar("struct ABC { int a; };\n"  // struct initialization
3212                        "void clear(struct ABC &abc);\n"
3213                        "int f() {\n"
3214                        "    struct ABC abc;\n"
3215                        "    clear(abc);\n"
3216                        "    return abc.a;\n"
3217                        "}");
3218         ASSERT_EQUALS("", errout.str());
3219 
3220         checkUninitVar("void write_packet() {\n"
3221                        "    time_t now0;\n"
3222                        "    time(&now0);\n"
3223                        "}", "test.c");
3224         ASSERT_EQUALS("", errout.str());
3225 
3226         checkUninitVar("void write_packet() {\n"
3227                        "    time_t* now0;\n"
3228                        "    time(now0);\n"
3229                        "}", "test.c");
3230         ASSERT_EQUALS("[test.c:3]: (error) Uninitialized variable: now0\n", errout.str());
3231 
3232         checkUninitVar("void write_packet() {\n"
3233                        "    char now0;\n"
3234                        "    strcmp(&now0, sth);\n"
3235                        "}", "test.c");
3236         ASSERT_EQUALS("[test.c:3]: (error) Uninitialized variable: now0\n", errout.str());
3237 
3238         // #2775 - uninitialized struct pointer in subfunction
3239         // extracttests.start: struct Fred {int x;};
3240         checkUninitVar("void a(struct Fred *fred) {\n"
3241                        "    fred->x = 0;\n"
3242                        "}\n"
3243                        "\n"
3244                        "void b() {\n"
3245                        "    struct Fred *p;\n"
3246                        "    a(p);\n"
3247                        "}");
3248         ASSERT_EQUALS("[test.cpp:7]: (error) Uninitialized variable: p\n", errout.str());
3249 
3250         // #2946 - FP array is initialized in subfunction
3251         checkUninitVar("void a(char *buf) {\n"
3252                        "    buf[0] = 0;\n"
3253                        "}\n"
3254                        "void b() {\n"
3255                        "    char buf[10];\n"
3256                        "    a(buf);\n"
3257                        "    buf[1] = buf[0];\n"
3258                        "}");
3259         ASSERT_EQUALS("", errout.str());
3260 
3261         // unknown macro
3262         checkUninitVar("void f() {\n"
3263                        "  struct listnode *item;\n"
3264                        "  list_for_each(item, &key_list) {}\n"
3265                        "}");
3266         ASSERT_EQUALS("", errout.str());
3267     }
3268 
uninitvar2_value()3269     void uninitvar2_value() {
3270         checkUninitVar("void f() {\n"
3271                        "    int i;\n"
3272                        "    if (x) {\n"
3273                        "        int y = -ENOMEM;\n"  // assume constant ENOMEM is nonzero since it's negated
3274                        "        if (y != 0) return;\n"
3275                        "        i++;\n"
3276                        "    }\n"
3277                        "}", "test.cpp", false);
3278         ASSERT_EQUALS("", errout.str());
3279 
3280         checkUninitVar("void f() {\n"
3281                        "    int i, y;\n"
3282                        "    if (x) {\n"
3283                        "        y = -ENOMEM;\n"  // assume constant ENOMEM is nonzero since it's negated
3284                        "        if (y != 0) return;\n"
3285                        "        i++;\n"
3286                        "    }\n"
3287                        "}", "test.cpp", false);
3288         ASSERT_EQUALS("", errout.str());
3289 
3290         checkUninitVar("void f() {\n"
3291                        "    int i, y;\n"
3292                        "    if (x) y = -ENOMEM;\n"  // assume constant ENOMEM is nonzero since it's negated
3293                        "    else y = get_value(i);\n"
3294                        "    if (y != 0) return;\n" // <- condition is always true if i is uninitialized
3295                        "    i++;\n"
3296                        "}");
3297         ASSERT_EQUALS("", errout.str());
3298 
3299         checkUninitVar("void f(int x) {\n"
3300                        "    int i;\n"
3301                        "    if (!x) i = 0;\n"
3302                        "    if (!x || i>0) {}\n" // <- error
3303                        "}");
3304         TODO_ASSERT_EQUALS("[test.cpp:4]: (error) Uninitialized variable: i\n", "", errout.str());
3305 
3306         checkUninitVar("void f(int x) {\n"
3307                        "    int i;\n"
3308                        "    if (x) i = 0;\n"
3309                        "    if (!x || i>0) {}\n" // <- no error
3310                        "}");
3311         ASSERT_EQUALS("", errout.str());
3312 
3313         checkUninitVar("void f(int x) {\n"
3314                        "    int i;\n"
3315                        "    if (!x) { }\n"
3316                        "    else i = 0;\n"
3317                        "    if (x || i>0) {}\n"
3318                        "}");
3319         ASSERT_EQUALS("[test.cpp:5]: (error) Uninitialized variable: i\n", errout.str());
3320 
3321         checkUninitVar("void f(int x) {\n"
3322                        "    int i;\n"
3323                        "    if (x) { }\n"
3324                        "    else i = 0;\n"
3325                        "    if (x || i>0) {}\n" // <- no error
3326                        "}");
3327         ASSERT_EQUALS("", errout.str());
3328 
3329         checkUninitVar("int f(int x) {\n"
3330                        "    int y;\n"
3331                        "    if (x) y = do_something();\n"
3332                        "    if (!x) return 0;\n"
3333                        "    return y;\n"
3334                        "}");
3335         ASSERT_EQUALS("", errout.str());
3336 
3337         // extracttests.start: int y;
3338         checkUninitVar("int f(int x) {\n" // FP with ?:
3339                        "    int a;\n"
3340                        "    if (x)\n"
3341                        "        a = y;\n"
3342                        "    return x ? 2*a : 0;\n"
3343                        "}");
3344         ASSERT_EQUALS("", errout.str());
3345 
3346         checkUninitVar("int f(int x) {\n"
3347                        "    int a;\n"
3348                        "    if (x)\n"
3349                        "        a = y;\n"
3350                        "    return y ? 2*a : 3*a;\n"
3351                        "}");
3352         ASSERT_EQUALS("[test.cpp:5]: (error) Uninitialized variable: a\n", errout.str());
3353 
3354         checkUninitVar("void f() {\n" // Don't crash
3355                        "    int a;\n"
3356                        "    dostuff(\"ab\" cd \"ef\", x?a:z);\n" // <- No AST is created for ?:
3357                        "}");
3358 
3359         // Unknown => bail out..
3360         checkUninitVar("void f(int x) {\n"
3361                        "    int i;\n"
3362                        "    if (a(x)) i = 0;\n"
3363                        "    if (b(x)) return;\n"
3364                        "    i++;\n" // <- no error if b(x) is always true when a(x) is false
3365                        "}");
3366         ASSERT_EQUALS("", errout.str());
3367 
3368         checkUninitVar("void f(int x) {\n"
3369                        "    int i;\n"
3370                        "    if (x) i = 0;\n"
3371                        "    while (condition) {\n"
3372                        "        if (x) i++;\n" // <- no error
3373                        "    }\n"
3374                        "}");
3375         ASSERT_EQUALS("", errout.str());
3376 
3377         checkUninitVar("void f(int x) {\n"
3378                        "    int i;\n"
3379                        "    if (x) i = 0;\n"
3380                        "    while (condition) {\n"
3381                        "        i++;\n"
3382                        "    }\n"
3383                        "}");
3384         TODO_ASSERT_EQUALS("error", "", errout.str());
3385     }
3386 
uninitStructMember()3387     void uninitStructMember() { // struct members
3388         checkUninitVar("struct AB { int a; int b; };\n"
3389                        "void f(void) {\n"
3390                        "    struct AB ab;\n"
3391                        "    int a = ab.a;\n"
3392                        "}");
3393         ASSERT_EQUALS("[test.cpp:4]: (error) Uninitialized struct member: ab.a\n", errout.str());
3394 
3395         checkUninitVar("struct AB { int a; int b; };\n"
3396                        "void f(void) {\n"
3397                        "    AB ab;\n"
3398                        "    int a = ab.a;\n"
3399                        "}");
3400         ASSERT_EQUALS("[test.cpp:4]: (error) Uninitialized struct member: ab.a\n", errout.str());
3401 
3402         checkUninitVar("struct AB { int a; int b; };\n"
3403                        "void f(void) {\n"
3404                        "    struct AB ab;\n"
3405                        "    ab.a = ab.a + 1;\n"
3406                        "}");
3407         ASSERT_EQUALS("[test.cpp:4]: (error) Uninitialized struct member: ab.a\n", errout.str());
3408 
3409         checkUninitVar("struct AB { int a; int b; };\n"
3410                        "void do_something(const struct AB ab);\n"
3411                        "void f(void) {\n"
3412                        "    struct AB ab;\n"
3413                        "    ab.a = 0;\n"
3414                        "    do_something(ab);\n"
3415                        "}\n", "test.c");
3416         ASSERT_EQUALS("[test.c:6]: (error) Uninitialized struct member: ab.b\n", errout.str());
3417 
3418         checkUninitVar("struct AB { int a; int b; };\n" // #4760
3419                        "void do_something(int a);\n"
3420                        "void f(void) {\n"
3421                        "    struct AB ab;\n"
3422                        "    do_something(ab.a);\n"
3423                        "}\n", "test.c");
3424         ASSERT_EQUALS("[test.c:5]: (error) Uninitialized struct member: ab.a\n", errout.str());
3425 
3426         checkUninitVar("struct AB { int a; int b; };\n"
3427                        "void do_something(const struct AB &ab) { a = ab.a; }\n"
3428                        "void f(void) {\n"
3429                        "    struct AB ab;\n"
3430                        "    ab.a = 0;\n"
3431                        "    do_something(ab);\n"
3432                        "}");
3433         ASSERT_EQUALS("", errout.str());
3434 
3435         checkUninitVar("struct AB { int a; int b; };\n"
3436                        "void f(void) {\n"
3437                        "    struct AB ab;\n"
3438                        "    int a = ab.a;\n"
3439                        "}\n", "test.c");
3440         ASSERT_EQUALS("[test.c:4]: (error) Uninitialized struct member: ab.a\n", errout.str());
3441 
3442         checkUninitVar("struct AB { int a; int b; };\n"
3443                        "void f(void) {\n"
3444                        "    AB ab1;\n"
3445                        "    AB ab2 = { ab1.a, 0 };\n"
3446                        "}");
3447         ASSERT_EQUALS("[test.cpp:4]: (error) Uninitialized struct member: ab1.a\n", errout.str());
3448 
3449         checkUninitVar("struct AB { int a; int b; };\n"
3450                        "void f(void) {\n"
3451                        "    struct AB ab;\n"
3452                        "    buf[ab.a] = 0;\n"
3453                        "}\n", "test.c");
3454         ASSERT_EQUALS("[test.c:4]: (error) Uninitialized struct member: ab.a\n", errout.str());
3455 
3456         checkUninitVar("struct AB { int a; int b; };\n"
3457                        "void f(void) {\n"
3458                        "    struct AB ab;\n"
3459                        "    ab.a = 1;\n"
3460                        "    x = ab;\n"
3461                        "}\n", "test.c");
3462         ASSERT_EQUALS("[test.c:5]: (error) Uninitialized struct member: ab.b\n", errout.str());
3463 
3464         checkUninitVar("struct AB { int a; int b; };\n"
3465                        "void f(void) {\n"
3466                        "    struct AB ab;\n"
3467                        "    ab.a = 1;\n"
3468                        "    x = *(&ab);\n"
3469                        "}\n", "test.c");
3470         ASSERT_EQUALS("[test.c:5]: (error) Uninitialized struct member: ab.b\n", errout.str());
3471 
3472         checkUninitVar("void f(void) {\n"
3473                        "    struct AB ab;\n"
3474                        "    int x;\n"
3475                        "    ab.a = (addr)&x;\n"
3476                        "    dostuff(&ab,0);\n"
3477                        "}\n", "test.c");
3478         ASSERT_EQUALS("", errout.str());
3479 
3480         checkUninitVar("struct Element {\n"
3481                        "    static void f() { }\n"
3482                        "};\n"
3483                        "void test() {\n"
3484                        "    Element *element; element->f();\n"
3485                        "}");
3486         ASSERT_EQUALS("[test.cpp:5]: (error) Uninitialized variable: element\n", errout.str());
3487 
3488         checkUninitVar("struct Element {\n"
3489                        "    static void f() { }\n"
3490                        "};\n"
3491                        "void test() {\n"
3492                        "    Element *element; (*element).f();\n"
3493                        "}");
3494         ASSERT_EQUALS("[test.cpp:5]: (error) Uninitialized variable: element\n", errout.str());
3495 
3496         checkUninitVar("struct Element {\n"
3497                        "    static int v;\n"
3498                        "};\n"
3499                        "void test() {\n"
3500                        "    Element *element; element->v;\n"
3501                        "}");
3502         ASSERT_EQUALS("[test.cpp:5]: (error) Uninitialized variable: element\n", errout.str());
3503 
3504         checkUninitVar("struct Element {\n"
3505                        "    static int v;\n"
3506                        "};\n"
3507                        "void test() {\n"
3508                        "    Element *element; (*element).v;\n"
3509                        "}");
3510         ASSERT_EQUALS("[test.cpp:5]: (error) Uninitialized variable: element\n", errout.str());
3511 
3512         checkUninitVar("struct Element {\n"
3513                        "    void f() { }\n"
3514                        "};\n"
3515                        "void test() {\n"
3516                        "    Element *element; element->f();\n"
3517                        "}");
3518         ASSERT_EQUALS("[test.cpp:5]: (error) Uninitialized variable: element\n", errout.str());
3519 
3520         checkUninitVar("struct Element {\n"
3521                        "    void f() { }\n"
3522                        "};\n"
3523                        "void test() {\n"
3524                        "    Element *element; (*element).f();\n"
3525                        "}");
3526         ASSERT_EQUALS("[test.cpp:5]: (error) Uninitialized variable: element\n", errout.str());
3527 
3528         checkUninitVar("struct Element {\n"
3529                        "    int v;\n"
3530                        "};\n"
3531                        "void test() {\n"
3532                        "    Element *element; element->v;\n"
3533                        "}");
3534         ASSERT_EQUALS("[test.cpp:5]: (error) Uninitialized variable: element\n", errout.str());
3535 
3536         checkUninitVar("struct Element {\n"
3537                        "    int v;\n"
3538                        "};\n"
3539                        "void test() {\n"
3540                        "    Element *element; (*element).v;\n"
3541                        "}");
3542         ASSERT_EQUALS("[test.cpp:5]: (error) Uninitialized variable: element\n", errout.str());
3543 
3544         checkUninitVar("struct AB { int a; int b; };\n"  // pass struct member by address
3545                        "void f(void) {\n"
3546                        "    struct AB ab;\n"
3547                        "    assign(&ab.a, 0);\n"
3548                        "}\n", "test.c");
3549         ASSERT_EQUALS("", errout.str());
3550 
3551         checkUninitVar("struct Cstring { char *text; int size, alloc; };\n"
3552                        "int maybe();\n"
3553                        "void f() {\n"
3554                        "    Cstring res;\n"
3555                        "    if ( ! maybe() ) return;\n"  // <- fp goes away if this is removed
3556                        "    ( ((res).text = (void*)0), ((res).size = (res).alloc = 0) );\n"  // <- fp goes away if parentheses are removed
3557                        "}");
3558         ASSERT_EQUALS("", errout.str());
3559 
3560         {
3561             const char argDirectionsTestXmlData[] = "<?xml version=\"1.0\"?>\n"
3562                                                     "<def>\n"
3563                                                     "  <function name=\"uninitvar_funcArgInTest\">\n"
3564                                                     "    <arg nr=\"1\" direction=\"in\"/>\n"
3565                                                     "  </function>\n"
3566                                                     "  <function name=\"uninitvar_funcArgOutTest\">\n"
3567                                                     "    <arg nr=\"1\" direction=\"out\"/>\n"
3568                                                     "  </function>\n"
3569                                                     "</def>";
3570 
3571             ASSERT_EQUALS(true, settings.library.loadxmldata(argDirectionsTestXmlData, sizeof(argDirectionsTestXmlData) / sizeof(argDirectionsTestXmlData[0])));
3572 
3573             checkUninitVar("struct AB { int a; };\n"
3574                            "void f(void) {\n"
3575                            "    struct AB ab;\n"
3576                            "    uninitvar_funcArgInTest(&ab);\n"
3577                            "    x = ab;\n"
3578                            "}\n", "test.c");
3579             ASSERT_EQUALS("[test.c:5]: (error) Uninitialized struct member: ab.a\n", errout.str());
3580 
3581             checkUninitVar("struct AB { int a; };\n"
3582                            "void f(void) {\n"
3583                            "    struct AB ab;\n"
3584                            "    uninitvar_funcArgOutTest(&ab);\n"
3585                            "    x = ab;\n"
3586                            "}\n", "test.c");
3587             ASSERT_EQUALS("", errout.str());
3588         }
3589 
3590         checkUninitVar("struct AB { int a; int b; };\n"
3591                        "void do_something(const struct AB ab);\n"
3592                        "void f(void) {\n"
3593                        "    struct AB ab;\n"
3594                        "    ab.a = 0;\n"
3595                        "    ab.b = 0;\n"
3596                        "    do_something(ab);\n"
3597                        "}\n", "test.c");
3598         ASSERT_EQUALS("", errout.str());
3599 
3600         {
3601             checkUninitVar("struct AB { char a[10]; };\n"
3602                            "void f(void) {\n"
3603                            "    struct AB ab;\n"
3604                            "    strcpy(ab.a, STR);\n"
3605                            "}\n", "test.c");
3606             ASSERT_EQUALS("", errout.str());
3607 
3608             checkUninitVar("struct AB { unsigned char a[10]; };\n" // #8999 - cast
3609                            "void f(void) {\n"
3610                            "    struct AB ab;\n"
3611                            "    strcpy((char *)ab.a, STR);\n"
3612                            "}\n", "test.c");
3613             ASSERT_EQUALS("", errout.str());
3614 
3615             checkUninitVar("struct AB { char a[10]; };\n"
3616                            "void f(void) {\n"
3617                            "    struct AB ab;\n"
3618                            "    strcpy(x, ab.a);\n"
3619                            "}\n", "test.c");
3620             TODO_ASSERT_EQUALS("[test.c:4]: (error) Uninitialized variable: ab.a\n", "", errout.str());
3621 
3622             checkUninitVar("struct AB { int a; };\n"
3623                            "void f(void) {\n"
3624                            "    struct AB ab;\n"
3625                            "    dosomething(ab.a);\n"
3626                            "}\n", "test.c");
3627             ASSERT_EQUALS("", errout.str());
3628         }
3629 
3630         checkUninitVar("struct AB { int a; int b; };\n"
3631                        "void do_something(const struct AB ab);\n"
3632                        "void f(void) {\n"
3633                        "    struct AB ab;\n"
3634                        "    ab = getAB();\n"
3635                        "    do_something(ab);\n"
3636                        "}\n", "test.c");
3637         ASSERT_EQUALS("", errout.str());
3638 
3639         {
3640             // #6769 - calling method that might assign struct members
3641             checkUninitVar("struct AB { int a; int b; void set(); };\n"
3642                            "void f(void) {\n"
3643                            "    struct AB ab;\n"
3644                            "    ab.set();\n"
3645                            "    x = ab;\n"
3646                            "}");
3647             ASSERT_EQUALS("", errout.str());
3648 
3649             checkUninitVar("struct AB { int a; int get() const; };\n"
3650                            "void f(void) {\n"
3651                            "    struct AB ab;\n"
3652                            "    ab.get();\n"
3653                            "    x = ab;\n"
3654                            "}");
3655             ASSERT_EQUALS("[test.cpp:5]: (error) Uninitialized struct member: ab.a\n", errout.str());
3656 
3657             checkUninitVar("struct AB { int a; void dostuff() {} };\n"
3658                            "void f(void) {\n"
3659                            "    struct AB ab;\n"
3660                            "    ab.dostuff();\n"
3661                            "    x = ab;\n"
3662                            "}");
3663             TODO_ASSERT_EQUALS("error", "", errout.str());
3664         }
3665 
3666         checkUninitVar("struct AB { int a; struct { int b; int c; } s; };\n"
3667                        "void do_something(const struct AB ab);\n"
3668                        "void f(void) {\n"
3669                        "    struct AB ab;\n"
3670                        "    ab.a = 1;\n"
3671                        "    ab.s.b = 2;\n"
3672                        "    ab.s.c = 3;\n"
3673                        "    do_something(ab);\n"
3674                        "}\n", "test.c");
3675         ASSERT_EQUALS("", errout.str());
3676 
3677         checkUninitVar("struct conf {\n"
3678                        "    char x;\n"
3679                        "};\n"
3680                        "\n"
3681                        "void do_something(struct conf ant_conf);\n"
3682                        "\n"
3683                        "void f(void) {\n"
3684                        "   struct conf c;\n"
3685                        "   initdata(&c);\n"
3686                        "   do_something(c);\n"
3687                        "}\n", "test.c");
3688         ASSERT_EQUALS("", errout.str());
3689 
3690         checkUninitVar("struct PIXEL {\n"
3691                        "    union  {\n"
3692                        "        struct { unsigned char red,green,blue,alpha; };\n"
3693                        "        unsigned int color;\n"
3694                        "    };\n"
3695                        "};\n"
3696                        "\n"
3697                        "unsigned char f() {\n"
3698                        "    struct PIXEL p1;\n"
3699                        "    p1.color = 255;\n"
3700                        "    return p1.red;\n"
3701                        "}");
3702         ASSERT_EQUALS("", errout.str());
3703 
3704         checkUninitVar("struct AB { int a; int b; };\n"
3705                        "int f() {\n"
3706                        "  struct AB *ab;\n"
3707                        "  for (i = 1; i < 10; i++) {\n"
3708                        "    if (condition && (ab = getab()) != NULL) {\n"
3709                        "      a = ab->a;\n"
3710                        "    }\n"
3711                        "  }\n"
3712                        "}");
3713         ASSERT_EQUALS("", errout.str());
3714 
3715         checkUninitVar("struct AB { int a; int b; };\n"
3716                        "int f(int x) {\n"
3717                        "  struct AB *ab;\n"
3718                        "  if (x == 0) {\n"
3719                        "    ab = getab();\n"
3720                        "  }\n"
3721                        "  if (x == 0 && (ab != NULL || ab->a == 0)) { }\n"
3722                        "}");
3723         ASSERT_EQUALS("", errout.str());
3724 
3725         checkUninitVar("struct A { int *x; };\n" // declarationId is 0 for "delete"
3726                        "void foo(void *info, void*p);\n"
3727                        "void bar(void) {\n"
3728                        "  struct A *delete = 0;\n"
3729                        "  foo( info, NULL );\n"
3730                        "}");
3731         ASSERT_EQUALS("", errout.str());
3732 
3733         checkUninitVar("struct ABC { int a; int b; int c; };\n"
3734                        "void foo(int x, const struct ABC *abc);\n"
3735                        "void bar(void) {\n"
3736                        "  struct ABC abc;\n"
3737                        "  foo(123, &abc);\n"
3738                        "  return abc.b;\n"
3739                        "}");
3740         /* TODO ASSERT_EQUALS("[test.cpp:5]: (error) Uninitialized struct member: abc.a\n"
3741                       "[test.cpp:5]: (error) Uninitialized struct member: abc.b\n"
3742                       "[test.cpp:5]: (error) Uninitialized struct member: abc.c\n", errout.str()); */
3743 
3744         checkUninitVar("struct ABC { int a; int b; int c; };\n"
3745                        "void foo() {\n"
3746                        "  struct ABC abc;\n"
3747                        "  dostuff((uint32_t *)&abc.a);\n"
3748                        "}");
3749         ASSERT_EQUALS("", errout.str());
3750 
3751         checkUninitVar("void f(void) {\n"
3752                        "    struct tm t;\n"
3753                        "    t.tm_year = 123;\n"
3754                        "}");
3755         ASSERT_EQUALS("", errout.str());
3756 
3757         // return
3758         checkUninitVar("struct AB { int a; int b; };\n"
3759                        "void f(void) {\n"
3760                        "    struct AB ab;\n"
3761                        "    ab.a = 0;\n"
3762                        "    return ab.b;\n"
3763                        "}\n", "test.c");
3764         ASSERT_EQUALS("[test.c:5]: (error) Uninitialized struct member: ab.b\n", errout.str());
3765 
3766         checkUninitVar("struct AB { int a; int b; };\n"
3767                        "void f(void) {\n"
3768                        "    struct AB ab;\n"
3769                        "    ab.a = 0;\n"
3770                        "    return ab.a;\n"
3771                        "}\n", "test.c");
3772         ASSERT_EQUALS("", errout.str());
3773 
3774         checkUninitVar("struct S { int a; int b; };\n" // #8299
3775                        "void f(void) {\n"
3776                        "    struct S s;\n"
3777                        "    s.a = 0;\n"
3778                        "    return s;\n"
3779                        "}\n");
3780         ASSERT_EQUALS("[test.cpp:5]: (error) Uninitialized struct member: s.b\n", errout.str());
3781 
3782         checkUninitVar("struct S { int a; int b; };\n" // #9810
3783                        "void f(void) {\n"
3784                        "    struct S s;\n"
3785                        "    return s.a ? 1 : 2;\n"
3786                        "}\n");
3787         ASSERT_EQUALS("[test.cpp:4]: (error) Uninitialized struct member: s.a\n", errout.str());
3788 
3789         // checkIfForWhileHead
3790         checkUninitVar("struct FRED {\n"
3791                        "    int a;\n"
3792                        "    int b;\n"
3793                        "};\n"
3794                        "\n"
3795                        "void f(void) {\n"
3796                        "   struct FRED fred;\n"
3797                        "   fred.a = do_something();\n"
3798                        "   if (fred.a == 0) { }\n"
3799                        "}\n", "test.c");
3800         ASSERT_EQUALS("", errout.str());
3801 
3802         checkUninitVar("struct FRED {\n"
3803                        "    int a;\n"
3804                        "    int b;\n"
3805                        "};\n"
3806                        "\n"
3807                        "void f(void) {\n"
3808                        "   struct FRED fred;\n"
3809                        "   fred.a = do_something();\n"
3810                        "   if (fred.b == 0) { }\n"
3811                        "}\n", "test.c", false);
3812         ASSERT_EQUALS("[test.c:9]: (error) Uninitialized struct member: fred.b\n", errout.str());
3813 
3814         checkUninitVar("struct Fred { int a; };\n"
3815                        "void f() {\n"
3816                        "    struct Fred fred;\n"
3817                        "    if (fred.a==1) {}\n"
3818                        "}", "test.c");
3819         ASSERT_EQUALS("[test.c:4]: (error) Uninitialized struct member: fred.a\n", errout.str());
3820 
3821         checkUninitVar("struct S { int n; int m; };\n"
3822                        "void f(void) {\n"
3823                        " struct S s;\n"
3824                        " for (s.n = 0; s.n <= 10; s.n++) { }\n"
3825                        "}", "test.c");
3826         ASSERT_EQUALS("", errout.str());
3827 
3828         checkUninitVar("void test2() {\n"
3829                        "  struct { char type; } s_d;\n"
3830                        "  if (foo(&s_d.type)){}\n"
3831                        "}");
3832         ASSERT_EQUALS("", errout.str());
3833 
3834         // for
3835         checkUninitVar("struct AB { int a; };\n"
3836                        "void f() {\n"
3837                        "    struct AB ab;\n"
3838                        "    while (x) { clear(ab); z = ab.a; }\n"
3839                        "}");
3840         ASSERT_EQUALS("", errout.str());
3841 
3842         checkUninitVar("struct AB { int a; };\n"
3843                        "void f() {\n"
3844                        "    struct AB ab;\n"
3845                        "    while (x) { ab.a = ab.a + 1; }\n"
3846                        "}");
3847         ASSERT_EQUALS("[test.cpp:4]: (error) Uninitialized struct member: ab.a\n", errout.str());
3848 
3849         checkUninitVar("struct AB { int a; };\n"
3850                        "void f() {\n"
3851                        "    struct AB ab;\n"
3852                        "    while (x) { init(&ab); z = ab.a; }\n"
3853                        "}");
3854         ASSERT_EQUALS("", errout.str());
3855 
3856         // address of member
3857         checkUninitVar("struct AB { int a[10]; int b; };\n"
3858                        "void f() {\n"
3859                        "    struct AB ab;\n"
3860                        "    int *p = ab.a;\n"
3861                        "}");
3862         ASSERT_EQUALS("", errout.str());
3863 
3864         // Reference
3865         checkUninitVar("struct A { int x; };\n"
3866                        "void foo() {\n"
3867                        "  struct A a;\n"
3868                        "  int& x = a.x;\n"
3869                        "  x = 0;\n"
3870                        "  return a.x;\n"
3871                        "}");
3872         ASSERT_EQUALS("", errout.str());
3873 
3874         // non static data-member initialization
3875         checkUninitVar("struct AB { int a=1; int b; };\n"
3876                        "void f(void) {\n"
3877                        "    struct AB ab;\n"
3878                        "    int a = ab.a;\n"
3879                        "    int b = ab.b;\n"
3880                        "}");
3881         ASSERT_EQUALS("[test.cpp:5]: (error) Uninitialized struct member: ab.b\n", errout.str());
3882 
3883         // STL class member
3884         checkUninitVar("struct A {\n"
3885                        "    std::map<int, int> m;\n"
3886                        "    int i;\n"
3887                        "};\n"
3888                        "void foo() {\n"
3889                        "    A a;\n"
3890                        "    x = a.m;\n"
3891                        "}");
3892         ASSERT_EQUALS("", errout.str());
3893 
3894         // Unknown type (C++)
3895         checkUninitVar("struct A {\n"
3896                        "    C m;\n"
3897                        "    int i;\n"
3898                        "};\n"
3899                        "void foo() {\n"
3900                        "    A a;\n"
3901                        "    x = a.m;\n"
3902                        "}", "test.cpp");
3903         ASSERT_EQUALS("", errout.str());
3904 
3905         // Unknown type (C)
3906         checkUninitVar("struct A {\n"
3907                        "    C m;\n"
3908                        "    int i;\n"
3909                        "};\n"
3910                        "void foo() {\n"
3911                        "    A a;\n"
3912                        "    x = a.m;\n"
3913                        "}", "test.c");
3914         ASSERT_EQUALS("[test.c:7]: (error) Uninitialized struct member: a.m\n", errout.str());
3915 
3916         // Type with constructor
3917         checkUninitVar("class C { C(); }\n"
3918                        "struct A {\n"
3919                        "    C m;\n"
3920                        "    int i;\n"
3921                        "};\n"
3922                        "void foo() {\n"
3923                        "    A a;\n"
3924                        "    x = a.m;\n"
3925                        "}");
3926         ASSERT_EQUALS("", errout.str());
3927     }
3928 
uninitvar2_while()3929     void uninitvar2_while() {
3930         // extracttests.start: int a;
3931 
3932         // for, while
3933         checkUninitVar("void f() {\n"
3934                        "    int x;\n"
3935                        "    while (a) {\n"
3936                        "        x = x + 1;\n"
3937                        "    }\n"
3938                        "}");
3939         ASSERT_EQUALS("[test.cpp:4]: (error) Uninitialized variable: x\n", errout.str());
3940 
3941         checkUninitVar("void f() {\n"
3942                        "    int x;\n"
3943                        "    do {\n"
3944                        "        x = x + 1;\n"
3945                        "    } while (a);\n"
3946                        "}");
3947         ASSERT_EQUALS("[test.cpp:4]: (error) Uninitialized variable: x\n", errout.str());
3948 
3949         checkUninitVar("void f() {\n"
3950                        "    for (int x = x; x < 10; x++) {}\n"
3951                        "}");
3952         ASSERT_EQUALS("[test.cpp:2]: (error) Uninitialized variable: x\n", errout.str());
3953 
3954         // extracttests.start: struct Element{Element*Next();};
3955         checkUninitVar("void f() {\n"
3956                        "    for (Element *ptr3 = ptr3->Next(); ptr3; ptr3 = ptr3->Next()) {}\n"
3957                        "}");
3958         ASSERT_EQUALS("[test.cpp:2]: (error) Uninitialized variable: ptr3\n", errout.str());
3959 
3960         // extracttests.start: int a;
3961         checkUninitVar("void f() {\n"
3962                        "    int x;\n"
3963                        "    while (a) {\n"
3964                        "        init(&x);\n"
3965                        "        x++;\n"
3966                        "    }\n"
3967                        "}");
3968         ASSERT_EQUALS("", errout.str());
3969 
3970         checkUninitVar("void f() {\n"
3971                        "    int x;\n"
3972                        "    while (a) {\n"
3973                        "        if (b) x++;\n"
3974                        "        else x = 0;\n"
3975                        "    }\n"
3976                        "}");
3977         ASSERT_EQUALS("", errout.str());
3978 
3979         checkUninitVar("void f() {\n"
3980                        "    int x;\n"
3981                        "    for (int i = 0; i < 10; i += x) {\n"
3982                        "        x = y;\n"
3983                        "    }\n"
3984                        "}");
3985         ASSERT_EQUALS("", errout.str());
3986 
3987         checkUninitVar("void f() {\n"
3988                        "    int x;\n"
3989                        "    for (int i = 0; i < 10; i += x) { }\n"
3990                        "}");
3991         ASSERT_EQUALS("[test.cpp:3]: (error) Uninitialized variable: x\n", errout.str());
3992 
3993         checkUninitVar("int f() {\n"
3994                        "    int i;\n"
3995                        "    for (i=0;i<9;++i)\n"
3996                        "        if (foo()) return i;\n"
3997                        "    return 9;\n"
3998                        "}");
3999         ASSERT_EQUALS("", errout.str());
4000 
4001         checkUninitVar("void f() {\n"
4002                        "    int i;\n"
4003                        "    do {} while (!getvalue(&i));\n"
4004                        "    i++;\n"
4005                        "}");
4006         ASSERT_EQUALS("", errout.str());
4007 
4008         checkUninitVar("int f(void) {\n"
4009                        "   int x;\n"
4010                        "   while (a()) {\n"  // <- condition must always be true or there will be problem
4011                        "       if (b()) {\n"
4012                        "           x = 1;\n"
4013                        "           break;"
4014                        "       }\n"
4015                        "   }\n"
4016                        "   return x;\n"
4017                        "}");
4018         TODO_ASSERT_EQUALS("error", "", errout.str());
4019 
4020         checkUninitVar("int f(void) {\n"
4021                        "   int x;\n"
4022                        "   while (a()) {\n"
4023                        "       if (b() && (x=1)) {\n"
4024                        "           return x;\n"
4025                        "       }\n"
4026                        "   }\n"
4027                        "   return 0;\n"
4028                        "}");
4029         ASSERT_EQUALS("", errout.str());
4030 
4031         // extracttests.start: void do_something(int);
4032         checkUninitVar("void f(void) {\n"
4033                        "   int x;\n"
4034                        "   for (;;) {\n"
4035                        "       int a = x+1;\n"
4036                        "       do_something(a);\n"
4037                        "   }\n"
4038                        "}");
4039         ASSERT_EQUALS("[test.cpp:4]: (error) Uninitialized variable: x\n", errout.str());
4040 
4041         checkUninitVar("struct AB {int a; int b;};\n"
4042                        "void f(void) {\n"
4043                        "   struct AB ab;\n"
4044                        "   while (true) {\n"
4045                        "       int a = 1+ab.a;\n"
4046                        "       do_something(a);\n"
4047                        "   }\n"
4048                        "}\n", "test.c");
4049         ASSERT_EQUALS("[test.c:5]: (error) Uninitialized struct member: ab.a\n", errout.str());
4050 
4051         checkUninitVar("void f(int i) {\n" // #4569 fp
4052                        "    float *buffer;\n"
4053                        "    if(i>10) buffer = f;\n"
4054                        "    if(i>10) {\n"
4055                        "        for (int i=0;i<10;i++)\n"
4056                        "            buffer[i] = 0;\n" // <- fp
4057                        "    }\n"
4058                        "}");
4059         ASSERT_EQUALS("", errout.str());
4060 
4061         checkUninitVar("void f(){\n" // #4519 - fp: inline assembler in loop
4062                        "    int x;\n"
4063                        "    for (int i = 0; i < 10; i++) {\n"
4064                        "        asm(\"foo\");\n"
4065                        "        if (x & 0xf1) { }\n"
4066                        "    }\n"
4067                        "}");
4068         ASSERT_EQUALS("", errout.str());
4069 
4070         checkUninitVar("static void f(void) {\n"
4071                        "    struct ABC *abc;\n"
4072                        "    for (i = 0; i < 10; i++)\n"
4073                        "        x += sizeof(*abc);\n"
4074                        "}");
4075         ASSERT_EQUALS("", errout.str());
4076 
4077         checkUninitVar("void f(void) {\n" // #4879
4078                        "    int i;\n"
4079                        "    while (x) {\n"
4080                        "        for (i = 0; i < 5; i++)\n"
4081                        "            a[i] = b[i];\n"
4082                        "    }\n"
4083                        "}");
4084         ASSERT_EQUALS("", errout.str());
4085 
4086         checkUninitVar("void f(void) {\n" // #5658
4087                        "    struct Foo *foo;\n"
4088                        "    while (true) {\n"
4089                        "            foo = malloc(sizeof(*foo));\n"
4090                        "            foo->x = 0;\n"
4091                        "    }\n"
4092                        "}");
4093         ASSERT_EQUALS("", errout.str());
4094 
4095         checkUninitVar("void f(void) {\n"
4096                        "  int i;\n"
4097                        "  while (x) {\n"
4098                        "    for (i=0,y=i;;){}\n"
4099                        "  }\n"
4100                        "}");
4101         ASSERT_EQUALS("", errout.str());
4102 
4103         checkUninitVar("void f() {\n"
4104                        "  char *p = (char *)malloc(256);\n"
4105                        "  while(*p && *p == '_')\n"
4106                        "    p++;\n"
4107                        "}");
4108         ASSERT_EQUALS("[test.cpp:3]: (error) Memory is allocated but not initialized: *p\n", errout.str());
4109 
4110         // #6646 - init in for loop
4111         checkUninitVar("void f() {\n" // No FP
4112                        "  for (int i;;i++)\n"
4113                        "    dostuff(&i);\n"
4114                        "}");
4115         ASSERT_EQUALS("", errout.str());
4116 
4117         // extracttests.start: int a;
4118         checkUninitVar("void f() {\n" // No FN
4119                        "  for (int i;;i++)\n"
4120                        "    a=i;\n"
4121                        "}");
4122         ASSERT_EQUALS("[test.cpp:2]: (error) Uninitialized variable: i\n", errout.str());
4123     }
4124 
uninitvar2_4494()4125     void uninitvar2_4494() {
4126         checkUninitVar("namespace N1 {\n"
4127                        "    class Fred {\n"
4128                        "    public:\n"
4129                        "        static void f1(char *p) { *p = 0; }\n"
4130                        "    };\n"
4131                        "    void fa(void) { char *p; Fred::f1(p); }\n"
4132                        "    void fb(void) { char *p; Fred::f2(p); }\n"
4133                        "    void fc(void) { char *p; ::N1::Fred::f1(p); }\n"
4134                        "    void fd(void) { char *p; ::N1::Fred::f2(p); }\n"
4135                        "}\n"
4136                        "namespace N2 {\n"
4137                        "    static void f1(char *p) { *p = 0; }\n"
4138                        "    void fa(void) { char *p; f1(p); }\n"
4139                        "    void fb(void) { char *p; f2(p); }\n"
4140                        "    void fc(void) { char *p; N1::Fred::f1(p); }\n"
4141                        "    void fd(void) { char *p; N1::Fred::f2(p); }\n"
4142                        "    void fe(void) { char *p; ::N1::Fred::f1(p); }\n"
4143                        "    void ff(void) { char *p; ::N1::Fred::f2(p); }\n"
4144                        "    void fg(void) { char *p; Foo::f1(p); }\n"
4145                        "    void fh(void) { char *p; Foo::f2(p); }\n"
4146                        "}");
4147         ASSERT_EQUALS("[test.cpp:6]: (error) Uninitialized variable: p\n"
4148                       "[test.cpp:8]: (error) Uninitialized variable: p\n"
4149                       "[test.cpp:13]: (error) Uninitialized variable: p\n"
4150                       "[test.cpp:15]: (error) Uninitialized variable: p\n"
4151                       "[test.cpp:17]: (error) Uninitialized variable: p\n", errout.str());
4152 
4153         checkUninitVar("class Fred {\n"
4154                        "public:\n"
4155                        "    void f1(char *p) { *p = 0; }\n"
4156                        "};\n"
4157                        "Fred fred;\n"
4158                        "void f(void) {\n"
4159                        "    char *p;\n"
4160                        "    fred.f1(p);\n"
4161                        "}");
4162         ASSERT_EQUALS("[test.cpp:8]: (error) Uninitialized variable: p\n", errout.str());
4163 
4164         checkUninitVar("class Fred {\n"
4165                        "public:\n"
4166                        "    class Wilma {\n"
4167                        "    public:\n"
4168                        "        class Barney {\n"
4169                        "        public:\n"
4170                        "            class Betty {\n"
4171                        "            public:\n"
4172                        "                void f1(char *p) { *p = 0; }\n"
4173                        "            };\n"
4174                        "            Betty betty;\n"
4175                        "        };\n"
4176                        "        Barney barney;\n"
4177                        "    };\n"
4178                        "    Wilma wilma;\n"
4179                        "};\n"
4180                        "Fred fred;\n"
4181                        "void f(void) {\n"
4182                        "    char *p;\n"
4183                        "    fred.wilma.barney.betty.f1(p);\n"
4184                        "}");
4185         ASSERT_EQUALS("[test.cpp:20]: (error) Uninitialized variable: p\n", errout.str());
4186     }
4187 
uninitvar2_malloc()4188     void uninitvar2_malloc() {
4189         checkUninitVar("int f() {\n"
4190                        "    int *p = (int*)malloc(40);\n"
4191                        "    return *p;\n"
4192                        "}");
4193         ASSERT_EQUALS("[test.cpp:3]: (error) Memory is allocated but not initialized: p\n", errout.str());
4194 
4195         checkUninitVar("void f() {\n"
4196                        "    int *p = (int*)malloc(40);\n"
4197                        "    int var = *p;\n"
4198                        "}");
4199         ASSERT_EQUALS("[test.cpp:3]: (error) Memory is allocated but not initialized: p\n", errout.str());
4200 
4201         checkUninitVar("struct AB { int a; int b; };\n"
4202                        "int f() {\n"
4203                        "    struct AB *ab = (AB*)malloc(sizeof(struct AB));\n"
4204                        "    return ab->a;\n"
4205                        "}");
4206         ASSERT_EQUALS("[test.cpp:4]: (error) Memory is allocated but not initialized: ab\n"
4207                       "[test.cpp:4]: (error) Uninitialized struct member: ab.a\n",
4208                       errout.str());
4209 
4210         checkUninitVar("struct t_udf_file {  int dir_left; };\n"
4211                        "\n"
4212                        "void f() {\n"
4213                        "  struct t_udf_file *newf;\n"
4214                        "  newf = malloc(sizeof(*newf));\n"
4215                        "  if (!newf) {};\n"
4216                        "}");
4217         ASSERT_EQUALS("", errout.str());
4218 
4219         checkUninitVar("void f() {\n"
4220                        "    char *s = malloc(100);\n"
4221                        "    if (s != NULL) { }\n"
4222                        "}");
4223         ASSERT_EQUALS("", errout.str());
4224 
4225         checkUninitVar("void f() {\n"
4226                        "    char *p = malloc(100);\n"
4227                        "    p || assert_failed();\n"
4228                        "}");
4229         ASSERT_EQUALS("", errout.str());
4230 
4231         checkUninitVar("void f() {\n"
4232                        "    char *p = malloc(100);\n"
4233                        "    x = p;\n"
4234                        "}");
4235         ASSERT_EQUALS("", errout.str());
4236 
4237         checkUninitVar("int* f() {\n"
4238                        "    int *p = (int*)malloc(40);\n"
4239                        "    return p;\n"
4240                        "}");
4241         ASSERT_EQUALS("", errout.str());
4242 
4243         // function parameter (treat it as initialized until malloc is used)
4244         checkUninitVar("int f(int *p) {\n"
4245                        "    if (*p == 1) {}\n" // no error
4246                        "    p = (int*)malloc(256);\n"
4247                        "    return *p;\n" // error
4248                        "}");
4249         ASSERT_EQUALS("[test.cpp:4]: (error) Memory is allocated but not initialized: p\n", errout.str());
4250 
4251         checkUninitVar("struct AB { int a; int b; };\n"
4252                        "int f(struct AB *ab) {\n"
4253                        "    if (ab->a == 1) {}\n" // no error
4254                        "    ab = (AB*)malloc(sizeof(struct AB));\n"
4255                        "    return ab->a;\n" // error
4256                        "}");
4257         ASSERT_EQUALS("[test.cpp:5]: (error) Uninitialized struct member: ab.a\n", errout.str());
4258 
4259         checkUninitVar("struct AB { int a; int b; };\n"
4260                        "void do_something(struct AB *ab);\n" // unknown function
4261                        "void f() {\n"
4262                        "    struct AB *ab = (AB*)malloc(sizeof(struct AB));\n"
4263                        "    do_something(ab);\n"
4264                        "}");
4265         ASSERT_EQUALS("", errout.str());
4266 
4267         // analysis failed. varid 0.
4268         checkUninitVar("void *vlc_custom_create (vlc_object_t *parent, size_t length, const char *typename) {\n"
4269                        "  assert (length >= sizeof (vlc_object_t));\n"
4270                        "}");
4271         ASSERT_EQUALS("", errout.str());
4272     }
4273 
uninitvar_ternaryexpression()4274     void uninitvar_ternaryexpression() { // #4683
4275         checkUninitVar("struct B { int asd; };\n"
4276                        "int f() {\n"
4277                        "    int a=0;\n"
4278                        "    struct B *b;\n"
4279                        "    if (x) {\n"
4280                        "        a = 1;\n"
4281                        "        b = p;\n"
4282                        "    }\n"
4283                        "    return a ? b->asd : 0;\n"
4284                        "}");
4285         ASSERT_EQUALS("", errout.str());
4286     }
4287 
uninitvar_rangeBasedFor()4288     void uninitvar_rangeBasedFor() {
4289         checkUninitVar("void function(Entry& entry) {\n" // #7078
4290                        "    for (auto* expr : entry.exprs) {\n"
4291                        "        expr->operate();\n"
4292                        "        expr->operate();\n"
4293                        "    }\n"
4294                        "}");
4295         ASSERT_EQUALS("", errout.str());
4296 
4297         checkUninitVar("void f() {\n"
4298                        "    int *item;\n"
4299                        "    for (item: itemList) {}\n"
4300                        "}");
4301         ASSERT_EQUALS("", errout.str());
4302 
4303         checkUninitVar("void f() {\n"
4304                        "    int buf[10];\n"
4305                        "    for (int &i: buf) { i = 0; }\n"
4306                        "}");
4307         ASSERT_EQUALS("", errout.str());
4308     }
4309 
uninitvar_static()4310     void uninitvar_static() { // #8734
4311         checkUninitVar("struct X { "
4312                        "  typedef struct { int p; } P_t; "
4313                        "  static int arr[]; "
4314                        "}; "
4315                        "int X::arr[] = {42}; "
4316                        "void f() { "
4317                        "  std::vector<X::P_t> result; "
4318                        "  X::P_t P; "
4319                        "  P.p = 0; "
4320                        "  result.push_back(P); "
4321                        "}");
4322         ASSERT_EQUALS("", errout.str());
4323     }
4324 
checkExpr()4325     void checkExpr() {
4326         checkUninitVar("struct AB { int a; int b; };\n"
4327                        "void f() {\n"
4328                        "    struct AB *ab = (struct AB*)calloc(1, sizeof(*ab));\n"
4329                        "}");
4330         ASSERT_EQUALS("", errout.str());
4331     }
4332 
trac_4871()4333     void trac_4871() { // #4871
4334         checkUninitVar("void pickup(int a) {\n"
4335                        "bool using_planner_action;\n"
4336                        "if (a)   {\n"
4337                        "  using_planner_action = false;\n"
4338                        "}\n"
4339                        "else {\n"
4340                        "  try\n"
4341                        "  {}\n"
4342                        "  catch (std::exception &ex) {\n"
4343                        "    return;\n"
4344                        "  }\n"
4345                        "  using_planner_action = true;\n"
4346                        "}\n"
4347                        "if (using_planner_action) {}\n"
4348                        "}");
4349         ASSERT_EQUALS("", errout.str());
4350     }
4351 
syntax_error()4352     void syntax_error() { // Ticket #5073
4353         const char code[] = "struct flex_array {};\n"
4354                             "struct cgroup_taskset {};\n"
4355                             "void cgroup_attach_task() {\n"
4356                             "  struct flex_array *group;\n"
4357                             "  struct cgroup_taskset tset = { };\n"
4358                             "  do { } while_each_thread(leader, tsk);\n"
4359                             "}";
4360         ASSERT_THROW(checkUninitVar(code), InternalError);
4361     }
4362 
trac_5970()4363     void trac_5970() { // Ticket #5970
4364         checkUninitVar("void DES_ede3_ofb64_encrypt() {\n"
4365                        "  DES_cblock d;\n"
4366                        "  char *dp;\n"
4367                        "  dp=(char *)d;\n"
4368                        "  init(dp);\n"
4369                        "}", "test.c");
4370         // FP Unknown type ASSERT_EQUALS("", errout.str());
4371     }
4372 
valueFlowUninit(const char code[])4373     void valueFlowUninit(const char code[]) {
4374         // Clear the error buffer..
4375         errout.str("");
4376 
4377         // Tokenize..
4378         settings.debugwarnings = false;
4379         settings.certainty.disable(Certainty::experimental);
4380 
4381         Tokenizer tokenizer(&settings, this);
4382         std::istringstream istr(code);
4383         tokenizer.tokenize(istr, "test.cpp");
4384 
4385         // Check for redundant code..
4386         CheckUninitVar checkuninitvar(&tokenizer, &settings, this);
4387         checkuninitvar.valueFlowUninit();
4388     }
4389 
4390 
valueFlowUninit()4391     void valueFlowUninit() {
4392         valueFlowUninit("void f() {\n"
4393                         "  int x;\n"
4394                         "  switch (x) {}\n"
4395                         "}");
4396         ASSERT_EQUALS("[test.cpp:3]: (error) Uninitialized variable: x\n", errout.str());
4397 
4398         valueFlowUninit("int f() {\n"
4399                         "  int x;\n"
4400                         "  init(x);\n"
4401                         "  return x;\n" // TODO: inconclusive ?
4402                         "}");
4403         ASSERT_EQUALS("", errout.str());
4404 
4405         valueFlowUninit("void f() {\n" // #8172
4406                         "  char **x;\n"
4407                         "  if (2 < sizeof(*x)) {}\n"
4408                         "}");
4409         ASSERT_EQUALS("", errout.str());
4410 
4411         valueFlowUninit("void foo() {\n" // #5259 - False negative
4412                         "    int a;\n"
4413                         "    int x[] = {a,2};\n"
4414                         "}");
4415         ASSERT_EQUALS("[test.cpp:3]: (error) Uninitialized variable: a\n", errout.str());
4416 
4417         valueFlowUninit("void foo()\n"
4418                         "{\n"
4419                         "    int x;\n"
4420                         "    int *y = &x;\n"
4421                         "}");
4422         ASSERT_EQUALS("", errout.str());
4423 
4424         valueFlowUninit("void foo()\n"
4425                         "{\n"
4426                         "    int *x;\n"
4427                         "    int *&y = x;\n"
4428                         "    y = nullptr;\n"
4429                         "}");
4430         ASSERT_EQUALS("", errout.str());
4431 
4432         valueFlowUninit("void foo()\n"
4433                         "{\n"
4434                         "    int x = xyz::x;\n"
4435                         "}");
4436         ASSERT_EQUALS("", errout.str());
4437 
4438         valueFlowUninit("void f()\n"
4439                         "{\n"
4440                         "    extern int a;\n"
4441                         "    a++;\n"
4442                         "}");
4443         ASSERT_EQUALS("", errout.str());
4444 
4445         valueFlowUninit("static void foo()\n"
4446                         "{\n"
4447                         "    int x, y;\n"
4448                         "    x = (y = 10);\n"
4449                         "    int z = y * 2;\n"
4450                         "}");
4451         ASSERT_EQUALS("", errout.str());
4452 
4453         valueFlowUninit("static void foo() {\n"
4454                         "    int x, y;\n"
4455                         "    x = ((y) = 10);\n"
4456                         "}");
4457         ASSERT_EQUALS("", errout.str());
4458 
4459         valueFlowUninit("static void foo()\n"
4460                         "{\n"
4461                         "    Foo p;\n"
4462                         "    p.abcd();\n"
4463                         "}");
4464         ASSERT_EQUALS("", errout.str());
4465 
4466         valueFlowUninit("static void foo()\n"
4467                         "{\n"
4468                         "    Foo p;\n"
4469                         "    int x = p.abcd();\n"
4470                         "}");
4471         ASSERT_EQUALS("", errout.str());
4472 
4473         // struct
4474         valueFlowUninit("struct AB { int a; int b; };\n"
4475                         "void f(void) {\n"
4476                         "  AB ab;\n"
4477                         "  AB *p = &ab;\n"
4478                         "  p->a = 1;\n"
4479                         "}\n");
4480         ASSERT_EQUALS("", errout.str());
4481 
4482         valueFlowUninit("struct S {\n"
4483                         "    S& rIo;\n"
4484                         "    S(S&);\n"
4485                         "    void Write();\n"
4486                         "};\n"
4487                         "void foo(bool b, struct S &io) {\n"
4488                         "    S* p;\n"
4489                         "    if (b)\n"
4490                         "        p = new S(io);\n"
4491                         "    p->Write();\n"
4492                         "}");
4493         ASSERT_EQUALS("[test.cpp:8] -> [test.cpp:10]: (error) Uninitialized variable: p\n", errout.str());
4494 
4495         // Unknown types
4496         {
4497             valueFlowUninit("void a()\n"
4498                             "{\n"
4499                             "    A ret;\n"
4500                             "    return ret;\n"
4501                             "}");
4502             ASSERT_EQUALS("", errout.str());
4503 
4504             // #3916 - avoid false positive
4505             valueFlowUninit("void f(float x) {\n"
4506                             "  union lf { long l; float f; } u_lf;\n"
4507                             "  float hx = (u_lf.f = (x), u_lf.l);\n"
4508                             "}");
4509             ASSERT_EQUALS("", errout.str());
4510         }
4511 
4512         valueFlowUninit("void a()\n"
4513                         "{\n"
4514                         "    int x[10];\n"
4515                         "    int *y = x;\n"
4516                         "}");
4517         ASSERT_EQUALS("", errout.str());
4518 
4519         valueFlowUninit("void a()\n"
4520                         "{\n"
4521                         "    int x;\n"
4522                         "    int *y = &x;\n"
4523                         "    *y = 0;\n"
4524                         "    x++;\n"
4525                         "}");
4526         ASSERT_EQUALS("", errout.str());
4527 
4528         valueFlowUninit("void a()\n"
4529                         "{\n"
4530                         "    char x[10], y[10];\n"
4531                         "    char *z = x;\n"
4532                         "    memset(z, 0, sizeof(x));\n"
4533                         "    memcpy(y, x, sizeof(x));\n"
4534                         "}");
4535         ASSERT_EQUALS("", errout.str());
4536 
4537         // Handling >> and <<
4538         {
4539             valueFlowUninit("int a() {\n"
4540                             "    int ret;\n"
4541                             "    std::cin >> ret;\n"
4542                             "    ret++;\n"
4543                             "}");
4544             ASSERT_EQUALS("", errout.str());
4545 
4546             valueFlowUninit("void f(int b) {\n"
4547                             "    int a;\n"
4548                             "    std::cin >> b >> a;\n"
4549                             "    return a;"
4550                             "}");
4551             ASSERT_EQUALS("", errout.str());
4552 
4553             valueFlowUninit("void foo() {\n"   // #3707
4554                             "    Node node;\n"
4555                             "    int x;\n"
4556                             "    node[\"abcd\"] >> x;\n"
4557                             "}");
4558             ASSERT_EQUALS("", errout.str());
4559 
4560             valueFlowUninit("int a(FArchive &arc) {\n"  // #3060 (initialization through operator<<)
4561                             "    int *p;\n"
4562                             "    arc << p;\n"  // <- TODO initialization?
4563                             "    return *p;\n"
4564                             "}");
4565             ASSERT_EQUALS("[test.cpp:3]: (error) Uninitialized variable: p\n"
4566                           "[test.cpp:4]: (error) Uninitialized variable: p\n", errout.str());
4567 
4568             // #4320
4569             valueFlowUninit("void f() {\n"
4570                             "    int a;\n"
4571                             "    a << 1;\n"
4572                             "    return a;\n"
4573                             "}");
4574             ASSERT_EQUALS("[test.cpp:3]: (error) Uninitialized variable: a\n"
4575                           "[test.cpp:4]: (error) Uninitialized variable: a\n",
4576                           errout.str());
4577 
4578             // #9750
4579             valueFlowUninit("struct S {\n"
4580                             "    int one;\n"
4581                             "    int two;\n"
4582                             "};\n"
4583                             "\n"
4584                             "void test(std::istringstream& in) {\n"
4585                             "    S p;\n"
4586                             "    in >> p.one >> p.two;\n"
4587                             "}");
4588             ASSERT_EQUALS("", errout.str());
4589         }
4590 
4591         valueFlowUninit("struct S { int x; };\n" // #9417
4592                         "void f() {\n"
4593                         "    S s;\n"
4594                         "    return s(1);\n"
4595                         "}");
4596         ASSERT_EQUALS("", errout.str());
4597 
4598         valueFlowUninit("void a() {\n"   // asm
4599                         "    int x;\n"
4600                         "    asm();\n"
4601                         "    x++;\n"
4602                         "}");
4603         ASSERT_EQUALS("", errout.str());
4604 
4605         valueFlowUninit("void a()\n"
4606                         "{\n"
4607                         "    int x[10];\n"
4608                         "    struct xyz xyz1 = { .x = x };\n"
4609                         "}");
4610         ASSERT_EQUALS("", errout.str());
4611 
4612         valueFlowUninit("void foo()\n"
4613                         "{\n"
4614                         "   char *buf = malloc(100);\n"
4615                         "   struct ABC *abc = buf;\n"
4616                         "}");
4617         ASSERT_EQUALS("", errout.str());
4618 
4619         valueFlowUninit("class Fred {\n"
4620                         "public:\n"
4621                         "    FILE *f;\n"
4622                         "    ~Fred();\n"
4623                         "}\n"
4624                         "Fred::~Fred()\n"
4625                         "{\n"
4626                         "    fclose(f);\n"
4627                         "}");
4628         ASSERT_EQUALS("", errout.str());
4629 
4630         valueFlowUninit("void f()\n"
4631                         "{\n"
4632                         "    int c;\n"
4633                         "    ab(sizeof(xyz), &c);\n"
4634                         "    if (c);\n"
4635                         "}");
4636         ASSERT_EQUALS("", errout.str());
4637 
4638         valueFlowUninit("void f()\n"
4639                         "{\n"
4640                         "    int c;\n"
4641                         "    a = (f2(&c));\n"
4642                         "    c++;\n"
4643                         "}");
4644         ASSERT_EQUALS("", errout.str());
4645 
4646         // goto/setjmp/longjmp..
4647         valueFlowUninit("void foo(int x)\n"
4648                         "{\n"
4649                         "    long b;\n"
4650                         "    if (g()) {\n"
4651                         "        b =2;\n"
4652                         "        goto found;\n"
4653                         "    }\n"
4654                         "\n"
4655                         "    return;\n"
4656                         "\n"
4657                         "found:\n"
4658                         "    int a = b;\n"
4659                         "}");
4660         ASSERT_EQUALS("", errout.str());
4661 
4662         valueFlowUninit("int foo()\n"
4663                         "{\n"
4664                         "    jmp_buf env;\n"
4665                         "    int a;\n"
4666                         "    int val = setjmp(env);\n"
4667                         "    if(val)\n"
4668                         "        return a;\n"
4669                         "    a = 1;\n"
4670                         "    longjmp(env, 1);\n"
4671                         "}");
4672         ASSERT_EQUALS("", errout.str());
4673 
4674         // range for..
4675         valueFlowUninit("void f() {\n"
4676                         "    X *item;\n"
4677                         "    for (item: itemList) {}\n"
4678                         "}");
4679         ASSERT_EQUALS("", errout.str());
4680 
4681         valueFlowUninit("X f() {\n"
4682                         "    if (!itemList.empty()) {\n"
4683                         "        X* item;\n"
4684                         "        for(item: itemList) {}\n"
4685                         "        return *item;\n"
4686                         "    }\n"
4687                         "    return X{};\n"
4688                         "}\n");
4689         ASSERT_EQUALS("", errout.str());
4690 
4691         // macro_for..
4692         valueFlowUninit("int foo()\n"
4693                         "{\n"
4694                         "  int retval;\n"
4695                         "  if (condition) {\n"
4696                         "    for12(1,2) { }\n"
4697                         "    retval = 1;\n"
4698                         "  }\n"
4699                         "  else\n"
4700                         "    retval = 2;\n"
4701                         "  return retval;\n"
4702                         "}");
4703         ASSERT_EQUALS("", errout.str());
4704 
4705         valueFlowUninit("void foo(struct qb_list_head *list) {\n"
4706                         "    struct qb_list_head *iter;\n"
4707                         "    qb_list_for_each(iter, list) {}\n"
4708                         "}\n");
4709         ASSERT_EQUALS("", errout.str());
4710 
4711         valueFlowUninit("void json_parse_nat_type_flags(json_t *root) {\n"
4712                         "    int index;\n"
4713                         "    json_array_foreach(root, index, value) {}\n"
4714                         "}");
4715         ASSERT_EQUALS("", errout.str());
4716 
4717         valueFlowUninit("int foo()\n"
4718                         "{\n"
4719                         "    int i;\n"
4720                         "    goto exit;\n"
4721                         "    i++;\n"
4722                         "exit:\n"
4723                         "}");
4724         ASSERT_EQUALS("", errout.str());
4725 
4726         valueFlowUninit("int foo() {\n"
4727                         "    int x,y=0;\n"
4728                         "again:\n"
4729                         "    if (y) return x;\n"
4730                         "    x = a;\n"
4731                         "    y = 1;\n"
4732                         "    goto again;\n"
4733                         "}");
4734         ASSERT_EQUALS("", errout.str());
4735 
4736         // #4040 - False positive
4737         valueFlowUninit("int f(int x)  {\n"
4738                         "    int iter;\n"
4739                         "    {\n"
4740                         "        union\n"
4741                         "        {\n"
4742                         "            int asInt;\n"
4743                         "            double asDouble;\n"
4744                         "        };\n"
4745                         "\n"
4746                         "        iter = x;\n"
4747                         "    }\n"
4748                         "    return 1 + iter;\n"
4749                         "}");
4750         ASSERT_EQUALS("", errout.str());
4751 
4752         // C++11 style initialization
4753         valueFlowUninit("int f() {\n"
4754                         "    int i = 0;\n"
4755                         "    int j{ i };\n"
4756                         "    return j;\n"
4757                         "}");
4758         ASSERT_EQUALS("", errout.str());
4759 
4760         // Ticket #5646
4761         valueFlowUninit("float foo() {\n"
4762                         "  float source[2] = {3.1, 3.1};\n"
4763                         "  float (*sink)[2] = &source;\n"
4764                         "  return (*sink)[0];\n"
4765                         "}");
4766         ASSERT_EQUALS("", errout.str());
4767 
4768         // Ticket #8755
4769         valueFlowUninit("void f(int b) {\n"
4770                         "    int a;\n"
4771                         "    if (b == 10)\n"
4772                         "        a = 1;\n"
4773                         "    if (b == 13)\n"
4774                         "        a = 1;\n"
4775                         "    if (b == 'x') {}\n"
4776                         "    if (a) {}\n"
4777                         "}");
4778         TODO_ASSERT_EQUALS("[test.cpp:8]: (error) Uninitialized variable: a\n", "", errout.str());
4779 
4780         valueFlowUninit("void h() {\n"
4781                         "  int i;\n"
4782                         "  int* v = &i;\n"
4783                         "  sscanf(\"0\", \"%d\", v);\n"
4784                         "}");
4785         ASSERT_EQUALS("", errout.str());
4786 
4787         valueFlowUninit("void test(int p) {\n"
4788                         "    int f;\n"
4789                         "    if (p > 0)\n"
4790                         "        f = 0;\n"
4791                         "    if (p > 1)\n"
4792                         "        f += 1;\n"
4793                         "}");
4794         ASSERT_EQUALS("", errout.str());
4795 
4796         valueFlowUninit("unsigned char get();\n"
4797                         "char f() {\n"
4798                         "    unsigned char c;\n"
4799                         "    do {\n"
4800                         "        c = get();\n"
4801                         "    } while (isalpha(c) == 0);\n"
4802                         "    return static_cast<char>(c);\n"
4803                         "}\n");
4804         ASSERT_EQUALS("", errout.str());
4805 
4806         valueFlowUninit("void f(int x)\n"
4807                         "{\n"
4808                         "   int i;\n"
4809                         "   char value;\n"
4810                         "   for(i = 0; i < 1; i++) {\n"
4811                         "       if(x > 1)\n"
4812                         "           value = 0;\n"
4813                         "    }\n"
4814                         "    printf(\"\", value);\n"
4815                         "}\n");
4816         ASSERT_EQUALS("[test.cpp:6] -> [test.cpp:9]: (error) Uninitialized variable: value\n", errout.str());
4817 
4818         valueFlowUninit("void f(int x)\n"
4819                         "{\n"
4820                         "   int i;\n"
4821                         "   char value;\n"
4822                         "   for(i = 0; i < 1; i++) {\n"
4823                         "       if(x > 1)\n"
4824                         "           value = 0;\n"
4825                         "       else\n"
4826                         "           value = 1;\n"
4827                         "    }\n"
4828                         "    printf(\"\", value);\n"
4829                         "}\n");
4830         ASSERT_EQUALS("", errout.str());
4831 
4832         // function pointers
4833         valueFlowUninit("int f (const struct FileFuncDefs *ffd) {\n" // #10279
4834                         "  int c;\n"
4835                         "  (*ffd->zread)(&c, 1);\n"
4836                         "  return c;\n"
4837                         "}\n");
4838         ASSERT_EQUALS("", errout.str());
4839 
4840         valueFlowUninit("int foo(unsigned int code) {\n" // #10279
4841                         "  int res;\n\n"
4842                         "  (* (utility_table[code])) (&res);\n"
4843                         "  return (res);\n"
4844                         "}\n");
4845         ASSERT_EQUALS("", errout.str());
4846 
4847         valueFlowUninit("struct Archive {\n"
4848                         "    bool isNull;\n"
4849                         "    friend void operator&(const Archive &, bool &isNull);\n"
4850                         "};\n"
4851                         "void load(Archive& ar) {\n"
4852                         "    bool isNull;\n"
4853                         "    ar & isNull;\n"
4854                         "    if (!isNull) {}\n"
4855                         "}\n");
4856         ASSERT_EQUALS("", errout.str());
4857 
4858         // #10119
4859         valueFlowUninit("struct Foo {\n"
4860                         "    int i{};\n"
4861                         "    static const float cf;\n"
4862                         "};\n"
4863                         "const float Foo::cf = 0.1f;\n"
4864                         "int bar() {\n"
4865                         "    Foo f;\n"
4866                         "    return f.i;\n"
4867                         "}\n");
4868         ASSERT_EQUALS("", errout.str());
4869 
4870         // #10326
4871         valueFlowUninit("void foo() {\n"
4872                         "    int cnt;\n"
4873                         "    do {\n"
4874                         "        cnt = 32 ;\n"
4875                         "    }\n"
4876                         "    while ( 0 ) ;\n"
4877                         "    if (cnt != 0) {}\n"
4878                         "}\n");
4879         ASSERT_EQUALS("", errout.str());
4880 
4881         // #10327 - avoid extra warnings for uninitialized variable
4882         valueFlowUninit("void dowork( int me ) {\n"
4883                         "    if ( me == 0 ) {}\n" // <- not uninitialized
4884                         "}\n"
4885                         "\n"
4886                         "int main() {\n"
4887                         "    int me;\n"
4888                         "     dowork(me);\n" // <- me is uninitialized
4889                         "}");
4890         ASSERT_EQUALS("[test.cpp:7]: (error) Uninitialized variable: me\n", errout.str());
4891 
4892         valueFlowUninit("int foo() {\n"
4893                         "  int x;\n"
4894                         "  int a = x;\n" // <- x is uninitialized
4895                         "  return a;\n" // <- a has been initialized
4896                         "}");
4897         ASSERT_EQUALS("[test.cpp:3]: (error) Uninitialized variable: x\n", errout.str());
4898 
4899         // #10468
4900         valueFlowUninit("uint32_t foo(uint32_t in) {\n"
4901                         "    uint32_t out, mask = 0x7F;\n"
4902                         "    while (mask ^ 0x7FFFFFFF)\n"
4903                         "        out = in & ~mask;\n"
4904                         "    return out;\n"
4905                         "}\n");
4906         ASSERT_EQUALS("", errout.str());
4907     }
4908 
uninitvar_ipa()4909     void uninitvar_ipa() {
4910         // #8825
4911         valueFlowUninit("typedef struct  {\n"
4912                         "    int flags;\n"
4913                         "} someType_t;\n"
4914                         "void bar(const someType_t * const p)  {\n"
4915                         "    if( (p->flags & 0xF000) == 0xF000){}\n"
4916                         "}\n"
4917                         "void f(void) {\n"
4918                         "    someType_t gVar;\n"
4919                         "    bar(&gVar);\n"
4920                         "}");
4921         ASSERT_EQUALS("[test.cpp:9] -> [test.cpp:5]: (error) Uninitialized variable: flags\n", errout.str());
4922 
4923         valueFlowUninit("typedef struct\n"
4924                         "{\n"
4925                         "        int flags[3];\n"
4926                         "} someType_t;\n"
4927                         "void f(void) {\n"
4928                         "        someType_t gVar;\n"
4929                         "        if(gVar.flags[1] == 42){}\n"
4930                         "}");
4931         ASSERT_EQUALS("[test.cpp:7]: (error) Uninitialized variable: flags\n", errout.str());
4932 
4933         valueFlowUninit("void foo() {\n" // #10293
4934                         "  union {\n"
4935                         "    struct hdr cm;\n"
4936                         "    char control[123];\n"
4937                         "  } u;\n"
4938                         "  char *x = u.control;\n" // <- no error
4939                         "}");
4940         ASSERT_EQUALS("", errout.str());
4941 
4942         valueFlowUninit("struct pc_data {\n"
4943                         "    struct {\n"
4944                         "        char   * strefa;\n"
4945                         "    } wampiryzm;\n"
4946                         "};\n"
4947                         "void f() {\n"
4948                         "    struct pc_data *pcdata;\n"
4949                         "    if ( *pcdata->wampiryzm.strefa == '\\0' ) { }\n"
4950                         "}");
4951         ASSERT_EQUALS("[test.cpp:8]: (error) Uninitialized variable: pcdata\n", errout.str());
4952 
4953         // # 9293
4954         valueFlowUninit("struct S {\n"
4955                         "  int x;\n"
4956                         "  int y;\n"
4957                         "};\n"
4958                         "\n"
4959                         "void f() {\n"
4960                         "    struct S s1;\n"
4961                         "    int * x = &s1.x;\n"
4962                         "    struct S s2 = {*x, 0};\n"
4963                         "}");
4964         ASSERT_EQUALS("[test.cpp:8] -> [test.cpp:9]: (error) Uninitialized variable: *x\n", errout.str());
4965 
4966         valueFlowUninit("struct S {\n"
4967                         "  int x;\n"
4968                         "  int y;\n"
4969                         "};\n"
4970                         "\n"
4971                         "void f() {\n"
4972                         "    struct S s1;\n"
4973                         "    struct S s2;\n"
4974                         "    int * x = &s1.x;\n"
4975                         "    s2.x = *x;\n"
4976                         "}");
4977         ASSERT_EQUALS("[test.cpp:9] -> [test.cpp:10]: (error) Uninitialized variable: *x\n", errout.str());
4978 
4979         valueFlowUninit("void f(bool * x) {\n"
4980                         "    *x = false;\n"
4981                         "}\n"
4982                         "void g() {\n"
4983                         "    bool b;\n"
4984                         "    f(&b);\n"
4985                         "}");
4986         ASSERT_EQUALS("", errout.str());
4987 
4988         valueFlowUninit("void f(bool * x) {\n"
4989                         "    if (x != nullptr)\n"
4990                         "        x = 1;\n"
4991                         "}\n"
4992                         "void g() {\n"
4993                         "    bool x;\n"
4994                         "    f(&x);\n"
4995                         "}");
4996         ASSERT_EQUALS("", errout.str());
4997 
4998         valueFlowUninit("void f() {\n"
4999                         "    bool b;\n"
5000                         "    bool * x = &b;\n"
5001                         "    if (x != nullptr)\n"
5002                         "        x = 1;\n"
5003                         "}");
5004         ASSERT_EQUALS("", errout.str());
5005 
5006         valueFlowUninit("struct A { bool b; };"
5007                         "void f(A * x) {\n"
5008                         "    x->b = false;\n"
5009                         "}\n"
5010                         "void g() {\n"
5011                         "    A b;\n"
5012                         "    f(&b);\n"
5013                         "}");
5014         ASSERT_EQUALS("", errout.str());
5015 
5016         valueFlowUninit("std::string f() {\n"
5017                         "    std::ostringstream ostr;\n"
5018                         "    ostr << \"\";\n"
5019                         "    return ostr.str();\n"
5020                         "}");
5021         ASSERT_EQUALS("", errout.str());
5022         // #9281
5023         valueFlowUninit("struct s {\n"
5024                         "    char a[20];\n"
5025                         "};\n"
5026                         "void c(struct s *sarg) {\n"
5027                         "    sarg->a[0] = '\\0';\n"
5028                         "}\n"
5029                         "void b(struct s *sarg) {\n"
5030                         "    c(sarg);\n"
5031                         "}\n"
5032                         "void a() {\n"
5033                         "    struct s s1;\n"
5034                         "    b(&s1);\n"
5035                         "}");
5036         ASSERT_EQUALS("", errout.str());
5037 
5038         // # 9290
5039         valueFlowUninit("struct A {\n"
5040                         "    double x;\n"
5041                         "};\n"
5042                         "double b() {\n"
5043                         "    A * c;\n"
5044                         "    c->x = 42;\n"
5045                         "    return c->x;\n"
5046                         "}");
5047         ASSERT_EQUALS("[test.cpp:6]: (error) Uninitialized variable: c\n"
5048                       "[test.cpp:7]: (error) Uninitialized variable: c\n",
5049                       errout.str());
5050 
5051         valueFlowUninit("struct A {\n"
5052                         "    double x;\n"
5053                         "};\n"
5054                         "double b() {\n"
5055                         "    A c;\n"
5056                         "    c.x = 42;\n"
5057                         "    return c.x;\n"
5058                         "}");
5059         ASSERT_EQUALS("", errout.str());
5060 
5061         valueFlowUninit("struct A {\n"
5062                         "    double x;\n"
5063                         "};\n"
5064                         "double d(A * e) {\n"
5065                         "    e->x = 42;\n"
5066                         "    return e->x;\n"
5067                         "}\n"
5068                         "double b() {\n"
5069                         "    A c;\n"
5070                         "    return d(&c);\n"
5071                         "}");
5072         ASSERT_EQUALS("", errout.str());
5073 
5074         // # 9302
5075         valueFlowUninit("struct VZ   {\n"
5076                         "    double typ;\n"
5077                         "};\n"
5078                         "void read() {\n"
5079                         "    struct VZ vz;\n"
5080                         "    struct VZ* pvz = &vz;\n"
5081                         "    vz.typ      = 42;\n"
5082                         "    if (pvz->typ == 0)\n"
5083                         "        return;\n"
5084                         "}");
5085         ASSERT_EQUALS("", errout.str());
5086 
5087         // # 9305
5088         valueFlowUninit("struct kf {\n"
5089                         "    double x;\n"
5090                         "};\n"
5091                         "void set(kf* k) {\n"
5092                         "    k->x = 0;\n"
5093                         "}\n"
5094                         "void cal() {\n"
5095                         "    KF b;\n"
5096                         "    KF* pb = &b;\n"
5097                         "    set( pb);\n"
5098                         "    if (pb->x)\n"
5099                         "        return;\n"
5100                         "}");
5101         ASSERT_EQUALS("", errout.str());
5102 
5103         // # 9348
5104         valueFlowUninit("void f(int *a) {\n"
5105                         "  int b = 0;\n"
5106                         "  memcpy(a, &b, sizeof(b));\n"
5107                         "}\n"
5108                         "void g() {\n"
5109                         "  int i;\n"
5110                         "  f(&i);\n"
5111                         "}");
5112         ASSERT_EQUALS("", errout.str());
5113 
5114         // # 9631
5115         valueFlowUninit("static void g(bool * result, int num, int num2, size_t * buflen) {\n"
5116                         "  if (*result && *buflen >= 5) {}\n"
5117                         "}\n"
5118                         "void f() {\n"
5119                         "  size_t bytesCopied;\n"
5120                         "  bool copied_all = true;\n"
5121                         "  g(&copied_all, 5, 6, &bytesCopied);\n"
5122                         "}");
5123         ASSERT_EQUALS("[test.cpp:7] -> [test.cpp:2]: (error) Uninitialized variable: *buflen\n", errout.str());
5124 
5125     }
5126 
uninitvar_memberfunction()5127     void uninitvar_memberfunction() {
5128         // # 8715
5129         valueFlowUninit("struct C {\n"
5130                         "    int x();\n"
5131                         "};\n"
5132                         "void f() {\n"
5133                         "    C *c;\n"
5134                         "    if (c->x() == 4) {}\n"
5135                         "}");
5136         ASSERT_EQUALS("[test.cpp:6]: (error) Uninitialized variable: c\n", errout.str());
5137 
5138         valueFlowUninit("struct A { \n"
5139                         "    int i; \n"
5140                         "    void f();\n"
5141                         "};\n"
5142                         "void g() {\n"
5143                         "    A a;\n"
5144                         "    a.f();\n"
5145                         "}\n");
5146         ASSERT_EQUALS("", errout.str());
5147     }
5148 
uninitvar_nonmember()5149     void uninitvar_nonmember() {
5150         valueFlowUninit("struct Foo {\n"
5151                         "  int bar;\n"
5152                         "};\n"
5153                         "\n"
5154                         "int main() {\n"
5155                         "  Foo* foo;\n"
5156                         "  foo->bar = 3;\n"
5157                         "}");
5158         ASSERT_EQUALS("[test.cpp:7]: (error) Uninitialized variable: foo\n", errout.str());
5159     }
5160 
isVariableUsageDeref()5161     void isVariableUsageDeref() {
5162         // *p
5163         checkUninitVar("void f() {\n"
5164                        "    char a[10];\n"
5165                        "    char c = *a;\n"
5166                        "}");
5167         ASSERT_EQUALS("[test.cpp:3]: (error) Uninitialized variable: a\n", errout.str());
5168 
5169         // extracttests.start: extern const int SIZE;
5170         checkUninitVar("void f() {\n"
5171                        "    char a[SIZE+10];\n"
5172                        "    char c = *a;\n"
5173                        "}");
5174         ASSERT_EQUALS("[test.cpp:3]: (error) Uninitialized variable: a\n", errout.str());
5175 
5176         checkUninitVar("void f() {\n"
5177                        "    char a[10];\n"
5178                        "    *a += 10;\n"
5179                        "}");
5180         ASSERT_EQUALS("[test.cpp:3]: (error) Uninitialized variable: a\n", errout.str());
5181 
5182         checkUninitVar("void f() {\n"
5183                        "  int a[10][10];\n"
5184                        "  dostuff(*a);\n"
5185                        "}");
5186         ASSERT_EQUALS("", errout.str());
5187 
5188         checkUninitVar("void f() {\n"
5189                        "    void (*fp[1]) (void) = {function1};\n"
5190                        "    (*fp[0])();\n"
5191                        "}");
5192         ASSERT_EQUALS("", errout.str());
5193     }
5194 
ctu(const char code[])5195     void ctu(const char code[]) {
5196         // Clear the error buffer..
5197         errout.str("");
5198 
5199         // Tokenize..
5200         Tokenizer tokenizer(&settings, this);
5201         std::istringstream istr(code);
5202         tokenizer.tokenize(istr, "test.cpp");
5203 
5204         CTU::FileInfo *ctu = CTU::getFileInfo(&tokenizer);
5205 
5206         // Check code..
5207         std::list<Check::FileInfo*> fileInfo;
5208         CheckUninitVar check(&tokenizer, &settings, this);
5209         fileInfo.push_back(check.getFileInfo(&tokenizer, &settings));
5210         check.analyseWholeProgram(ctu, fileInfo, settings, *this);
5211         while (!fileInfo.empty()) {
5212             delete fileInfo.back();
5213             fileInfo.pop_back();
5214         }
5215         delete ctu;
5216     }
5217 
ctu()5218     void ctu() {
5219         ctu("void f(int *p) {\n"
5220             "    a = *p;\n"
5221             "}\n"
5222             "int main() {\n"
5223             "  int x;\n"
5224             "  f(&x);\n"
5225             "}");
5226         ASSERT_EQUALS("[test.cpp:6] -> [test.cpp:2]: (error) Using argument p that points at uninitialized variable x\n", errout.str());
5227 
5228         ctu("void use(int *p) { a = *p + 3; }\n"
5229             "void call(int x, int *p) { x++; use(p); }\n"
5230             "int main() {\n"
5231             "  int x;\n"
5232             "  call(4,&x);\n"
5233             "}");
5234         ASSERT_EQUALS("[test.cpp:5] -> [test.cpp:2] -> [test.cpp:1]: (error) Using argument p that points at uninitialized variable x\n", errout.str());
5235 
5236         ctu("void dostuff(int *x, int *y) {\n"
5237             "  if (!var)\n"
5238             "    return -1;\n"  // <- early return
5239             "  *x = *y;\n"
5240             "}\n"
5241             "\n"
5242             "void f() {\n"
5243             "  int x;\n"
5244             "  dostuff(a, &x);\n"
5245             "}");
5246         ASSERT_EQUALS("", errout.str());
5247 
5248         ctu("void dostuff(int *x, int *y) {\n"
5249             "  if (cond)\n"
5250             "    *y = -1;\n"  // <- conditionally written
5251             "  *x = *y;\n"
5252             "}\n"
5253             "\n"
5254             "void f() {\n"
5255             "  int x;\n"
5256             "  dostuff(a, &x);\n"
5257             "}");
5258         ASSERT_EQUALS("", errout.str());
5259 
5260         ctu("void f(int *p) {\n"
5261             "    a = sizeof(*p);\n"
5262             "}\n"
5263             "int main() {\n"
5264             "  int x;\n"
5265             "  f(&x);\n"
5266             "}");
5267         ASSERT_EQUALS("", errout.str());
5268 
5269         ctu("void f(int *v) {\n"
5270             "  std::cin >> *v;\n"
5271             "}\n"
5272             "int main() {\n"
5273             "  int x;\n"
5274             "  f(&x);\n"
5275             "}");
5276         // TODO ASSERT_EQUALS("", errout.str());
5277     }
5278 };
5279 
5280 REGISTER_TEST(TestUninitVar)
5281