Variable usage: Better aliasing support (Ticket #1729)

This commit is contained in:
Robert Reif 2010-07-08 07:59:47 +02:00 committed by Daniel Marjamäki
parent 49626e427e
commit 2d6dfa57e1
2 changed files with 133 additions and 19 deletions

View File

@ -565,7 +565,7 @@ public:
void use(unsigned int varid);
void modified(unsigned int varid);
VariableUsage *find(unsigned int varid);
void alias(unsigned int varid1, unsigned int varid2);
void alias(unsigned int varid1, unsigned int varid2, bool replace);
void erase(unsigned int varid)
{
_varUsage.erase(varid);
@ -578,35 +578,43 @@ private:
VariableMap _varUsage;
};
void Variables::alias(unsigned int varid1, unsigned int varid2)
/**
* Alias the 2 given variables. Either replace the existing aliases if
* they exist or merge them. You would replace an existing alias when this
* assignment is in the same scope as the previous assignment. You might
* merge the aliases when this assignment is in a different scope from the
* previous assignment depending on the relationship of the 2 scopes.
*/
void Variables::alias(unsigned int varid1, unsigned int varid2, bool replace)
{
VariableUsage *var1 = find(varid1);
VariableUsage *var2 = find(varid2);
// alias to self
if (varid1 == varid2)
{
VariableUsage *var = find(varid1);
if (var)
var->use();
if (var1)
var1->use();
return;
}
std::set<unsigned int>::iterator i;
VariableUsage *var1 = find(varid1);
// remove var1 from all aliases
for (i = var1->_aliases.begin(); i != var1->_aliases.end(); ++i)
if (replace)
{
VariableUsage *temp = find(*i);
// remove var1 from all aliases
for (i = var1->_aliases.begin(); i != var1->_aliases.end(); ++i)
{
VariableUsage *temp = find(*i);
if (temp)
temp->_aliases.erase(var1->_name->varId());
if (temp)
temp->_aliases.erase(var1->_name->varId());
}
// remove all aliases from var1
var1->_aliases.clear();
}
// remove all aliases from var1
var1->_aliases.clear();
VariableUsage *var2 = find(varid2);
// var1 gets all var2s aliases
for (i = var2->_aliases.begin(); i != var2->_aliases.end(); ++i)
{
@ -925,13 +933,15 @@ static int doAssignment(Variables &variables, const Token *tok, bool dereference
var2->_type == Variables::array ||
var2->_type == Variables::pointer)
{
variables.alias(varid1, varid2);
bool replace = true;
variables.alias(varid1, varid2, replace);
}
}
}
else if (var1->_type == Variables::reference)
{
variables.alias(varid1, varid2);
variables.alias(varid1, varid2, true);
}
else
{

View File

@ -1796,6 +1796,56 @@ private:
"}");
ASSERT_EQUALS("", errout.str());
functionVariableUsage("void foo()\n"
"{\n"
" char buf[8];\n"
" char *srcdata;\n"
" if (a()) {\n"
" buf[0] = 1;\n"
" srcdata = buf;\n"
" srcdata = vdata;\n"
" }\n"
" b(srcdata);\n"
"}");
TODO_ASSERT_EQUALS(std::string("[test.cpp:3]: (style) Variable 'buf' is assigned a value that is never used\n"), errout.str());
functionVariableUsage("void foo()\n"
"{\n"
" char buf[8];\n"
" char *srcdata;\n"
" if (a()) {\n"
" buf[0] = 1;\n"
" srcdata = buf;\n"
" }\n"
" srcdata = vdata;\n"
" b(srcdata);\n"
"}");
TODO_ASSERT_EQUALS(std::string("[test.cpp:3]: (style) Variable 'buf' is assigned a value that is never used\n"), errout.str());
functionVariableUsage("void foo()\n"
"{\n"
" char buf[8];\n"
" char *srcdata;\n"
" if (a()) {\n"
" srcdata = buf;\n"
" }\n"
" srcdata = vdata;\n"
" b(srcdata);\n"
"}");
TODO_ASSERT_EQUALS(std::string("[test.cpp:3]: (style) Unused variable: buf\n"), errout.str());
functionVariableUsage("void foo()\n"
"{\n"
" char buf[8];\n"
" char *srcdata;\n"
" if (a()) {\n"
" srcdata = vdata;\n"
" }\n"
" srcdata = buf;\n"
" b(srcdata);\n"
"}");
ASSERT_EQUALS(std::string(""), errout.str());
functionVariableUsage("void foo()\n"
"{\n"
" char buf[8];\n"
@ -1810,6 +1860,60 @@ private:
" b(srcdata);\n"
"}");
ASSERT_EQUALS("", errout.str());
functionVariableUsage("void foo()\n"
"{\n"
" char buf[8];\n"
" char *srcdata;\n"
" char vdata[8];\n"
" if (a()) {\n"
" buf[0] = 1;\n"
" srcdata = buf;\n"
" srcdata = vdata;\n"
" }\n"
" b(srcdata);\n"
"}");
TODO_ASSERT_EQUALS(std::string("[test.cpp:3]: (style) Variable 'buf' is assigned a value that is never used\n"), errout.str());
functionVariableUsage("void foo()\n"
"{\n"
" char buf[8];\n"
" char *srcdata;\n"
" char vdata[8];\n"
" if (a()) {\n"
" buf[0] = 1;\n"
" srcdata = buf;\n"
" }\n"
" srcdata = vdata;\n"
" b(srcdata);\n"
"}");
TODO_ASSERT_EQUALS(std::string("[test.cpp:3]: (style) Variable 'buf' is assigned a value that is never used\n"), errout.str());
functionVariableUsage("void foo()\n"
"{\n"
" char buf[8];\n"
" char *srcdata;\n"
" char vdata[8];\n"
" if (a()) {\n"
" srcdata = buf;\n"
" }\n"
" srcdata = vdata;\n"
" b(srcdata);\n"
"}");
TODO_ASSERT_EQUALS(std::string("[test.cpp:3]: (style) Unused variable: buf\n"), errout.str());
functionVariableUsage("void foo()\n"
"{\n"
" char buf[8];\n"
" char *srcdata;\n"
" char vdata[8];\n"
" if (a()) {\n"
" srcdata = vdata;\n"
" }\n"
" srcdata = buf;\n"
" b(srcdata);\n"
"}");
TODO_ASSERT_EQUALS(std::string("[test.cpp:5]: (style) Unused variable: vdata\n"), errout.str());
}
void localvaralias7() // ticket 1732