Skip to content

Commit a0e7c5b

Browse files
authored
Fix danmar#7458 (FP unusedStructMember with struct in union) (danmar#7844)
1 parent 9ac99f0 commit a0e7c5b

File tree

2 files changed

+33
-0
lines changed

2 files changed

+33
-0
lines changed

lib/checkunusedvar.cpp

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1599,6 +1599,23 @@ void CheckUnusedVar::checkStructMemberUsage()
15991599
if (bailout)
16001600
continue;
16011601

1602+
// #7458 - if struct is declared inside union and any struct member is used,
1603+
// then don't warn about other struct members
1604+
if (scope.type == ScopeType::eStruct && scope.nestedIn && scope.nestedIn->type == ScopeType::eUnion) {
1605+
bool structMemberUsed = false;
1606+
1607+
for (const Token *tok = scope.nestedIn->bodyStart; tok; tok = tok->next()) {
1608+
if (tok->variable() && tok != tok->variable()->nameToken() && tok->variable()->scope() == &scope) {
1609+
structMemberUsed = true;
1610+
break;
1611+
}
1612+
}
1613+
1614+
// Skip reporting unused members if this struct is in a union and any member is used
1615+
if (structMemberUsed)
1616+
continue;
1617+
}
1618+
16021619
for (const Variable &var : scope.varlist) {
16031620
// only warn for variables without side effects
16041621
if (!var.typeStartToken()->isStandardType() && !var.isPointer() && !astIsContainer(var.nameToken()) && !isRecordTypeWithoutSideEffects(var.type()))

test/testunusedvar.cpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1411,6 +1411,22 @@ class TestUnusedVar : public TestFixture {
14111411
ASSERT_EQUALS("[test.cpp:3:9]: (style) union member 'abc::a' is never used. [unusedStructMember]\n"
14121412
"[test.cpp:4:9]: (style) union member 'abc::b' is never used. [unusedStructMember]\n"
14131413
"[test.cpp:5:9]: (style) union member 'abc::c' is never used. [unusedStructMember]\n", errout_str());
1414+
1415+
// #7458 - union with anonymous struct should not cause false positive
1416+
checkStructMemberUsage("union DoubleInt {\n"
1417+
" double asDouble;\n"
1418+
" uint64_t asInt;\n"
1419+
" struct {\n"
1420+
" uint32_t lo, hi;\n" // <- no FP about lo because hi is used
1421+
" } asIntel;\n"
1422+
"};\n"
1423+
"void f() {\n"
1424+
" union DoubleInt di;\n"
1425+
" di.asIntel.hi = 3;\n"
1426+
"}");
1427+
ASSERT_EQUALS("[test.cpp:2:12]: (style) union member 'DoubleInt::asDouble' is never used. [unusedStructMember]\n"
1428+
"[test.cpp:3:14]: (style) union member 'DoubleInt::asInt' is never used. [unusedStructMember]\n",
1429+
errout_str());
14141430
}
14151431

14161432
void structmember2() {

0 commit comments

Comments
 (0)