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