diff --git a/lib/checkother.cpp b/lib/checkother.cpp index 6f76f95e4..025f83790 100644 --- a/lib/checkother.cpp +++ b/lib/checkother.cpp @@ -860,6 +860,12 @@ void CheckOther::checkStructMemberUsage() const std::string s("( struct| " + tok->next()->str() + " * ) & %var% ["); if (Token::findmatch(tok, s.c_str())) structname = ""; + + // Try to prevent false positives when struct members are not used directly. + if (Token::findmatch(tok, (structname + " *").c_str())) + structname = ""; + else if (Token::findmatch(tok, (structname + " %type% *").c_str())) + structname = ""; } if (tok->str() == "}") @@ -867,6 +873,7 @@ void CheckOther::checkStructMemberUsage() if (!structname.empty() && Token::Match(tok, "[{;]")) { + // Declaring struct variable.. std::string varname; if (Token::Match(tok->next(), "%type% %var% [;[]")) varname = tok->strAt(2); @@ -879,6 +886,7 @@ void CheckOther::checkStructMemberUsage() else continue; + // Check if the struct variable is anywhere in the file const std::string usagePattern(". " + varname); bool used = false; for (const Token *tok2 = _tokenizer->tokens(); tok2; tok2 = tok2->next()) diff --git a/test/testunusedvar.cpp b/test/testunusedvar.cpp index 8ed5fb9ac..26bf7aa0f 100644 --- a/test/testunusedvar.cpp +++ b/test/testunusedvar.cpp @@ -58,6 +58,8 @@ private: TEST_CASE(structmember4); TEST_CASE(structmember5); TEST_CASE(structmember6); + TEST_CASE(structmember7); + TEST_CASE(structmember8); TEST_CASE(localvar1); TEST_CASE(localvar2); @@ -200,6 +202,48 @@ private: ASSERT_EQUALS("", errout.str()); } + void structmember7() + { + check("struct AB\n" + "{\n" + " int a;\n" + " int b;\n" + "};\n" + "\n" + "void foo(struct AB *ab)\n" + "{\n" + " ab->a = 0;\n" + "}\n"); + ASSERT_EQUALS("", errout.str()); + + check("struct AB\n" + "{\n" + " int a;\n" + " int b;\n" + "};\n" + "\n" + "void foo(struct AB _shuge *ab)\n" + "{\n" + " ab->a = 0;\n" + "}\n"); + ASSERT_EQUALS("", errout.str()); + } + + void structmember8() + { + check("struct AB\n" + "{\n" + " int a;\n" + " int b;\n" + "};\n" + "\n" + "void foo(char *ab)\n" + "{\n" + " ((AB *)ab)->b = 0;\n" + "}\n"); + ASSERT_EQUALS("", errout.str()); + } +