Fixed #1356 (Double-False positive: uninitialized variable)
This commit is contained in:
parent
1b0c81a24b
commit
fb09b2fd37
|
@ -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))
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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()
|
||||||
|
|
Loading…
Reference in New Issue