Fix #10847 (FP: unusedStructMember) (#5177)

This commit is contained in:
Daniel Marjamäki 2023-06-20 22:34:54 +02:00 committed by GitHub
parent bb962e2bc3
commit f2510228cb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 37 additions and 2 deletions

View File

@ -1515,6 +1515,11 @@ void CheckUnusedVar::checkStructMemberUsage()
// Check if the struct member variable is used anywhere in the file // Check if the struct member variable is used anywhere in the file
bool use = false; bool use = false;
for (const Token *tok = mTokenizer->tokens(); tok; tok = tok->next()) { for (const Token *tok = mTokenizer->tokens(); tok; tok = tok->next()) {
if (Token::Match(tok, ". %name%") && !tok->next()->variable() && !tok->next()->function() && tok->next()->str() == var.name()) {
// not known => assume variable is used
use = true;
break;
}
if (tok->variable() != &var) if (tok->variable() != &var)
continue; continue;
if (tok != var.nameToken()) { if (tok != var.nameToken()) {

View File

@ -71,6 +71,7 @@ private:
TEST_CASE(structmember21); // #4759 TEST_CASE(structmember21); // #4759
TEST_CASE(structmember22); // #11016 TEST_CASE(structmember22); // #11016
TEST_CASE(structmember23); TEST_CASE(structmember23);
TEST_CASE(structmember24); // #10847
TEST_CASE(structmember_macro); TEST_CASE(structmember_macro);
TEST_CASE(classmember); TEST_CASE(classmember);
@ -275,6 +276,9 @@ private:
} }
void checkStructMemberUsageP(const char code[]) { void checkStructMemberUsageP(const char code[]) {
// Clear the error buffer..
errout.str("");
// Raw tokens.. // Raw tokens..
std::vector<std::string> files(1, "test.cpp"); std::vector<std::string> files(1, "test.cpp");
std::istringstream istr(code); std::istringstream istr(code);
@ -300,6 +304,9 @@ private:
void checkFunctionVariableUsageP(const char code[], const char* filename = "test.cpp") { void checkFunctionVariableUsageP(const char code[], const char* filename = "test.cpp") {
// Clear the error buffer..
errout.str("");
// Raw tokens.. // Raw tokens..
std::vector<std::string> files(1, filename); std::vector<std::string> files(1, filename);
std::istringstream istr(code); std::istringstream istr(code);
@ -1707,7 +1714,7 @@ private:
" t.i = 0;\n" // <- used " t.i = 0;\n" // <- used
" g(t);\n" " g(t);\n"
"};\n"); "};\n");
TODO_ASSERT_EQUALS("", "[test.cpp:1]: (style) struct member 'T::i' is never used.\n", errout.str()); // due to removeMacroInClassDef() ASSERT_EQUALS("", errout.str()); // due to removeMacroInClassDef()
} }
void structmember18() { // #10684 void structmember18() { // #10684
@ -1869,7 +1876,7 @@ private:
"public:\n" "public:\n"
" int f() { return 0; }\n" " int f() { return 0; }\n"
"};\n" "};\n"
"C C;\n" "C c;\n"
"int g() {\n" "int g() {\n"
" return c.f();\n" " return c.f();\n"
"}\n" "}\n"
@ -1905,6 +1912,29 @@ private:
ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS("", errout.str());
} }
void structmember24() { // #10847
checkStructMemberUsage("struct S { std::map<int, S*> m; };\n"
"std::map<int, S*> u;\n"
"std::map<int, S*>::iterator f() {\n"
" return u.find(0)->second->m.begin();\n"
"}\n");
ASSERT_EQUALS("", errout.str());
checkStructMemberUsage("struct S { int i; };\n"
"void f() {\n"
" std::map<int, S> m = { { 0, S() } };\n"
" m[0].i = 1;\n"
"}\n");
ASSERT_EQUALS("", errout.str());
checkStructMemberUsage("struct S { bool b; };\n"
"std::vector<S> v;\n"
"bool f() {\n"
" return v.begin()->b;\n"
"}\n");
ASSERT_EQUALS("", errout.str());
}
void structmember_macro() { void structmember_macro() {
checkStructMemberUsageP("#define S(n) struct n { int a, b, c; };\n" checkStructMemberUsageP("#define S(n) struct n { int a, b, c; };\n"
"S(unused);\n"); "S(unused);\n");