Fix #10826 FN: unusedStructMember (#3858)

This commit is contained in:
chrchr-github 2022-02-26 18:53:00 +01:00 committed by GitHub
parent dbc80787e1
commit 441b437cea
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 32 additions and 9 deletions

View File

@ -1445,7 +1445,7 @@ void CheckUnusedVar::checkStructMemberUsage()
continue; continue;
// Bail out if some data is casted to struct.. // Bail out if some data is casted to struct..
const std::string castPattern("( struct| " + scope.className + " * ) & %name% ["); const std::string castPattern("( struct| " + scope.className + " * ) &| %name%");
if (Token::findmatch(scope.bodyEnd, castPattern.c_str())) if (Token::findmatch(scope.bodyEnd, castPattern.c_str()))
continue; continue;
@ -1465,13 +1465,9 @@ void CheckUnusedVar::checkStructMemberUsage()
if (bailout) if (bailout)
continue; continue;
// Try to prevent false positives when struct members are not used directly.
if (Token::findmatch(scope.bodyEnd, (scope.className + " %type%| *").c_str()))
continue;
for (const Variable &var : scope.varlist) { for (const Variable &var : scope.varlist) {
// declaring a POD member variable? // only warn for variables without side effects
if (!var.typeStartToken()->isStandardType() && !var.isPointer()) if (!var.typeStartToken()->isStandardType() && !var.isPointer() && !astIsContainer(var.nameToken()) && !isRecordTypeWithoutSideEffects(var.type()))
continue; continue;
// Check if the struct member variable is used anywhere in the file // Check if the struct member variable is used anywhere in the file

View File

@ -66,6 +66,7 @@ private:
TEST_CASE(structmember16); // #10485 TEST_CASE(structmember16); // #10485
TEST_CASE(structmember17); // #10591 TEST_CASE(structmember17); // #10591
TEST_CASE(structmember18); // #10684 TEST_CASE(structmember18); // #10684
TEST_CASE(structmember19); // #10826
TEST_CASE(localvar1); TEST_CASE(localvar1);
TEST_CASE(localvar2); TEST_CASE(localvar2);
@ -1405,7 +1406,7 @@ private:
"{\n" "{\n"
" ab->a = 0;\n" " ab->a = 0;\n"
"}"); "}");
ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS("[test.cpp:4]: (style) struct member 'AB::b' is never used.\n", errout.str());
checkStructMemberUsage("struct AB\n" checkStructMemberUsage("struct AB\n"
"{\n" "{\n"
@ -1417,7 +1418,7 @@ private:
"{\n" "{\n"
" ab->a = 0;\n" " ab->a = 0;\n"
"}"); "}");
ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS("[test.cpp:4]: (style) struct member 'AB::b' is never used.\n", errout.str());
} }
void structmember8() { void structmember8() {
@ -1626,6 +1627,32 @@ private:
ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS("", errout.str());
} }
void structmember19() { // #10826
checkStructMemberUsage("class C {};\n"
"struct S {\n"
" char* p;\n"
" std::string str;\n"
" C c;\n"
"};\n"
"void f(S* s) {}\n");
ASSERT_EQUALS("[test.cpp:3]: (style) struct member 'S::p' is never used.\n"
"[test.cpp:4]: (style) struct member 'S::str' is never used.\n"
"[test.cpp:5]: (style) struct member 'S::c' is never used.\n",
errout.str());
checkStructMemberUsage("class C {};\n"
"struct S {\n"
" char* p;\n"
" std::string str;\n"
" C c;\n"
"};\n"
"void f(S& s) {}\n");
ASSERT_EQUALS("[test.cpp:3]: (style) struct member 'S::p' is never used.\n"
"[test.cpp:4]: (style) struct member 'S::str' is never used.\n"
"[test.cpp:5]: (style) struct member 'S::c' is never used.\n",
errout.str());
}
void functionVariableUsage_(const char* file, int line, const char code[], const char filename[] = "test.cpp") { void functionVariableUsage_(const char* file, int line, const char code[], const char filename[] = "test.cpp") {
// Clear the error buffer.. // Clear the error buffer..
errout.str(""); errout.str("");