diff --git a/lib/checkunusedvar.cpp b/lib/checkunusedvar.cpp index 7a75e60b1..87a92dfd2 100644 --- a/lib/checkunusedvar.cpp +++ b/lib/checkunusedvar.cpp @@ -1270,6 +1270,16 @@ void CheckUnusedVar::checkStructMemberUsage() if (Token::findmatch(scope->classEnd, castPattern.c_str())) continue; + // Bail out if struct is used in sizeof.. + for (const Token *tok = scope->classEnd; nullptr != (tok = Token::findsimplematch(tok, "sizeof ("));) { + if (Token::Match(tok->tokAt(2), ("struct| " + scope->className).c_str())) { + bailout = true; + break; + } + } + if (bailout) + continue; + // Try to prevent false positives when struct members are not used directly. if (Token::findmatch(scope->classEnd, (scope->className + " %type%| *").c_str())) continue; diff --git a/test/testunusedvar.cpp b/test/testunusedvar.cpp index a4aa7255e..8c08c8c84 100644 --- a/test/testunusedvar.cpp +++ b/test/testunusedvar.cpp @@ -48,6 +48,7 @@ private: TEST_CASE(structmember10); TEST_CASE(structmember11); // #4168 - initialization with {} / passed by address to unknown function TEST_CASE(structmember12); // #7179 - FP unused structmember + TEST_CASE(structmember_sizeof); TEST_CASE(localvar1); TEST_CASE(localvar2); @@ -461,6 +462,22 @@ private: ASSERT_EQUALS("[test.cpp:3]: (style) struct member 'AB::a' is never used.\n", errout.str()); } + void structmember_sizeof() { + checkStructMemberUsage("struct Header {\n" + " uint8_t message_type;\n" + "}\n" + "\n" + "input.skip(sizeof(Header));"); + ASSERT_EQUALS("", errout.str()); + + checkStructMemberUsage("struct Header {\n" + " uint8_t message_type;\n" + "}\n" + "\n" + "input.skip(sizeof(struct Header));"); + ASSERT_EQUALS("", errout.str()); + } + void functionVariableUsage(const char code[], const char filename[]="test.cpp") { // Clear the error buffer.. errout.str("");