From 5d7f30b88f3399df5e59fc127a9d43d037b8e93f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Thu, 15 Aug 2013 16:13:58 +0200 Subject: [PATCH] reassign var: better handling of struct members --- lib/checkother.cpp | 10 +++++++--- test/testother.cpp | 32 ++++++++++++++++++++++++++++++++ 2 files changed, 39 insertions(+), 3 deletions(-) diff --git a/lib/checkother.cpp b/lib/checkother.cpp index 2ccb6b941..2ce209449 100644 --- a/lib/checkother.cpp +++ b/lib/checkother.cpp @@ -596,8 +596,8 @@ static void eraseNotLocalArg(std::map& container, co void CheckOther::checkRedundantAssignment() { - bool performance = _settings->isEnabled("performance"); - bool warning = _settings->isEnabled("warning"); + const bool performance = _settings->isEnabled("performance"); + const bool warning = _settings->isEnabled("warning"); if (!warning && !performance) return; @@ -637,8 +637,12 @@ void CheckOther::checkRedundantAssignment() initialized.insert(tok->varId()); } + const Token *startToken = tok; + while (Token::Match(startToken, "%var%|::|.")) + startToken = startToken->previous(); + std::map::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()) { bool error = true; // Ensure that variable is not used on right side for (const Token* tok2 = tok->tokAt(2); tok2; tok2 = tok2->next()) { diff --git a/test/testother.cpp b/test/testother.cpp index a924a60b2..022fa0625 100644 --- a/test/testother.cpp +++ b/test/testother.cpp @@ -5938,6 +5938,38 @@ private: " return bar(x);\n" "}"); 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() {