From bef9e73e60a61a382f4341cfb70730ea67948132 Mon Sep 17 00:00:00 2001 From: chrchr-github <78114321+chrchr-github@users.noreply.github.com> Date: Mon, 29 Jan 2024 12:23:03 +0100 Subject: [PATCH] Fix #11067 FP mismatchingContainerIterator with container holding iterators (#5915) --- lib/checkstl.cpp | 4 +++- test/teststl.cpp | 26 ++++++++++++++++++++++++++ 2 files changed, 29 insertions(+), 1 deletion(-) diff --git a/lib/checkstl.cpp b/lib/checkstl.cpp index f1e7c01d23c..26fb07c5945 100644 --- a/lib/checkstl.cpp +++ b/lib/checkstl.cpp @@ -704,7 +704,7 @@ static bool isSameIteratorContainerExpression(const Token* tok1, if (kind == ValueFlow::Value::LifetimeKind::Address) { return isSameExpression(true, false, getAddressContainer(tok1), getAddressContainer(tok2), library, false, false); } - return false; + return astContainerYield(tok2) == Library::Container::Yield::ITEM; } static ValueFlow::Value getLifetimeIteratorValue(const Token* tok, MathLib::bigint path = 0) @@ -868,6 +868,8 @@ void CheckStl::mismatchingContainerIterator() continue; if (val.lifetimeKind != ValueFlow::Value::LifetimeKind::Iterator) continue; + if (iterTok->str() == "*" && iterTok->astOperand1()->valueType() && iterTok->astOperand1()->valueType()->type == ValueType::ITERATOR) + continue; if (isSameIteratorContainerExpression(tok, val.tokvalue, mSettings->library)) continue; mismatchingContainerIteratorError(tok, iterTok, val.tokvalue); diff --git a/test/teststl.cpp b/test/teststl.cpp index f02afead149..4426f3460a7 100644 --- a/test/teststl.cpp +++ b/test/teststl.cpp @@ -2135,6 +2135,32 @@ class TestStl : public TestFixture { " s.v.erase(s.v.begin() + m);\n" "}\n"); ASSERT_EQUALS("", errout.str()); + + // #11067 + check("struct S {\n" + " std::vector v;\n" + " std::list::const_iterator> li;\n" + " void f();\n" + "};\n" + "void S::f() {\n" + " v.erase(*li.begin());\n" + " li.pop_front();\n" + "}\n"); + ASSERT_EQUALS("", errout.str()); + + check("void f(std::set& a, std::stack::iterator>& b) {\n" + " while (!b.empty()) {\n" + " a.erase(b.top());\n" + " b.pop();\n" + " }\n" + "}\n"); + ASSERT_EQUALS("", errout.str()); + + check("void f(std::vector& a, std::vector::iterator>& b) {\n" + " auto it = b.begin();\n" + " a.erase(*it);\n" + "}\n"); + ASSERT_EQUALS("", errout.str()); } // Dereferencing invalid pointer