Fix FPs and crashes with byDerefCopy (#1503)
* Fix FP when inserting a range into a container * Formatting * Fix crash
This commit is contained in:
parent
ba564076db
commit
3e1b34dd8f
|
@ -2649,7 +2649,7 @@ struct LifetimeStore {
|
||||||
const Variable *var = getLifetimeVariable(tok2, errorPath);
|
const Variable *var = getLifetimeVariable(tok2, errorPath);
|
||||||
if (!var)
|
if (!var)
|
||||||
continue;
|
continue;
|
||||||
for (const Token *tok3 = tok; tok != var->declEndToken(); tok3 = tok3->previous()) {
|
for (const Token *tok3 = tok; tok3 && tok3 != var->declEndToken(); tok3 = tok3->previous()) {
|
||||||
if (tok3->varId() == var->declarationId()) {
|
if (tok3->varId() == var->declarationId()) {
|
||||||
LifetimeStore{tok3, message, type} .byVal(tok, tokenlist, errorLogger, settings, pred);
|
LifetimeStore{tok3, message, type} .byVal(tok, tokenlist, errorLogger, settings, pred);
|
||||||
break;
|
break;
|
||||||
|
@ -2699,8 +2699,10 @@ static void valueFlowLifetimeFunction(Token *tok, TokenList *tokenlist, ErrorLog
|
||||||
const bool isPointer = endTypeTok && Token::simpleMatch(endTypeTok->previous(), "*");
|
const bool isPointer = endTypeTok && Token::simpleMatch(endTypeTok->previous(), "*");
|
||||||
Token *vartok = tok->tokAt(-2);
|
Token *vartok = tok->tokAt(-2);
|
||||||
std::vector<const Token *> args = getArguments(tok);
|
std::vector<const Token *> args = getArguments(tok);
|
||||||
if (args.size() == 2 && astCanonicalType(args[0]) == astCanonicalType(args[1]) &&
|
std::size_t n = args.size();
|
||||||
(((astIsIterator(args[0]) && astIsIterator(args[1])) || (astIsPointer(args[0]) && astIsPointer(args[1]))))) {
|
if (n > 1 && astCanonicalType(args[n - 2]) == astCanonicalType(args[n - 1]) &&
|
||||||
|
(((astIsIterator(args[n - 2]) && astIsIterator(args[n - 1])) ||
|
||||||
|
(astIsPointer(args[n - 2]) && astIsPointer(args[n - 1]))))) {
|
||||||
LifetimeStore{args.back(), "Added to container '" + vartok->str() + "'.", ValueFlow::Value::Object} .byDerefCopy(
|
LifetimeStore{args.back(), "Added to container '" + vartok->str() + "'.", ValueFlow::Value::Object} .byDerefCopy(
|
||||||
vartok, tokenlist, errorLogger, settings);
|
vartok, tokenlist, errorLogger, settings);
|
||||||
} else if (!args.empty() && astIsPointer(args.back()) == isPointer) {
|
} else if (!args.empty() && astIsPointer(args.back()) == isPointer) {
|
||||||
|
|
|
@ -1420,6 +1420,19 @@ private:
|
||||||
"[test.cpp:5] -> [test.cpp:6] -> [test.cpp:4] -> [test.cpp:6]: (error) Non-local variable 'v' will use object that points to local variable 'i'.\n",
|
"[test.cpp:5] -> [test.cpp:6] -> [test.cpp:4] -> [test.cpp:6]: (error) Non-local variable 'v' will use object that points to local variable 'i'.\n",
|
||||||
errout.str());
|
errout.str());
|
||||||
|
|
||||||
|
check("struct A {\n"
|
||||||
|
" std::vector<int*> m;\n"
|
||||||
|
" void f() {\n"
|
||||||
|
" int x;\n"
|
||||||
|
" std::vector<int*> v;\n"
|
||||||
|
" v.push_back(&x);\n"
|
||||||
|
" m.insert(m.end(), v.begin(), v.end());\n"
|
||||||
|
" }\n"
|
||||||
|
"};\n");
|
||||||
|
ASSERT_EQUALS(
|
||||||
|
"[test.cpp:6] -> [test.cpp:6] -> [test.cpp:6] -> [test.cpp:4] -> [test.cpp:7]: (error) Non-local variable 'm' will use object that points to local variable 'x'.\n",
|
||||||
|
errout.str());
|
||||||
|
|
||||||
check("struct A {\n"
|
check("struct A {\n"
|
||||||
" std::vector<std::string> v;\n"
|
" std::vector<std::string> v;\n"
|
||||||
" void f() {\n"
|
" void f() {\n"
|
||||||
|
@ -1483,6 +1496,27 @@ private:
|
||||||
" return g([&]() { return v.data(); });\n"
|
" return g([&]() { return v.data(); });\n"
|
||||||
"}\n");
|
"}\n");
|
||||||
ASSERT_EQUALS("", errout.str());
|
ASSERT_EQUALS("", errout.str());
|
||||||
|
|
||||||
|
check("std::vector<int> g();\n"
|
||||||
|
"struct A {\n"
|
||||||
|
" std::vector<int> m;\n"
|
||||||
|
" void f() {\n"
|
||||||
|
" std::vector<int> v = g();\n"
|
||||||
|
" m.insert(m.end(), v.begin(), v.end());\n"
|
||||||
|
" }\n"
|
||||||
|
"};\n");
|
||||||
|
ASSERT_EQUALS("", errout.str());
|
||||||
|
|
||||||
|
check("class A {\n"
|
||||||
|
" int f( P p ) {\n"
|
||||||
|
" std::vector< S > maps;\n"
|
||||||
|
" m2.insert( m1.begin(), m1.end() );\n"
|
||||||
|
" }\n"
|
||||||
|
" struct B {};\n"
|
||||||
|
" std::map< S, B > m1;\n"
|
||||||
|
" std::map< S, B > m2;\n"
|
||||||
|
"};\n");
|
||||||
|
ASSERT_EQUALS("", errout.str());
|
||||||
}
|
}
|
||||||
|
|
||||||
void danglingLifetime() {
|
void danglingLifetime() {
|
||||||
|
|
Loading…
Reference in New Issue