Skip to content

Commit 1253770

Browse files
Merge branch 'cppcheck-opensource:main' into chr_14935_II
2 parents 129e4b7 + 1ef5ef3 commit 1253770

3 files changed

Lines changed: 55 additions & 2 deletions

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;

lib/vf_settokenvalue.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -384,7 +384,7 @@ namespace ValueFlow
384384
setTokenValueCast(parent, valueType, std::move(value), settings);
385385
}
386386

387-
else if (parent->str() == ":") {
387+
else if (parent->str() == ":" && Token::simpleMatch(parent->astParent(), "?")) {
388388
setTokenValue(parent,std::move(value),settings);
389389
}
390390

test/testother.cpp

Lines changed: 49 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() {
@@ -12903,6 +12945,13 @@ class TestOther : public TestFixture {
1290312945
" cif::condition mWhere;\n"
1290412946
"};\n");
1290512947
ASSERT_EQUALS("", errout_str());
12948+
12949+
check("void g(std::string);\n" // #14928
12950+
"void f(std::string s) {\n"
12951+
" g(std::move(s));\n"
12952+
" for (char c : s) {}\n"
12953+
"}\n");
12954+
ASSERT_EQUALS("[test.cpp:4:19]: (warning) Access of moved variable 's'. [accessMoved]\n", errout_str());
1290612955
}
1290712956

1290812957
void moveTernary()

0 commit comments

Comments
 (0)