diff --git a/lib/vf_analyzers.cpp b/lib/vf_analyzers.cpp index 27c27934f31..b3e692be891 100644 --- a/lib/vf_analyzers.cpp +++ b/lib/vf_analyzers.cpp @@ -228,7 +228,8 @@ struct ValueFlowAnalyzer : Analyzer { if (inconclusive) return Action::Read | Action::Inconclusive; if (isVariableChanged(tok, getIndirect(tok), getSettings())) { - if (Token::Match(tok->astParent(), "*|[|.|++|--")) + if (Token::Match(tok->astParent(), "*|[|.|++|--") || + (Token::Match(tok->astParent(), "%assign%") && tok->astParent()->str().size() > 1)) // compound assignment return Action::Read | Action::Invalid; // Check if its assigned to the same value if (value && !value->isImpossible() && Token::simpleMatch(tok->astParent(), "=") && astIsLHS(tok) && diff --git a/test/testnullpointer.cpp b/test/testnullpointer.cpp index ca5c183c911..111e04c35f6 100644 --- a/test/testnullpointer.cpp +++ b/test/testnullpointer.cpp @@ -4707,7 +4707,7 @@ class TestNullPointer : public TestFixture { " p += a;\n" " *p = 0;\n" "}\n"); - ASSERT_EQUALS("", errout_str()); + ASSERT_EQUALS("[test.cpp:2:7]: (error) Pointer addition with NULL pointer. [nullPointerArithmetic]\n", errout_str()); check("int f(int *p = 0) {\n" " if (p == 0) {\n" diff --git a/test/testuninitvar.cpp b/test/testuninitvar.cpp index 4d1a913ed3a..31581ce62a2 100644 --- a/test/testuninitvar.cpp +++ b/test/testuninitvar.cpp @@ -6846,6 +6846,15 @@ class TestUninitVar : public TestFixture { " return a[0];\n" "}\n"); ASSERT_EQUALS("", errout_str()); + + valueFlowUninit("void f(int i) {\n" + " int x, y;\n" + " x += i;\n" + " y <<= i;\n" + "}\n"); + ASSERT_EQUALS("[test.cpp:3:5]: (error) Uninitialized variable: x [uninitvar]\n" + "[test.cpp:4:5]: (error) Uninitialized variable: y [uninitvar]\n", + errout_str()); } void valueFlowUninitBreak() { // Do not show duplicate warnings about the same uninitialized value diff --git a/test/testvalueflow.cpp b/test/testvalueflow.cpp index 3609bf2aee2..7ec73a4868f 100644 --- a/test/testvalueflow.cpp +++ b/test/testvalueflow.cpp @@ -1110,6 +1110,22 @@ class TestValueFlow : public TestFixture { " g(std::move(x)).f(1);\n" "}\n"; ASSERT_EQUALS(false, testValueOfX(code, 5U, ValueFlow::Value::MoveKind::MovedVariable)); + + code = "void f(std::string x) {\n" // #15155 + " std::string a{ std::move(x) };\n" + " x += \"abc\";\n" + "}\n"; + ASSERT_EQUALS(true, testValueOfX(code, 3U, ValueFlow::Value::MoveKind::MovedVariable)); + + code = "struct S {\n" + " S& operator<<=(int i);\n" + " std::string m;\n" + "};\n" + "void f(S x) {\n" + " S a{ std::move(x) };\n" + " x <<= 5;\n" + "}"; + ASSERT_EQUALS(true, testValueOfX(code, 7U, ValueFlow::Value::MoveKind::MovedVariable)); } void valueFlowCalculations() {