Find iterator mismatch when using temporary containers (#3579)
This commit is contained in:
parent
c14920218c
commit
8dcea26c10
|
@ -344,9 +344,14 @@ void CheckStl::iteratorsError(const Token* tok, const Token* containerTok, const
|
||||||
void CheckStl::iteratorsError(const Token* tok, const Token* containerTok, const std::string& containerName)
|
void CheckStl::iteratorsError(const Token* tok, const Token* containerTok, const std::string& containerName)
|
||||||
{
|
{
|
||||||
std::list<const Token*> callstack = { tok, containerTok };
|
std::list<const Token*> callstack = { tok, containerTok };
|
||||||
reportError(callstack, Severity::error, "iterators3",
|
reportError(callstack,
|
||||||
"$symbol:" + containerName + "\n"
|
Severity::error,
|
||||||
"Same iterator is used with containers '" + containerName + "' that are defined in different scopes.", CWE664, Certainty::normal);
|
"iterators3",
|
||||||
|
"$symbol:" + containerName +
|
||||||
|
"\n"
|
||||||
|
"Same iterator is used with containers '$symbol' that are temporaries or defined in different scopes.",
|
||||||
|
CWE664,
|
||||||
|
Certainty::normal);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Error message used when dereferencing an iterator that has been erased..
|
// Error message used when dereferencing an iterator that has been erased..
|
||||||
|
@ -709,8 +714,11 @@ static bool isSameIteratorContainerExpression(const Token* tok1,
|
||||||
const Library& library,
|
const Library& library,
|
||||||
ValueFlow::Value::LifetimeKind kind = ValueFlow::Value::LifetimeKind::Iterator)
|
ValueFlow::Value::LifetimeKind kind = ValueFlow::Value::LifetimeKind::Iterator)
|
||||||
{
|
{
|
||||||
if (isSameExpression(true, false, tok1, tok2, library, false, false))
|
if (isSameExpression(true, false, tok1, tok2, library, false, false)) {
|
||||||
|
if (astIsContainerOwned(tok1) && isTemporary(true, tok1, &library))
|
||||||
|
return false;
|
||||||
return true;
|
return true;
|
||||||
|
}
|
||||||
if (kind == ValueFlow::Value::LifetimeKind::Address) {
|
if (kind == ValueFlow::Value::LifetimeKind::Address) {
|
||||||
return isSameExpression(true, false, getAddressContainer(tok1), getAddressContainer(tok2), library, false, false);
|
return isSameExpression(true, false, getAddressContainer(tok1), getAddressContainer(tok2), library, false, false);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1305,7 +1305,9 @@ private:
|
||||||
" }\n"
|
" }\n"
|
||||||
" }\n"
|
" }\n"
|
||||||
"}");
|
"}");
|
||||||
ASSERT_EQUALS("[test.cpp:7] -> [test.cpp:4]: (error) Same iterator is used with containers 'l1' that are defined in different scopes.\n", errout.str());
|
ASSERT_EQUALS(
|
||||||
|
"[test.cpp:7] -> [test.cpp:4]: (error) Same iterator is used with containers 'l1' that are temporaries or defined in different scopes.\n",
|
||||||
|
errout.str());
|
||||||
|
|
||||||
check("void foo()\n"
|
check("void foo()\n"
|
||||||
"{\n"
|
"{\n"
|
||||||
|
@ -1320,7 +1322,7 @@ private:
|
||||||
"}");
|
"}");
|
||||||
TODO_ASSERT_EQUALS(
|
TODO_ASSERT_EQUALS(
|
||||||
"[test.cpp:7] -> [test.cpp:4]: (error) Same iterator is used with containers 'l1' that are defined in different scopes.\n",
|
"[test.cpp:7] -> [test.cpp:4]: (error) Same iterator is used with containers 'l1' that are defined in different scopes.\n",
|
||||||
"[test.cpp:7] -> [test.cpp:7]: (error) Same iterator is used with containers 'l1' that are defined in different scopes.\n[test.cpp:7]: (error) Dangerous comparison using operator< on iterator.\n",
|
"[test.cpp:7] -> [test.cpp:7]: (error) Same iterator is used with containers 'l1' that are temporaries or defined in different scopes.\n[test.cpp:7]: (error) Dangerous comparison using operator< on iterator.\n",
|
||||||
errout.str());
|
errout.str());
|
||||||
|
|
||||||
check("void foo()\n"
|
check("void foo()\n"
|
||||||
|
@ -1336,7 +1338,7 @@ private:
|
||||||
" }\n"
|
" }\n"
|
||||||
"}");
|
"}");
|
||||||
ASSERT_EQUALS(
|
ASSERT_EQUALS(
|
||||||
"[test.cpp:8] -> [test.cpp:4]: (error) Same iterator is used with containers 'l1' that are defined in different scopes.\n",
|
"[test.cpp:8] -> [test.cpp:4]: (error) Same iterator is used with containers 'l1' that are temporaries or defined in different scopes.\n",
|
||||||
errout.str());
|
errout.str());
|
||||||
|
|
||||||
check("void foo()\n"
|
check("void foo()\n"
|
||||||
|
@ -1352,7 +1354,18 @@ private:
|
||||||
" }\n"
|
" }\n"
|
||||||
"}");
|
"}");
|
||||||
ASSERT_EQUALS(
|
ASSERT_EQUALS(
|
||||||
"[test.cpp:8] -> [test.cpp:7]: (error) Same iterator is used with containers 'l1' that are defined in different scopes.\n",
|
"[test.cpp:8] -> [test.cpp:7]: (error) Same iterator is used with containers 'l1' that are temporaries or defined in different scopes.\n",
|
||||||
|
errout.str());
|
||||||
|
|
||||||
|
check("std::set<int> g() {\n"
|
||||||
|
" static const std::set<int> s = {1};\n"
|
||||||
|
" return s;\n"
|
||||||
|
"}\n"
|
||||||
|
"void f() {\n"
|
||||||
|
" if (g().find(2) == g().end()) {}\n"
|
||||||
|
"}\n");
|
||||||
|
ASSERT_EQUALS(
|
||||||
|
"[test.cpp:6] -> [test.cpp:6]: (error) Same iterator is used with containers 'g()' that are temporaries or defined in different scopes.\n",
|
||||||
errout.str());
|
errout.str());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue