Fixed #3699 (cppcheck hangs with 100% cpu load on parsing preprocessor code)

This commit is contained in:
Ahti Legonkov 2012-04-22 06:49:42 +02:00 committed by Daniel Marjamäki
parent 8dfde7def8
commit 79af6f65d7
2 changed files with 30 additions and 3 deletions

View File

@ -890,10 +890,18 @@ static void simplifyVarMap(std::map<std::string, std::string> &variables)
// TODO: 1. tokenize the value, replace each token like this.
// TODO: 2. handle function-macros too.
std::set<std::string> seenVariables;
std::map<std::string, std::string>::iterator it = variables.find(varValue);
while (it != variables.end() && it->first != it->second && it != i) {
varValue = it->second;
it = variables.find(varValue);
while (it != variables.end() && it->first != it->second) {
if (seenVariables.find(it->first) != seenVariables.end()) {
// We have already seen this variable. there is a cycle of #define that we can't process at
// this time. Stop trying to simplify the current variable and leave it as is.
break;
} else {
seenVariables.insert(it->first);
varValue = it->second;
it = variables.find(varValue);
}
}
}
}

View File

@ -132,6 +132,7 @@ private:
TEST_CASE(if_macro_eq_macro); // #3536
TEST_CASE(ticket_3675);
TEST_CASE(ticket_3699);
TEST_CASE(multiline1);
TEST_CASE(multiline2);
@ -1550,6 +1551,24 @@ private:
// There's nothing to assert. It just needs to not hang.
}
void ticket_3699() {
const std::string code("#define INLINE __forceinline\n"
"#define inline __forceinline\n"
"#define __forceinline inline\n"
"#if !defined(_WIN32)\n"
"#endif\n"
"INLINE inline __forceinline\n"
);
Settings settings;
Preprocessor preprocessor(&settings, this);
std::istringstream istr(code);
std::map<std::string, std::string> actual;
preprocessor.preprocess(istr, actual, "file.c");
// First, it must not hang. Second, inline must becomes inline, and __forceinline must become __forceinline.
ASSERT_EQUALS("\n\n\n\n\n$$$__forceinline $$inline $$__forceinline\n", actual[""]);
}
void multiline1() {
const char filedata[] = "#define str \"abc\" \\\n"
" \"def\" \n"