Skip to content

Commit 8cf85df

Browse files
committed
Fix #6552: false constant value warnings after overloaded extraction
1 parent c976cac commit 8cf85df

3 files changed

Lines changed: 53 additions & 0 deletions

File tree

lib/astutils.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2712,6 +2712,20 @@ bool isVariableChanged(const Token *tok, int indirect, const Settings &settings,
27122712
if (tok2->isCpp() && Token::Match(tok2->astParent(), ">>|&") && astIsRHS(tok2) && isLikelyStreamRead(tok2->astParent()))
27132713
return true;
27142714

2715+
// An overloaded >>= can extract into its right-hand operand by reference.
2716+
if (tok2->isCpp() && Token::simpleMatch(tok2->astParent(), ">>=") && astIsRHS(tok2) &&
2717+
!astIsIntegral(tok2->astParent()->astOperand1(), false)) {
2718+
const ValueType* lhsType = tok2->astParent()->astOperand1()->valueType();
2719+
if (!lhsType || !lhsType->typeScope)
2720+
return true;
2721+
const auto operators = lhsType->typeScope->functionMap.equal_range("operator>>=");
2722+
for (auto it = operators.first; it != operators.second; ++it) {
2723+
const Variable* arg = it->second->getArgumentVar(0);
2724+
if (!arg || (!arg->isConst() && arg->isReference()))
2725+
return true;
2726+
}
2727+
}
2728+
27152729
if (isLikelyStream(tok2))
27162730
return true;
27172731

test/testastutils.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -229,6 +229,10 @@ class TestAstUtils : public TestFixture {
229229
}
230230

231231
void isVariableChangedTest() {
232+
// Built-in shifts do not modify their right-hand operand. #6552
233+
ASSERT_EQUALS(false, isVariableChanged("void f(int shift, int bits) { bits >>= shift; }\n", "{", "}"));
234+
ASSERT_EQUALS(false, isVariableChanged("void f(const double x, const Value& value) { value >>= x; }\n", "{", "}"));
235+
ASSERT_EQUALS(true, isVariableChanged("void f(double x, const Value& value) { value >>= x; }\n", "{", "}"));
232236
// #8211 - no lhs for >> , do not crash
233237
(void)isVariableChanged("void f() {\n"
234238
" int b;\n"

test/testcondition.cpp

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,7 @@ class TestCondition : public TestFixture {
129129
TEST_CASE(knownConditionAfterBailout); // #12526
130130
TEST_CASE(knownConditionIncDecOperator);
131131
TEST_CASE(knownConditionFloating);
132+
TEST_CASE(knownConditionShiftAssignment);
132133
}
133134

134135
struct CheckOptions
@@ -6687,6 +6688,40 @@ class TestCondition : public TestFixture {
66876688
ASSERT_EQUALS("", errout_str());
66886689
}
66896690

6691+
void knownConditionShiftAssignment() { // #6552
6692+
check("struct Value { void operator>>=(double&) const; };\n"
6693+
"bool f(const Value& value, bool extract) {\n"
6694+
" double x = 0.5;\n"
6695+
" if (extract) value >>= x;\n"
6696+
" return x < 0;\n"
6697+
"}\n");
6698+
ASSERT_EQUALS("", errout_str());
6699+
6700+
check("struct Value { void operator>>=(double) const; };\n"
6701+
"bool f(const Value& value) {\n"
6702+
" double x = 0.5;\n"
6703+
" value >>= x;\n"
6704+
" return x < 0;\n"
6705+
"}\n");
6706+
ASSERT_EQUALS("[test.cpp:5:14]: (style) Return value 'x<0' is always false [knownConditionTrueFalse]\n", errout_str());
6707+
6708+
check("struct Value { void operator>>=(const double&) const; };\n"
6709+
"bool f(const Value& value) {\n"
6710+
" double x = 0.5;\n"
6711+
" value >>= x;\n"
6712+
" return x < 0;\n"
6713+
"}\n");
6714+
ASSERT_EQUALS("[test.cpp:5:14]: (style) Return value 'x<0' is always false [knownConditionTrueFalse]\n", errout_str());
6715+
6716+
check("struct Value { void operator>>=(const double&) const; };\n"
6717+
"bool f(const Value& value) {\n"
6718+
" const double x = 0.5;\n"
6719+
" value >>= x;\n"
6720+
" return x < 0;\n"
6721+
"}\n");
6722+
ASSERT_EQUALS("[test.cpp:5:14]: (style) Return value 'x<0' is always false [knownConditionTrueFalse]\n", errout_str());
6723+
}
6724+
66906725
void knownConditionFloating() {
66916726
check("void foo() {\n" // #11199
66926727
" float f = 1.0;\n"

0 commit comments

Comments
 (0)