Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions lib/checkunusedvar.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1599,6 +1599,23 @@ void CheckUnusedVar::checkStructMemberUsage()
if (bailout)
continue;

// #7458 - if struct is declared inside union and any struct member is used,
// then don't warn about other struct members
if (scope.type == ScopeType::eStruct && scope.nestedIn && scope.nestedIn->type == ScopeType::eUnion) {
bool structMemberUsed = false;

for (const Token *tok = scope.nestedIn->bodyStart; tok; tok = tok->next()) {
if (tok->variable() && tok != tok->variable()->nameToken() && tok->variable()->scope() == &scope) {
structMemberUsed = true;
break;
}
}

// Skip reporting unused members if this struct is in a union and any member is used
if (structMemberUsed)
continue;
}

for (const Variable &var : scope.varlist) {
// only warn for variables without side effects
if (!var.typeStartToken()->isStandardType() && !var.isPointer() && !astIsContainer(var.nameToken()) && !isRecordTypeWithoutSideEffects(var.type()))
Expand Down
16 changes: 16 additions & 0 deletions test/testunusedvar.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1409,6 +1409,22 @@ class TestUnusedVar : public TestFixture {
ASSERT_EQUALS("[test.cpp:3:9]: (style) union member 'abc::a' is never used. [unusedStructMember]\n"
"[test.cpp:4:9]: (style) union member 'abc::b' is never used. [unusedStructMember]\n"
"[test.cpp:5:9]: (style) union member 'abc::c' is never used. [unusedStructMember]\n", errout_str());

// #7458 - union with anonymous struct should not cause false positive
checkStructMemberUsage("union DoubleInt {\n"
" double asDouble;\n"
" uint64_t asInt;\n"
" struct {\n"
" uint32_t lo, hi;\n" // <- no FP about lo because hi is used
" } asIntel;\n"
"};\n"
"void f() {\n"
" union DoubleInt di;\n"
" di.asIntel.hi = 3;\n"
"}");
ASSERT_EQUALS("[test.cpp:2:12]: (style) union member 'DoubleInt::asDouble' is never used. [unusedStructMember]\n"
"[test.cpp:3:14]: (style) union member 'DoubleInt::asInt' is never used. [unusedStructMember]\n",
errout_str());
}

void structmember2() {
Expand Down