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
6 changes: 5 additions & 1 deletion lib/checkother.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -700,8 +700,12 @@ void CheckOtherImpl::checkRedundantAssignment()
// Get next assignment..
const Token *nextAssign = fwdAnalysis.reassign(tokenToCheck, start, scope->bodyEnd);
// extra check for union
if (nextAssign && tokenToCheck != tok->astOperand1())
if (nextAssign && tokenToCheck != tok->astOperand1()) {
nextAssign = fwdAnalysis.reassign(tok->astOperand1(), start, scope->bodyEnd);
// reading another member of the same union in the rhs is a use through aliasing
if (nextAssign && fwdAnalysis.hasOperand(nextAssign->astOperand2(), tokenToCheck))
nextAssign = nullptr;
}

if (!nextAssign)
continue;
Expand Down
42 changes: 42 additions & 0 deletions test/testother.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11063,6 +11063,48 @@ class TestOther : public TestFixture {
" Dst.s->y = Src.s->y;\n"
"}\n");
ASSERT_EQUALS("", errout_str());

// Ticket #14371 "redundantAssignment when using a union"
check("union U {\n"
" struct {\n"
" unsigned int abcd;\n"
" } u32;\n"
" struct {\n"
" unsigned short ab;\n"
" unsigned short cd;\n"
" } u16;\n"
"};\n"
"void f1() {\n"
" U m;\n"
" m.u32.abcd = 1234;\n"
" m.u32.abcd = 5 * m.u16.ab;\n"
"}\n"
"void f2(unsigned int a, unsigned short b) {\n"
" U m;\n"
" m.u32.abcd = a;\n"
" m.u32.abcd += 0x8000;\n"
" m.u32.abcd = m.u16.ab * b;\n"
"}\n"
"void f3(unsigned int seed) {\n"
" U m, other;\n"
" other.u32.abcd = seed;\n"
" m.u32.abcd = 1234;\n"
" m.u32.abcd = other.u16.ab * 2;\n"
"}\n"
"void f4(unsigned short x) {\n"
" U m;\n"
" m.u16.ab = x;\n"
" m.u16.cd = 0;\n"
" m.u16.ab = m.u32.abcd / 53;\n"
"}\n"
"void f5(unsigned short x, unsigned int y) {\n"
" U m;\n"
" m.u16.ab = x;\n"
" m.u16.cd = 0;\n"
" m.u16.ab = y;\n"
"}\n", dinit(CheckOptions, $.inconclusive = false));
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"
"[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());
}

void redundantVarAssignment_7133() {
Expand Down
Loading