Skip to content

Commit

Permalink
Fix #12895 FP redundantAssignment with union (danmar#6567)
Browse files Browse the repository at this point in the history
  • Loading branch information
chrchr-github authored Jul 2, 2024
1 parent 04b07a4 commit 83578c8
Show file tree
Hide file tree
Showing 2 changed files with 108 additions and 90 deletions.
3 changes: 3 additions & 0 deletions lib/checkother.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -527,6 +527,9 @@ void CheckOther::checkRedundantAssignment()

// Get next assignment..
const Token *nextAssign = fwdAnalysis.reassign(tokenToCheck, start, scope->bodyEnd);
// extra check for union
if (nextAssign && tokenToCheck != tok->astOperand1())
nextAssign = fwdAnalysis.reassign(tok->astOperand1(), start, scope->bodyEnd);

if (!nextAssign)
continue;
Expand Down
195 changes: 105 additions & 90 deletions test/testother.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,7 @@ class TestOther : public TestFixture {
TEST_CASE(redundantVarAssignment);
TEST_CASE(redundantVarAssignment_trivial);
TEST_CASE(redundantVarAssignment_struct);
TEST_CASE(redundantVarAssignment_union);
TEST_CASE(redundantVarAssignment_7133);
TEST_CASE(redundantVarAssignment_stackoverflow);
TEST_CASE(redundantVarAssignment_lambda);
Expand Down Expand Up @@ -4492,96 +4493,6 @@ class TestOther : public TestFixture {
" }\n"
"}");
ASSERT_EQUALS("", errout_str());

// Ticket #5115 "redundantAssignment when using a union"
check("void main(void)\n"
"{\n"
" short lTotal = 0;\n"
" union\n"
" {\n"
" short l1;\n"
" struct\n"
" {\n"
" unsigned char b1;\n"
" unsigned char b2;\n"
" } b;\n"
" } u;\n"
" u.l1 = 1;\n"
" lTotal += u.b.b1;\n"
" u.l1 = 2;\n" //Should not show RedundantAssignment
"}", true, false, false);
ASSERT_EQUALS("", errout_str());

// Ticket #5115 "redundantAssignment when using a union"
check("void main(void)\n"
"{\n"
" short lTotal = 0;\n"
" union\n"
" {\n"
" short l1;\n"
" struct\n"
" {\n"
" unsigned char b1;\n"
" unsigned char b2;\n"
" } b;\n"
" } u;\n"
" u.l1 = 1;\n"
" u.l1 = 2;\n"
"}", true, false, false);
ASSERT_EQUALS("[test.cpp:13] -> [test.cpp:14]: (style) Variable 'u.l1' is reassigned a value before the old one has been used.\n", errout_str());

// Ticket #10093 "redundantAssignment when using a union"
check("typedef union fixed32_union {\n"
" struct {\n"
" unsigned32 abcd;\n"
" } u32;\n"
" struct {\n"
" unsigned16 ab;\n"
" unsigned16 cd;\n"
" } u16;"
" struct {\n"
" unsigned8 a;\n"
" unsigned8 b;\n"
" unsigned8 c;\n"
" unsigned8 d;\n"
" } b;\n"
"} fixed32;\n"
"void func1(void) {\n"
" fixed32 m;\n"
" m.u16.ab = 47;\n"
" m.u16.cd = 0;\n"
" m.u16.ab = m.u32.abcd / 53;\n"
"}", true, false, false);
ASSERT_EQUALS("", errout_str());

// Ticket #10093 "redundantAssignment when using a union"
check("typedef union{\n"
" char as_char[4];\n"
" int as_int;\n"
"} union_t;\n"
"void fn(char *data, int len) {\n"
" int i;\n"
" for (i = 0; i < len; i++)\n"
" data[i] = 'a';\n"
"}\n"
"int main(int argc, char *argv[]) {\n"
" union_t u;\n"
" u.as_int = 42;\n"
" fn(&u.as_char[0], 4);\n"
" u.as_int = 0;\n"
"}", true, false, false);
ASSERT_EQUALS("", errout_str());

// Ticket #5115 "redundantAssignment when using a union"
check("void foo(char *ptr) {\n"
" union {\n"
" char * s8;\n"
" unsigned long long u64;\n"
" } addr;\n"
" addr.s8 = ptr;\n"
" addr.u64 += 8;\n"
"}", true, false, false);
ASSERT_EQUALS("", errout_str());
}

void switchRedundantOperationTest() {
Expand Down Expand Up @@ -9790,6 +9701,110 @@ class TestOther : public TestFixture {
ASSERT_EQUALS("", errout_str());
}

void redundantVarAssignment_union() {
// Ticket #5115 "redundantAssignment when using a union"
check("void main(void)\n"
"{\n"
" short lTotal = 0;\n"
" union\n"
" {\n"
" short l1;\n"
" struct\n"
" {\n"
" unsigned char b1;\n"
" unsigned char b2;\n"
" } b;\n"
" } u;\n"
" u.l1 = 1;\n"
" lTotal += u.b.b1;\n"
" u.l1 = 2;\n" //Should not show RedundantAssignment
"}", true, false, false);
ASSERT_EQUALS("", errout_str());

// Ticket #5115 "redundantAssignment when using a union"
check("void main(void)\n"
"{\n"
" short lTotal = 0;\n"
" union\n"
" {\n"
" short l1;\n"
" struct\n"
" {\n"
" unsigned char b1;\n"
" unsigned char b2;\n"
" } b;\n"
" } u;\n"
" u.l1 = 1;\n"
" u.l1 = 2;\n"
"}", true, false, false);
ASSERT_EQUALS("[test.cpp:13] -> [test.cpp:14]: (style) Variable 'u.l1' is reassigned a value before the old one has been used.\n", errout_str());

// Ticket #10093 "redundantAssignment when using a union"
check("typedef union fixed32_union {\n"
" struct {\n"
" unsigned32 abcd;\n"
" } u32;\n"
" struct {\n"
" unsigned16 ab;\n"
" unsigned16 cd;\n"
" } u16;"
" struct {\n"
" unsigned8 a;\n"
" unsigned8 b;\n"
" unsigned8 c;\n"
" unsigned8 d;\n"
" } b;\n"
"} fixed32;\n"
"void func1(void) {\n"
" fixed32 m;\n"
" m.u16.ab = 47;\n"
" m.u16.cd = 0;\n"
" m.u16.ab = m.u32.abcd / 53;\n"
"}", true, false, false);
ASSERT_EQUALS("", errout_str());

// Ticket #10093 "redundantAssignment when using a union"
check("typedef union{\n"
" char as_char[4];\n"
" int as_int;\n"
"} union_t;\n"
"void fn(char *data, int len) {\n"
" int i;\n"
" for (i = 0; i < len; i++)\n"
" data[i] = 'a';\n"
"}\n"
"int main(int argc, char *argv[]) {\n"
" union_t u;\n"
" u.as_int = 42;\n"
" fn(&u.as_char[0], 4);\n"
" u.as_int = 0;\n"
"}", true, false, false);
ASSERT_EQUALS("", errout_str());

// Ticket #5115 "redundantAssignment when using a union"
check("void foo(char *ptr) {\n"
" union {\n"
" char * s8;\n"
" unsigned long long u64;\n"
" } addr;\n"
" addr.s8 = ptr;\n"
" addr.u64 += 8;\n"
"}", true, false, false);
ASSERT_EQUALS("", errout_str());

check("struct S {\n" // #12895
" int x, y;\n"
"};\n"
"union U {\n"
" S* s;\n"
"};\n"
"void f(const U& Src, const U& Dst) {\n"
" Dst.s->x = Src.s->x;\n"
" Dst.s->y = Src.s->y;\n"
"}\n");
ASSERT_EQUALS("", errout_str());
}

void redundantVarAssignment_7133() {
// #7133
check("sal_Int32 impl_Export() {\n"
Expand Down

0 comments on commit 83578c8

Please sign in to comment.