Fix 10406: FP danglingLifetime with pointer-to-pointer (#3401)
This commit is contained in:
parent
818fd248e1
commit
c92dab1329
|
@ -589,7 +589,7 @@ static void setTokenValue(Token* tok, ValueFlow::Value value, const Settings* se
|
|||
return;
|
||||
if (value.lifetimeKind == ValueFlow::Value::LifetimeKind::Iterator && astIsIterator(parent)) {
|
||||
setTokenValue(parent,value,settings);
|
||||
} else if (astIsPointer(tok) && astIsPointer(parent) &&
|
||||
} else if (astIsPointer(tok) && astIsPointer(parent) && !parent->isUnaryOp("*") &&
|
||||
(parent->isArithmeticalOp() || parent->isCast())) {
|
||||
setTokenValue(parent,value,settings);
|
||||
}
|
||||
|
|
|
@ -332,6 +332,24 @@ private:
|
|||
return false;
|
||||
}
|
||||
|
||||
bool testLifetimeOfX(const char code[], unsigned int linenr, const char value[], ValueFlow::Value::LifetimeScope lifetimeScope = ValueFlow::Value::LifetimeScope::Local) {
|
||||
// Tokenize..
|
||||
Tokenizer tokenizer(&settings, this);
|
||||
std::istringstream istr(code);
|
||||
tokenizer.tokenize(istr, "test.cpp");
|
||||
|
||||
for (const Token *tok = tokenizer.tokens(); tok; tok = tok->next()) {
|
||||
if (tok->str() == "x" && tok->linenr() == linenr) {
|
||||
for (const ValueFlow::Value &v : tok->values()) {
|
||||
if (v.isLifetimeValue() && v.lifetimeScope == lifetimeScope && Token::simpleMatch(v.tokvalue, value, strlen(value)))
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool testValueOfX(const char code[], unsigned int linenr, int value, ValueFlow::Value::ValueType type) {
|
||||
// Tokenize..
|
||||
Tokenizer tokenizer(&settings, this);
|
||||
|
@ -532,14 +550,14 @@ private:
|
|||
" auto x = [&]() { return a + 1; };\n"
|
||||
" auto b = x;\n"
|
||||
"}\n";
|
||||
ASSERT_EQUALS(true, testValueOfX(code, 4, "a + 1", ValueFlow::Value::ValueType::LIFETIME));
|
||||
ASSERT_EQUALS(true, testLifetimeOfX(code, 4, "a + 1"));
|
||||
|
||||
code = "void f() {\n"
|
||||
" int a = 1;\n"
|
||||
" auto x = [=]() { return a + 1; };\n"
|
||||
" auto b = x;\n"
|
||||
"}\n";
|
||||
ASSERT_EQUALS(false, testValueOfX(code, 4, "a ;", ValueFlow::Value::ValueType::LIFETIME));
|
||||
ASSERT_EQUALS(false, testLifetimeOfX(code, 4, "a ;"));
|
||||
|
||||
code = "void f(int v) {\n"
|
||||
" int a = v;\n"
|
||||
|
@ -547,14 +565,42 @@ private:
|
|||
" auto x = [=]() { return p + 1; };\n"
|
||||
" auto b = x;\n"
|
||||
"}\n";
|
||||
ASSERT_EQUALS(true, testValueOfX(code, 5, "a ;", ValueFlow::Value::ValueType::LIFETIME));
|
||||
ASSERT_EQUALS(true, testLifetimeOfX(code, 5, "a ;"));
|
||||
|
||||
code = "void f() {\n"
|
||||
" std::vector<int> v;\n"
|
||||
" auto x = v.begin();\n"
|
||||
" auto it = x;\n"
|
||||
"}\n";
|
||||
ASSERT_EQUALS(true, testValueOfX(code, 4, "v . begin", ValueFlow::Value::ValueType::LIFETIME));
|
||||
ASSERT_EQUALS(true, testLifetimeOfX(code, 4, "v . begin"));
|
||||
|
||||
code = "void f() {\n"
|
||||
" std::vector<int> v;\n"
|
||||
" auto x = v.begin() + 1;\n"
|
||||
" auto it = x;\n"
|
||||
"}\n";
|
||||
ASSERT_EQUALS(true, testLifetimeOfX(code, 4, "v . begin"));
|
||||
|
||||
code = "int* f() {\n"
|
||||
" std::vector<int> v;\n"
|
||||
" int * x = v.data();\n"
|
||||
" return x;\n"
|
||||
"}\n";
|
||||
ASSERT_EQUALS(true, testLifetimeOfX(code, 4, "v . data"));
|
||||
|
||||
code = "int* f() {\n"
|
||||
" std::vector<int> v;\n"
|
||||
" int * x = v.data() + 1;\n"
|
||||
" return x;\n"
|
||||
"}\n";
|
||||
ASSERT_EQUALS(true, testLifetimeOfX(code, 4, "v . data"));
|
||||
|
||||
code = "int f(int* a) {\n"
|
||||
" int **p = &a;\n"
|
||||
" int * x = *p;\n"
|
||||
" return x; \n"
|
||||
"}\n";
|
||||
ASSERT_EQUALS(false, testLifetimeOfX(code, 4, "a"));
|
||||
|
||||
code = "void f() {\n"
|
||||
" int i = 0;\n"
|
||||
|
|
Loading…
Reference in New Issue