Fix FN for distinct structs with identical members
This commit is contained in:
parent
14c792f41e
commit
da15efb3f6
|
@ -1232,34 +1232,43 @@ void CheckUnusedVar::checkStructMemberUsage()
|
||||||
structname.clear();
|
structname.clear();
|
||||||
|
|
||||||
if (!structname.empty() && Token::Match(tok, "[{;]")) {
|
if (!structname.empty() && Token::Match(tok, "[{;]")) {
|
||||||
// declaring a POD variable?
|
// declaring a POD member variable?
|
||||||
if (!tok->next()->isStandardType())
|
if (!tok->next()->isStandardType())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// Declaring struct variable..
|
// Declaring struct member variable..
|
||||||
const std::string* varname;
|
const std::string* memberVarName;
|
||||||
|
|
||||||
if (Token::Match(tok->next(), "%type% %name% [;[]"))
|
if (Token::Match(tok->next(), "%type% %name% [;[]"))
|
||||||
varname = &tok->strAt(2);
|
memberVarName = &tok->strAt(2);
|
||||||
else if (Token::Match(tok->next(), "%type% %type%|* %name% [;[]"))
|
else if (Token::Match(tok->next(), "%type% %type%|* %name% [;[]"))
|
||||||
varname = &tok->strAt(3);
|
memberVarName = &tok->strAt(3);
|
||||||
else if (Token::Match(tok->next(), "%type% %type% * %name% [;[]"))
|
else if (Token::Match(tok->next(), "%type% %type% * %name% [;[]"))
|
||||||
varname = &tok->strAt(4);
|
memberVarName = &tok->strAt(4);
|
||||||
else
|
else
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// Check if the struct variable is used anywhere in the file
|
// Check if the struct member variable is used anywhere in the file
|
||||||
const std::string usagePattern(". " + *varname);
|
const std::string usagePattern(". " + *memberVarName);
|
||||||
bool used = false;
|
bool used = false;
|
||||||
for (const Token *tok2 = _tokenizer->tokens(); tok2; tok2 = tok2->next()) {
|
const Token* usageTok = _tokenizer->tokens();
|
||||||
if (Token::simpleMatch(tok2, usagePattern.c_str())) {
|
while ((usageTok = Token::findsimplematch(usageTok->next(), usagePattern.c_str())) != nullptr) {
|
||||||
|
// Locate the containing struct variable and ensure it's of the same type, not a random struct
|
||||||
|
const Token* structVarTok = usageTok->previous();
|
||||||
|
// Walk backwards over array accesses
|
||||||
|
while (structVarTok && structVarTok->link())
|
||||||
|
structVarTok = structVarTok->link()->previous();
|
||||||
|
if (!structVarTok)
|
||||||
|
continue;
|
||||||
|
const Variable* structVar = structVarTok->variable();
|
||||||
|
if (structVar && structVar->type() && structVar->type()->name() == structname) {
|
||||||
used = true;
|
used = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!used) {
|
if (!used) {
|
||||||
unusedStructMemberError(tok->next(), structname, *varname, tok->scope()->type == Scope::eUnion);
|
unusedStructMemberError(tok->next(), structname, *memberVarName, tok->scope()->type == Scope::eUnion);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -222,6 +222,34 @@ private:
|
||||||
"[test.cpp:4]: (style) union member 'abc::b' is never used.\n"
|
"[test.cpp:4]: (style) union member 'abc::b' is never used.\n"
|
||||||
"[test.cpp:5]: (style) union member 'abc::c' is never used.\n", errout.str());
|
"[test.cpp:5]: (style) union member 'abc::c' is never used.\n", errout.str());
|
||||||
|
|
||||||
|
checkStructMemberUsage("struct A\n"
|
||||||
|
"{\n"
|
||||||
|
" int a;\n"
|
||||||
|
"};\n"
|
||||||
|
"struct B\n"
|
||||||
|
"{\n"
|
||||||
|
" int a;\n"
|
||||||
|
"};\n"
|
||||||
|
"void foo()\n"
|
||||||
|
"{\n"
|
||||||
|
" A a;\n"
|
||||||
|
" a.a;\n"
|
||||||
|
"}");
|
||||||
|
ASSERT_EQUALS("[test.cpp:7]: (style) struct member 'B::a' is never used.\n", errout.str());
|
||||||
|
|
||||||
|
checkStructMemberUsage("struct A\n"
|
||||||
|
"{\n"
|
||||||
|
" int a;\n"
|
||||||
|
"};\n"
|
||||||
|
"struct B\n"
|
||||||
|
"{\n"
|
||||||
|
" int a;\n"
|
||||||
|
"};\n"
|
||||||
|
"void foo(A* a)\n"
|
||||||
|
"{\n"
|
||||||
|
" a->a;\n"
|
||||||
|
"}");
|
||||||
|
ASSERT_EQUALS("[test.cpp:7]: (style) struct member 'B::a' is never used.\n", errout.str());
|
||||||
}
|
}
|
||||||
|
|
||||||
void structmember2() {
|
void structmember2() {
|
||||||
|
|
Loading…
Reference in New Issue