reassign var: better handling of struct members

This commit is contained in:
Daniel Marjamäki 2013-08-15 16:13:58 +02:00
parent dc439f65f8
commit 5d7f30b88f
2 changed files with 39 additions and 3 deletions

View File

@ -596,8 +596,8 @@ static void eraseNotLocalArg(std::map<unsigned int, const Token*>& container, co
void CheckOther::checkRedundantAssignment() void CheckOther::checkRedundantAssignment()
{ {
bool performance = _settings->isEnabled("performance"); const bool performance = _settings->isEnabled("performance");
bool warning = _settings->isEnabled("warning"); const bool warning = _settings->isEnabled("warning");
if (!warning && !performance) if (!warning && !performance)
return; return;
@ -637,8 +637,12 @@ void CheckOther::checkRedundantAssignment()
initialized.insert(tok->varId()); initialized.insert(tok->varId());
} }
const Token *startToken = tok;
while (Token::Match(startToken, "%var%|::|."))
startToken = startToken->previous();
std::map<unsigned int, const Token*>::iterator it = varAssignments.find(tok->varId()); std::map<unsigned int, const Token*>::iterator it = varAssignments.find(tok->varId());
if (tok->next()->isAssignmentOp() && Token::Match(tok->previous(), "[;{}]")) { // Assignment if (tok->next()->isAssignmentOp() && Token::Match(startToken, "[;{}]")) { // Assignment
if (it != varAssignments.end()) { if (it != varAssignments.end()) {
bool error = true; // Ensure that variable is not used on right side bool error = true; // Ensure that variable is not used on right side
for (const Token* tok2 = tok->tokAt(2); tok2; tok2 = tok2->next()) { for (const Token* tok2 = tok->tokAt(2); tok2; tok2 = tok2->next()) {

View File

@ -5938,6 +5938,38 @@ private:
" return bar(x);\n" " return bar(x);\n"
"}"); "}");
ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS("", errout.str());
// struct member..
check("struct AB { int a; int b; };\n"
"\n"
"int f() {\n"
" struct AB ab;\n"
" ab.a = 1;\n"
" ab.a = 2;\n"
" return ab.a;\n"
"}");
ASSERT_EQUALS("[test.cpp:5] -> [test.cpp:6]: (performance, inconclusive) Variable 'a' is reassigned a value before the old one has been used if variable is no semaphore variable.\n", errout.str());
check("struct AB { int a; int b; };\n"
"\n"
"int f() {\n"
" struct AB ab;\n"
" ab.a = 1;\n"
" ab = do_something();\n"
" return ab.a;\n"
"}");
TODO_ASSERT_EQUALS("error", "", errout.str());
check("struct AB { int a; int b; };\n"
"\n"
"int f() {\n"
" struct AB ab;\n"
" ab.a = 1;\n"
" do_something(&ab);\n"
" ab.a = 2;\n"
" return ab.a;\n"
"}");
ASSERT_EQUALS("", errout.str());
} }
void redundantMemWrite() { void redundantMemWrite() {