|
17 | 17 | */ |
18 | 18 |
|
19 | 19 | #include "checknullpointer.h" |
| 20 | +#include "checkuninitvar.h" |
20 | 21 | #include "library.h" |
21 | 22 | #include "settings.h" |
22 | 23 | #include "testsuite.h" |
@@ -105,6 +106,7 @@ class TestNullPointer : public TestFixture { |
105 | 106 | TEST_CASE(nullpointer_internal_error); // #5080 |
106 | 107 | TEST_CASE(ticket6505); |
107 | 108 | TEST_CASE(subtract); |
| 109 | + TEST_CASE(ctu); |
108 | 110 | } |
109 | 111 |
|
110 | 112 | void check(const char code[], bool inconclusive = false, const char filename[] = "test.cpp") { |
@@ -2572,6 +2574,67 @@ class TestNullPointer : public TestFixture { |
2572 | 2574 | "}\n"); |
2573 | 2575 | ASSERT_EQUALS("[test.cpp:3] -> [test.cpp:2]: (warning) Either the condition '!s' is redundant or there is overflow in pointer subtraction.\n", errout.str()); |
2574 | 2576 | } |
| 2577 | + |
| 2578 | + void ctu(const char code[]) { |
| 2579 | + // Clear the error buffer.. |
| 2580 | + errout.str(""); |
| 2581 | + |
| 2582 | + // Tokenize.. |
| 2583 | + Tokenizer tokenizer(&settings, this); |
| 2584 | + std::istringstream istr(code); |
| 2585 | + tokenizer.tokenize(istr, "test.cpp"); |
| 2586 | + tokenizer.simplifyTokenList2(); |
| 2587 | + |
| 2588 | + // Check code.. |
| 2589 | + std::list<Check::FileInfo*> fileInfo; |
| 2590 | + CheckUninitVar check(&tokenizer, &settings, this); |
| 2591 | + fileInfo.push_back(check.getFileInfo(&tokenizer, &settings)); |
| 2592 | + check.analyseWholeProgram(fileInfo, settings, *this); |
| 2593 | + while (!fileInfo.empty()) { |
| 2594 | + delete fileInfo.back(); |
| 2595 | + fileInfo.pop_back(); |
| 2596 | + } |
| 2597 | + } |
| 2598 | + |
| 2599 | + void ctu() { |
| 2600 | + ctu("void f(int *fp) {\n" |
| 2601 | + " a = *fp;\n" |
| 2602 | + "}\n" |
| 2603 | + "int main() {\n" |
| 2604 | + " int *p = 0;\n" |
| 2605 | + " f(p);\n" |
| 2606 | + "}"); |
| 2607 | + ASSERT_EQUALS("[test.cpp:6] -> [test.cpp:2]: (error) Null pointer dereference: fp\n", errout.str()); |
| 2608 | + |
| 2609 | + ctu("void use(int *p) { a = *p + 3; }\n" |
| 2610 | + "void call(int x, int *p) { x++; use(p); }\n" |
| 2611 | + "int main() {\n" |
| 2612 | + " call(4,0);\n" |
| 2613 | + "}"); |
| 2614 | + ASSERT_EQUALS("[test.cpp:2] -> [test.cpp:1]: (error) Null pointer dereference: p\n", errout.str()); |
| 2615 | + |
| 2616 | + ctu("void dostuff(int *x, int *y) {\n" |
| 2617 | + " if (!var)\n" |
| 2618 | + " return -1;\n" // <- early return |
| 2619 | + " *x = *y;\n" |
| 2620 | + "}\n" |
| 2621 | + "\n" |
| 2622 | + "void f() {\n" |
| 2623 | + " dostuff(a, 0);\n" |
| 2624 | + "}"); |
| 2625 | + ASSERT_EQUALS("", errout.str()); |
| 2626 | + |
| 2627 | + ctu("void dostuff(int *x, int *y) {\n" |
| 2628 | + " if (cond)\n" |
| 2629 | + " *y = -1;\n" // <- conditionally written |
| 2630 | + " *x = *y;\n" |
| 2631 | + "}\n" |
| 2632 | + "\n" |
| 2633 | + "void f() {\n" |
| 2634 | + " dostuff(a, 0);\n" |
| 2635 | + "}"); |
| 2636 | + ASSERT_EQUALS("", errout.str()); |
| 2637 | + } |
2575 | 2638 | }; |
2576 | 2639 |
|
2577 | 2640 | REGISTER_TEST(TestNullPointer) |
0 commit comments