diff --git a/lib/tokenize.cpp b/lib/tokenize.cpp index 78d2e433e..86b167057 100644 --- a/lib/tokenize.cpp +++ b/lib/tokenize.cpp @@ -7433,6 +7433,7 @@ void Tokenizer::simplifyEnum() if (!shadowId.empty()) shadowId.push(shadowId.top()); + // are there shadow arguments? if (Token::simpleMatch(tok2->previous(), ") {") || Token::simpleMatch(tok2->tokAt(-2), ") const {")) { std::set shadowArg; for (const Token* arg = tok2; arg && arg->str() != "("; arg = arg->previous()) { @@ -7448,7 +7449,24 @@ void Tokenizer::simplifyEnum() } } + // are there shadow variables in the scope? + std::set shadowVars; + for (const Token *tok3 = tok2->next(); tok3 && tok3->str() != "}"; tok3 = tok3->next()) { + if (tok3->str() == "{") + tok3 = tok3->link(); // skip inner scopes + else if (tok3->isName() && enumValues.find(tok3->str()) != enumValues.end()) { + if (Token::Match(tok3->previous(), "*|%type%") || Token::Match(tok3->previous(), "& %type% =")) // variable declaration? + shadowVars.insert(tok3->str()); + } + } + if (!shadowVars.empty()) { + if (shadowId.empty()) + shadowId.push(shadowVars); + else + shadowId.top().insert(shadowVars.begin(), shadowVars.end()); + } } + // Function head } else if (Token::Match(tok2, "%var% (")) { const Token *prev = tok2->previous(); diff --git a/test/testsimplifytokens.cpp b/test/testsimplifytokens.cpp index b1d6f7ce2..b0436bdab 100644 --- a/test/testsimplifytokens.cpp +++ b/test/testsimplifytokens.cpp @@ -7334,9 +7334,18 @@ private: ASSERT_EQUALS("struct X { X ( int ) { int y ; y = ( int ) 1 ; } } ;", checkSimplifyEnum(code)); } - void enum37() { // #4280 - const char code[] = "enum { a, b }; void f(int a) { return a + 1; }"; - ASSERT_EQUALS("void f ( int a ) { return a + 1 ; }", checkSimplifyEnum(code)); + void enum37() { // #4280 - shadow variables + const char code1[] = "enum { a, b }; void f(int a) { return a + 1; }"; + ASSERT_EQUALS("void f ( int a ) { return a + 1 ; }", checkSimplifyEnum(code1)); + + const char code2[] = "enum { a, b }; void f() { int a; }"; + ASSERT_EQUALS("void f ( ) { int a ; }", checkSimplifyEnum(code2)); + + const char code3[] = "enum { a, b }; void f() { int *a=do_something(); }"; + ASSERT_EQUALS("void f ( ) { int * a ; a = do_something ( ) ; }", checkSimplifyEnum(code3)); + + const char code4[] = "enum { a, b }; void f() { int &a=x; }"; + ASSERT_EQUALS("void f ( ) { int & a = x ; }", checkSimplifyEnum(code4)); } void enumscope1() { // #3949 - don't simplify enum from one function in another function