diff --git a/lib/tokenize.cpp b/lib/tokenize.cpp index 26da443e1..37733031e 100644 --- a/lib/tokenize.cpp +++ b/lib/tokenize.cpp @@ -5918,7 +5918,6 @@ bool Tokenizer::simplifyKnownVariables() if (varid == 0) continue; - // skip loop variable if (Token::Match(tok2->tokAt(-2), "(|:: %type%")) { @@ -5929,6 +5928,11 @@ bool Tokenizer::simplifyKnownVariables() continue; } + // struct name.. + const std::string structname(Token::Match(tok2->tokAt(-3), "[;{}] %var% .") ? + (tok2->strAt(-2) + " .") : + std::string("")); + if (tok2->str() == tok2->strAt(2)) continue; @@ -6148,11 +6152,16 @@ bool Tokenizer::simplifyKnownVariables() } // Using the variable in condition.. - if (Token::Match(tok3->previous(), "if ( %varid% ==|!=|<|<=|>|>=|)", varid) || - Token::Match(tok3, "( %varid% ==|!=|<|<=|>|>=", varid) || - Token::Match(tok3, "!|==|!=|<|<=|>|>= %varid% ==|!=|<|<=|>|>=|)", varid) || + if (Token::Match(tok3->previous(), ("if ( " + structname + " %varid% ==|!=|<|<=|>|>=|)").c_str(), varid) || + Token::Match(tok3, ("( " + structname + " %varid% ==|!=|<|<=|>|>=").c_str(), varid) || + Token::Match(tok3, ("!|==|!=|<|<=|>|>= " + structname + " %varid% ==|!=|<|<=|>|>=|)").c_str(), varid) || Token::Match(tok3->previous(), "strlen|free ( %varid% )", varid)) { + if (!structname.empty()) + { + tok3->deleteNext(); + tok3->deleteNext(); + } tok3 = tok3->next(); tok3->str(value); tok3->varId(valueVarId); @@ -6160,7 +6169,7 @@ bool Tokenizer::simplifyKnownVariables() } // Variable is used in function call.. - if (Token::Match(tok3, "%var% ( %varid% ,", varid)) + if (Token::Match(tok3, ("%var% ( " + structname + " %varid% ,").c_str(), varid)) { const char * const functionName[] = { @@ -6172,6 +6181,11 @@ bool Tokenizer::simplifyKnownVariables() if (tok3->str() == functionName[i]) { Token *par1 = tok3->next()->next(); + if (!structname.empty()) + { + par1->deleteThis(); + par1->deleteThis(); + } par1->str(value); par1->varId(valueVarId); break; @@ -6180,8 +6194,13 @@ bool Tokenizer::simplifyKnownVariables() } // array usage - if (Token::Match(tok3, "[(,] %varid% [+-*/[]", varid)) + if (Token::Match(tok3, ("[(,] " + structname + " %varid% [+-*/[]").c_str(), varid)) { + if (!structname.empty()) + { + tok3->deleteNext(); + tok3->deleteNext(); + } tok3 = tok3->next(); tok3->str(value); tok3->varId(valueVarId); @@ -6189,12 +6208,17 @@ bool Tokenizer::simplifyKnownVariables() } // Variable is used in calculation.. - if (((tok3->previous()->varId() > 0) && Token::Match(tok3, "& %varid%", varid)) || - Token::Match(tok3, "[=+-*/[] %varid% [=?+-*/;])]", varid) || - Token::Match(tok3, "[(=+-*/[] %varid% <<|>>", varid) || - Token::Match(tok3, "<<|>> %varid% [+-*/;])]", varid) || - Token::Match(tok3->previous(), "[=+-*/[] ( %varid%", varid)) + if (((tok3->previous()->varId() > 0) && Token::Match(tok3, ("& " + structname + " %varid%").c_str(), varid)) || + Token::Match(tok3, ("[=+-*/[] " + structname + " %varid% [=?+-*/;])]").c_str(), varid) || + Token::Match(tok3, ("[(=+-*/[] " + structname + " %varid% <<|>>").c_str(), varid) || + Token::Match(tok3, ("<<|>> " + structname + " %varid% [+-*/;])]").c_str(), varid) || + Token::Match(tok3->previous(), ("[=+-*/[] ( " + structname + " %varid%").c_str(), varid)) { + if (!structname.empty()) + { + tok3->deleteNext(); + tok3->deleteNext(); + } tok3 = tok3->next(); tok3->str(value); tok3->varId(valueVarId); diff --git a/test/testtokenize.cpp b/test/testtokenize.cpp index 575e6ca6f..23b274e0d 100644 --- a/test/testtokenize.cpp +++ b/test/testtokenize.cpp @@ -123,6 +123,7 @@ private: TEST_CASE(simplifyKnownVariables30); TEST_CASE(simplifyKnownVariables31); TEST_CASE(simplifyKnownVariables32); // const + TEST_CASE(simplifyKnownVariables33); // struct variable TEST_CASE(simplifyKnownVariablesBailOutAssign); TEST_CASE(simplifyKnownVariablesBailOutFor1); TEST_CASE(simplifyKnownVariablesBailOutFor2); @@ -1878,6 +1879,19 @@ private: ASSERT_EQUALS(expected, tokenizeAndStringify(code, true)); } + void simplifyKnownVariables33() + { + const char code[] = "static void foo(struct Foo *foo) {\n" + " foo->a = 23;\n" + " x[foo->a] = 0;\n" + "}\n"; + const char expected[] = "static void foo ( struct Foo * foo ) {\n" + "foo . a = 23 ;\n" + "x [ 23 ] = 0 ;\n" + "}"; + ASSERT_EQUALS(expected, tokenizeAndStringify(code, true)); + } + void simplifyKnownVariablesBailOutAssign() { const char code[] = "int foo() {\n"