|
22 | 22 | #include "config.h" |
23 | 23 | #include "ctu.h" |
24 | 24 | #include "library.h" |
| 25 | +#include "preprocessor.h" |
25 | 26 | #include "settings.h" |
26 | 27 | #include "testsuite.h" |
27 | 28 | #include "tokenize.h" |
28 | 29 |
|
29 | | -#include <tinyxml2.h> |
30 | 30 | #include <list> |
| 31 | +#include <simplecpp.h> |
31 | 32 | #include <string> |
32 | | - |
| 33 | +#include <tinyxml2.h> |
33 | 34 |
|
34 | 35 | class TestBufferOverrun : public TestFixture { |
35 | 36 | public: |
@@ -67,6 +68,45 @@ class TestBufferOverrun : public TestFixture { |
67 | 68 | checkBufferOverrun.runChecks(&tokenizer, &settings, this); |
68 | 69 | } |
69 | 70 |
|
| 71 | + void checkP(const char code[], const char* filename = "test.cpp") |
| 72 | + { |
| 73 | + // Clear the error buffer.. |
| 74 | + errout.str(""); |
| 75 | + |
| 76 | + Settings* settings = &settings0; |
| 77 | + settings->severity.enable(Severity::style); |
| 78 | + settings->severity.enable(Severity::warning); |
| 79 | + settings->severity.enable(Severity::portability); |
| 80 | + settings->severity.enable(Severity::performance); |
| 81 | + settings->standards.c = Standards::CLatest; |
| 82 | + settings->standards.cpp = Standards::CPPLatest; |
| 83 | + settings->certainty.enable(Certainty::inconclusive); |
| 84 | + settings->certainty.disable(Certainty::experimental); |
| 85 | + |
| 86 | + // Raw tokens.. |
| 87 | + std::vector<std::string> files(1, filename); |
| 88 | + std::istringstream istr(code); |
| 89 | + const simplecpp::TokenList tokens1(istr, files, files[0]); |
| 90 | + |
| 91 | + // Preprocess.. |
| 92 | + simplecpp::TokenList tokens2(files); |
| 93 | + std::map<std::string, simplecpp::TokenList*> filedata; |
| 94 | + simplecpp::preprocess(tokens2, tokens1, files, filedata, simplecpp::DUI()); |
| 95 | + |
| 96 | + Preprocessor preprocessor(*settings, nullptr); |
| 97 | + preprocessor.setDirectives(tokens1); |
| 98 | + |
| 99 | + // Tokenizer.. |
| 100 | + Tokenizer tokenizer(settings, this); |
| 101 | + tokenizer.createTokens(std::move(tokens2)); |
| 102 | + tokenizer.simplifyTokens1(""); |
| 103 | + tokenizer.setPreprocessor(&preprocessor); |
| 104 | + |
| 105 | + // Check for buffer overruns.. |
| 106 | + CheckBufferOverrun checkBufferOverrun(&tokenizer, settings, this); |
| 107 | + checkBufferOverrun.runChecks(&tokenizer, settings, this); |
| 108 | + } |
| 109 | + |
70 | 110 | void run() OVERRIDE { |
71 | 111 | LOAD_LIB_2(settings0.library, "std.cfg"); |
72 | 112 |
|
@@ -136,6 +176,7 @@ class TestBufferOverrun : public TestFixture { |
136 | 176 | TEST_CASE(array_index_57); // #10023 |
137 | 177 | TEST_CASE(array_index_58); // #7524 |
138 | 178 | TEST_CASE(array_index_59); // #10413 |
| 179 | + TEST_CASE(array_index_60); // #10617, #9824 |
139 | 180 | TEST_CASE(array_index_multidim); |
140 | 181 | TEST_CASE(array_index_switch_in_for); |
141 | 182 | TEST_CASE(array_index_for_in_for); // FP: #2634 |
@@ -1665,6 +1706,29 @@ class TestBufferOverrun : public TestFixture { |
1665 | 1706 | ASSERT_EQUALS("", errout.str()); |
1666 | 1707 | } |
1667 | 1708 |
|
| 1709 | + void array_index_60() |
| 1710 | + { |
| 1711 | + checkP("#define CKR(B) if (!(B)) { return -1; }\n" |
| 1712 | + "int f(int i) {\n" |
| 1713 | + " const int A[3] = {};\n" |
| 1714 | + " CKR(i < 3);\n" |
| 1715 | + " if (i > 0)\n" |
| 1716 | + " i = A[i];\n" |
| 1717 | + " return i;\n" |
| 1718 | + "}\n"); |
| 1719 | + ASSERT_EQUALS("", errout.str()); |
| 1720 | + |
| 1721 | + checkP("#define ASSERT(expression, action) if (expression) {action;}\n" |
| 1722 | + "int array[5];\n" |
| 1723 | + "void func (int index) {\n" |
| 1724 | + " ASSERT(index > 5, return);\n" |
| 1725 | + " array[index]++;\n" |
| 1726 | + "}\n"); |
| 1727 | + ASSERT_EQUALS( |
| 1728 | + "[test.cpp:4] -> [test.cpp:5]: (warning) Either the condition 'index>5' is redundant or the array 'array[5]' is accessed at index 5, which is out of bounds.\n", |
| 1729 | + errout.str()); |
| 1730 | + } |
| 1731 | + |
1668 | 1732 | void array_index_multidim() { |
1669 | 1733 | check("void f()\n" |
1670 | 1734 | "{\n" |
|
0 commit comments