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),
|
||||
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)
|
||||
: sign(s),
|
||||
type(t),
|
||||
|
@ -1195,8 +1182,6 @@ public:
|
|||
containerTypeToken(nullptr),
|
||||
originalTypeName(otn)
|
||||
{}
|
||||
ValueType &operator=(const ValueType &other) = delete;
|
||||
|
||||
static ValueType parseDecl(const Token *type, const Settings *settings);
|
||||
|
||||
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 (!isLifetimeBorrowed(parent, settings))
|
||||
return;
|
||||
if (value.lifetimeKind == ValueFlow::Value::LifetimeKind::Iterator && astIsIterator(parent)) {
|
||||
setTokenValue(parent,value,settings);
|
||||
} else if (astIsPointer(tok) && astIsPointer(parent) &&
|
||||
|
@ -3497,6 +3499,17 @@ bool isLifetimeBorrowed(const Token *tok, const Settings *settings)
|
|||
if (!Token::simpleMatch(tok, "{")) {
|
||||
const ValueType *vt = tok->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))
|
||||
return true;
|
||||
if (isLifetimeOwned(vt, vtParent))
|
||||
|
|
|
@ -2156,6 +2156,22 @@ private:
|
|||
" return v;\n"
|
||||
"}\n");
|
||||
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() {
|
||||
|
|
Loading…
Reference in New Issue