diff --git a/lib/checkautovariables.cpp b/lib/checkautovariables.cpp index 189ece060..b2d49adc9 100644 --- a/lib/checkautovariables.cpp +++ b/lib/checkautovariables.cpp @@ -465,6 +465,20 @@ static bool isDeadTemporary(bool cpp, const Token* tok, const Token* expr, const return true; } +static bool isEscapedReference(const Variable* var) +{ + if (!var) + return false; + if (!var->isReference()) + return false; + if (!var->declEndToken()) + return false; + if (!Token::simpleMatch(var->declEndToken(), "=")) + return false; + const Token* vartok = var->declEndToken()->astOperand2(); + return !isTemporary(true, vartok, nullptr, false); +} + void CheckAutoVariables::checkVarLifetimeScope(const Token * start, const Token * end) { if (!start) @@ -512,7 +526,8 @@ void CheckAutoVariables::checkVarLifetimeScope(const Token * start, const Token continue; if (!isLifetimeBorrowed(tok, mSettings)) continue; - if ((tokvalue->variable() && isInScope(tokvalue->variable()->nameToken(), scope)) || + if ((tokvalue->variable() && !isEscapedReference(tokvalue->variable()) && + isInScope(tokvalue->variable()->nameToken(), scope)) || isDeadTemporary(mTokenizer->isCPP(), tokvalue, tok, &mSettings->library)) { errorReturnDanglingLifetime(tok, &val); break; diff --git a/test/testautovariables.cpp b/test/testautovariables.cpp index 34f9b20b8..53905735d 100644 --- a/test/testautovariables.cpp +++ b/test/testautovariables.cpp @@ -1647,6 +1647,15 @@ private: " g(&x);\n" "}\n"); ASSERT_EQUALS("", errout.str()); + + check("struct Data {\n" + " std::string path;\n" + "};\n" + "const char* foo() {\n" + " const Data& data = getData();\n" + " return data.path.c_str();\n" + "}\n"); + ASSERT_EQUALS("", errout.str()); } void danglingReference() {