Fixed #1356 (Double-False positive: uninitialized variable)

This commit is contained in:
Daniel Marjamäki 2010-02-07 13:34:39 +01:00
parent 1b0c81a24b
commit fb09b2fd37
4 changed files with 50 additions and 15 deletions

View File

@ -1013,7 +1013,7 @@ static bool hasDeallocation(const Token * first, const Token * last)
for (const Token * tok = first; tok && (tok != last); tok = tok->next()) for (const Token * tok = first; tok && (tok != last); tok = tok->next())
{ {
// check for deallocating memory // check for deallocating memory
if (Token::Match(tok, "{|;|, free ( %type%")) if (Token::Match(tok, "{|;|, free ( %var%"))
{ {
const Token * var = tok->tokAt(3); const Token * var = tok->tokAt(3);
@ -1023,7 +1023,7 @@ static bool hasDeallocation(const Token * first, const Token * last)
while (tok1 && (tok1 != last)) while (tok1 && (tok1 != last))
{ {
if (Token::Match(tok1, "%type% =")) if (Token::Match(tok1, "%var% ="))
{ {
if (tok1->str() == var->str()) if (tok1->str() == var->str())
return true; return true;
@ -1032,7 +1032,7 @@ static bool hasDeallocation(const Token * first, const Token * last)
tok1 = tok1->next(); tok1 = tok1->next();
} }
} }
else if (Token::Match(tok, "{|;|, delete [ ] %type%")) else if (Token::Match(tok, "{|;|, delete [ ] %var%"))
{ {
const Token * var = tok->tokAt(4); const Token * var = tok->tokAt(4);
@ -1042,7 +1042,7 @@ static bool hasDeallocation(const Token * first, const Token * last)
while (tok1 && (tok1 != last)) while (tok1 && (tok1 != last))
{ {
if (Token::Match(tok1, "%type% = new [")) if (Token::Match(tok1, "%var% = new ["))
{ {
if (tok1->str() == var->str()) if (tok1->str() == var->str())
return true; return true;
@ -1051,7 +1051,7 @@ static bool hasDeallocation(const Token * first, const Token * last)
tok1 = tok1->next(); tok1 = tok1->next();
} }
} }
else if (Token::Match(tok, "{|;|, delete %type%")) else if (Token::Match(tok, "{|;|, delete %var%"))
{ {
const Token * var = tok->tokAt(2); const Token * var = tok->tokAt(2);
@ -1061,7 +1061,7 @@ static bool hasDeallocation(const Token * first, const Token * last)
while (tok1 && (tok1 != last)) while (tok1 && (tok1 != last))
{ {
if (Token::Match(tok1, "%type% = new")) if (Token::Match(tok1, "%var% = new"))
{ {
if (tok1->str() == var->str()) if (tok1->str() == var->str())
return true; return true;
@ -1187,7 +1187,7 @@ void CheckClass::operatorEqToSelf()
if (tok1->tokAt(-(1 + nameLength)) && nameMatch(name, tok1->tokAt(-(1 + nameLength)), nameLength)) if (tok1->tokAt(-(1 + nameLength)) && nameMatch(name, tok1->tokAt(-(1 + nameLength)), nameLength))
{ {
// check forward for proper function signature // check forward for proper function signature
std::string pattern = "const " + nameString + " & %type% )"; std::string pattern = "const " + nameString + " & %var% )";
if (Token::Match(tok->tokAt(3), pattern.c_str())) if (Token::Match(tok->tokAt(3), pattern.c_str()))
{ {
const Token * rhs = tok->tokAt(5 + nameLength); const Token * rhs = tok->tokAt(5 + nameLength);
@ -1224,17 +1224,15 @@ void CheckClass::operatorEqToSelf()
while (tok1 && !Token::Match(tok1, "class|struct %var%")) while (tok1 && !Token::Match(tok1, "class|struct %var%"))
tok1 = tok1->previous(); tok1 = tok1->previous();
if (tok1 && Token::Match(tok1, "struct %var%")) if (Token::Match(tok1, "struct|class %var%"))
name = tok1->tokAt(1);
else if (tok1 && Token::Match(tok1, "class %var%"))
name = tok1->tokAt(1); name = tok1->tokAt(1);
if (!hasMultipleInheritanceInline(tok1)) if (!hasMultipleInheritanceInline(tok1))
{ {
if (tok->tokAt(-2) && tok->tokAt(-2)->str() == name->str()) if (Token::simpleMatch(tok->tokAt(-2), name->str().c_str()))
{ {
// check forward for proper function signature // check forward for proper function signature
if (Token::Match(tok->tokAt(3), "const %type% & %type% )")) if (Token::Match(tok->tokAt(3), "const %type% & %var% )"))
{ {
const Token * rhs = tok->tokAt(6); const Token * rhs = tok->tokAt(6);
@ -1242,9 +1240,9 @@ void CheckClass::operatorEqToSelf()
{ {
tok1 = tok->tokAt(2)->link(); tok1 = tok->tokAt(2)->link();
if (tok1 && tok1->tokAt(1) && tok1->tokAt(1)->str() == "{" && tok1->tokAt(1)->link()) if (tok1 && Token::simpleMatch(tok1->next(), "{"))
{ {
const Token *first = tok1->tokAt(1); const Token *first = tok1->next();
const Token *last = first->link(); const Token *last = first->link();
if (!hasAssignSelf(first, last, rhs)) if (!hasAssignSelf(first, last, rhs))

View File

@ -390,6 +390,9 @@ bool Token::Match(const Token *tok, const char pattern[], unsigned int varid)
if (!tok->isName()) if (!tok->isName())
return false; return false;
if (tok->varId() != 0)
return false;
if (tok->str() == "delete") if (tok->str() == "delete")
return false; return false;

View File

@ -1830,6 +1830,9 @@ void Tokenizer::setVarId()
if (Token::Match(tok, "[,;{}(] %type%")) if (Token::Match(tok, "[,;{}(] %type%"))
tok = tok->next(); tok = tok->next();
if (tok->str() == "new" || tok->str() == "unsigned")
continue;
if (Token::Match(tok, "class|struct %type% :|{|;")) if (Token::Match(tok, "class|struct %type% :|{|;"))
continue; continue;

View File

@ -126,6 +126,7 @@ private:
TEST_CASE(varidclass2); TEST_CASE(varidclass2);
TEST_CASE(varidclass3); TEST_CASE(varidclass3);
TEST_CASE(varidclass4); TEST_CASE(varidclass4);
TEST_CASE(varidclass5);
TEST_CASE(file1); TEST_CASE(file1);
TEST_CASE(file2); TEST_CASE(file2);
@ -1537,7 +1538,7 @@ private:
"5: b@2 * a@1 ;\n" "5: b@2 * a@1 ;\n"
"6: }\n"); "6: }\n");
TODO_ASSERT_EQUALS(expected, actual); ASSERT_EQUALS(expected, actual);
} }
void varidStl() void varidStl()
@ -1932,6 +1933,36 @@ private:
ASSERT_EQUALS(expected, actual); ASSERT_EQUALS(expected, actual);
} }
void varidclass5()
{
const std::string code("class A { };\n"
"class B\n"
"{\n"
" A *a;\n"
" B() : a(new A)\n"
" { }\n"
"};\n");
// tokenize..
Tokenizer tokenizer;
std::istringstream istr(code);
tokenizer.tokenize(istr, "test.cpp");
tokenizer.setVarId();
// result..
const std::string actual(tokenizer.tokens()->stringifyList(true));
const std::string expected("\n\n##file 0\n"
"1: class A { } ;\n"
"2: class B\n"
"3: {\n"
"4: A * a@1 ;\n"
"5: B ( ) : a@1 ( new A )\n"
"6: { }\n"
"7: } ;\n");
ASSERT_EQUALS(expected, actual);
}
void file1() void file1()