Fixed #1004 (improve check: Unintialized variable not detected when using a reference (&))

This commit is contained in:
Daniel Marjamäki 2010-01-31 16:29:12 +01:00
parent 15f8472302
commit 1375a60e3f
3 changed files with 94 additions and 4 deletions

View File

@ -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;

View File

@ -295,6 +295,9 @@ private:
*/
bool simplifyRedundantParanthesis();
/** Simplify references */
void simplifyReference();
/**
* Simplify functions like "void f(x) int x; {"
* into "void f(int x) {"

View File

@ -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)