From 45573ad101677f44a7161b7ce503d328616add8f Mon Sep 17 00:00:00 2001 From: Robert Reif Date: Fri, 16 Apr 2010 15:57:09 +0200 Subject: [PATCH] Fixed #1607 (false positive: variable is assigned a value that is never used) --- lib/checkother.cpp | 22 +++++++++++++++++++++- test/testunusedvar.cpp | 13 +++++++++++-- 2 files changed, 32 insertions(+), 3 deletions(-) diff --git a/lib/checkother.cpp b/lib/checkother.cpp index c2e2416ec..4f50b774b 100644 --- a/lib/checkother.cpp +++ b/lib/checkother.cpp @@ -470,6 +470,7 @@ public: read = false; write = false; modified = false; + aliased = false; } /** variable is used.. set both read+write */ @@ -489,6 +490,7 @@ public: bool read; bool write; bool modified; // read/modify/write + bool aliased; // pointer or reference }; void CheckOther::functionVariableUsage() @@ -572,7 +574,19 @@ void CheckOther::functionVariableUsage() { varUsage[tok->strAt(3)].declare = true; if (tok->tokAt(4)->str() == "=") + { varUsage[tok->strAt(3)].write = true; + if (Token::Match(tok->tokAt(5), "%var% = &| %var%") && + tok->tokAt(5)->str() == tok->tokAt(3)->str()) + { + varUsage[tok->strAt(3)].aliased = true; + } + } + else if (Token::Match(tok->tokAt(5), "%var% = &| %var%") && + tok->tokAt(5)->str() == tok->tokAt(3)->str()) + { + varUsage[tok->strAt(3)].aliased = true; + } tok = tok->tokAt(3); } } @@ -580,6 +594,7 @@ void CheckOther::functionVariableUsage() else if (Token::Match(tok, "[;{}] const %type% *|& %var% ;|=")) { varUsage[tok->strAt(4)].declare = true; + varUsage[tok->strAt(4)].aliased = true; if (tok->tokAt(5)->str() == "=") varUsage[tok->strAt(4)].write = true; tok = tok->tokAt(4); @@ -588,6 +603,7 @@ void CheckOther::functionVariableUsage() else if (Token::Match(tok, "[;{}] struct|union %type% *|& %var% ;|=")) { varUsage[tok->strAt(4)].declare = true; + varUsage[tok->strAt(4)].aliased = true; if (tok->tokAt(5)->str() == "=") varUsage[tok->strAt(4)].write = true; tok = tok->tokAt(4); @@ -596,6 +612,7 @@ void CheckOther::functionVariableUsage() else if (Token::Match(tok, "[;{}] const struct|union %type% *|& %var% ;|=")) { varUsage[tok->strAt(5)].declare = true; + varUsage[tok->strAt(5)].aliased = true; if (tok->tokAt(6)->str() == "=") varUsage[tok->strAt(5)].write = true; tok = tok->tokAt(5); @@ -605,6 +622,7 @@ void CheckOther::functionVariableUsage() { varUsage[tok->strAt(3)].declare = true; varUsage[tok->strAt(3)].write = true; + varUsage[tok->strAt(3)].aliased = true; if (tok->tokAt(5)->varId() > 0) { if (varUsage.find(tok->tokAt(5)->str()) != varUsage.end()) @@ -621,6 +639,7 @@ void CheckOther::functionVariableUsage() else if (Token::Match(tok, "[;{}] %type% *|& %var% [ %num% ] ;|=") && (tok->next()->isStandardType() || tok->next()->str() == "void")) { varUsage[tok->strAt(3)].declare = true; + varUsage[tok->strAt(3)].aliased = true; if (tok->tokAt(7)->str() == "=") varUsage[tok->strAt(3)].write = true; tok = tok->tokAt(6); @@ -629,6 +648,7 @@ void CheckOther::functionVariableUsage() else if (Token::Match(tok, "[;{}] const %type% *|& %var% [ %num% ] ;|=") && (tok->tokAt(2)->isStandardType() || tok->tokAt(2)->str() == "void")) { varUsage[tok->strAt(4)].declare = true; + varUsage[tok->strAt(4)].aliased = true; if (tok->tokAt(8)->str() == "=") varUsage[tok->strAt(4)].write = true; tok = tok->tokAt(7); @@ -697,7 +717,7 @@ void CheckOther::functionVariableUsage() unassignedVariableError(tok1, varname); } - else if (!usage.read && !usage.modified) + else if (!usage.read && !usage.modified && !usage.aliased) { unreadVariableError(tok1, varname); } diff --git a/test/testunusedvar.cpp b/test/testunusedvar.cpp index a57b6ac9b..812f53224 100644 --- a/test/testunusedvar.cpp +++ b/test/testunusedvar.cpp @@ -491,7 +491,7 @@ private: " char *i;\n" " i = fgets();\n" "}\n"); - ASSERT_EQUALS("[test.cpp:2]: (style) Variable 'i' is assigned a value that is never used\n", errout.str()); + TODO_ASSERT_EQUALS("[test.cpp:2]: (style) Variable 'i' is assigned a value that is never used\n", errout.str()); functionVariableUsage("void foo()\n" "{\n" @@ -506,6 +506,15 @@ private: "}\n"); ASSERT_EQUALS("", errout.str()); + functionVariableUsage("int a[10];\n" + "void foo()\n" + "{\n" + " int *p = a;\n" + " for (int i = 0; i < 10; i++)\n" + " p[i] = 0;\n" + "}\n"); + ASSERT_EQUALS("", errout.str()); + functionVariableUsage("int a[10];\n" "void foo()\n" "{\n" @@ -513,7 +522,7 @@ private: " for (int i = 0; i < 10; i++)\n" " p[i] = 0;\n" "}\n"); - ASSERT_EQUALS("[test.cpp:3]: (style) Variable 'p' is assigned a value that is never used\n", errout.str()); + ASSERT_EQUALS("", errout.str()); } void localvarasm()