diff --git a/lib/tokenize.cpp b/lib/tokenize.cpp index 2ecb7fdc4..4d7192662 100644 --- a/lib/tokenize.cpp +++ b/lib/tokenize.cpp @@ -5258,6 +5258,22 @@ void Tokenizer::simplifyInitVar() } } +static bool isOp(const Token *tok) +{ + return bool(tok && + (tok->str() == "&&" || + tok->str() == "||" || + tok->str() == "==" || + tok->str() == "!=" || + tok->str() == "<" || + tok->str() == "<=" || + tok->str() == ">" || + tok->str() == ">=" || + tok->str() == "<<" || + tok->str() == ">>" || + Token::Match(tok, "[;+-*/%&|^]"))); +} + Token * Tokenizer::initVar(Token * tok) { // call constructor of class => no simplification @@ -5344,6 +5360,7 @@ bool Tokenizer::simplifyKnownVariables() const bool pointeralias(tok2->tokAt(2)->isName() || tok2->tokAt(2)->str() == "&"); std::string value; + unsigned int valueVarId = 0; Token *tok3 = NULL; bool valueIsPointer = false; @@ -5375,7 +5392,10 @@ bool Tokenizer::simplifyKnownVariables() // no break => the value of the counter value is known after the for loop.. const std::string compareop = tok2->strAt(5); if (compareop == "<") + { value = tok2->strAt(6); + valueVarId = tok2->tokAt(6)->varId(); + } else value = MathLib::toString(MathLib::toLongNumber(tok2->strAt(6)) + 1); @@ -5385,11 +5405,16 @@ bool Tokenizer::simplifyKnownVariables() else { value = tok2->strAt(2); + valueVarId = tok2->tokAt(2)->varId(); if (value == "]") + { value = tok2->strAt(4); + valueVarId = tok2->tokAt(4)->varId(); + } else if (value == "&") { value = tok2->strAt(3); + valueVarId = tok2->tokAt(3)->varId(); // *ptr = &var; *ptr = 5; // equals @@ -5513,6 +5538,7 @@ bool Tokenizer::simplifyKnownVariables() { tok3 = tok3->next(); tok3->str(value); + tok3->varId(valueVarId); ret = true; } @@ -5520,11 +5546,12 @@ bool Tokenizer::simplifyKnownVariables() if (Token::Match(tok3, "[=+-*/[] %varid% [=?+-*/;])]", varid) || 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)) { tok3 = tok3->next(); tok3->str(value); + tok3->varId(valueVarId); if (tok3->previous()->str() == "*" && valueIsPointer) { tok3 = tok3->previous(); @@ -5553,11 +5580,13 @@ bool Tokenizer::simplifyKnownVariables() if (tok4->next()->varId() == varid) { tok4->next()->str(value); + tok4->next()->varId(valueVarId); ret = true; } if (tok4->tokAt(3)->varId() == varid) { tok4->tokAt(3)->str(value); + tok4->tokAt(3)->varId(valueVarId); ret = true; } } @@ -5566,11 +5595,13 @@ bool Tokenizer::simplifyKnownVariables() if (tok3->next()->varId() == varid) { tok3->next()->str(value); + tok3->next()->varId(valueVarId); ret = true; } else if (tok3->tokAt(3)->varId() == varid) { tok3->tokAt(3)->str(value); + tok3->tokAt(3)->varId(valueVarId); ret = true; } } @@ -5586,11 +5617,15 @@ bool Tokenizer::simplifyKnownVariables() { tok3 = tok3->next(); tok3->str(value); + tok3->varId(valueVarId); tok3->deleteNext(); } incdec(value, op); if (!Token::simpleMatch(tok2->tokAt(-2), "for (")) + { tok2->tokAt(2)->str(value); + tok2->tokAt(2)->varId(valueVarId); + } ret = true; } @@ -5599,6 +5634,7 @@ bool Tokenizer::simplifyKnownVariables() { incdec(value, tok3->strAt(1)); tok2->tokAt(2)->str(value); + tok2->tokAt(2)->varId(valueVarId); if (Token::Match(tok3, "[;{}] %any% %any% ;")) { Token::eraseTokens(tok3, tok3->tokAt(3)); @@ -5607,21 +5643,25 @@ bool Tokenizer::simplifyKnownVariables() { tok3->deleteNext(); tok3->next()->str(value); + tok3->next()->varId(valueVarId); } tok3 = tok3->next(); ret = true; } // return variable.. - if (Token::Match(tok3, "return %varid% ;", varid)) + if (Token::Match(tok3, "return %varid% %any%", varid) && + isOp(tok3->tokAt(2))) { tok3->next()->str(value); + tok3->next()->varId(valueVarId); } else if (pointeralias && Token::Match(tok3, "return * %varid% ;", varid)) { tok3->deleteNext(); tok3->next()->str(value); + tok3->next()->varId(valueVarId); } } } diff --git a/test/testtokenize.cpp b/test/testtokenize.cpp index f3f83dd0c..deaab568d 100644 --- a/test/testtokenize.cpp +++ b/test/testtokenize.cpp @@ -111,6 +111,7 @@ private: TEST_CASE(simplifyKnownVariables26); TEST_CASE(simplifyKnownVariables27); TEST_CASE(simplifyKnownVariables28); + TEST_CASE(simplifyKnownVariables29); // ticket #1811 TEST_CASE(match1); @@ -1358,6 +1359,314 @@ private: simplifyKnownVariables(code)); } + void simplifyKnownVariables29() // ticket #1811 + { + { + const char code[] = "int foo(int u, int v)\n" + "{\n" + " int h = u;\n" + " int i = v;\n" + " return h + i;\n" + "}\n"; + const char expected[] = "\n\n##file 0\n" + "1: int foo ( int u@1 , int v@2 )\n" + "2: {\n" + "3: ; ;\n" + "4: ; ;\n" + "5: return u@1 + v@2 ;\n" + "6: }\n"; + ASSERT_EQUALS(expected, tokenizeDebugListing(code, true)); + } + + { + const char code[] = "int foo(int u, int v)\n" + "{\n" + " int h = u;\n" + " int i = v;\n" + " return h - i;\n" + "}\n"; + const char expected[] = "\n\n##file 0\n" + "1: int foo ( int u@1 , int v@2 )\n" + "2: {\n" + "3: ; ;\n" + "4: ; ;\n" + "5: return u@1 - v@2 ;\n" + "6: }\n"; + ASSERT_EQUALS(expected, tokenizeDebugListing(code, true)); + } + + { + const char code[] = "int foo(int u, int v)\n" + "{\n" + " int h = u;\n" + " int i = v;\n" + " return h * i;\n" + "}\n"; + const char expected[] = "\n\n##file 0\n" + "1: int foo ( int u@1 , int v@2 )\n" + "2: {\n" + "3: ; ;\n" + "4: ; ;\n" + "5: return u@1 * v@2 ;\n" + "6: }\n"; + ASSERT_EQUALS(expected, tokenizeDebugListing(code, true)); + } + + { + const char code[] = "int foo(int u, int v)\n" + "{\n" + " int h = u;\n" + " int i = v;\n" + " return h / i;\n" + "}\n"; + const char expected[] = "\n\n##file 0\n" + "1: int foo ( int u@1 , int v@2 )\n" + "2: {\n" + "3: ; ;\n" + "4: ; ;\n" + "5: return u@1 / v@2 ;\n" + "6: }\n"; + ASSERT_EQUALS(expected, tokenizeDebugListing(code, true)); + } + + { + const char code[] = "int foo(int u, int v)\n" + "{\n" + " int h = u;\n" + " int i = v;\n" + " return h & i;\n" + "}\n"; + const char expected[] = "\n\n##file 0\n" + "1: int foo ( int u@1 , int v@2 )\n" + "2: {\n" + "3: ; ;\n" + "4: ; ;\n" + "5: return u@1 & v@2 ;\n" + "6: }\n"; + TODO_ASSERT_EQUALS(expected, tokenizeDebugListing(code, true)); + } + + { + const char code[] = "int foo(int u, int v)\n" + "{\n" + " int h = u;\n" + " int i = v;\n" + " return h | i;\n" + "}\n"; + const char expected[] = "\n\n##file 0\n" + "1: int foo ( int u@1 , int v@2 )\n" + "2: {\n" + "3: ; ;\n" + "4: ; ;\n" + "5: return u@1 | v@2 ;\n" + "6: }\n"; + TODO_ASSERT_EQUALS(expected, tokenizeDebugListing(code, true)); + } + + { + const char code[] = "int foo(int u, int v)\n" + "{\n" + " int h = u;\n" + " int i = v;\n" + " return h ^ i;\n" + "}\n"; + const char expected[] = "\n\n##file 0\n" + "1: int foo ( int u@1 , int v@2 )\n" + "2: {\n" + "3: ; ;\n" + "4: ; ;\n" + "5: return u@1 ^ v@2 ;\n" + "6: }\n"; + TODO_ASSERT_EQUALS(expected, tokenizeDebugListing(code, true)); + } + + { + const char code[] = "int foo(int u, int v)\n" + "{\n" + " int h = u;\n" + " int i = v;\n" + " return h % i;\n" + "}\n"; + const char expected[] = "\n\n##file 0\n" + "1: int foo ( int u@1 , int v@2 )\n" + "2: {\n" + "3: ; ;\n" + "4: ; ;\n" + "5: return u@1 % v@2 ;\n" + "6: }\n"; + TODO_ASSERT_EQUALS(expected, tokenizeDebugListing(code, true)); + } + + { + const char code[] = "int foo(int u, int v)\n" + "{\n" + " int h = u;\n" + " int i = v;\n" + " return h >> i;\n" + "}\n"; + const char expected[] = "\n\n##file 0\n" + "1: int foo ( int u@1 , int v@2 )\n" + "2: {\n" + "3: ; ;\n" + "4: ; ;\n" + "5: return u@1 >> v@2 ;\n" + "6: }\n"; + ASSERT_EQUALS(expected, tokenizeDebugListing(code, true)); + } + + { + const char code[] = "int foo(int u, int v)\n" + "{\n" + " int h = u;\n" + " int i = v;\n" + " return h << i;\n" + "}\n"; + const char expected[] = "\n\n##file 0\n" + "1: int foo ( int u@1 , int v@2 )\n" + "2: {\n" + "3: ; ;\n" + "4: ; ;\n" + "5: return u@1 << v@2 ;\n" + "6: }\n"; + ASSERT_EQUALS(expected, tokenizeDebugListing(code, true)); + } + + { + const char code[] = "bool foo(int u, int v)\n" + "{\n" + " int h = u;\n" + " int i = v;\n" + " return h == i;\n" + "}\n"; + const char expected[] = "\n\n##file 0\n" + "1: bool foo ( int u@1 , int v@2 )\n" + "2: {\n" + "3: ; ;\n" + "4: ; ;\n" + "5: return u@1 == v@2 ;\n" + "6: }\n"; + TODO_ASSERT_EQUALS(expected, tokenizeDebugListing(code, true)); + } + + { + const char code[] = "bool foo(int u, int v)\n" + "{\n" + " int h = u;\n" + " int i = v;\n" + " return h != i;\n" + "}\n"; + const char expected[] = "\n\n##file 0\n" + "1: bool foo ( int u@1 , int v@2 )\n" + "2: {\n" + "3: ; ;\n" + "4: ; ;\n" + "5: return u@1 != v@2 ;\n" + "6: }\n"; + TODO_ASSERT_EQUALS(expected, tokenizeDebugListing(code, true)); + } + + { + const char code[] = "bool foo(int u, int v)\n" + "{\n" + " int h = u;\n" + " int i = v;\n" + " return h > i;\n" + "}\n"; + const char expected[] = "\n\n##file 0\n" + "1: bool foo ( int u@1 , int v@2 )\n" + "2: {\n" + "3: ; ;\n" + "4: ; ;\n" + "5: return u@1 > v@2 ;\n" + "6: }\n"; + TODO_ASSERT_EQUALS(expected, tokenizeDebugListing(code, true)); + } + + { + const char code[] = "bool foo(int u, int v)\n" + "{\n" + " int h = u;\n" + " int i = v;\n" + " return h >= i;\n" + "}\n"; + const char expected[] = "\n\n##file 0\n" + "1: bool foo ( int u@1 , int v@2 )\n" + "2: {\n" + "3: ; ;\n" + "4: ; ;\n" + "5: return u@1 >= v@2 ;\n" + "6: }\n"; + TODO_ASSERT_EQUALS(expected, tokenizeDebugListing(code, true)); + } + + { + const char code[] = "bool foo(int u, int v)\n" + "{\n" + " int h = u;\n" + " int i = v;\n" + " return h < i;\n" + "}\n"; + const char expected[] = "\n\n##file 0\n" + "1: bool foo ( int u@1 , int v@2 )\n" + "2: {\n" + "3: ; ;\n" + "4: ; ;\n" + "5: return u@1 < v@2 ;\n" + "6: }\n"; + TODO_ASSERT_EQUALS(expected, tokenizeDebugListing(code, true)); + } + + { + const char code[] = "bool foo(int u, int v)\n" + "{\n" + " int h = u;\n" + " int i = v;\n" + " return h <= i;\n" + "}\n"; + const char expected[] = "\n\n##file 0\n" + "1: bool foo ( int u@1 , int v@2 )\n" + "2: {\n" + "3: ; ;\n" + "4: ; ;\n" + "5: return u@1 <= v@2 ;\n" + "6: }\n"; + TODO_ASSERT_EQUALS(expected, tokenizeDebugListing(code, true)); + } + + { + const char code[] = "bool foo(int u, int v)\n" + "{\n" + " int h = u;\n" + " int i = v;\n" + " return h && i;\n" + "}\n"; + const char expected[] = "\n\n##file 0\n" + "1: bool foo ( int u@1 , int v@2 )\n" + "2: {\n" + "3: ; ;\n" + "4: ; ;\n" + "5: return u@1 && v@2 ;\n" + "6: }\n"; + TODO_ASSERT_EQUALS(expected, tokenizeDebugListing(code, true)); + } + + { + const char code[] = "bool foo(int u, int v)\n" + "{\n" + " int h = u;\n" + " int i = v;\n" + " return h || i;\n" + "}\n"; + const char expected[] = "\n\n##file 0\n" + "1: bool foo ( int u@1 , int v@2 )\n" + "2: {\n" + "3: ; ;\n" + "4: ; ;\n" + "5: return u@1 || v@2 ;\n" + "6: }\n"; + TODO_ASSERT_EQUALS(expected, tokenizeDebugListing(code, true)); + } + } void match1() {