diff --git a/lib/preprocessor.cpp b/lib/preprocessor.cpp index 901dc57cffe..ecd3aa02709 100644 --- a/lib/preprocessor.cpp +++ b/lib/preprocessor.cpp @@ -721,13 +721,18 @@ static simplecpp::DUI createDUI(const Settings &mSettings, const std::string &cf dui.undefined = mSettings.userUndefs; // -U dui.includePaths = mSettings.includePaths; // -I dui.includes = mSettings.userIncludes; // --include - // TODO: use mSettings.standards.stdValue instead if (lang == Standards::Language::CPP) { - dui.std = mSettings.standards.getCPP(); + dui.std = mSettings.standards.stdValueCPP; + if (dui.std.empty()) { + dui.std = mSettings.standards.getCPP(); + } splitcfg(mSettings.platform.getLimitsDefines(Standards::getCPP(dui.std)), dui.defines, ""); } else if (lang == Standards::Language::C) { - dui.std = mSettings.standards.getC(); + dui.std = mSettings.standards.stdValueC; + if (dui.std.empty()) { + dui.std = mSettings.standards.getC(); + } splitcfg(mSettings.platform.getLimitsDefines(Standards::getC(dui.std)), dui.defines, ""); } dui.clearIncludeCache = mSettings.clearIncludeCache; diff --git a/test/testpreprocessor.cpp b/test/testpreprocessor.cpp index 91caca5b8af..f5a6798d834 100644 --- a/test/testpreprocessor.cpp +++ b/test/testpreprocessor.cpp @@ -238,6 +238,9 @@ class TestPreprocessor : public TestFixture { TEST_CASE(predefine5); // automatically define __cplusplus TEST_CASE(predefine6); // automatically define __STDC_VERSION__ + + TEST_CASE(strictAnsi); + TEST_CASE(invalidElIf); // #2942 segfault // Preprocessor::getConfigs @@ -289,6 +292,8 @@ class TestPreprocessor : public TestFixture { TEST_CASE(testMissingIncludeMixed); TEST_CASE(testMissingIncludeCheckConfig); + TEST_CASE(hasInclude); + TEST_CASE(limitsDefines); TEST_CASE(hashCalculation); @@ -2036,6 +2041,23 @@ class TestPreprocessor : public TestFixture { ASSERT_EQUALS("", PreprocessorHelper::getcode(settings0, *this, code, "", "test.cpp")); } + void strictAnsi() { + const char code[] = "#ifdef __STRICT_ANSI__\n123\n#endif"; + Settings settings; + + settings.standards.setStd("gnu99"); + ASSERT_EQUALS("", PreprocessorHelper::getcode(settings, *this, code, "", "test.c")); + + settings.standards.setStd("c99"); + ASSERT_EQUALS("\n123", PreprocessorHelper::getcode(settings, *this, code, "", "test.c")); + + settings.standards.setStd("gnu++11"); + ASSERT_EQUALS("", PreprocessorHelper::getcode(settings, *this, code, "", "test.cpp")); + + settings.standards.setStd("c++11"); + ASSERT_EQUALS("\n123", PreprocessorHelper::getcode(settings, *this, code, "", "test.cpp")); + } + void invalidElIf() { // #2942 - segfault const char code[] = "#elif (){\n"; @@ -2547,6 +2569,23 @@ class TestPreprocessor : public TestFixture { "test.c:11:0: information: Include file: <" + missing4 + "> not found. Please note: Cppcheck does not need standard library headers to get proper results. [missingIncludeSystem]\n", errout_str()); } + void hasInclude() { + const char code[] = "#if __has_include()\n123\n#endif"; + Settings settings; + + settings.standards.setStd("c++11"); + ASSERT_EQUALS("", PreprocessorHelper::getcode(settings, *this, code, "", "test.cpp")); + ASSERT_EQUALS("[test.cpp:1:0]: (error) failed to evaluate #if condition, division/modulo by zero [preprocessorErrorDirective]\n", errout_str()); + + settings.standards.setStd("c++17"); + ASSERT_EQUALS("", PreprocessorHelper::getcode(settings, *this, code, "", "test.cpp")); + ASSERT_EQUALS("", errout_str()); + + settings.standards.setStd("gnu++11"); + ASSERT_EQUALS("", PreprocessorHelper::getcode(settings, *this, code, "", "test.cpp")); + ASSERT_EQUALS("", errout_str()); + } + void limitsDefines() { // #11928 / #10045 const char code[] = "void f(long l) {\n"