Skip to content

Commit 7474765

Browse files
Fix #14371: FP redundantAssignment for nested union members (#8748)
1 parent 93546a2 commit 7474765

2 files changed

Lines changed: 47 additions & 1 deletion

File tree

lib/checkother.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -700,8 +700,12 @@ void CheckOtherImpl::checkRedundantAssignment()
700700
// Get next assignment..
701701
const Token *nextAssign = fwdAnalysis.reassign(tokenToCheck, start, scope->bodyEnd);
702702
// extra check for union
703-
if (nextAssign && tokenToCheck != tok->astOperand1())
703+
if (nextAssign && tokenToCheck != tok->astOperand1()) {
704704
nextAssign = fwdAnalysis.reassign(tok->astOperand1(), start, scope->bodyEnd);
705+
// reading another member of the same union in the rhs is a use through aliasing
706+
if (nextAssign && fwdAnalysis.hasOperand(nextAssign->astOperand2(), tokenToCheck))
707+
nextAssign = nullptr;
708+
}
705709

706710
if (!nextAssign)
707711
continue;

test/testother.cpp

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11063,6 +11063,48 @@ class TestOther : public TestFixture {
1106311063
" Dst.s->y = Src.s->y;\n"
1106411064
"}\n");
1106511065
ASSERT_EQUALS("", errout_str());
11066+
11067+
// Ticket #14371 "redundantAssignment when using a union"
11068+
check("union U {\n"
11069+
" struct {\n"
11070+
" unsigned int abcd;\n"
11071+
" } u32;\n"
11072+
" struct {\n"
11073+
" unsigned short ab;\n"
11074+
" unsigned short cd;\n"
11075+
" } u16;\n"
11076+
"};\n"
11077+
"void f1() {\n"
11078+
" U m;\n"
11079+
" m.u32.abcd = 1234;\n"
11080+
" m.u32.abcd = 5 * m.u16.ab;\n"
11081+
"}\n"
11082+
"void f2(unsigned int a, unsigned short b) {\n"
11083+
" U m;\n"
11084+
" m.u32.abcd = a;\n"
11085+
" m.u32.abcd += 0x8000;\n"
11086+
" m.u32.abcd = m.u16.ab * b;\n"
11087+
"}\n"
11088+
"void f3(unsigned int seed) {\n"
11089+
" U m, other;\n"
11090+
" other.u32.abcd = seed;\n"
11091+
" m.u32.abcd = 1234;\n"
11092+
" m.u32.abcd = other.u16.ab * 2;\n"
11093+
"}\n"
11094+
"void f4(unsigned short x) {\n"
11095+
" U m;\n"
11096+
" m.u16.ab = x;\n"
11097+
" m.u16.cd = 0;\n"
11098+
" m.u16.ab = m.u32.abcd / 53;\n"
11099+
"}\n"
11100+
"void f5(unsigned short x, unsigned int y) {\n"
11101+
" U m;\n"
11102+
" m.u16.ab = x;\n"
11103+
" m.u16.cd = 0;\n"
11104+
" m.u16.ab = y;\n"
11105+
"}\n", dinit(CheckOptions, $.inconclusive = false));
11106+
ASSERT_EQUALS("[test.cpp:24:16] -> [test.cpp:25:16]: (style) Variable 'm.u32.abcd' is reassigned a value before the old one has been used. [redundantAssignment]\n"
11107+
"[test.cpp:35:14] -> [test.cpp:37:14]: (style) Variable 'm.u16.ab' is reassigned a value before the old one has been used. [redundantAssignment]\n", errout_str());
1106611108
}
1106711109

1106811110
void redundantVarAssignment_7133() {

0 commit comments

Comments
 (0)