Skip to content

Commit c363207

Browse files
authored
some missingInclude/missingIncludeSystem fixes and tests (#4027)
* do not emit `missingInclude` and `missingIncludeSystem` errors when not enabled / fixed and improved TestPreprocessor::inline_suppression_for_missing_include() * testpreprocessor.cpp: added missing tests for `missingInclude` and `missingIncludeSystem` * cppcheckexecutor.cpp: `missingIncludeSystem` was not emitted in normal analysis if `missingInclude` existed * dmake * added `run-dmake` as `testrunner` dependency
1 parent 4587178 commit c363207

File tree

5 files changed

+117
-13
lines changed

5 files changed

+117
-13
lines changed

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -695,7 +695,7 @@ test/testplatform.o: test/testplatform.cpp externals/tinyxml2/tinyxml2.h lib/col
695695
test/testpostfixoperator.o: test/testpostfixoperator.cpp lib/check.h lib/checkpostfixoperator.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/importproject.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/standards.h lib/suppressions.h lib/templatesimplifier.h lib/timer.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/valueflow.h test/testsuite.h
696696
$(CXX) ${INCLUDE_FOR_TEST} $(CPPFLAGS) $(CPPFILESDIR) $(CXXFLAGS) $(UNDEF_STRICT_ANSI) -c -o test/testpostfixoperator.o test/testpostfixoperator.cpp
697697

698-
test/testpreprocessor.o: test/testpreprocessor.cpp externals/simplecpp/simplecpp.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/importproject.h lib/library.h lib/mathlib.h lib/platform.h lib/preprocessor.h lib/settings.h lib/standards.h lib/suppressions.h lib/timer.h lib/utils.h test/testsuite.h
698+
test/testpreprocessor.o: test/testpreprocessor.cpp externals/simplecpp/simplecpp.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/importproject.h lib/library.h lib/mathlib.h lib/platform.h lib/preprocessor.h lib/settings.h lib/standards.h lib/suppressions.h lib/templatesimplifier.h lib/timer.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/valueflow.h test/testsuite.h test/testutils.h
699699
$(CXX) ${INCLUDE_FOR_TEST} $(CPPFLAGS) $(CPPFILESDIR) $(CXXFLAGS) $(UNDEF_STRICT_ANSI) -c -o test/testpreprocessor.o test/testpreprocessor.cpp
700700

701701
test/testprocessexecutor.o: test/testprocessexecutor.cpp cli/executor.h cli/processexecutor.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/importproject.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/standards.h lib/suppressions.h lib/templatesimplifier.h lib/timer.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/valueflow.h test/testsuite.h test/testutils.h

cli/cppcheckexecutor.cpp

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1018,9 +1018,16 @@ int CppCheckExecutor::check_internal(CppCheck& cppcheck)
10181018
"files are found. Please check your project's include directories and add all of them "
10191019
"as include directories for Cppcheck. To see what files Cppcheck cannot find use "
10201020
"--check-config.",
1021-
Preprocessor::missingIncludeFlag ? "missingInclude" : "missingIncludeSystem",
1021+
"",
10221022
Certainty::normal);
1023-
reportInfo(msg);
1023+
if (Preprocessor::missingIncludeFlag) {
1024+
msg.id = "missingInclude";
1025+
reportInfo(msg);
1026+
}
1027+
if (Preprocessor::missingSystemIncludeFlag) {
1028+
msg.id = "missingIncludeSystem";
1029+
reportInfo(msg);
1030+
}
10241031
}
10251032
}
10261033

lib/preprocessor.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -840,6 +840,9 @@ void Preprocessor::error(const std::string &filename, unsigned int linenr, const
840840
// Report that include is missing
841841
void Preprocessor::missingInclude(const std::string &filename, unsigned int linenr, const std::string &header, HeaderTypes headerType)
842842
{
843+
if (!mSettings.checks.isEnabled(Checks::missingInclude) && !mSettings.checkConfiguration)
844+
return;
845+
843846
const std::string fname = Path::fromNativeSeparators(filename);
844847
Suppressions::ErrorMessage errorMessage;
845848
errorMessage.errorId = "missingInclude";
@@ -855,6 +858,7 @@ void Preprocessor::missingInclude(const std::string &filename, unsigned int line
855858
missingSystemIncludeFlag = true;
856859
else
857860
missingIncludeFlag = true;
861+
858862
if (mErrorLogger && mSettings.checkConfiguration) {
859863

860864
std::list<ErrorMessage::FileLocation> locationList;

test/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ if (BUILD_TESTS)
3333

3434
add_dependencies(testrunner copy_cfg)
3535
add_dependencies(testrunner copy_addons)
36+
add_dependencies(testrunner run-dmake)
3637

3738
if (LIBXML2_XMLLINT_EXECUTABLE)
3839
# TODO: run the CMake implementation of the tests

test/testpreprocessor.cpp

Lines changed: 102 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
#include "preprocessor.h"
2626
#include "settings.h"
2727
#include "testsuite.h"
28+
#include "testutils.h"
2829

2930
#include <atomic>
3031
#include <cstring>
@@ -200,8 +201,9 @@ class TestPreprocessor : public TestFixture {
200201
TEST_CASE(invalid_define_1); // #2605 - hang for: '#define ='
201202
TEST_CASE(invalid_define_2); // #4036 - hang for: '#define () {(int f(x) }'
202203

203-
// inline suppression, missingInclude
204+
// inline suppression, missingInclude/missingIncludeSystem
204205
TEST_CASE(inline_suppression_for_missing_include);
206+
TEST_CASE(inline_suppression_for_missing_include_check_config);
205207

206208
// Using -D to predefine symbols
207209
TEST_CASE(predefine1);
@@ -254,6 +256,9 @@ class TestPreprocessor : public TestFixture {
254256
TEST_CASE(testDirectiveIncludeTypes);
255257
TEST_CASE(testDirectiveIncludeLocations);
256258
TEST_CASE(testDirectiveIncludeComments);
259+
260+
TEST_CASE(testMissingInclude);
261+
TEST_CASE(testMissingIncludeCheckConfig);
257262
}
258263

259264
void preprocess(const char* code, std::map<std::string, std::string>& actual, const char filename[] = "file.c") {
@@ -1931,25 +1936,55 @@ class TestPreprocessor : public TestFixture {
19311936
preprocess("#define () {(int f(x) }\n", actual); // don't hang
19321937
}
19331938

1934-
void inline_suppression_for_missing_include() {
1939+
void inline_suppression_for_missing_include_internal(bool checkConfig) {
19351940
Preprocessor::missingIncludeFlag = false;
1941+
Preprocessor::missingSystemIncludeFlag = false;
19361942
Settings settings;
1943+
settings.checkConfiguration = checkConfig;
19371944
settings.inlineSuppressions = true;
1938-
settings.severity.fill();
1945+
settings.severity.clear();
1946+
// --check-config needs to report this regardless of the emanled checks
1947+
if (!checkConfig)
1948+
settings.checks.enable(Checks::missingInclude);
19391949
Preprocessor preprocessor(settings, this);
19401950

1941-
std::istringstream src("// cppcheck-suppress missingInclude\n"
1951+
const std::string code("// cppcheck-suppress missingInclude\n"
19421952
"#include \"missing.h\"\n"
1943-
"int x;");
1944-
std::string processedFile;
1945-
std::list<std::string> cfg;
1946-
std::list<std::string> paths;
1947-
1953+
"// cppcheck-suppress missingIncludeSystem\n"
1954+
"#include <missing2.h>\n");
19481955
// Don't report that the include is missing
19491956
errout.str("");
1950-
preprocessor.preprocess(src, processedFile, cfg, "test.c", paths);
1957+
preprocessor.getcode(code, "", "test.c");
19511958
ASSERT_EQUALS("", errout.str());
19521959
ASSERT_EQUALS(false, Preprocessor::missingIncludeFlag);
1960+
ASSERT_EQUALS(false, Preprocessor::missingSystemIncludeFlag);
1961+
1962+
auto suppressions = settings.nomsg.getSuppressions();
1963+
ASSERT_EQUALS(2, suppressions.size());
1964+
1965+
auto suppr = suppressions.front();
1966+
suppressions.pop_front();
1967+
ASSERT_EQUALS("missingInclude", suppr.errorId);
1968+
ASSERT_EQUALS("test.c", suppr.fileName);
1969+
ASSERT_EQUALS(2, suppr.lineNumber);
1970+
ASSERT_EQUALS(true, suppr.checked);
1971+
ASSERT_EQUALS(true, suppr.matched);
1972+
1973+
suppr = suppressions.front();
1974+
suppressions.pop_front();
1975+
ASSERT_EQUALS("missingIncludeSystem", suppr.errorId);
1976+
ASSERT_EQUALS("test.c", suppr.fileName);
1977+
ASSERT_EQUALS(4, suppr.lineNumber);
1978+
ASSERT_EQUALS(true, suppr.checked);
1979+
ASSERT_EQUALS(true, suppr.matched);
1980+
}
1981+
1982+
void inline_suppression_for_missing_include() {
1983+
inline_suppression_for_missing_include_internal(false);
1984+
}
1985+
1986+
void inline_suppression_for_missing_include_check_config() {
1987+
inline_suppression_for_missing_include_internal(true);
19531988
}
19541989

19551990
void predefine1() {
@@ -2395,6 +2430,63 @@ class TestPreprocessor : public TestFixture {
23952430
preprocessor.dump(ostr);
23962431
ASSERT_EQUALS(dumpdata, ostr.str());
23972432
}
2433+
2434+
void testMissingInclude() {
2435+
Preprocessor::missingIncludeFlag = false;
2436+
Preprocessor::missingSystemIncludeFlag = false;
2437+
2438+
Settings settings;
2439+
settings.severity.clear();
2440+
settings.checks.enable(Checks::missingInclude);
2441+
Preprocessor preprocessor(settings, this);
2442+
2443+
ScopedFile header("header.h", "");
2444+
ScopedFile header2("header2.h", "");
2445+
2446+
std::string code("#include \"missing.h\"\n"
2447+
"#include <header.h>\n"
2448+
"#include <missing2.h>\n"
2449+
"#include \"header2.h\"");
2450+
errout.str("");
2451+
preprocessor.getcode(code, "", "test.c");
2452+
ASSERT_EQUALS(true, Preprocessor::missingIncludeFlag);
2453+
ASSERT_EQUALS(true, Preprocessor::missingSystemIncludeFlag);
2454+
2455+
// the expected messages are emited outside of the Preprocessor
2456+
ASSERT_EQUALS("", errout.str());
2457+
2458+
Preprocessor::missingIncludeFlag = false;
2459+
Preprocessor::missingSystemIncludeFlag = false;
2460+
}
2461+
2462+
void testMissingIncludeCheckConfig() {
2463+
Preprocessor::missingIncludeFlag = false;
2464+
Preprocessor::missingSystemIncludeFlag = false;
2465+
2466+
Settings settings;
2467+
settings.checkConfiguration = true;
2468+
settings.severity.clear();
2469+
// needs to be reported regardless of enabled checks
2470+
Preprocessor preprocessor(settings, this);
2471+
2472+
ScopedFile header("header.h", "");
2473+
ScopedFile header2("header2.h", "");
2474+
2475+
std::string code("#include \"missing.h\"\n"
2476+
"#include <header.h>\n"
2477+
"#include <missing2.h>\n"
2478+
"#include \"header2.h\"");
2479+
errout.str("");
2480+
preprocessor.getcode(code, "", "test.c");
2481+
ASSERT_EQUALS(true, Preprocessor::missingIncludeFlag);
2482+
ASSERT_EQUALS(true, Preprocessor::missingSystemIncludeFlag);
2483+
2484+
ASSERT_EQUALS("[test.c:1]: (information) Include file: \"missing.h\" not found.\n"
2485+
"[test.c:3]: (information) Include file: <missing2.h> not found. Please note: Cppcheck does not need standard library headers to get proper results.\n", errout.str());
2486+
2487+
Preprocessor::missingIncludeFlag = false;
2488+
Preprocessor::missingSystemIncludeFlag = false;
2489+
}
23982490
};
23992491

24002492
REGISTER_TEST(TestPreprocessor)

0 commit comments

Comments
 (0)