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 #include "checkmemoryleak.h" 19 #include "config.h" 20 #include "settings.h" 21 #include "symboldatabase.h" 22 #include "testsuite.h" 23 #include "token.h" 24 #include "tokenize.h" 25 26 #include <list> 27 #include <string> 28 29 30 class TestMemleak : private TestFixture { 31 public: TestMemleak()32 TestMemleak() : TestFixture("TestMemleak") {} 33 34 private: 35 Settings settings; 36 run()37 void run() OVERRIDE { 38 TEST_CASE(testFunctionReturnType); 39 TEST_CASE(open); 40 } 41 functionReturnType(const char code[])42 CheckMemoryLeak::AllocType functionReturnType(const char code[]) { 43 // Clear the error buffer.. 44 errout.str(""); 45 46 // Tokenize.. 47 Tokenizer tokenizer(&settings, this); 48 std::istringstream istr(code); 49 tokenizer.tokenize(istr, "test.cpp"); 50 51 const CheckMemoryLeak c(&tokenizer, this, &settings); 52 53 return c.functionReturnType(&tokenizer.getSymbolDatabase()->scopeList.front().functionList.front()); 54 } 55 testFunctionReturnType()56 void testFunctionReturnType() { 57 { 58 const char code[] = "const char *foo()\n" 59 "{ return 0; }"; 60 ASSERT_EQUALS(CheckMemoryLeak::No, functionReturnType(code)); 61 } 62 63 { 64 const char code[] = "Fred *newFred()\n" 65 "{ return new Fred; }"; 66 ASSERT_EQUALS(CheckMemoryLeak::New, functionReturnType(code)); 67 } 68 69 { 70 const char code[] = "char *foo()\n" 71 "{ return new char[100]; }"; 72 ASSERT_EQUALS(CheckMemoryLeak::NewArray, functionReturnType(code)); 73 } 74 75 { 76 const char code[] = "char *foo()\n" 77 "{\n" 78 " char *p = new char[100];\n" 79 " return p;\n" 80 "}"; 81 ASSERT_EQUALS(CheckMemoryLeak::NewArray, functionReturnType(code)); 82 } 83 } 84 open()85 void open() { 86 const char code[] = "class A {\n" 87 " static int open() {\n" 88 " return 1;\n" 89 " }\n" 90 "\n" 91 " A() {\n" 92 " int ret = open();\n" 93 " }\n" 94 "};\n"; 95 96 // Clear the error buffer.. 97 errout.str(""); 98 99 Tokenizer tokenizer(&settings, this); 100 std::istringstream istr(code); 101 tokenizer.tokenize(istr, "test.cpp"); 102 103 // there is no allocation 104 const Token *tok = Token::findsimplematch(tokenizer.tokens(), "ret ="); 105 const CheckMemoryLeak check(&tokenizer, nullptr, &settings); 106 ASSERT_EQUALS(CheckMemoryLeak::No, check.getAllocationType(tok->tokAt(2), 1)); 107 } 108 }; 109 110 REGISTER_TEST(TestMemleak) 111 112 113 114 115 116 class TestMemleakInFunction : public TestFixture { 117 public: TestMemleakInFunction()118 TestMemleakInFunction() : TestFixture("TestMemleakInFunction") {} 119 120 private: 121 Settings settings0; 122 Settings settings1; 123 Settings settings2; 124 check(const char code[])125 void check(const char code[]) { 126 // Clear the error buffer.. 127 errout.str(""); 128 129 Settings *settings = &settings1; 130 131 // Tokenize.. 132 Tokenizer tokenizer(settings, this); 133 std::istringstream istr(code); 134 tokenizer.tokenize(istr, "test.cpp"); 135 136 // Check for memory leaks.. 137 CheckMemoryLeakInFunction checkMemoryLeak(&tokenizer, settings, this); 138 checkMemoryLeak.checkReallocUsage(); 139 } 140 141 run()142 void run() OVERRIDE { 143 LOAD_LIB_2(settings1.library, "std.cfg"); 144 LOAD_LIB_2(settings1.library, "posix.cfg"); 145 LOAD_LIB_2(settings2.library, "std.cfg"); 146 147 TEST_CASE(realloc1); 148 TEST_CASE(realloc2); 149 TEST_CASE(realloc3); 150 TEST_CASE(realloc4); 151 TEST_CASE(realloc5); 152 TEST_CASE(realloc7); 153 TEST_CASE(realloc8); 154 TEST_CASE(realloc9); 155 TEST_CASE(realloc10); 156 TEST_CASE(realloc11); 157 TEST_CASE(realloc12); 158 TEST_CASE(realloc13); 159 TEST_CASE(realloc14); 160 TEST_CASE(realloc15); 161 TEST_CASE(realloc16); 162 TEST_CASE(realloc17); 163 TEST_CASE(realloc18); 164 TEST_CASE(realloc19); 165 TEST_CASE(realloc20); 166 TEST_CASE(realloc21); 167 TEST_CASE(realloc22); 168 TEST_CASE(realloc23); 169 TEST_CASE(realloc24); // #9228 170 TEST_CASE(reallocarray1); 171 } 172 realloc1()173 void realloc1() { 174 check("void foo()\n" 175 "{\n" 176 " char *a = (char *)malloc(10);\n" 177 " a = realloc(a, 100);\n" 178 "}"); 179 ASSERT_EQUALS("[test.cpp:4]: (error) Common realloc mistake: \'a\' nulled but not freed upon failure\n", errout.str()); 180 } 181 realloc2()182 void realloc2() { 183 check("void foo()\n" 184 "{\n" 185 " char *a = (char *)malloc(10);\n" 186 " a = (char *)realloc(a, 100);\n" 187 " free(a);\n" 188 "}"); 189 190 ASSERT_EQUALS("[test.cpp:4]: (error) Common realloc mistake: \'a\' nulled but not freed upon failure\n", errout.str()); 191 } 192 realloc3()193 void realloc3() { 194 check("void foo()\n" 195 "{\n" 196 " char *a = 0;\n" 197 " if ((a = realloc(a, 100)) == NULL)\n" 198 " return;\n" 199 " free(a);\n" 200 "}"); 201 202 ASSERT_EQUALS("", errout.str()); 203 } 204 realloc4()205 void realloc4() { 206 check("void foo()\n" 207 "{\n" 208 " static char *a = 0;\n" 209 " if ((a = realloc(a, 100)) == NULL)\n" 210 " return;\n" 211 " free(a);\n" 212 "}"); 213 214 TODO_ASSERT_EQUALS("[test.cpp:5]: (error) Memory leak: a\n", 215 "[test.cpp:4]: (error) Common realloc mistake: \'a\' nulled but not freed upon failure\n", 216 errout.str()); 217 } 218 realloc5()219 void realloc5() { 220 check("void foo()\n" 221 "{\n" 222 " char *buf;\n" 223 " char *new_buf;\n" 224 " buf = calloc( 10 );\n" 225 " new_buf = realloc ( buf, 20);\n" 226 " if ( !new_buf )\n" 227 " free(buf);\n" 228 " else\n" 229 " free(new_buf);\n" 230 "}"); 231 ASSERT_EQUALS("", errout.str()); 232 } 233 realloc7()234 void realloc7() { 235 check("bool foo(size_t nLen, char* pData)\n" 236 "{\n" 237 " pData = (char*) realloc(pData, sizeof(char) + (nLen + 1)*sizeof(char));\n" 238 " if ( pData == NULL )\n" 239 " {\n" 240 " return false;\n" 241 " }\n" 242 " free(pData);\n" 243 " return true;\n" 244 "}"); 245 ASSERT_EQUALS("", errout.str()); 246 } 247 realloc8()248 void realloc8() { 249 check("void foo()\n" 250 "{\n" 251 " char *origBuf = m_buf;\n" 252 " m_buf = (char *) realloc (m_buf, m_capacity + growBy);\n" 253 " if (!m_buf) {\n" 254 " m_buf = origBuf;\n" 255 " }\n" 256 "}"); 257 ASSERT_EQUALS("", errout.str()); 258 } 259 realloc9()260 void realloc9() { 261 check("void foo()\n" 262 "{\n" 263 " x = realloc(x,100);\n" 264 "}"); 265 ASSERT_EQUALS("", errout.str()); 266 } 267 realloc10()268 void realloc10() { 269 check("void foo() {\n" 270 " char *pa, *pb;\n" 271 " pa = pb = malloc(10);\n" 272 " pa = realloc(pa, 20);" 273 " exit();\n" 274 "}"); 275 ASSERT_EQUALS("", errout.str()); 276 } 277 realloc11()278 void realloc11() { 279 check("void foo() {\n" 280 " char *p;\n" 281 " p = realloc(p, size);\n" 282 " if (!p)\n" 283 " error();\n" 284 " usep(p);\n" 285 "}"); 286 ASSERT_EQUALS("", errout.str()); 287 } 288 realloc12()289 void realloc12() { 290 check("void foo(int x)\n" 291 "{\n" 292 " char *a = 0;\n" 293 " if ((a = realloc(a, x + 100)) == NULL)\n" 294 " return;\n" 295 " free(a);\n" 296 "}"); 297 ASSERT_EQUALS("", errout.str()); 298 } 299 realloc13()300 void realloc13() { 301 check("void foo()\n" 302 "{\n" 303 " char **str;\n" 304 " *str = realloc(*str,100);\n" 305 " free (*str);\n" 306 "}"); 307 ASSERT_EQUALS("[test.cpp:4]: (error) Common realloc mistake: \'str\' nulled but not freed upon failure\n", errout.str()); 308 } 309 realloc14()310 void realloc14() { 311 check("void foo() {\n" 312 " char *p;\n" 313 " p = realloc(p, size + 1);\n" 314 " if (!p)\n" 315 " error();\n" 316 " usep(p);\n" 317 "}"); 318 ASSERT_EQUALS("", errout.str()); 319 } 320 realloc15()321 void realloc15() { 322 check("bool foo() {\n" 323 " char ** m_options;\n" 324 " m_options = (char**)realloc( m_options, 2 * sizeof(char*));\n" 325 " if( m_options == NULL )\n" 326 " return false;\n" 327 " return true;\n" 328 "}"); 329 ASSERT_EQUALS("[test.cpp:3]: (error) Common realloc mistake: \'m_options\' nulled but not freed upon failure\n", errout.str()); 330 } 331 realloc16()332 void realloc16() { 333 check("void f(char *zLine) {\n" 334 " zLine = realloc(zLine, 42);\n" 335 " if (zLine) {\n" 336 " free(zLine);\n" 337 " }\n" 338 "}"); 339 ASSERT_EQUALS("", errout.str()); 340 } 341 realloc17()342 void realloc17() { 343 check("void foo()\n" 344 "{\n" 345 " void ***a = malloc(sizeof(a));\n" 346 " ***a = realloc(***(a), sizeof(a) * 2);\n" 347 "}"); 348 ASSERT_EQUALS("[test.cpp:4]: (error) Common realloc mistake: \'a\' nulled but not freed upon failure\n", errout.str()); 349 } 350 realloc18()351 void realloc18() { 352 check("void foo()\n" 353 "{\n" 354 " void *a = malloc(sizeof(a));\n" 355 " a = realloc((void*)a, sizeof(a) * 2);\n" 356 "}"); 357 ASSERT_EQUALS("[test.cpp:4]: (error) Common realloc mistake: \'a\' nulled but not freed upon failure\n", errout.str()); 358 } 359 realloc19()360 void realloc19() { 361 check("void foo()\n" 362 "{\n" 363 " void *a = malloc(sizeof(a));\n" 364 " a = (realloc((void*)((a)), sizeof(a) * 2));\n" 365 "}"); 366 ASSERT_EQUALS("[test.cpp:4]: (error) Common realloc mistake: \'a\' nulled but not freed upon failure\n", errout.str()); 367 } 368 realloc20()369 void realloc20() { 370 check("void foo()\n" 371 "{\n" 372 " void *a = malloc(sizeof(a));\n" 373 " a = realloc((a) + 1, sizeof(a) * 2);\n" 374 "}"); 375 ASSERT_EQUALS("", errout.str()); 376 } 377 realloc21()378 void realloc21() { 379 check("char *foo(char *bs0)\n" 380 "{\n" 381 " char *bs = bs0;\n" 382 " bs = realloc(bs, 100);\n" 383 " if (bs == NULL) return bs0;\n" 384 " return bs;\n" 385 "}"); 386 ASSERT_EQUALS("", errout.str()); 387 } 388 realloc22()389 void realloc22() { 390 check("void foo(char **bsp)\n" 391 "{\n" 392 " char *bs = *bsp;\n" 393 " bs = realloc(bs, 100);\n" 394 " if (bs == NULL) return;\n" 395 " *bsp = bs;\n" 396 "}"); 397 ASSERT_EQUALS("", errout.str()); 398 } 399 realloc23()400 void realloc23() { 401 check("void foo(struct ABC *s)\n" 402 "{\n" 403 " uint32_t *cigar = s->cigar;\n" 404 " if (!(cigar = realloc(cigar, 100 * sizeof(*cigar))))\n" 405 " return;\n" 406 " s->cigar = cigar;\n" 407 "}"); 408 ASSERT_EQUALS("", errout.str()); 409 } 410 realloc24()411 void realloc24() { // #9228 412 check("void f() {\n" 413 "void *a = NULL;\n" 414 "a = realloc(a, 20);\n" 415 "}"); 416 ASSERT_EQUALS("", errout.str()); 417 418 check("void f() {\n" 419 "void *a = NULL;\n" 420 "a = malloc(10);\n" 421 "a = realloc(a, 20);\n" 422 "}"); 423 ASSERT_EQUALS("[test.cpp:4]: (error) Common realloc mistake: \'a\' nulled but not freed upon failure\n", errout.str()); 424 425 check("void f() {\n" 426 "void *a = std::nullptr;\n" 427 "a = malloc(10);\n" 428 "a = realloc(a, 20);\n" 429 "}"); 430 ASSERT_EQUALS("[test.cpp:4]: (error) Common realloc mistake: \'a\' nulled but not freed upon failure\n", errout.str()); 431 432 check("void f(char *b) {\n" 433 "void *a = NULL;\n" 434 "a = b;\n" 435 "a = realloc(a, 20);\n" 436 "}"); 437 ASSERT_EQUALS("", errout.str()); 438 } 439 reallocarray1()440 void reallocarray1() { 441 check("void foo()\n" 442 "{\n" 443 " char *a = (char *)malloc(10);\n" 444 " a = reallocarray(a, 100, 2);\n" 445 "}"); 446 ASSERT_EQUALS("[test.cpp:4]: (error) Common reallocarray mistake: \'a\' nulled but not freed upon failure\n", errout.str()); 447 } 448 }; 449 450 REGISTER_TEST(TestMemleakInFunction) 451 452 453 454 455 456 457 458 459 class TestMemleakInClass : public TestFixture { 460 public: TestMemleakInClass()461 TestMemleakInClass() : TestFixture("TestMemleakInClass") {} 462 463 private: 464 Settings settings; 465 466 /** 467 * Tokenize and execute leak check for given code 468 * @param code Source code 469 */ check(const char code[])470 void check(const char code[]) { 471 // Clear the error buffer.. 472 errout.str(""); 473 474 // Tokenize.. 475 Tokenizer tokenizer(&settings, this); 476 std::istringstream istr(code); 477 tokenizer.tokenize(istr, "test.cpp"); 478 479 // Check for memory leaks.. 480 CheckMemoryLeakInClass checkMemoryLeak(&tokenizer, &settings, this); 481 checkMemoryLeak.check(); 482 } 483 run()484 void run() OVERRIDE { 485 settings.severity.enable(Severity::warning); 486 settings.severity.enable(Severity::style); 487 488 LOAD_LIB_2(settings.library, "std.cfg"); 489 490 TEST_CASE(class1); 491 TEST_CASE(class2); 492 TEST_CASE(class3); 493 TEST_CASE(class4); 494 TEST_CASE(class6); 495 TEST_CASE(class7); 496 TEST_CASE(class8); 497 TEST_CASE(class9); 498 TEST_CASE(class10); 499 TEST_CASE(class11); 500 TEST_CASE(class12); 501 TEST_CASE(class13); 502 TEST_CASE(class14); 503 TEST_CASE(class15); 504 TEST_CASE(class16); 505 TEST_CASE(class17); 506 TEST_CASE(class18); 507 TEST_CASE(class19); // ticket #2219 508 TEST_CASE(class20); 509 TEST_CASE(class21); // ticket #2517 510 TEST_CASE(class22); // ticket #3012 511 TEST_CASE(class23); // ticket #3303 512 TEST_CASE(class24); // ticket #3806 - false positive in copy constructor 513 TEST_CASE(class25); // ticket #4367 - false positive implementation for destructor is not seen 514 515 TEST_CASE(staticvar); 516 517 TEST_CASE(free_member_in_sub_func); 518 519 TEST_CASE(mismatch1); 520 TEST_CASE(mismatch2); // #5659 521 522 // allocating member variable in public function 523 TEST_CASE(func1); 524 TEST_CASE(func2); 525 } 526 527 class1()528 void class1() { 529 check("class Fred\n" 530 "{\n" 531 "private:\n" 532 " char *str1;\n" 533 " char *str2;\n" 534 "public:\n" 535 " Fred();\n" 536 " ~Fred();\n" 537 "};\n" 538 "\n" 539 "Fred::Fred()\n" 540 "{\n" 541 " str1 = new char[10];\n" 542 " str2 = new char[10];\n" 543 "}\n" 544 "\n" 545 "Fred::~Fred()\n" 546 "{\n" 547 " delete [] str2;\n" 548 "}"); 549 ASSERT_EQUALS("[test.cpp:4]: (style) Class 'Fred' is unsafe, 'Fred::str1' can leak by wrong usage.\n", errout.str()); 550 551 check("class Fred\n" 552 "{\n" 553 "private:\n" 554 " char *str1;\n" 555 " char *str2;\n" 556 "public:\n" 557 " Fred()\n" 558 " {\n" 559 " str1 = new char[10];\n" 560 " str2 = new char[10];\n" 561 " }\n" 562 " ~Fred()\n" 563 " {\n" 564 " delete [] str2;\n" 565 " }\n" 566 "};"); 567 ASSERT_EQUALS("[test.cpp:4]: (style) Class 'Fred' is unsafe, 'Fred::str1' can leak by wrong usage.\n", errout.str()); 568 } 569 class2()570 void class2() { 571 check("class Fred\n" 572 "{\n" 573 "private:\n" 574 " char *str1;\n" 575 "public:\n" 576 " Fred();\n" 577 " ~Fred();\n" 578 "};\n" 579 "\n" 580 "Fred::Fred()\n" 581 "{\n" 582 " str1 = new char[10];\n" 583 "}\n" 584 "\n" 585 "Fred::~Fred()\n" 586 "{\n" 587 " free(str1);\n" 588 "}"); 589 ASSERT_EQUALS("[test.cpp:17]: (error) Mismatching allocation and deallocation: Fred::str1\n", errout.str()); 590 591 check("class Fred\n" 592 "{\n" 593 "private:\n" 594 " char *str1;\n" 595 "public:\n" 596 " Fred()\n" 597 " {\n" 598 " str1 = new char[10];\n" 599 " }\n" 600 " ~Fred()\n" 601 " {\n" 602 " free(str1);\n" 603 " }\n" 604 "};"); 605 ASSERT_EQUALS("[test.cpp:12]: (error) Mismatching allocation and deallocation: Fred::str1\n", errout.str()); 606 } 607 class3()608 void class3() { 609 check("class Token;\n" 610 "\n" 611 "class Tokenizer\n" 612 "{\n" 613 "private:\n" 614 " Token *_tokens;\n" 615 "\n" 616 "public:\n" 617 " Tokenizer();\n" 618 " ~Tokenizer();\n" 619 " void deleteTokens(Token *tok);\n" 620 "};\n" 621 "\n" 622 "Tokenizer::Tokenizer()\n" 623 "{\n" 624 " _tokens = new Token;\n" 625 "}\n" 626 "\n" 627 "Tokenizer::~Tokenizer()\n" 628 "{\n" 629 " deleteTokens(_tokens);\n" 630 "}\n" 631 "\n" 632 "void Tokenizer::deleteTokens(Token *tok)\n" 633 "{\n" 634 " while (tok)\n" 635 " {\n" 636 " Token *next = tok->next();\n" 637 " delete tok;\n" 638 " tok = next;\n" 639 " }\n" 640 "}"); 641 642 ASSERT_EQUALS("", errout.str()); 643 644 check("class Token;\n" 645 "\n" 646 "class Tokenizer\n" 647 "{\n" 648 "private:\n" 649 " Token *_tokens;\n" 650 "\n" 651 "public:\n" 652 " Tokenizer()\n" 653 " {\n" 654 " _tokens = new Token;\n" 655 " }\n" 656 " ~Tokenizer()\n" 657 " {\n" 658 " deleteTokens(_tokens);\n" 659 " }\n" 660 " void deleteTokens(Token *tok)\n" 661 " {\n" 662 " while (tok)\n" 663 " {\n" 664 " Token *next = tok->next();\n" 665 " delete tok;\n" 666 " tok = next;\n" 667 " }\n" 668 " }\n" 669 "};"); 670 671 ASSERT_EQUALS("", errout.str()); 672 } 673 class4()674 void class4() { 675 check("struct ABC;\n" 676 "class Fred\n" 677 "{\n" 678 "private:\n" 679 " void addAbc(ABC *abc);\n" 680 "public:\n" 681 " void click();\n" 682 "};\n" 683 "\n" 684 "void Fred::addAbc(ABC* abc)\n" 685 "{\n" 686 " AbcPosts->Add(abc);\n" 687 "}\n" 688 "\n" 689 "void Fred::click()\n" 690 "{\n" 691 " ABC *p = new ABC;\n" 692 " addAbc( p );\n" 693 "}"); 694 ASSERT_EQUALS("", errout.str()); 695 696 check("struct ABC;\n" 697 "class Fred\n" 698 "{\n" 699 "private:\n" 700 " void addAbc(ABC* abc)\n" 701 " {\n" 702 " AbcPosts->Add(abc);\n" 703 " }\n" 704 "public:\n" 705 " void click()\n" 706 " {\n" 707 " ABC *p = new ABC;\n" 708 " addAbc( p );\n" 709 " }\n" 710 "};"); 711 ASSERT_EQUALS("", errout.str()); 712 } 713 class6()714 void class6() { 715 check("class Fred\n" 716 "{\n" 717 "public:\n" 718 " void foo();\n" 719 "};\n" 720 "\n" 721 "void Fred::foo()\n" 722 "{\n" 723 " char *str = new char[100];\n" 724 " delete [] str;\n" 725 " hello();\n" 726 "}"); 727 ASSERT_EQUALS("", errout.str()); 728 729 check("class Fred\n" 730 "{\n" 731 "public:\n" 732 " void foo()\n" 733 " {\n" 734 " char *str = new char[100];\n" 735 " delete [] str;\n" 736 " hello();\n" 737 " }\n" 738 "};"); 739 ASSERT_EQUALS("", errout.str()); 740 } 741 class7()742 void class7() { 743 check("class Fred\n" 744 "{\n" 745 "public:\n" 746 " int *i;\n" 747 " Fred();\n" 748 " ~Fred();\n" 749 "};\n" 750 "\n" 751 "Fred::Fred()\n" 752 "{\n" 753 " this->i = new int;\n" 754 "}\n" 755 "Fred::~Fred()\n" 756 "{\n" 757 " delete this->i;\n" 758 "}"); 759 ASSERT_EQUALS("", errout.str()); 760 761 check("class Fred\n" 762 "{\n" 763 "public:\n" 764 " int *i;\n" 765 " Fred()\n" 766 " {\n" 767 " this->i = new int;\n" 768 " }\n" 769 " ~Fred()\n" 770 " {\n" 771 " delete this->i;\n" 772 " }\n" 773 "};"); 774 ASSERT_EQUALS("", errout.str()); 775 } 776 class8()777 void class8() { 778 check("class A\n" 779 "{\n" 780 "public:\n" 781 " void a();\n" 782 " void doNothing() { }\n" 783 "};\n" 784 "\n" 785 "void A::a()\n" 786 "{\n" 787 " int* c = new int(1);\n" 788 " delete c;\n" 789 " doNothing(c);\n" 790 "}"); 791 ASSERT_EQUALS("", errout.str()); 792 793 check("class A\n" 794 "{\n" 795 "public:\n" 796 " void a()\n" 797 " {\n" 798 " int* c = new int(1);\n" 799 " delete c;\n" 800 " doNothing(c);\n" 801 " }\n" 802 " void doNothing() { }\n" 803 "};"); 804 ASSERT_EQUALS("", errout.str()); 805 } 806 class9()807 void class9() { 808 check("class A\n" 809 "{\n" 810 "public:\n" 811 " int * p;\n" 812 " A();\n" 813 " ~A();\n" 814 "};\n" 815 "\n" 816 "A::A()\n" 817 "{ p = new int; }\n" 818 "\n" 819 "A::~A()\n" 820 "{ delete (p); }"); 821 ASSERT_EQUALS("", errout.str()); 822 823 check("class A\n" 824 "{\n" 825 "public:\n" 826 " int * p;\n" 827 " A()\n" 828 " { p = new int; }\n" 829 " ~A()\n" 830 " { delete (p); }\n" 831 "};"); 832 ASSERT_EQUALS("", errout.str()); 833 } 834 class10()835 void class10() { 836 check("class A\n" 837 "{\n" 838 "public:\n" 839 " int * p;\n" 840 " A();\n" 841 "};\n" 842 "A::A()\n" 843 "{ p = new int; }"); 844 ASSERT_EQUALS("[test.cpp:4]: (style) Class 'A' is unsafe, 'A::p' can leak by wrong usage.\n", errout.str()); 845 846 check("class A\n" 847 "{\n" 848 "public:\n" 849 " int * p;\n" 850 " A() { p = new int; }\n" 851 "};"); 852 ASSERT_EQUALS("[test.cpp:4]: (style) Class 'A' is unsafe, 'A::p' can leak by wrong usage.\n", errout.str()); 853 } 854 class11()855 void class11() { 856 check("class A\n" 857 "{\n" 858 "public:\n" 859 " int * p;\n" 860 " A() : p(new int[10])\n" 861 " { }" 862 "};"); 863 ASSERT_EQUALS("[test.cpp:4]: (style) Class 'A' is unsafe, 'A::p' can leak by wrong usage.\n", errout.str()); 864 865 check("class A\n" 866 "{\n" 867 "public:\n" 868 " int * p;\n" 869 " A();\n" 870 "};\n" 871 "A::A() : p(new int[10])\n" 872 "{ }"); 873 ASSERT_EQUALS("[test.cpp:4]: (style) Class 'A' is unsafe, 'A::p' can leak by wrong usage.\n", errout.str()); 874 } 875 class12()876 void class12() { 877 check("class A\n" 878 "{\n" 879 "private:\n" 880 " int *p;\n" 881 "public:\n" 882 " A();\n" 883 " ~A();\n" 884 " void cleanup();" 885 "};\n" 886 "\n" 887 "A::A()\n" 888 "{ p = new int[10]; }\n" 889 "\n" 890 "A::~A()\n" 891 "{ }\n" 892 "\n" 893 "void A::cleanup()\n" 894 "{ delete [] p; }"); 895 ASSERT_EQUALS("[test.cpp:4]: (style) Class 'A' is unsafe, 'A::p' can leak by wrong usage.\n", errout.str()); 896 897 check("class A\n" 898 "{\n" 899 "private:\n" 900 " int *p;\n" 901 "public:\n" 902 " A()\n" 903 " { p = new int[10]; }\n" 904 " ~A()\n" 905 " { }\n" 906 " void cleanup()\n" 907 " { delete [] p; }\n" 908 "};"); 909 ASSERT_EQUALS("[test.cpp:4]: (style) Class 'A' is unsafe, 'A::p' can leak by wrong usage.\n", errout.str()); 910 } 911 class13()912 void class13() { 913 check("class A\n" 914 "{\n" 915 "private:\n" 916 " int *p;\n" 917 "public:\n" 918 " A();\n" 919 " ~A();\n" 920 " void foo();" 921 "};\n" 922 "\n" 923 "A::A()\n" 924 "{ }\n" 925 "\n" 926 "A::~A()\n" 927 "{ }\n" 928 "\n" 929 "void A::foo()\n" 930 "{ p = new int[10]; delete [] p; }"); 931 ASSERT_EQUALS("[test.cpp:17]: (warning) Possible leak in public function. The pointer 'p' is not deallocated before it is allocated.\n", errout.str()); 932 933 check("class A\n" 934 "{\n" 935 "private:\n" 936 " int *p;\n" 937 "public:\n" 938 " A()\n" 939 " { }\n" 940 " ~A()\n" 941 " { }\n" 942 " void foo()\n" 943 " { p = new int[10]; delete [] p; }\n" 944 "};"); 945 ASSERT_EQUALS("[test.cpp:11]: (warning) Possible leak in public function. The pointer 'p' is not deallocated before it is allocated.\n", errout.str()); 946 } 947 class14()948 void class14() { 949 check("class A\n" 950 "{\n" 951 " int *p;\n" 952 "public:\n" 953 " void init();\n" 954 "};\n" 955 "\n" 956 "void A::init()\n" 957 "{ p = new int[10]; }"); 958 ASSERT_EQUALS("[test.cpp:9]: (warning) Possible leak in public function. The pointer 'p' is not deallocated before it is allocated.\n" 959 "[test.cpp:3]: (style) Class 'A' is unsafe, 'A::p' can leak by wrong usage.\n", errout.str()); 960 961 check("class A\n" 962 "{\n" 963 " int *p;\n" 964 "public:\n" 965 " void init()\n" 966 " { p = new int[10]; }\n" 967 "};"); 968 ASSERT_EQUALS("[test.cpp:6]: (warning) Possible leak in public function. The pointer 'p' is not deallocated before it is allocated.\n" 969 "[test.cpp:3]: (style) Class 'A' is unsafe, 'A::p' can leak by wrong usage.\n", errout.str()); 970 971 972 check("class A\n" 973 "{\n" 974 " int *p;\n" 975 "public:\n" 976 " void init();\n" 977 "};\n" 978 "\n" 979 "void A::init()\n" 980 "{ p = new int; }"); 981 ASSERT_EQUALS("[test.cpp:9]: (warning) Possible leak in public function. The pointer 'p' is not deallocated before it is allocated.\n" 982 "[test.cpp:3]: (style) Class 'A' is unsafe, 'A::p' can leak by wrong usage.\n", errout.str()); 983 984 check("class A\n" 985 "{\n" 986 " int *p;\n" 987 "public:\n" 988 " void init()\n" 989 " { p = new int; }\n" 990 "};"); 991 ASSERT_EQUALS("[test.cpp:6]: (warning) Possible leak in public function. The pointer 'p' is not deallocated before it is allocated.\n" 992 "[test.cpp:3]: (style) Class 'A' is unsafe, 'A::p' can leak by wrong usage.\n", errout.str()); 993 994 995 check("class A\n" 996 "{\n" 997 " int *p;\n" 998 "public:\n" 999 " void init();\n" 1000 "};\n" 1001 "\n" 1002 "void A::init()\n" 1003 "{ p = malloc(sizeof(int)*10); }"); 1004 ASSERT_EQUALS("[test.cpp:9]: (warning) Possible leak in public function. The pointer 'p' is not deallocated before it is allocated.\n" 1005 "[test.cpp:3]: (style) Class 'A' is unsafe, 'A::p' can leak by wrong usage.\n", errout.str()); 1006 1007 check("class A\n" 1008 "{\n" 1009 " int *p;\n" 1010 "public:\n" 1011 " void init()\n" 1012 " { p = malloc(sizeof(int)*10); }\n" 1013 "};"); 1014 ASSERT_EQUALS("[test.cpp:6]: (warning) Possible leak in public function. The pointer 'p' is not deallocated before it is allocated.\n" 1015 "[test.cpp:3]: (style) Class 'A' is unsafe, 'A::p' can leak by wrong usage.\n", errout.str()); 1016 } 1017 class15()1018 void class15() { 1019 check("class A\n" 1020 "{\n" 1021 " int *p;\n" 1022 "public:\n" 1023 " A();\n" 1024 " ~A() { delete [] p; }\n" 1025 "};\n" 1026 "A::A()\n" 1027 "{ p = new int[10]; }"); 1028 ASSERT_EQUALS("", errout.str()); 1029 1030 check("class A\n" 1031 "{\n" 1032 " int *p;\n" 1033 "public:\n" 1034 " A()\n" 1035 " { p = new int[10]; }\n" 1036 " ~A() { delete [] p; }\n" 1037 "};"); 1038 ASSERT_EQUALS("", errout.str()); 1039 1040 1041 check("class A\n" 1042 "{\n" 1043 " int *p;\n" 1044 "public:\n" 1045 " A();\n" 1046 " ~A() { delete p; }\n" 1047 "};\n" 1048 "A::A()\n" 1049 "{ p = new int; }"); 1050 ASSERT_EQUALS("", errout.str()); 1051 1052 check("class A\n" 1053 "{\n" 1054 " int *p;\n" 1055 "public:\n" 1056 " A()\n" 1057 " { p = new int; }\n" 1058 " ~A() { delete p; }\n" 1059 "};"); 1060 ASSERT_EQUALS("", errout.str()); 1061 1062 1063 check("class A\n" 1064 "{\n" 1065 " int *p;\n" 1066 "public:\n" 1067 " A();\n" 1068 " ~A() { free(p); }\n" 1069 "};\n" 1070 "A::A()\n" 1071 "{ p = malloc(sizeof(int)*10); }"); 1072 ASSERT_EQUALS("", errout.str()); 1073 1074 check("class A\n" 1075 "{\n" 1076 " int *p;\n" 1077 "public:\n" 1078 " A()\n" 1079 " { p = malloc(sizeof(int)*10); }\n" 1080 " ~A() { free(p); }\n" 1081 "};"); 1082 ASSERT_EQUALS("", errout.str()); 1083 } 1084 class16()1085 void class16() { 1086 // Ticket #1510 1087 check("class A\n" 1088 "{\n" 1089 " int *a;\n" 1090 " int *b;\n" 1091 "public:\n" 1092 " A() { a = b = new int[10]; }\n" 1093 " ~A() { delete [] a; }\n" 1094 "};"); 1095 ASSERT_EQUALS("", errout.str()); 1096 } 1097 class17()1098 void class17() { 1099 // Ticket #1557 1100 check("class A {\n" 1101 "private:\n" 1102 " char *pd;\n" 1103 "public:\n" 1104 " void foo();\n" 1105 "};\n" 1106 "\n" 1107 "void A::foo()\n" 1108 "{\n" 1109 " A::pd = new char[12];\n" 1110 " delete [] A::pd;\n" 1111 "}"); 1112 ASSERT_EQUALS("[test.cpp:10]: (warning) Possible leak in public function. The pointer 'pd' is not deallocated before it is allocated.\n", errout.str()); 1113 1114 check("class A {\n" 1115 "private:\n" 1116 " char *pd;\n" 1117 "public:\n" 1118 " void foo()\n" 1119 " {\n" 1120 " pd = new char[12];\n" 1121 " delete [] pd;\n" 1122 " }\n" 1123 "};"); 1124 ASSERT_EQUALS("[test.cpp:7]: (warning) Possible leak in public function. The pointer 'pd' is not deallocated before it is allocated.\n", errout.str()); 1125 1126 check("class A {\n" 1127 "private:\n" 1128 " char *pd;\n" 1129 "public:\n" 1130 " void foo();\n" 1131 "};\n" 1132 "\n" 1133 "void A::foo()\n" 1134 "{\n" 1135 " pd = new char[12];\n" 1136 " delete [] pd;\n" 1137 "}"); 1138 ASSERT_EQUALS("[test.cpp:10]: (warning) Possible leak in public function. The pointer 'pd' is not deallocated before it is allocated.\n", errout.str()); 1139 } 1140 class18()1141 void class18() { 1142 // Ticket #853 1143 check("class A : public x\n" 1144 "{\n" 1145 "public:\n" 1146 " A()\n" 1147 " {\n" 1148 " a = new char[10];\n" 1149 " foo(a);\n" 1150 " }\n" 1151 "private:\n" 1152 " char *a;\n" 1153 "};"); 1154 ASSERT_EQUALS("", errout.str()); 1155 1156 check("class A : public x\n" 1157 "{\n" 1158 "public:\n" 1159 " A();\n" 1160 "private:\n" 1161 " char *a;\n" 1162 "};\n" 1163 "A::A()\n" 1164 "{\n" 1165 " a = new char[10];\n" 1166 " foo(a);\n" 1167 "}"); 1168 ASSERT_EQUALS("", errout.str()); 1169 } 1170 class19()1171 void class19() { 1172 // Ticket #2219 1173 check("class Foo\n" 1174 "{\n" 1175 "private:\n" 1176 " TRadioButton* rp1;\n" 1177 " TRadioButton* rp2;\n" 1178 "public:\n" 1179 " Foo();\n" 1180 "};\n" 1181 "Foo::Foo()\n" 1182 "{\n" 1183 " rp1 = new TRadioButton(this);\n" 1184 " rp2 = new TRadioButton(this);\n" 1185 "}"); 1186 ASSERT_EQUALS("", errout.str()); 1187 1188 check("class TRadioButton { };\n" 1189 "class Foo\n" 1190 "{\n" 1191 "private:\n" 1192 " TRadioButton* rp1;\n" 1193 " TRadioButton* rp2;\n" 1194 "public:\n" 1195 " Foo();\n" 1196 "};\n" 1197 "Foo::Foo()\n" 1198 "{\n" 1199 " rp1 = new TRadioButton;\n" 1200 " rp2 = new TRadioButton;\n" 1201 "}"); 1202 ASSERT_EQUALS("[test.cpp:5]: (style) Class 'Foo' is unsafe, 'Foo::rp1' can leak by wrong usage.\n" 1203 "[test.cpp:6]: (style) Class 'Foo' is unsafe, 'Foo::rp2' can leak by wrong usage.\n", errout.str()); 1204 1205 check("class TRadioButton { };\n" 1206 "class Foo\n" 1207 "{\n" 1208 "private:\n" 1209 " TRadioButton* rp1;\n" 1210 " TRadioButton* rp2;\n" 1211 "public:\n" 1212 " Foo();\n" 1213 " ~Foo();\n" 1214 "};\n" 1215 "Foo::Foo()\n" 1216 "{\n" 1217 " rp1 = new TRadioButton;\n" 1218 " rp2 = new TRadioButton;\n" 1219 "}\n" 1220 "Foo::~Foo()\n" 1221 "{\n" 1222 " delete rp1;\n" 1223 " delete rp2;\n" 1224 "}"); 1225 ASSERT_EQUALS("", errout.str()); 1226 } 1227 class20()1228 void class20() { 1229 check("namespace ns1 {\n" 1230 " class Fred\n" 1231 " {\n" 1232 " private:\n" 1233 " char *str1;\n" 1234 " char *str2;\n" 1235 " public:\n" 1236 " Fred()\n" 1237 " {\n" 1238 " str1 = new char[10];\n" 1239 " str2 = new char[10];\n" 1240 " }\n" 1241 " ~Fred()\n" 1242 " {\n" 1243 " delete [] str2;\n" 1244 " }\n" 1245 " };\n" 1246 "}"); 1247 ASSERT_EQUALS("[test.cpp:5]: (style) Class 'Fred' is unsafe, 'Fred::str1' can leak by wrong usage.\n", errout.str()); 1248 1249 check("namespace ns1 {\n" 1250 " class Fred\n" 1251 " {\n" 1252 " private:\n" 1253 " char *str1;\n" 1254 " char *str2;\n" 1255 " public:\n" 1256 " Fred();\n" 1257 " ~Fred();\n" 1258 " };\n" 1259 "\n" 1260 " Fred::Fred()\n" 1261 " {\n" 1262 " str1 = new char[10];\n" 1263 " str2 = new char[10];\n" 1264 " }\n" 1265 "\n" 1266 " Fred::~Fred()\n" 1267 " {\n" 1268 " delete [] str2;\n" 1269 " }\n" 1270 "}"); 1271 ASSERT_EQUALS("[test.cpp:5]: (style) Class 'Fred' is unsafe, 'Fred::str1' can leak by wrong usage.\n", errout.str()); 1272 1273 check("namespace ns1 {\n" 1274 " class Fred\n" 1275 " {\n" 1276 " private:\n" 1277 " char *str1;\n" 1278 " char *str2;\n" 1279 " public:\n" 1280 " Fred();\n" 1281 " ~Fred();\n" 1282 " };\n" 1283 "}\n" 1284 "ns1::Fred::Fred()\n" 1285 "{\n" 1286 " str1 = new char[10];\n" 1287 " str2 = new char[10];\n" 1288 "}\n" 1289 "\n" 1290 "ns1::Fred::~Fred()\n" 1291 "{\n" 1292 " delete [] str2;\n" 1293 "}"); 1294 ASSERT_EQUALS("[test.cpp:5]: (style) Class 'Fred' is unsafe, 'Fred::str1' can leak by wrong usage.\n", errout.str()); 1295 1296 check("namespace ns1 {\n" 1297 " namespace ns2 {\n" 1298 " class Fred\n" 1299 " {\n" 1300 " private:\n" 1301 " char *str1;\n" 1302 " char *str2;\n" 1303 " public:\n" 1304 " Fred();\n" 1305 " ~Fred();\n" 1306 " };\n" 1307 " }\n" 1308 "}\n" 1309 "ns1::ns2::Fred::Fred()\n" 1310 "{\n" 1311 " str1 = new char[10];\n" 1312 " str2 = new char[10];\n" 1313 "}\n" 1314 "\n" 1315 "ns1::ns2::Fred::~Fred()\n" 1316 "{\n" 1317 " delete [] str2;\n" 1318 "}"); 1319 ASSERT_EQUALS("[test.cpp:6]: (style) Class 'Fred' is unsafe, 'Fred::str1' can leak by wrong usage.\n", errout.str()); 1320 1321 check("namespace ns1 {\n" 1322 " namespace ns2 {\n" 1323 " namespace ns3 {\n" 1324 " class Fred\n" 1325 " {\n" 1326 " private:\n" 1327 " char *str1;\n" 1328 " char *str2;\n" 1329 " public:\n" 1330 " Fred();\n" 1331 " ~Fred();\n" 1332 " };\n" 1333 " }\n" 1334 " }\n" 1335 "}\n" 1336 "ns1::ns2::ns3::Fred::Fred()\n" 1337 "{\n" 1338 " str1 = new char[10];\n" 1339 " str2 = new char[10];\n" 1340 "}\n" 1341 "\n" 1342 "ns1::ns2::ns3::Fred::~Fred()\n" 1343 "{\n" 1344 " delete [] str2;\n" 1345 "}"); 1346 ASSERT_EQUALS("[test.cpp:7]: (style) Class 'Fred' is unsafe, 'Fred::str1' can leak by wrong usage.\n", errout.str()); 1347 } 1348 class21()1349 void class21() { // ticket #2517 1350 check("struct B { };\n" 1351 "struct C\n" 1352 "{\n" 1353 " B * b;\n" 1354 " C(B * x) : b(x) { }\n" 1355 "};\n" 1356 "class A\n" 1357 "{\n" 1358 " B *b;\n" 1359 " C *c;\n" 1360 "public:\n" 1361 " A() : b(new B()), c(new C(b)) { }\n" 1362 "}"); 1363 ASSERT_EQUALS("[test.cpp:9]: (style) Class 'A' is unsafe, 'A::b' can leak by wrong usage.\n" 1364 "[test.cpp:10]: (style) Class 'A' is unsafe, 'A::c' can leak by wrong usage.\n", errout.str()); 1365 1366 check("struct B { };\n" 1367 "struct C\n" 1368 "{\n" 1369 " B * b;\n" 1370 " C(B * x) : b(x) { }\n" 1371 "};\n" 1372 "class A\n" 1373 "{\n" 1374 " B *b;\n" 1375 " C *c;\n" 1376 "public:\n" 1377 " A()\n" 1378 " {\n" 1379 " b = new B();\n" 1380 " c = new C(b);\n" 1381 " }\n" 1382 "}"); 1383 ASSERT_EQUALS("[test.cpp:9]: (style) Class 'A' is unsafe, 'A::b' can leak by wrong usage.\n" 1384 "[test.cpp:10]: (style) Class 'A' is unsafe, 'A::c' can leak by wrong usage.\n", errout.str()); 1385 } 1386 class22()1387 void class22() { // ticket #3012 - false positive 1388 check("class Fred {\n" 1389 "private:\n" 1390 " int * a;\n" 1391 "private:\n" 1392 " Fred() { a = new int; }\n" 1393 " ~Fred() { (delete(a), (a)=NULL); }\n" 1394 "};"); 1395 ASSERT_EQUALS("", errout.str()); 1396 } 1397 class23()1398 void class23() { // ticket #3303 - false positive 1399 check("class CDataImpl {\n" 1400 "public:\n" 1401 " CDataImpl() { m_refcount = 1; }\n" 1402 " void Release() { if (--m_refcount == 0) delete this; }\n" 1403 "private:\n" 1404 " int m_refcount;\n" 1405 "};\n" 1406 "\n" 1407 "class CData {\n" 1408 "public:\n" 1409 " CData() : m_impl(new CDataImpl()) { }\n" 1410 " ~CData() { if (m_impl) m_impl->Release(); }\n" 1411 "private:\n" 1412 " CDataImpl *m_impl;\n" 1413 "};"); 1414 ASSERT_EQUALS("", errout.str()); 1415 } 1416 class24()1417 void class24() { // ticket #3806 - false positive in copy constructor 1418 check("class Fred {\n" 1419 "private:\n" 1420 " int * a;\n" 1421 "public:\n" 1422 " Fred(const Fred &fred) { a = new int; }\n" 1423 " ~Fred() { delete a; }\n" 1424 "};"); 1425 ASSERT_EQUALS("", errout.str()); 1426 } 1427 class25()1428 void class25() { // ticket #4367 - false positive when implementation for destructor is not seen 1429 check("class Fred {\n" 1430 "private:\n" 1431 " int * a;\n" 1432 "public:\n" 1433 " Fred() { a = new int; }\n" 1434 " ~Fred();\n" 1435 "};"); 1436 ASSERT_EQUALS("", errout.str()); 1437 } 1438 staticvar()1439 void staticvar() { 1440 check("class A\n" 1441 "{\n" 1442 "private:\n" 1443 " static int * p;\n" 1444 "public:" 1445 " A()\n" 1446 " {\n" 1447 " if (!p)\n" 1448 " p = new int[100];\n" 1449 " }\n" 1450 "};"); 1451 ASSERT_EQUALS("", errout.str()); 1452 } 1453 1454 free_member_in_sub_func()1455 void free_member_in_sub_func() { 1456 // Member function 1457 check("class Tokenizer\n" 1458 "{\n" 1459 "public:\n" 1460 " Tokenizer();\n" 1461 " ~Tokenizer();\n" 1462 "\n" 1463 "private:\n" 1464 " int *_tokens;\n" 1465 " static void deleteTokens(int *tok);\n" 1466 "};\n" 1467 "\n" 1468 "Tokenizer::Tokenizer()\n" 1469 "{\n" 1470 " _tokens = new int;\n" 1471 "}\n" 1472 "\n" 1473 "Tokenizer::~Tokenizer()\n" 1474 "{\n" 1475 " deleteTokens(_tokens);\n" 1476 " _tokens = 0;\n" 1477 "}\n" 1478 "\n" 1479 "void Tokenizer::deleteTokens(int *tok)\n" 1480 "{\n" 1481 " delete tok;\n" 1482 "}"); 1483 ASSERT_EQUALS("", errout.str()); 1484 1485 // Global function 1486 check("void deleteTokens(int *tok)\n" 1487 "{\n" 1488 " delete tok;\n" 1489 "}\n" 1490 "class Tokenizer\n" 1491 "{\n" 1492 "public:\n" 1493 " Tokenizer();\n" 1494 " ~Tokenizer();\n" 1495 "\n" 1496 "private:\n" 1497 " int *_tokens;\n" 1498 "};\n" 1499 "\n" 1500 "Tokenizer::Tokenizer()\n" 1501 "{\n" 1502 " _tokens = new int;\n" 1503 "}\n" 1504 "\n" 1505 "Tokenizer::~Tokenizer()\n" 1506 "{\n" 1507 " deleteTokens(_tokens);\n" 1508 " _tokens = 0;\n" 1509 "}"); 1510 ASSERT_EQUALS("", errout.str()); 1511 } 1512 mismatch1()1513 void mismatch1() { 1514 check("class A\n" 1515 "{\n" 1516 "public:\n" 1517 " A(int i);\n" 1518 " ~A();\n" 1519 "private:\n" 1520 " char* pkt_buffer;\n" 1521 "};\n" 1522 "\n" 1523 "A::A(int i)\n" 1524 "{\n" 1525 " pkt_buffer = new char[8192];\n" 1526 " if (i != 1) {\n" 1527 " delete pkt_buffer;\n" 1528 " pkt_buffer = 0;\n" 1529 " }\n" 1530 "}\n" 1531 "\n" 1532 "A::~A() {\n" 1533 " delete [] pkt_buffer;\n" 1534 "}"); 1535 ASSERT_EQUALS("[test.cpp:14]: (error) Mismatching allocation and deallocation: A::pkt_buffer\n", errout.str()); 1536 } 1537 mismatch2()1538 void mismatch2() { // #5659 1539 check("namespace NS\n" 1540 "{\n" 1541 "class Foo\n" 1542 "{\n" 1543 "public:\n" 1544 " void fct();\n" 1545 "\n" 1546 "private:\n" 1547 " char* data_;\n" 1548 "};\n" 1549 "}\n" 1550 "\n" 1551 "using namespace NS;\n" 1552 "\n" 1553 "void Foo::fct()\n" 1554 "{\n" 1555 " data_ = new char[42];\n" 1556 " delete data_;\n" 1557 " data_ = 0;\n" 1558 "}"); 1559 ASSERT_EQUALS("[test.cpp:17]: (warning) Possible leak in public function. The pointer 'data_' is not deallocated before it is allocated.\n" 1560 "[test.cpp:18]: (error) Mismatching allocation and deallocation: Foo::data_\n", errout.str()); 1561 1562 check("namespace NS\n" 1563 "{\n" 1564 "class Foo\n" 1565 "{\n" 1566 "public:\n" 1567 " void fct(int i);\n" 1568 "\n" 1569 "private:\n" 1570 " char* data_;\n" 1571 "};\n" 1572 "}\n" 1573 "\n" 1574 "using namespace NS;\n" 1575 "\n" 1576 "void Foo::fct(int i)\n" 1577 "{\n" 1578 " data_ = new char[42];\n" 1579 " delete data_;\n" 1580 " data_ = 0;\n" 1581 "}"); 1582 ASSERT_EQUALS("[test.cpp:17]: (warning) Possible leak in public function. The pointer 'data_' is not deallocated before it is allocated.\n" 1583 "[test.cpp:18]: (error) Mismatching allocation and deallocation: Foo::data_\n", errout.str()); 1584 } 1585 func1()1586 void func1() { 1587 check("class Fred\n" 1588 "{\n" 1589 "private:\n" 1590 " char *s;\n" 1591 "public:\n" 1592 " Fred() { s = 0; }\n" 1593 " ~Fred() { free(s); }\n" 1594 " void xy()\n" 1595 " { s = malloc(100); }\n" 1596 "};"); 1597 ASSERT_EQUALS("[test.cpp:9]: (warning) Possible leak in public function. The pointer 's' is not deallocated before it is allocated.\n", errout.str()); 1598 1599 check("class Fred\n" 1600 "{\n" 1601 "public:\n" 1602 " Fred() { s = 0; }\n" 1603 " ~Fred() { free(s); }\n" 1604 " void xy()\n" 1605 " { s = malloc(100); }\n" 1606 "private:\n" 1607 " char *s;\n" 1608 "};"); 1609 ASSERT_EQUALS("[test.cpp:7]: (warning) Possible leak in public function. The pointer 's' is not deallocated before it is allocated.\n", errout.str()); 1610 } 1611 func2()1612 void func2() { 1613 check("class Fred\n" 1614 "{\n" 1615 "private:\n" 1616 " char *s;\n" 1617 "public:\n" 1618 " Fred() { s = 0; }\n" 1619 " ~Fred() { free(s); }\n" 1620 " const Fred & operator = (const Fred &f)\n" 1621 " { s = malloc(100); }\n" 1622 "};"); 1623 ASSERT_EQUALS("[test.cpp:9]: (warning) Possible leak in public function. The pointer 's' is not deallocated before it is allocated.\n", errout.str()); 1624 } 1625 }; 1626 1627 REGISTER_TEST(TestMemleakInClass) 1628 1629 1630 1631 1632 1633 1634 1635 class TestMemleakStructMember : public TestFixture { 1636 public: TestMemleakStructMember()1637 TestMemleakStructMember() : TestFixture("TestMemleakStructMember") {} 1638 1639 private: 1640 Settings settings; 1641 check(const char code[],bool isCPP=true)1642 void check(const char code[], bool isCPP = true) { 1643 // Clear the error buffer.. 1644 errout.str(""); 1645 1646 // Tokenize.. 1647 Tokenizer tokenizer(&settings, this); 1648 std::istringstream istr(code); 1649 tokenizer.tokenize(istr, isCPP ? "test.cpp" : "test.c"); 1650 1651 // Check for memory leaks.. 1652 CheckMemoryLeakStructMember checkMemoryLeakStructMember(&tokenizer, &settings, this); 1653 checkMemoryLeakStructMember.check(); 1654 } 1655 run()1656 void run() OVERRIDE { 1657 LOAD_LIB_2(settings.library, "std.cfg"); 1658 LOAD_LIB_2(settings.library, "posix.cfg"); 1659 1660 // testing that errors are detected 1661 TEST_CASE(err); 1662 1663 // handle / bail out when "goto" is found 1664 TEST_CASE(goto_); 1665 1666 // Don't report errors if the struct is returned 1667 TEST_CASE(ret1); 1668 TEST_CASE(ret2); 1669 1670 // assignments 1671 TEST_CASE(assign1); 1672 TEST_CASE(assign2); 1673 TEST_CASE(assign3); 1674 1675 // Failed allocation 1676 TEST_CASE(failedAllocation); 1677 1678 TEST_CASE(function1); // Deallocating in function 1679 TEST_CASE(function2); // #2848: Taking address in function 1680 TEST_CASE(function3); // #3024: kernel list 1681 TEST_CASE(function4); // #3038: Deallocating in function 1682 1683 // Handle if-else 1684 TEST_CASE(ifelse); 1685 1686 // Linked list 1687 TEST_CASE(linkedlist); 1688 1689 // struct variable is a global variable 1690 TEST_CASE(globalvar); 1691 1692 // local struct variable 1693 TEST_CASE(localvars); 1694 1695 // struct variable is a reference variable 1696 TEST_CASE(refvar); 1697 1698 // Segmentation fault in CheckMemoryLeakStructMember 1699 TEST_CASE(trac5030); 1700 1701 TEST_CASE(varid); // #5201: Analysis confused by (variable).attribute notation 1702 TEST_CASE(varid_2); // #5315: Analysis confused by ((variable).attribute) notation 1703 1704 TEST_CASE(customAllocation); 1705 1706 TEST_CASE(lambdaInForLoop); // #9793 1707 } 1708 err()1709 void err() { 1710 check("static void foo()\n" 1711 "{\n" 1712 " struct ABC *abc = malloc(sizeof(struct ABC));\n" 1713 " abc->a = malloc(10);\n" 1714 " free(abc);\n" 1715 "}"); 1716 ASSERT_EQUALS("[test.cpp:5]: (error) Memory leak: abc.a\n", errout.str()); 1717 1718 check("static void foo()\n" 1719 "{\n" 1720 " struct ABC *abc = malloc(sizeof(struct ABC));\n" 1721 " abc->a = malloc(10);\n" 1722 "}"); 1723 ASSERT_EQUALS("[test.cpp:5]: (error) Memory leak: abc.a\n", errout.str()); 1724 1725 check("static ABC * foo()\n" 1726 "{\n" 1727 " ABC *abc = malloc(sizeof(ABC));\n" 1728 " abc->a = malloc(10);\n" 1729 " abc->b = malloc(10);\n" 1730 " if (abc->b == 0)\n" 1731 " {\n" 1732 " return 0;\n" 1733 " }\n" 1734 " return abc;\n" 1735 "}"); 1736 ASSERT_EQUALS("[test.cpp:8]: (error) Memory leak: abc.a\n", errout.str()); 1737 1738 check("static void foo(int a)\n" 1739 "{\n" 1740 " ABC *abc = malloc(sizeof(ABC));\n" 1741 " abc->a = malloc(10);\n" 1742 " if (a == 1)\n" 1743 " {\n" 1744 " free(abc->a);\n" 1745 " return;\n" 1746 " }\n" 1747 "}"); 1748 ASSERT_EQUALS("[test.cpp:10]: (error) Memory leak: abc.a\n", errout.str()); 1749 } 1750 goto_()1751 void goto_() { 1752 check("static void foo()\n" 1753 "{\n" 1754 " struct ABC *abc = malloc(sizeof(struct ABC));\n" 1755 " abc->a = malloc(10);\n" 1756 " if (abc->a)\n" 1757 " { goto out; }\n" 1758 " free(abc);\n" 1759 " return;\n" 1760 "out:\n" 1761 " free(abc->a);\n" 1762 " free(abc);\n" 1763 "}"); 1764 ASSERT_EQUALS("", errout.str()); 1765 } 1766 ret1()1767 void ret1() { 1768 check("static ABC * foo()\n" 1769 "{\n" 1770 " struct ABC *abc = malloc(sizeof(struct ABC));\n" 1771 " abc->a = malloc(10);\n" 1772 " return abc;\n" 1773 "}"); 1774 ASSERT_EQUALS("", errout.str()); 1775 1776 check("static void foo(struct ABC *abc)\n" 1777 "{\n" 1778 " abc->a = malloc(10);\n" 1779 "}"); 1780 ASSERT_EQUALS("", errout.str()); 1781 1782 // #7302 1783 check("void* foo() {\n" 1784 " struct ABC abc;\n" 1785 " abc.a = malloc(10);\n" 1786 " return abc.a;\n" 1787 "}", false); 1788 ASSERT_EQUALS("", errout.str()); 1789 1790 check("void* foo() {\n" 1791 " struct ABC abc;\n" 1792 " abc.a = malloc(10);\n" 1793 " return abc.b;\n" 1794 "}", false); 1795 ASSERT_EQUALS("[test.c:4]: (error) Memory leak: abc.a\n", errout.str()); 1796 } 1797 ret2()1798 void ret2() { 1799 check("static ABC * foo()\n" 1800 "{\n" 1801 " struct ABC *abc = malloc(sizeof(struct ABC));\n" 1802 " abc->a = malloc(10);\n" 1803 " return &abc->self;\n" 1804 "}"); 1805 ASSERT_EQUALS("", errout.str()); 1806 } 1807 assign1()1808 void assign1() { 1809 check("static void foo()\n" 1810 "{\n" 1811 " struct ABC *abc = abc1;\n" 1812 " abc->a = malloc(10);\n" 1813 "}"); 1814 ASSERT_EQUALS("", errout.str()); 1815 1816 check("static void foo()\n" 1817 "{\n" 1818 " struct ABC *abc;\n" 1819 " abc1 = abc = malloc(sizeof(ABC));\n" 1820 " abc->a = malloc(10);\n" 1821 "}"); 1822 ASSERT_EQUALS("", errout.str()); 1823 1824 check("static void foo()\n" 1825 "{\n" 1826 " struct msn_entry *ptr;\n" 1827 " ptr = malloc(sizeof(struct msn_entry));\n" 1828 " ptr->msn = malloc(100);\n" 1829 " back = ptr;\n" 1830 "}"); 1831 ASSERT_EQUALS("", errout.str()); 1832 1833 } 1834 assign2()1835 void assign2() { 1836 check("static void foo() {\n" 1837 " struct ABC *abc = malloc(123);\n" 1838 " abc->a = abc->b = malloc(10);\n" 1839 "}"); 1840 ASSERT_EQUALS("", errout.str()); 1841 } 1842 assign3()1843 void assign3() { 1844 check("void f(struct s *f1) {\n" 1845 " struct s f2;\n" 1846 " f2.a = malloc(100);\n" 1847 " *f1 = f2;\n" 1848 "}", false); 1849 ASSERT_EQUALS("", errout.str()); 1850 } 1851 failedAllocation()1852 void failedAllocation() { 1853 check("static struct ABC * foo()\n" 1854 "{\n" 1855 " struct ABC *abc = malloc(sizeof(struct ABC));\n" 1856 " abc->a = malloc(10);\n" 1857 " if (!abc->a)\n" 1858 " {\n" 1859 " free(abc);\n" 1860 " return 0;\n" 1861 " }\n" 1862 " return abc;\n" 1863 "}"); 1864 ASSERT_EQUALS("", errout.str()); 1865 } 1866 function1()1867 void function1() { 1868 // Not found function => assume that the function may deallocate 1869 check("static void foo()\n" 1870 "{\n" 1871 " struct ABC *abc = malloc(sizeof(struct ABC));\n" 1872 " abc->a = malloc(10);\n" 1873 " func(abc);\n" 1874 "}"); 1875 ASSERT_EQUALS("", errout.str()); 1876 1877 check("static void foo()\n" 1878 "{\n" 1879 " struct ABC *abc = malloc(sizeof(struct ABC));\n" 1880 " abclist.push_back(abc);\n" 1881 " abc->a = malloc(10);\n" 1882 "}"); 1883 ASSERT_EQUALS("", errout.str()); 1884 } 1885 1886 // #2848: Taking address in function 'assign' function2()1887 void function2() { 1888 check("void f() {\n" 1889 " A a = { 0 };\n" 1890 " a.foo = (char *) malloc(10);\n" 1891 " assign(&a);\n" 1892 "}", false); 1893 ASSERT_EQUALS("", errout.str()); 1894 } 1895 1896 // #3024: kernel list function3()1897 void function3() { 1898 check("void f() {\n" 1899 " struct ABC *abc = malloc(100);\n" 1900 " abc.a = (char *) malloc(10);\n" 1901 " list_add_tail(&abc->list, head);\n" 1902 "}", false); 1903 ASSERT_EQUALS("", errout.str()); 1904 } 1905 1906 // #3038: deallocating in function function4()1907 void function4() { 1908 check("void a(char *p) { char *x = p; free(x); }\n" 1909 "void b() {\n" 1910 " struct ABC abc;\n" 1911 " abc.a = (char *) malloc(10);\n" 1912 " a(abc.a);\n" 1913 "}", false); 1914 ASSERT_EQUALS("", errout.str()); 1915 } 1916 ifelse()1917 void ifelse() { 1918 check("static void foo()\n" 1919 "{\n" 1920 " struct ABC *abc = malloc(sizeof(struct ABC));\n" 1921 " if (x)" 1922 " {\n" 1923 " abc->a = malloc(10);\n" 1924 " }\n" 1925 " else\n" 1926 " {\n" 1927 " free(abc);\n" 1928 " return;\n" 1929 " }\n" 1930 " free(abc->a);\n" 1931 " free(abc);\n" 1932 "}"); 1933 ASSERT_EQUALS("", errout.str()); 1934 } 1935 linkedlist()1936 void linkedlist() { 1937 // #3904 - false positive when linked list is used 1938 check("static void foo() {\n" 1939 " struct ABC *abc = malloc(sizeof(struct ABC));\n" 1940 " abc->next = malloc(sizeof(struct ABC));\n" 1941 " abc->next->next = NULL;\n" 1942 "\n" 1943 " while (abc) {\n" 1944 " struct ABC *next = abc->next;\n" 1945 " free(abc);\n" 1946 " abc = next;\n" 1947 " }\n" 1948 "}"); 1949 ASSERT_EQUALS("", errout.str()); 1950 } 1951 globalvar()1952 void globalvar() { 1953 check("struct ABC *abc;\n" 1954 "\n" 1955 "static void foo()\n" 1956 "{\n" 1957 " abc = malloc(sizeof(struct ABC));\n" 1958 " abc->a = malloc(10);\n" 1959 " return;\n" 1960 "}"); 1961 ASSERT_EQUALS("", errout.str()); 1962 } 1963 1964 // Ticket #933 Leaks with struct members not detected localvars()1965 void localvars() { 1966 // Test error case 1967 const char code1[] = "struct A {\n" 1968 " FILE* f;\n" 1969 " char* c;\n" 1970 " void* m;\n" 1971 "};\n" 1972 "\n" 1973 "void func() {\n" 1974 " struct A a;\n" 1975 " a.f = fopen(\"test\", \"r\");\n" 1976 " a.c = new char[12];\n" 1977 " a.m = malloc(12);\n" 1978 "}"; 1979 1980 check(code1, true); 1981 ASSERT_EQUALS("[test.cpp:12]: (error) Memory leak: a.f\n" 1982 "[test.cpp:12]: (error) Memory leak: a.c\n" 1983 "[test.cpp:12]: (error) Memory leak: a.m\n", errout.str()); 1984 check(code1, false); 1985 ASSERT_EQUALS("[test.c:12]: (error) Memory leak: a.f\n" 1986 "[test.c:12]: (error) Memory leak: a.m\n", errout.str()); 1987 1988 // Test OK case 1989 const char code2[] = "struct A {\n" 1990 " FILE* f;\n" 1991 " char* c;\n" 1992 " void* m;\n" 1993 "};\n" 1994 "\n" 1995 "void func() {\n" 1996 " struct A a;\n" 1997 " a.f = fopen(\"test\", \"r\");\n" 1998 " a.c = new char[12];\n" 1999 " a.m = malloc(12);\n" 2000 " fclose(a.f);\n" 2001 " delete [] a.c;\n" 2002 " free(a.m);\n" 2003 "}"; 2004 2005 check(code2, true); 2006 ASSERT_EQUALS("", errout.str()); 2007 check(code2, false); 2008 ASSERT_EQUALS("", errout.str()); 2009 2010 // Test unknown struct. In C++, it might have a destructor 2011 const char code3[] = "void func() {\n" 2012 " struct A a;\n" 2013 " a.f = fopen(\"test\", \"r\");\n" 2014 "}"; 2015 2016 check(code3, true); 2017 ASSERT_EQUALS("", errout.str()); 2018 check(code3, false); 2019 ASSERT_EQUALS("[test.c:4]: (error) Memory leak: a.f\n", errout.str()); 2020 2021 // Test struct with destructor 2022 const char code4[] = "struct A {\n" 2023 " FILE* f;\n" 2024 " ~A();\n" 2025 "};\n" 2026 "void func() {\n" 2027 " struct A a;\n" 2028 " a.f = fopen(\"test\", \"r\");\n" 2029 "}"; 2030 2031 check(code4, true); 2032 ASSERT_EQUALS("", errout.str()); 2033 } 2034 refvar()2035 void refvar() { // #8116 2036 check("struct Test\n" 2037 "{\n" 2038 " int* data;\n" 2039 "};\n" 2040 "\n" 2041 "void foo(Test* x)\n" 2042 "{\n" 2043 " Test& y = *x;\n" 2044 " y.data = malloc(10);\n" 2045 "}"); 2046 ASSERT_EQUALS("", errout.str()); 2047 } 2048 2049 // don't crash trac5030()2050 void trac5030() { 2051 check("bool bob( char const **column_ptrs ) {\n" 2052 "unique_ptr<char[]>otherbuffer{new char[otherbufsize+1]};\n" 2053 "char *const oldbuffer = otherbuffer.get();\n" 2054 "int const oldbufsize = otherbufsize;\n" 2055 "}"); 2056 ASSERT_EQUALS("", errout.str()); 2057 } 2058 varid()2059 void varid() { // #5201 2060 check("struct S {\n" 2061 " void *state_check_buff;\n" 2062 "};\n" 2063 "void f() {\n" 2064 " S s;\n" 2065 " (s).state_check_buff = (void* )malloc(1);\n" 2066 " if (s.state_check_buff == 0)\n" 2067 " return;\n" 2068 "}", false); 2069 ASSERT_EQUALS("[test.c:9]: (error) Memory leak: s.state_check_buff\n", errout.str()); 2070 } 2071 varid_2()2072 void varid_2() { // #5315 2073 check("typedef struct foo { char *realm; } foo;\n" 2074 "void build_principal() {\n" 2075 " foo f;\n" 2076 " ((f)->realm) = strdup(realm);\n" 2077 " if(f->realm == NULL) {}\n" 2078 "}", false); 2079 TODO_ASSERT_EQUALS("[test.c:6]: (error) Memory leak: f.realm\n", "", errout.str()); 2080 } 2081 customAllocation()2082 void customAllocation() { // #4770 2083 check("char *myalloc(void) {\n" 2084 " return malloc(100);\n" 2085 "}\n" 2086 "void func() {\n" 2087 " struct ABC abc;\n" 2088 " abc.a = myalloc();\n" 2089 "}", false); 2090 ASSERT_EQUALS("[test.c:7]: (error) Memory leak: abc.a\n", errout.str()); 2091 } 2092 lambdaInForLoop()2093 void lambdaInForLoop() { // #9793 2094 check( 2095 "struct S { int * p{nullptr}; };\n" 2096 "int main()\n" 2097 "{\n" 2098 " S s;\n" 2099 " s.p = new int[10];\n" 2100 " for (int i = 0; i < 10; ++i) {\n" 2101 " s.p[i] = []() { return 1; }();\n" 2102 " }\n" 2103 " delete[] s.p;\n" 2104 " return 0;\n" 2105 "}", true); 2106 ASSERT_EQUALS("", errout.str()); 2107 } 2108 }; 2109 2110 REGISTER_TEST(TestMemleakStructMember) 2111 2112 2113 2114 2115 2116 class TestMemleakNoVar : public TestFixture { 2117 public: TestMemleakNoVar()2118 TestMemleakNoVar() : TestFixture("TestMemleakNoVar") {} 2119 2120 private: 2121 Settings settings; 2122 check(const char code[])2123 void check(const char code[]) { 2124 // Clear the error buffer.. 2125 errout.str(""); 2126 2127 // Tokenize.. 2128 Tokenizer tokenizer(&settings, this); 2129 std::istringstream istr(code); 2130 tokenizer.tokenize(istr, "test.cpp"); 2131 2132 // Check for memory leaks.. 2133 CheckMemoryLeakNoVar checkMemoryLeakNoVar(&tokenizer, &settings, this); 2134 checkMemoryLeakNoVar.check(); 2135 } 2136 run()2137 void run() OVERRIDE { 2138 settings.certainty.setEnabled(Certainty::inconclusive, true); 2139 settings.libraries.emplace_back("posix"); 2140 settings.severity.enable(Severity::warning); 2141 2142 LOAD_LIB_2(settings.library, "std.cfg"); 2143 LOAD_LIB_2(settings.library, "posix.cfg"); 2144 2145 // pass allocated memory to function.. 2146 TEST_CASE(functionParameter); 2147 2148 // never use leakable resource 2149 TEST_CASE(missingAssignment); 2150 2151 // pass allocated memory to function using a smart pointer 2152 TEST_CASE(smartPointerFunctionParam); 2153 TEST_CASE(resourceLeak); 2154 2155 // Test getAllocationType for subfunction 2156 TEST_CASE(getAllocationType); 2157 } 2158 functionParameter()2159 void functionParameter() { 2160 // standard function.. 2161 check("void x() {\n" 2162 " strcpy(a, strdup(p));\n" 2163 "}"); 2164 ASSERT_EQUALS("[test.cpp:2]: (error) Allocation with strdup, strcpy doesn't release it.\n", errout.str()); 2165 2166 check("char *x() {\n" 2167 " char *ret = strcpy(malloc(10), \"abc\");\n" 2168 " return ret;\n" 2169 "}"); 2170 ASSERT_EQUALS("", errout.str()); 2171 2172 check("char *x() {\n" 2173 " return strcpy(malloc(10), \"abc\");\n" 2174 "}"); 2175 ASSERT_EQUALS("", errout.str()); 2176 2177 check("void x() {\n" 2178 " free(malloc(10));\n" 2179 "}"); 2180 ASSERT_EQUALS("", errout.str()); 2181 2182 // user function.. 2183 check("void set_error(const char *msg) {\n" 2184 "}\n" 2185 "\n" 2186 "void x() {\n" 2187 " set_error(strdup(p));\n" 2188 "}"); 2189 TODO_ASSERT_EQUALS("[test.cpp:5]: (error) Allocation with strdup, set_error doesn't release it.\n", "", errout.str()); 2190 2191 check("void f()\n" 2192 "{\n" 2193 " int fd;\n" 2194 " fd = mkstemp(strdup(\"/tmp/file.XXXXXXXX\"));\n" 2195 " close(fd);\n" 2196 "}"); 2197 TODO_ASSERT_EQUALS("[test.cpp:4]: (error) Allocation with strdup, mkstemp doesn't release it.\n", "", errout.str()); 2198 2199 check("void f()\n" 2200 "{\n" 2201 " if(TRUE || strcmp(strdup(a), b));\n" 2202 "}"); 2203 ASSERT_EQUALS("[test.cpp:3]: (error) Allocation with strdup, strcmp doesn't release it.\n", errout.str()); 2204 2205 check("void f()\n" 2206 "{\n" 2207 " if(!strcmp(strdup(a), b) == 0);\n" 2208 "}"); 2209 ASSERT_EQUALS("[test.cpp:3]: (error) Allocation with strdup, strcmp doesn't release it.\n", errout.str()); 2210 2211 check("void f()\n" 2212 "{\n" 2213 " 42, strcmp(strdup(a), b);\n" 2214 "}"); 2215 ASSERT_EQUALS("[test.cpp:3]: (error) Allocation with strdup, strcmp doesn't release it.\n", errout.str()); 2216 2217 check("void f() {\n" 2218 " assert(freopen(\"/dev/null\", \"r\", stdin));\n" 2219 "}"); 2220 ASSERT_EQUALS("", errout.str()); 2221 2222 check("void x() {\n" 2223 " strcpy(a, (void*)strdup(p));\n" 2224 "}"); 2225 ASSERT_EQUALS("[test.cpp:2]: (error) Allocation with strdup, strcpy doesn't release it.\n", errout.str()); 2226 2227 check("void* malloc1() {\n" 2228 " return (malloc(1));\n" 2229 "}"); 2230 ASSERT_EQUALS("", errout.str()); 2231 2232 check("char *x() {\n" 2233 " char *ret = (char*)strcpy(malloc(10), \"abc\");\n" 2234 " return ret;\n" 2235 "}"); 2236 ASSERT_EQUALS("", errout.str()); 2237 2238 check("void f() {\n" 2239 " free(malloc(1));\n" 2240 " strcpy(a, strdup(p));\n" 2241 "}"); 2242 ASSERT_EQUALS("[test.cpp:3]: (error) Allocation with strdup, strcpy doesn't release it.\n", errout.str()); 2243 2244 check("void f() {\n" 2245 " memcmp(calloc(10, 10), strdup(q), 100);\n" 2246 "}"); 2247 ASSERT_EQUALS("[test.cpp:2]: (error) Allocation with calloc, memcmp doesn't release it.\n" 2248 "[test.cpp:2]: (error) Allocation with strdup, memcmp doesn't release it.\n", errout.str()); 2249 2250 check("void* f(int size) {\n" 2251 " return (void*) malloc(size);\n" 2252 "}"); 2253 ASSERT_EQUALS("", errout.str()); 2254 2255 check("int* f(int size) {\n" 2256 " return static_cast<int*>(malloc(size));\n" 2257 "}"); 2258 ASSERT_EQUALS("", errout.str()); 2259 } 2260 missingAssignment()2261 void missingAssignment() { 2262 check("void x()\n" 2263 "{\n" 2264 " malloc(10);\n" 2265 "}"); 2266 ASSERT_EQUALS("[test.cpp:3]: (error) Return value of allocation function 'malloc' is not stored.\n", errout.str()); 2267 2268 check("void x()\n" 2269 "{\n" 2270 " calloc(10, 1);\n" 2271 "}"); 2272 ASSERT_EQUALS("[test.cpp:3]: (error) Return value of allocation function 'calloc' is not stored.\n", errout.str()); 2273 2274 check("void x()\n" 2275 "{\n" 2276 " strdup(\"Test\");\n" 2277 "}"); 2278 ASSERT_EQUALS("[test.cpp:3]: (error) Return value of allocation function 'strdup' is not stored.\n", errout.str()); 2279 2280 check("void x()\n" 2281 "{\n" 2282 " reallocarray(NULL, 10, 10);\n" 2283 "}"); 2284 ASSERT_EQUALS("[test.cpp:3]: (error) Return value of allocation function 'reallocarray' is not stored.\n", errout.str()); 2285 2286 check("void x()\n" 2287 "{\n" 2288 " (char*) malloc(10);\n" 2289 "}"); 2290 ASSERT_EQUALS("[test.cpp:3]: (error) Return value of allocation function 'malloc' is not stored.\n", errout.str()); 2291 2292 check("void x()\n" 2293 "{\n" 2294 " char* ptr = malloc(10);\n" 2295 " foo(ptr);\n" 2296 " free(ptr);\n" 2297 "}"); 2298 ASSERT_EQUALS("", errout.str()); 2299 2300 check("char** x(const char* str) {\n" 2301 " char* ptr[] = { malloc(10), malloc(5), strdup(str) };\n" 2302 " return ptr;\n" 2303 "}"); 2304 ASSERT_EQUALS("", errout.str()); 2305 2306 check("void x()\n" 2307 "{\n" 2308 " 42,malloc(42);\n" 2309 "}"); 2310 TODO_ASSERT_EQUALS("[test.cpp:3]: (error) Return value of allocation function 'malloc' is not stored.\n", "", errout.str()); 2311 2312 check("void *f()\n" 2313 "{\n" 2314 " return malloc(10);\n" 2315 "}\n" 2316 "void x()\n" 2317 "{\n" 2318 " f();\n" 2319 "}"); 2320 ASSERT_EQUALS("[test.cpp:7]: (error) Return value of allocation function 'f' is not stored.\n", errout.str()); 2321 2322 check("void f()\n" // #8100 2323 "{\n" 2324 " auto lambda = [](){return malloc(10);};\n" 2325 "}\n" 2326 "void x()\n" 2327 "{\n" 2328 " f();\n" 2329 "}"); 2330 ASSERT_EQUALS("", errout.str()); 2331 2332 check("void *f() {\n" // #8848 2333 " struct S { void *alloc() { return malloc(10); } };\n" 2334 "}\n" 2335 "void x()\n" 2336 "{\n" 2337 " f();\n" 2338 "}"); 2339 ASSERT_EQUALS("", errout.str()); 2340 2341 check("void x()\n" 2342 "{\n" 2343 " if(!malloc(5)) fail();\n" 2344 "}"); 2345 ASSERT_EQUALS("[test.cpp:3]: (error) Return value of allocation function 'malloc' is not stored.\n", errout.str()); 2346 2347 check("FOO* factory() {\n" 2348 " FOO* foo = new (std::nothrow) FOO;\n" 2349 " return foo;\n" 2350 "}"); 2351 ASSERT_EQUALS("", errout.str()); 2352 2353 // Ticket #6536 2354 check("struct S { S(int) {} };\n" 2355 "void foo(int i) {\n" 2356 " S socket(i);\n" 2357 "}"); 2358 ASSERT_EQUALS("", errout.str()); 2359 2360 // Ticket #6693 2361 check("struct CTest {\n" 2362 " void Initialise();\n" 2363 " void malloc();\n" 2364 "};\n" 2365 "void CTest::Initialise() {\n" 2366 " malloc();\n" 2367 "}"); 2368 ASSERT_EQUALS("", errout.str()); 2369 2370 check("void foo() {\n" // #7348 - cast 2371 " p = (::X*)malloc(42);\n" 2372 "}"); 2373 ASSERT_EQUALS("", errout.str()); 2374 2375 // #7182 "crash: CheckMemoryLeak::functionReturnType()" 2376 check("template<typename... Ts> auto unary_right_comma (Ts... ts) { return (ts , ...); }\n" 2377 "template<typename T, typename... Ts> auto binary_left_comma (T x, Ts... ts) { return (x , ... , ts); }\n" 2378 "int main() {\n" 2379 " unary_right_comma (a);\n" 2380 "}"); 2381 ASSERT_EQUALS("", errout.str()); 2382 } 2383 smartPointerFunctionParam()2384 void smartPointerFunctionParam() { 2385 check("void x() {\n" 2386 " f(shared_ptr<int>(new int(42)), g());\n" 2387 "}"); 2388 ASSERT_EQUALS("[test.cpp:2]: (warning, inconclusive) Unsafe allocation. If g() throws, memory could be leaked. Use make_shared<int>() instead.\n", errout.str()); 2389 2390 check("void x() {\n" 2391 " h(12, f(shared_ptr<int>(new int(42)), g()));\n" 2392 "}"); 2393 ASSERT_EQUALS("[test.cpp:2]: (warning, inconclusive) Unsafe allocation. If g() throws, memory could be leaked. Use make_shared<int>() instead.\n", errout.str()); 2394 2395 check("void x() {\n" 2396 " f(unique_ptr<int>(new int(42)), g());\n" 2397 "}"); 2398 ASSERT_EQUALS("[test.cpp:2]: (warning, inconclusive) Unsafe allocation. If g() throws, memory could be leaked. Use make_unique<int>() instead.\n", errout.str()); 2399 2400 check("void x() {\n" 2401 " f(g(), shared_ptr<int>(new int(42)));\n" 2402 "}"); 2403 ASSERT_EQUALS("[test.cpp:2]: (warning, inconclusive) Unsafe allocation. If g() throws, memory could be leaked. Use make_shared<int>() instead.\n", errout.str()); 2404 2405 check("void x() {\n" 2406 " f(g(), unique_ptr<int>(new int(42)));\n" 2407 "}"); 2408 ASSERT_EQUALS("[test.cpp:2]: (warning, inconclusive) Unsafe allocation. If g() throws, memory could be leaked. Use make_unique<int>() instead.\n", errout.str()); 2409 2410 check("void x() {\n" 2411 " f(shared_ptr<char>(new char), make_unique<int>(32));\n" 2412 "}"); 2413 ASSERT_EQUALS("[test.cpp:2]: (warning, inconclusive) Unsafe allocation. If make_unique<int>() throws, memory could be leaked. Use make_shared<char>() instead.\n", errout.str()); 2414 2415 check("void x() {\n" 2416 " f(g(124), h(\"test\", 234), shared_ptr<char>(new char));\n" 2417 "}"); 2418 ASSERT_EQUALS("[test.cpp:2]: (warning, inconclusive) Unsafe allocation. If h() throws, memory could be leaked. Use make_shared<char>() instead.\n", errout.str()); 2419 2420 check("void x() {\n" 2421 " f(shared_ptr<std::string>(new std::string(\"\")), g<std::string>());\n" 2422 "}"); 2423 ASSERT_EQUALS("[test.cpp:2]: (warning, inconclusive) Unsafe allocation. If g<std::string>() throws, memory could be leaked. Use make_shared<std::string>() instead.\n", errout.str()); 2424 2425 check("void g(int x) throw() { }\n" 2426 "void x() {\n" 2427 " f(g(124), shared_ptr<char>(new char));\n" 2428 "}"); 2429 ASSERT_EQUALS("", errout.str()); 2430 2431 check("void __declspec(nothrow) g(int x) { }\n" 2432 "void x() {\n" 2433 " f(g(124), shared_ptr<char>(new char));\n" 2434 "}"); 2435 ASSERT_EQUALS("", errout.str()); 2436 } resourceLeak()2437 void resourceLeak() { 2438 check("void foo() {\n" 2439 " fopen(\"file.txt\", \"r\");\n" 2440 "}"); 2441 ASSERT_EQUALS("[test.cpp:2]: (error) Return value of allocation function 'fopen' is not stored.\n", errout.str()); 2442 2443 check("void foo() {\n" 2444 " FILE f* = fopen(\"file.txt\", \"r\");\n" 2445 " freopen(\"file.txt\", \"r\", f);\n" 2446 "}"); 2447 ASSERT_EQUALS("[test.cpp:3]: (error) Return value of allocation function 'freopen' is not stored.\n", errout.str()); 2448 2449 check("void foo() {\n" 2450 " freopen(\"file.txt\", \"r\", stdin);\n" 2451 "}"); 2452 ASSERT_EQUALS("", errout.str()); 2453 2454 check("struct Holder {\n" 2455 " Holder(FILE* f) : file(f) {}\n" 2456 " ~Holder() { fclose(file); }\n" 2457 " FILE* file;\n" 2458 "};\n" 2459 "void foo() {\n" 2460 " Holder h ( fopen(\"file.txt\", \"r\"));\n" 2461 "}"); 2462 ASSERT_EQUALS("", errout.str()); 2463 2464 check("struct Holder {\n" 2465 " Holder(FILE* f) : file(f) {}\n" 2466 " ~Holder() { fclose(file); }\n" 2467 " FILE* file;\n" 2468 "};\n" 2469 "void foo() {\n" 2470 " Holder ( fopen(\"file.txt\", \"r\"));\n" 2471 "}"); 2472 ASSERT_EQUALS("", errout.str()); 2473 2474 check("struct Holder {\n" 2475 " Holder(FILE* f) : file(f) {}\n" 2476 " ~Holder() { fclose(file); }\n" 2477 " FILE* file;\n" 2478 "};\n" 2479 "void foo() {\n" 2480 " Holder h { fopen(\"file.txt\", \"r\")};\n" 2481 "}"); 2482 ASSERT_EQUALS("", errout.str()); 2483 2484 check("struct Holder {\n" 2485 " Holder(FILE* f) : file(f) {}\n" 2486 " ~Holder() { fclose(file); }\n" 2487 " FILE* file;\n" 2488 "};\n" 2489 "void foo() {\n" 2490 " Holder h = fopen(\"file.txt\", \"r\");\n" 2491 "}"); 2492 ASSERT_EQUALS("", errout.str()); 2493 2494 check("struct Holder {\n" 2495 " Holder(FILE* f) : file(f) {}\n" 2496 " ~Holder() { fclose(file); }\n" 2497 " FILE* file;\n" 2498 "};\n" 2499 "void foo() {\n" 2500 " Holder { fopen(\"file.txt\", \"r\")};\n" 2501 "}"); 2502 ASSERT_EQUALS("", errout.str()); 2503 2504 check("struct Holder {\n" 2505 " Holder(int i, FILE* f) : file(f) {}\n" 2506 " ~Holder() { fclose(file); }\n" 2507 " FILE* file;\n" 2508 "};\n" 2509 "void foo() {\n" 2510 " Holder { 0, fopen(\"file.txt\", \"r\")};\n" 2511 "}"); 2512 ASSERT_EQUALS("", errout.str()); 2513 } 2514 getAllocationType()2515 void getAllocationType() { 2516 // #7845 2517 check("class Thing { Thing(); };\n" 2518 "Thing * makeThing() { Thing *thing = new Thing; return thing; }\n" 2519 "\n" 2520 "void f() {\n" 2521 " makeThing();\n" 2522 "}"); 2523 ASSERT_EQUALS("", errout.str()); 2524 } 2525 }; 2526 REGISTER_TEST(TestMemleakNoVar) 2527 2528 2529