Skip to content

Commit 02dec63

Browse files
committed
Revert "Preprocessor: removed unreachable ConfigurationNotChecked finding (danmar#4790)" [skip ci]
This reverts commit 3813616.
1 parent 83664f5 commit 02dec63

File tree

3 files changed

+85
-0
lines changed

3 files changed

+85
-0
lines changed

lib/preprocessor.cpp

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -912,6 +912,10 @@ simplecpp::TokenList Preprocessor::preprocess(const std::string &cfg, std::vecto
912912

913913
tokens2.removeComments();
914914

915+
// ensure that guessed define macros without value are not used in the code
916+
if (!validateCfg(cfg, macroUsage))
917+
return simplecpp::TokenList(files);
918+
915919
return tokens2;
916920
}
917921

@@ -1059,6 +1063,44 @@ void Preprocessor::invalidSuppression(const simplecpp::Location& loc, const std:
10591063
error(loc, msg, "invalidSuppression");
10601064
}
10611065

1066+
bool Preprocessor::validateCfg(const std::string &cfg, const std::list<simplecpp::MacroUsage> &macroUsageList)
1067+
{
1068+
bool ret = true;
1069+
std::list<std::string> defines;
1070+
splitcfg(cfg, defines, emptyString);
1071+
for (const std::string &define : defines) {
1072+
if (define.find('=') != std::string::npos)
1073+
continue;
1074+
const std::string macroName(define.substr(0, define.find('(')));
1075+
for (const simplecpp::MacroUsage &mu : macroUsageList) {
1076+
if (mu.macroValueKnown)
1077+
continue;
1078+
if (mu.macroName != macroName)
1079+
continue;
1080+
const bool directiveLocation = std::any_of(mDirectives.cbegin(), mDirectives.cend(),
1081+
[=](const Directive &dir) {
1082+
return mu.useLocation.file() == dir.file && mu.useLocation.line == dir.linenr;
1083+
});
1084+
1085+
if (!directiveLocation) {
1086+
if (mSettings.severity.isEnabled(Severity::information))
1087+
validateCfgError(mu.useLocation.file(), mu.useLocation.line, cfg, macroName);
1088+
ret = false;
1089+
}
1090+
}
1091+
}
1092+
1093+
return ret;
1094+
}
1095+
1096+
void Preprocessor::validateCfgError(const std::string &file, const unsigned int line, const std::string &cfg, const std::string &macro)
1097+
{
1098+
const std::string id = "ConfigurationNotChecked";
1099+
ErrorMessage::FileLocation loc(file, line, 0);
1100+
const ErrorMessage errmsg({std::move(loc)}, mFile0, Severity::information, "Skipping configuration '" + cfg + "' since the value of '" + macro + "' is unknown. Use -D if you want to check it. You can use -U to skip it explicitly.", id, Certainty::normal);
1101+
mErrorLogger->reportInfo(errmsg);
1102+
}
1103+
10621104
void Preprocessor::getErrorMessages(ErrorLogger &errorLogger, const Settings &settings)
10631105
{
10641106
std::vector<std::string> files;
@@ -1069,6 +1111,7 @@ void Preprocessor::getErrorMessages(ErrorLogger &errorLogger, const Settings &se
10691111
loc.col = 2;
10701112
preprocessor.missingInclude(loc, "", UserHeader);
10711113
preprocessor.missingInclude(loc, "", SystemHeader);
1114+
preprocessor.validateCfgError("", 1, "X", "X");
10721115
preprocessor.error(loc, "message", simplecpp::Output::ERROR);
10731116
preprocessor.error(loc, "message", simplecpp::Output::SYNTAX_ERROR);
10741117
preprocessor.error(loc, "message", simplecpp::Output::UNHANDLED_CHAR_ERROR);

lib/preprocessor.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,15 @@ class CPPCHECKLIB WARN_UNUSED Preprocessor {
122122

123123
std::string getcode(const std::string &cfg, std::vector<std::string> &files, bool writeLocations);
124124

125+
/**
126+
* make sure empty configuration macros are not used in code. the given code must be a single configuration
127+
* @param cfg configuration
128+
* @param macroUsageList macro usage list
129+
* @return true => configuration is valid
130+
*/
131+
bool validateCfg(const std::string &cfg, const std::list<simplecpp::MacroUsage> &macroUsageList);
132+
void validateCfgError(const std::string &file, const unsigned int line, const std::string &cfg, const std::string &macro);
133+
125134
/**
126135
* Calculate HASH. Using toolinfo, tokens1, filedata.
127136
*

test/testpreprocessor.cpp

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -340,6 +340,9 @@ class TestPreprocessor : public TestFixture {
340340
TEST_CASE(getConfigsU6);
341341
TEST_CASE(getConfigsU7);
342342

343+
TEST_CASE(validateCfg1);
344+
TEST_CASE(validateCfg2);
345+
343346
TEST_CASE(getConfigsAndCodeIssue14317);
344347
TEST_CASE(getConfigsMostGeneralConfigIssue14317);
345348

@@ -2668,6 +2671,36 @@ class TestPreprocessor : public TestFixture {
26682671
ASSERT_EQUALS("\nY\n", getConfigsStr(code, "-DX"));
26692672
}
26702673

2674+
void validateCfg1() {
2675+
Preprocessor preprocessor(settings0, this);
2676+
2677+
std::vector<std::string> files(1, "test.c");
2678+
simplecpp::MacroUsage macroUsage(files, false);
2679+
macroUsage.useLocation.fileIndex = 0;
2680+
macroUsage.useLocation.line = 1;
2681+
macroUsage.macroName = "X";
2682+
std::list<simplecpp::MacroUsage> macroUsageList(1, macroUsage);
2683+
2684+
ASSERT_EQUALS(true, preprocessor.validateCfg("", macroUsageList));
2685+
ASSERT_EQUALS(false, preprocessor.validateCfg("X",macroUsageList));
2686+
ASSERT_EQUALS(false, preprocessor.validateCfg("A=42;X", macroUsageList));
2687+
ASSERT_EQUALS(true, preprocessor.validateCfg("X=1", macroUsageList));
2688+
ASSERT_EQUALS(true, preprocessor.validateCfg("Y", macroUsageList));
2689+
2690+
macroUsageList.front().macroValueKnown = true; // #8404
2691+
ASSERT_EQUALS(true, preprocessor.validateCfg("X", macroUsageList));
2692+
}
2693+
2694+
void validateCfg2() {
2695+
const char filedata[] = "#ifdef ABC\n"
2696+
"#endif\n"
2697+
"int i = ABC;";
2698+
2699+
std::map<std::string, std::string> actual;
2700+
preprocess(filedata, actual, "file.cpp");
2701+
ASSERT_EQUALS("[file.cpp:3]: (information) Skipping configuration 'ABC' since the value of 'ABC' is unknown. Use -D if you want to check it. You can use -U to skip it explicitly.\n", errout.str());
2702+
}
2703+
26712704
void getConfigsAndCodeIssue14317() {
26722705
const char filedata[] = "bool test() {\n"
26732706
"return\n"

0 commit comments

Comments
 (0)