diff --git a/lib/tokenize.cpp b/lib/tokenize.cpp index b43027f54..5af12facc 100644 --- a/lib/tokenize.cpp +++ b/lib/tokenize.cpp @@ -5762,6 +5762,47 @@ Token * Tokenizer::initVar(Token * tok) bool Tokenizer::simplifyKnownVariables() { bool ret = false; + + // constants.. + { + std::map constantValues; + for (Token *tok = _tokens; tok; tok = tok->next()) + { + if (Token::Match(tok, "static| const %type% %var% = %any% ;")) + { + Token *tok1 = tok; + + // start of statement + if (tok != _tokens && !Token::Match(tok->previous(),"[;{}]")) + continue; + // skip "static" + if (tok->str() == "static") + tok = tok->next(); + // pod type + if (!tok->next()->isStandardType()) + continue; + + const Token * const vartok = tok->tokAt(2); + const Token * const valuetok = tok->tokAt(4); + if (valuetok->isNumber() || Token::Match(valuetok, "%str% ;")) + { + constantValues[vartok->varId()] = valuetok->str(); + + // remove statement + while (tok1->str() != ";") + tok1->deleteThis(); + tok = tok1; + } + } + + else if (tok->varId() && constantValues.find(tok->varId()) != constantValues.end()) + { + tok->str(constantValues[tok->varId()]); + } + } + } + + // auto variables.. for (Token *tok = _tokens; tok; tok = tok->next()) { // Search for a block of code diff --git a/test/testtokenize.cpp b/test/testtokenize.cpp index 79f6c235c..7eb4f0b92 100644 --- a/test/testtokenize.cpp +++ b/test/testtokenize.cpp @@ -119,9 +119,10 @@ private: TEST_CASE(simplifyKnownVariables26); TEST_CASE(simplifyKnownVariables27); TEST_CASE(simplifyKnownVariables28); - TEST_CASE(simplifyKnownVariables29); // ticket #1811 + TEST_CASE(simplifyKnownVariables29); // ticket #1811 TEST_CASE(simplifyKnownVariables30); TEST_CASE(simplifyKnownVariables31); + TEST_CASE(simplifyKnownVariables32); // const TEST_CASE(simplifyKnownVariablesBailOutFor); TEST_CASE(simplifyKnownVariablesBailOutMemberFunction); @@ -1159,7 +1160,7 @@ private: "}\n"; ASSERT_EQUALS( - "const int foo = 0 ; int main ( ) { int foo ; foo = 0 ; }", + "; int main ( ) { int foo ; foo = 0 ; }", simplifyKnownVariables(code)); } @@ -1856,6 +1857,19 @@ private: ASSERT_EQUALS(expected, tokenizeAndStringify(code, true)); } + void simplifyKnownVariables32() + { + const char code[] = "void foo() {\n" + " const int x = 0;\n" + " bar(0,x);\n" + "}\n"; + const char expected[] = "void foo ( ) {\n" + ";\n" + "bar ( 0 , 0 ) ;\n" + "}"; + ASSERT_EQUALS(expected, tokenizeAndStringify(code, true)); + } + void simplifyKnownVariablesBailOutFor() { const char code[] = "void foo() {\n" @@ -3406,7 +3420,7 @@ private: std::ostringstream ostr; for (const Token *tok = tokenizer.tokens(); tok; tok = tok->next()) ostr << " " << tok->str(); - ASSERT_EQUALS(" void f ( ) { const int a = 45 ; { ; } } void g ( ) { ; }", ostr.str()); + ASSERT_EQUALS(" void f ( ) { ; { ; } } void g ( ) { ; }", ostr.str()); } void simplify_constants2() @@ -3432,7 +3446,7 @@ private: ostr << " " << tok->str(); std::ostringstream oss; - oss << " void f ( Foo & foo , Foo * foo2 ) { const int a = 45 ; foo . a = 90 ; foo2 . a = 45 ; }"; + oss << " void f ( Foo & foo , Foo * foo2 ) { ; foo . a = 90 ; foo2 . a = 45 ; }"; ASSERT_EQUALS(oss.str(), ostr.str()); }