Fix issue 9317: False positive returnDanglingLifetime when using reference to constant inside if statement (#2241)
This commit is contained in:
parent
6b6553e320
commit
cf1c766292
|
@ -1145,19 +1145,6 @@ public:
|
||||||
container(nullptr),
|
container(nullptr),
|
||||||
containerTypeToken(nullptr)
|
containerTypeToken(nullptr)
|
||||||
{}
|
{}
|
||||||
ValueType(const ValueType& vt)
|
|
||||||
: sign(vt.sign),
|
|
||||||
type(vt.type),
|
|
||||||
bits(vt.bits),
|
|
||||||
pointer(vt.pointer),
|
|
||||||
constness(vt.constness),
|
|
||||||
typeScope(vt.typeScope),
|
|
||||||
smartPointerType(vt.smartPointerType),
|
|
||||||
smartPointerTypeToken(vt.smartPointerTypeToken),
|
|
||||||
container(vt.container),
|
|
||||||
containerTypeToken(vt.containerTypeToken),
|
|
||||||
originalTypeName(vt.originalTypeName)
|
|
||||||
{}
|
|
||||||
ValueType(enum Sign s, enum Type t, nonneg int p)
|
ValueType(enum Sign s, enum Type t, nonneg int p)
|
||||||
: sign(s),
|
: sign(s),
|
||||||
type(t),
|
type(t),
|
||||||
|
@ -1195,8 +1182,6 @@ public:
|
||||||
containerTypeToken(nullptr),
|
containerTypeToken(nullptr),
|
||||||
originalTypeName(otn)
|
originalTypeName(otn)
|
||||||
{}
|
{}
|
||||||
ValueType &operator=(const ValueType &other) = delete;
|
|
||||||
|
|
||||||
static ValueType parseDecl(const Token *type, const Settings *settings);
|
static ValueType parseDecl(const Token *type, const Settings *settings);
|
||||||
|
|
||||||
static Type typeFromString(const std::string &typestr, bool longType);
|
static Type typeFromString(const std::string &typestr, bool longType);
|
||||||
|
|
|
@ -676,6 +676,8 @@ static void setTokenValue(Token* tok, const ValueFlow::Value &value, const Setti
|
||||||
}
|
}
|
||||||
|
|
||||||
if (value.isLifetimeValue()) {
|
if (value.isLifetimeValue()) {
|
||||||
|
if (!isLifetimeBorrowed(parent, settings))
|
||||||
|
return;
|
||||||
if (value.lifetimeKind == ValueFlow::Value::LifetimeKind::Iterator && astIsIterator(parent)) {
|
if (value.lifetimeKind == ValueFlow::Value::LifetimeKind::Iterator && astIsIterator(parent)) {
|
||||||
setTokenValue(parent,value,settings);
|
setTokenValue(parent,value,settings);
|
||||||
} else if (astIsPointer(tok) && astIsPointer(parent) &&
|
} else if (astIsPointer(tok) && astIsPointer(parent) &&
|
||||||
|
@ -3497,6 +3499,17 @@ bool isLifetimeBorrowed(const Token *tok, const Settings *settings)
|
||||||
if (!Token::simpleMatch(tok, "{")) {
|
if (!Token::simpleMatch(tok, "{")) {
|
||||||
const ValueType *vt = tok->valueType();
|
const ValueType *vt = tok->valueType();
|
||||||
const ValueType *vtParent = tok->astParent()->valueType();
|
const ValueType *vtParent = tok->astParent()->valueType();
|
||||||
|
ValueType svt;
|
||||||
|
// TODO: Move logic to ValueType
|
||||||
|
if (!vtParent && Token::simpleMatch(tok->astParent(), "return")) {
|
||||||
|
const Scope* fscope = tok->scope();
|
||||||
|
while(fscope && !fscope->function)
|
||||||
|
fscope = fscope->nestedIn;
|
||||||
|
if (fscope && fscope->function && fscope->function->retDef) {
|
||||||
|
svt = ValueType::parseDecl(fscope->function->retDef, settings);
|
||||||
|
vtParent = &svt;
|
||||||
|
}
|
||||||
|
}
|
||||||
if (isLifetimeBorrowed(vt, vtParent))
|
if (isLifetimeBorrowed(vt, vtParent))
|
||||||
return true;
|
return true;
|
||||||
if (isLifetimeOwned(vt, vtParent))
|
if (isLifetimeOwned(vt, vtParent))
|
||||||
|
|
|
@ -2156,6 +2156,22 @@ private:
|
||||||
" return v;\n"
|
" return v;\n"
|
||||||
"}\n");
|
"}\n");
|
||||||
ASSERT_EQUALS("", errout.str());
|
ASSERT_EQUALS("", errout.str());
|
||||||
|
|
||||||
|
check("std::string f(const std::string& x) {\n"
|
||||||
|
" const char c[] = \"\";\n"
|
||||||
|
" if (!x.empty())\n"
|
||||||
|
" return x + c;\n"
|
||||||
|
" return \"\";\n"
|
||||||
|
"}\n");
|
||||||
|
ASSERT_EQUALS("", errout.str());
|
||||||
|
|
||||||
|
check("std::string f(const std::string& x) {\n"
|
||||||
|
" const char c[] = \"123\";\n"
|
||||||
|
" if (!x.empty())\n"
|
||||||
|
" return c + 1;\n"
|
||||||
|
" return \"\";\n"
|
||||||
|
"}\n");
|
||||||
|
ASSERT_EQUALS("", errout.str());
|
||||||
}
|
}
|
||||||
|
|
||||||
void invalidLifetime() {
|
void invalidLifetime() {
|
||||||
|
|
Loading…
Reference in New Issue