Fixed #3699 (cppcheck hangs with 100% cpu load on parsing preprocessor code)
This commit is contained in:
parent
8dfde7def8
commit
79af6f65d7
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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"
|
||||
|
|
Loading…
Reference in New Issue