Fixed #1639 (False positive: unused variable value (pointer aliasing))
This commit is contained in:
parent
707d27f3d8
commit
eb276346c5
|
@ -503,6 +503,8 @@ public:
|
||||||
{
|
{
|
||||||
_varUsage.erase(varid);
|
_varUsage.erase(varid);
|
||||||
}
|
}
|
||||||
|
void eraseAliases(unsigned int varid);
|
||||||
|
void eraseAll(unsigned int varid);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
VariableMap _varUsage;
|
VariableMap _varUsage;
|
||||||
|
@ -551,6 +553,25 @@ void Variables::alias(unsigned int varid1, unsigned int varid2)
|
||||||
var2->_read = true;
|
var2->_read = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Variables::eraseAliases(unsigned int varid)
|
||||||
|
{
|
||||||
|
VariableUsage *usage = find(varid);
|
||||||
|
|
||||||
|
if (usage)
|
||||||
|
{
|
||||||
|
std::set<unsigned int>::iterator aliases;
|
||||||
|
|
||||||
|
for (aliases = usage->_aliases.begin(); aliases != usage->_aliases.end(); ++aliases)
|
||||||
|
erase(*aliases);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Variables::eraseAll(unsigned int varid)
|
||||||
|
{
|
||||||
|
eraseAliases(varid);
|
||||||
|
erase(varid);
|
||||||
|
}
|
||||||
|
|
||||||
void Variables::addVar(const Token *name,
|
void Variables::addVar(const Token *name,
|
||||||
VariableType type,
|
VariableType type,
|
||||||
bool write_)
|
bool write_)
|
||||||
|
@ -832,6 +853,26 @@ static int doAssignment(Variables &variables, const Token *tok, bool pointer)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// check for alias to struct member
|
||||||
|
// char c[10]; a.b = c;
|
||||||
|
else if (Token::Match(tok->tokAt(-2), "%var% ."))
|
||||||
|
{
|
||||||
|
if (Token::Match(tok->tokAt(2), "%var%"))
|
||||||
|
{
|
||||||
|
unsigned int varid2 = tok->tokAt(2)->varId();
|
||||||
|
Variables::VariableUsage *var2 = variables.find(varid2);
|
||||||
|
|
||||||
|
// struct member aliased to local variable
|
||||||
|
if (var2 && (var2->_type == Variables::array ||
|
||||||
|
var2->_type == Variables::pointer))
|
||||||
|
{
|
||||||
|
// erase aliased variable and all variables that alias it
|
||||||
|
// to prevent false positives
|
||||||
|
variables.eraseAll(varid2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return next;
|
return next;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -78,6 +78,7 @@ private:
|
||||||
TEST_CASE(localvar13); // ticket #1640
|
TEST_CASE(localvar13); // ticket #1640
|
||||||
TEST_CASE(localvaralias1);
|
TEST_CASE(localvaralias1);
|
||||||
TEST_CASE(localvaralias2); // ticket #1637
|
TEST_CASE(localvaralias2); // ticket #1637
|
||||||
|
TEST_CASE(localvaralias3); // ticket #1639
|
||||||
TEST_CASE(localvarasm);
|
TEST_CASE(localvarasm);
|
||||||
|
|
||||||
// Don't give false positives for variables in structs/unions
|
// Don't give false positives for variables in structs/unions
|
||||||
|
@ -1408,6 +1409,18 @@ private:
|
||||||
ASSERT_EQUALS(std::string(""), errout.str());
|
ASSERT_EQUALS(std::string(""), errout.str());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void localvaralias3() // ticket 1639
|
||||||
|
{
|
||||||
|
functionVariableUsage("void foo()\n"
|
||||||
|
"{\n"
|
||||||
|
" BROWSEINFO info;\n"
|
||||||
|
" char szDisplayName[MAX_PATH];\n"
|
||||||
|
" info.pszDisplayName = szDisplayName;\n"
|
||||||
|
" SHBrowseForFolder(&info);\n"
|
||||||
|
"}\n");
|
||||||
|
ASSERT_EQUALS(std::string(""), errout.str());
|
||||||
|
}
|
||||||
|
|
||||||
void localvarasm()
|
void localvarasm()
|
||||||
{
|
{
|
||||||
functionVariableUsage("void foo(int &b)\n"
|
functionVariableUsage("void foo(int &b)\n"
|
||||||
|
|
Loading…
Reference in New Issue