Skip to content

Commit c8d2b2b

Browse files
authored
fix #14015: Syntax error for __has_include with --std=gnu99 (danmar#7670)
1 parent 74d1ca4 commit c8d2b2b

File tree

2 files changed

+47
-3
lines changed

2 files changed

+47
-3
lines changed

lib/preprocessor.cpp

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -721,13 +721,18 @@ static simplecpp::DUI createDUI(const Settings &mSettings, const std::string &cf
721721
dui.undefined = mSettings.userUndefs; // -U
722722
dui.includePaths = mSettings.includePaths; // -I
723723
dui.includes = mSettings.userIncludes; // --include
724-
// TODO: use mSettings.standards.stdValue instead
725724
if (lang == Standards::Language::CPP) {
726-
dui.std = mSettings.standards.getCPP();
725+
dui.std = mSettings.standards.stdValueCPP;
726+
if (dui.std.empty()) {
727+
dui.std = mSettings.standards.getCPP();
728+
}
727729
splitcfg(mSettings.platform.getLimitsDefines(Standards::getCPP(dui.std)), dui.defines, "");
728730
}
729731
else if (lang == Standards::Language::C) {
730-
dui.std = mSettings.standards.getC();
732+
dui.std = mSettings.standards.stdValueC;
733+
if (dui.std.empty()) {
734+
dui.std = mSettings.standards.getC();
735+
}
731736
splitcfg(mSettings.platform.getLimitsDefines(Standards::getC(dui.std)), dui.defines, "");
732737
}
733738
dui.clearIncludeCache = mSettings.clearIncludeCache;

test/testpreprocessor.cpp

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -238,6 +238,9 @@ class TestPreprocessor : public TestFixture {
238238
TEST_CASE(predefine5); // automatically define __cplusplus
239239
TEST_CASE(predefine6); // automatically define __STDC_VERSION__
240240

241+
242+
TEST_CASE(strictAnsi);
243+
241244
TEST_CASE(invalidElIf); // #2942 segfault
242245

243246
// Preprocessor::getConfigs
@@ -289,6 +292,8 @@ class TestPreprocessor : public TestFixture {
289292
TEST_CASE(testMissingIncludeMixed);
290293
TEST_CASE(testMissingIncludeCheckConfig);
291294

295+
TEST_CASE(hasInclude);
296+
292297
TEST_CASE(limitsDefines);
293298

294299
TEST_CASE(hashCalculation);
@@ -2036,6 +2041,23 @@ class TestPreprocessor : public TestFixture {
20362041
ASSERT_EQUALS("", PreprocessorHelper::getcode(settings0, *this, code, "", "test.cpp"));
20372042
}
20382043

2044+
void strictAnsi() {
2045+
const char code[] = "#ifdef __STRICT_ANSI__\n123\n#endif";
2046+
Settings settings;
2047+
2048+
settings.standards.setStd("gnu99");
2049+
ASSERT_EQUALS("", PreprocessorHelper::getcode(settings, *this, code, "", "test.c"));
2050+
2051+
settings.standards.setStd("c99");
2052+
ASSERT_EQUALS("\n123", PreprocessorHelper::getcode(settings, *this, code, "", "test.c"));
2053+
2054+
settings.standards.setStd("gnu++11");
2055+
ASSERT_EQUALS("", PreprocessorHelper::getcode(settings, *this, code, "", "test.cpp"));
2056+
2057+
settings.standards.setStd("c++11");
2058+
ASSERT_EQUALS("\n123", PreprocessorHelper::getcode(settings, *this, code, "", "test.cpp"));
2059+
}
2060+
20392061
void invalidElIf() {
20402062
// #2942 - segfault
20412063
const char code[] = "#elif (){\n";
@@ -2547,6 +2569,23 @@ class TestPreprocessor : public TestFixture {
25472569
"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());
25482570
}
25492571

2572+
void hasInclude() {
2573+
const char code[] = "#if __has_include(<directory/non-existent-header.h>)\n123\n#endif";
2574+
Settings settings;
2575+
2576+
settings.standards.setStd("c++11");
2577+
ASSERT_EQUALS("", PreprocessorHelper::getcode(settings, *this, code, "", "test.cpp"));
2578+
ASSERT_EQUALS("[test.cpp:1:0]: (error) failed to evaluate #if condition, division/modulo by zero [preprocessorErrorDirective]\n", errout_str());
2579+
2580+
settings.standards.setStd("c++17");
2581+
ASSERT_EQUALS("", PreprocessorHelper::getcode(settings, *this, code, "", "test.cpp"));
2582+
ASSERT_EQUALS("", errout_str());
2583+
2584+
settings.standards.setStd("gnu++11");
2585+
ASSERT_EQUALS("", PreprocessorHelper::getcode(settings, *this, code, "", "test.cpp"));
2586+
ASSERT_EQUALS("", errout_str());
2587+
}
2588+
25502589
void limitsDefines() {
25512590
// #11928 / #10045
25522591
const char code[] = "void f(long l) {\n"

0 commit comments

Comments
 (0)