Fix 10406: FP danglingLifetime with pointer-to-pointer (#3401)

This commit is contained in:
Paul Fultz II 2021-08-14 14:37:17 -05:00 committed by GitHub
parent 818fd248e1
commit c92dab1329
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 51 additions and 5 deletions

View File

@ -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);
}

View File

@ -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"