diff --git a/lib/preprocessor.cpp b/lib/preprocessor.cpp index e2648f01f..3fccc9d62 100644 --- a/lib/preprocessor.cpp +++ b/lib/preprocessor.cpp @@ -1001,20 +1001,29 @@ static void simplifyVarMap(std::map &variables) for (std::map::iterator i = variables.begin(); i != variables.end(); ++i) { std::string& varValue = i->second; - // TODO: 1. tokenize the value, replace each token like this. - // TODO: 2. handle function-macros too. + // TODO: handle function-macros too. + // Bailout if variable A depends on variable B which depends on A.. std::set seenVariables; - std::map::iterator 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); + + TokenList tokenList(NULL); + std::istringstream istr(i->second); + if (tokenList.createTokens(istr)) { + for (Token *tok = tokenList.front(); tok; tok = tok->next()) { + if (tok->isName()) { + std::map::iterator it = variables.find(tok->str()); + 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); + } + } + } } } } diff --git a/test/testpreprocessor.cpp b/test/testpreprocessor.cpp index 9083cd7ef..9f4f33b72 100644 --- a/test/testpreprocessor.cpp +++ b/test/testpreprocessor.cpp @@ -226,6 +226,7 @@ private: TEST_CASE(define_if2); TEST_CASE(define_if3); TEST_CASE(define_if4); // #4079 - #define X +123 + TEST_CASE(define_if5); // #4516 - #define B (A & 0x00f0) TEST_CASE(define_ifdef); TEST_CASE(define_ifndef1); TEST_CASE(define_ifndef2); @@ -2738,6 +2739,16 @@ private: ASSERT_EQUALS("\n\nFOO\n\n", preprocessor.getcode(filedata,"","")); } + void define_if5() { // #4516 - #define B (A & 0x00f0) + const char filedata[] = "#define A 0x0010\n" + "#define B (A & 0x00f0)\n" + "#if B==0x0010\n" + "FOO\n" + "#endif"; + Preprocessor preprocessor(NULL, this); + ASSERT_EQUALS("\n\n\nFOO\n\n", preprocessor.getcode(filedata,"","")); + } + void define_ifdef() { { const char filedata[] = "#define ABC\n"