Fixed #1004 (improve check: Unintialized variable not detected when using a reference (&))
This commit is contained in:
parent
15f8472302
commit
1375a60e3f
|
@ -2466,6 +2466,9 @@ bool Tokenizer::simplifyTokenList()
|
|||
}
|
||||
}
|
||||
|
||||
// simplify references
|
||||
simplifyReference();
|
||||
|
||||
simplifyStd();
|
||||
|
||||
simplifyNamespaces();
|
||||
|
@ -4285,7 +4288,8 @@ bool Tokenizer::simplifyKnownVariables()
|
|||
Token::Match(tok2, "%var% = %str% ;") ||
|
||||
Token::Match(tok2, "%var% [ ] = %str% ;") ||
|
||||
Token::Match(tok2, "%var% = %bool% ;") ||
|
||||
Token::Match(tok2, "%var% = %var% ;")))
|
||||
Token::Match(tok2, "%var% = %var% ;") ||
|
||||
Token::Match(tok2, "%var% = & %var% ;")))
|
||||
{
|
||||
const unsigned int varid = tok2->varId();
|
||||
if (varid == 0)
|
||||
|
@ -4294,12 +4298,16 @@ bool Tokenizer::simplifyKnownVariables()
|
|||
if (tok2->str() == tok2->strAt(2))
|
||||
continue;
|
||||
|
||||
const bool pointeralias(tok2->tokAt(2)->isName());
|
||||
const bool pointeralias(tok2->tokAt(2)->isName() || tok2->tokAt(2)->str() == "&");
|
||||
|
||||
std::string value(tok2->strAt(2));
|
||||
if (value == "]")
|
||||
value = tok2->strAt(4);
|
||||
else if (value == "&")
|
||||
value = tok2->strAt(3);
|
||||
Token* bailOutFromLoop = 0;
|
||||
if (Token::simpleMatch(tok2->next(), "= &"))
|
||||
tok2 = tok2->tokAt(3);
|
||||
int indentlevel3 = indentlevel; // indentlevel for tok3
|
||||
for (Token *tok3 = tok2->next(); tok3; tok3 = tok3->next())
|
||||
{
|
||||
|
@ -4311,7 +4319,14 @@ bool Tokenizer::simplifyKnownVariables()
|
|||
{
|
||||
--indentlevel3;
|
||||
if (indentlevel3 < indentlevel)
|
||||
{
|
||||
if (Token::Match(tok2->tokAt(-3), "%var% = & %var% ;"))
|
||||
{
|
||||
tok2 = tok2->tokAt(-4);
|
||||
Token::eraseTokens(tok2, tok2->tokAt(5));
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (pointeralias && Token::Match(tok3, ("!!= " + value).c_str()))
|
||||
|
@ -4430,6 +4445,12 @@ bool Tokenizer::simplifyKnownVariables()
|
|||
{
|
||||
tok3->next()->str(value);
|
||||
}
|
||||
|
||||
else if (pointeralias && Token::Match(tok3, "return * %varid% ;", varid))
|
||||
{
|
||||
tok3->deleteNext();
|
||||
tok3->next()->str(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -4547,6 +4568,43 @@ bool Tokenizer::simplifyRedundantParanthesis()
|
|||
return ret;
|
||||
}
|
||||
|
||||
void Tokenizer::simplifyReference()
|
||||
{
|
||||
for (Token *tok = _tokens; tok; tok = tok->next())
|
||||
{
|
||||
// starting executable scope..
|
||||
if (Token::Match(tok, ") const| {"))
|
||||
{
|
||||
// replace references in this scope..
|
||||
if (tok->next()->str() != "{")
|
||||
tok = tok->next();
|
||||
Token * const end = tok->next()->link();
|
||||
for (Token *tok2 = tok; tok2 && tok2 != end; tok2 = tok2->next())
|
||||
{
|
||||
// found a reference..
|
||||
if (Token::Match(tok2, "[;{}] %type% & %var% (|= %var% )| ;"))
|
||||
{
|
||||
const unsigned int ref_id = tok2->tokAt(3)->varId();
|
||||
if (!ref_id)
|
||||
continue;
|
||||
|
||||
// replace reference in the code..
|
||||
for (Token *tok3 = tok2->tokAt(7); tok3 && tok3 != end; tok3 = tok3->next())
|
||||
{
|
||||
if (tok3->varId() == ref_id)
|
||||
{
|
||||
tok3->str(tok2->strAt(5));
|
||||
tok3->varId(tok2->tokAt(5)->varId());
|
||||
}
|
||||
}
|
||||
|
||||
Token::eraseTokens(tok2, tok2->tokAt(7));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool Tokenizer::simplifyCalculations()
|
||||
{
|
||||
bool ret = false;
|
||||
|
|
|
@ -295,6 +295,9 @@ private:
|
|||
*/
|
||||
bool simplifyRedundantParanthesis();
|
||||
|
||||
/** Simplify references */
|
||||
void simplifyReference();
|
||||
|
||||
/**
|
||||
* Simplify functions like "void f(x) int x; {"
|
||||
* into "void f(int x) {"
|
||||
|
|
|
@ -169,7 +169,8 @@ private:
|
|||
TEST_CASE(reverseArraySyntax)
|
||||
TEST_CASE(simplify_numeric_condition)
|
||||
|
||||
TEST_CASE(pointeralias);
|
||||
TEST_CASE(pointeralias1);
|
||||
TEST_CASE(pointeralias2);
|
||||
|
||||
TEST_CASE(reduceConstness);
|
||||
|
||||
|
@ -187,6 +188,9 @@ private:
|
|||
|
||||
// Tokenizer::simplifyInitVar
|
||||
TEST_CASE(simplifyInitVar);
|
||||
|
||||
// Tokenizer::simplifyReference
|
||||
TEST_CASE(simplifyReference);
|
||||
}
|
||||
|
||||
std::string tok(const char code[], bool simplify = true)
|
||||
|
@ -3094,7 +3098,7 @@ private:
|
|||
}
|
||||
|
||||
|
||||
void pointeralias()
|
||||
void pointeralias1()
|
||||
{
|
||||
{
|
||||
const char code[] = "void f()\n"
|
||||
|
@ -3179,6 +3183,23 @@ private:
|
|||
}
|
||||
}
|
||||
|
||||
void pointeralias2()
|
||||
{
|
||||
const char code[] = "void f()\n"
|
||||
"{\n"
|
||||
" int i;\n"
|
||||
" int *p = &i;\n"
|
||||
" return *p;\n"
|
||||
"}\n";
|
||||
const char expected[] = "void f ( ) "
|
||||
"{ "
|
||||
"int i ; "
|
||||
"; ; "
|
||||
"return i ; "
|
||||
"}";
|
||||
ASSERT_EQUALS(expected, tok(code));
|
||||
}
|
||||
|
||||
|
||||
void reduceConstness()
|
||||
{
|
||||
|
@ -3279,6 +3300,14 @@ private:
|
|||
ASSERT_EQUALS("void a ( ) { ; ; }", tok(code));
|
||||
}
|
||||
}
|
||||
|
||||
void simplifyReference()
|
||||
{
|
||||
ASSERT_EQUALS("void f ( ) { int a ; ; a ++ ; }",
|
||||
tok("void f() { int a; int &b(a); b++; }"));
|
||||
ASSERT_EQUALS("void f ( ) { int a ; a ++ ; }",
|
||||
tok("void f() { int a; int &b = a; b++; }"));
|
||||
}
|
||||
};
|
||||
|
||||
REGISTER_TEST(TestSimplifyTokens)
|
||||
|
|
Loading…
Reference in New Issue