diff --git a/lib/astutils.cpp b/lib/astutils.cpp index e31c73fc235..dad935c513b 100644 --- a/lib/astutils.cpp +++ b/lib/astutils.cpp @@ -2772,7 +2772,7 @@ static bool isExpressionChangedAt(const F& getExprTok, return true; if (tok->isLiteral() || tok->isKeyword() || tok->isStandardType() || Token::Match(tok, ",|;|:")) return false; - if (tok->exprId() != exprid) { + if (tok->exprId() != exprid || (!tok->varId() && !tok->isName())) { if (globalvar && Token::Match(tok, "%name% (") && !(tok->function() && tok->function()->isAttributePure())) // TODO: Is global variable really changed by function call? return true; diff --git a/test/teststl.cpp b/test/teststl.cpp index 1b26e57ebb4..f4083f0cf1a 100644 --- a/test/teststl.cpp +++ b/test/teststl.cpp @@ -70,6 +70,7 @@ class TestStl : public TestFixture { TEST_CASE(iterator26); // #9176 TEST_CASE(iterator27); // #10378 TEST_CASE(iterator28); // #10450 + TEST_CASE(iterator29); TEST_CASE(iteratorExpression); TEST_CASE(iteratorSameExpression); TEST_CASE(mismatchingContainerIterator); @@ -1846,6 +1847,37 @@ class TestStl : public TestFixture { ASSERT_EQUALS("[test.cpp:10]: (style) Consider using std::find_if algorithm instead of a raw loop.\n", errout.str()); } + void iterator29() + { + // #11511 + check("std::vector& g();\n" + "void f() {\n" + " auto v = g();\n" + " auto it = g().begin();\n" + " while (it != g().end())\n" + " it = v.erase(it);\n" + "}\n"); + ASSERT_EQUALS("[test.cpp:6]: (error) Iterator 'it' from different container 'v' are used together.\n", errout.str()); + + check("std::vector& g(int);\n" + "void f(int i, int j) {\n" + " auto& r = g(i);\n" + " auto it = g(j).begin();\n" + " while (it != g(j).end())\n" + " it = r.erase(it);\n" + "}\n"); + ASSERT_EQUALS("[test.cpp:6]: (error) Iterator 'it' from different container 'r' are used together.\n", errout.str()); + + check("std::vector& g();\n" + "void f() {\n" + " auto& r = g();\n" + " auto it = g().begin();\n" + " while (it != g().end())\n" + " it = r.erase(it);\n" + "}\n"); + ASSERT_EQUALS("", errout.str()); + } + void iteratorExpression() { check("std::vector& f();\n" "std::vector& g();\n"