diff --git a/lib/symboldatabase.h b/lib/symboldatabase.h index bc0f96c0e..a5aeb5469 100644 --- a/lib/symboldatabase.h +++ b/lib/symboldatabase.h @@ -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); diff --git a/lib/valueflow.cpp b/lib/valueflow.cpp index 5fe9f9b81..bd63d2bb2 100644 --- a/lib/valueflow.cpp +++ b/lib/valueflow.cpp @@ -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)) diff --git a/test/testautovariables.cpp b/test/testautovariables.cpp index e41f7cd44..21d7e0bbe 100644 --- a/test/testautovariables.cpp +++ b/test/testautovariables.cpp @@ -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() {