diff --git a/lib/checkautovariables.cpp b/lib/checkautovariables.cpp index 387e3fd3c2d..e778f3d5959 100644 --- a/lib/checkautovariables.cpp +++ b/lib/checkautovariables.cpp @@ -394,6 +394,8 @@ bool CheckAutoVariables::checkAutoVariableAssignment(const Token *expr, bool inc void CheckAutoVariables::errorAutoVariableAssignment(const Token *tok, bool inconclusive) { + diag(tok); + if (!inconclusive) { reportError(tok, Severity::error, "autoVariables", "Address of local auto-variable assigned to a function parameter.\n" @@ -674,14 +676,16 @@ void CheckAutoVariables::checkVarLifetimeScope(const Token * start, const Token const Token* nextTok = nextAfterAstRightmostLeaf(tok->astTop()); if (!nextTok) nextTok = tok->next(); - if (var && (!var->isLocal() || var->isStatic()) && !var->isArgument() && !(val.tokvalue && val.tokvalue->variable() && val.tokvalue->variable()->isStatic()) && + if (var && (!var->isLocal() || var->isStatic()) && (!var->isArgument() || (var->isReference() && isInScope(val.tokvalue, var->scope()))) && + !(val.tokvalue && val.tokvalue->variable() && val.tokvalue->variable()->isStatic()) && !isVariableChanged(nextTok, tok->scope()->bodyEnd, var->valueType() ? var->valueType()->pointer : 0, var->declarationId(), var->isGlobal(), *mSettings)) { - errorDanglngLifetime(tok2, &val, var->isLocal()); + if (!diag(tok2)) + errorDanglngLifetime(tok2, &val, var->isLocal()); break; } } @@ -823,8 +827,8 @@ void CheckAutoVariables::runChecks(const Tokenizer &tokenizer, ErrorLogger *erro { CheckAutoVariables checkAutoVariables(&tokenizer, &tokenizer.getSettings(), errorLogger); checkAutoVariables.assignFunctionArg(); - checkAutoVariables.checkVarLifetime(); checkAutoVariables.autoVariables(); + checkAutoVariables.checkVarLifetime(); } void CheckAutoVariables::getErrorMessages(ErrorLogger *errorLogger, const Settings *settings) const diff --git a/test/testautovariables.cpp b/test/testautovariables.cpp index bcdba7ca0dc..b06e3ba3e4a 100644 --- a/test/testautovariables.cpp +++ b/test/testautovariables.cpp @@ -2923,6 +2923,30 @@ class TestAutoVariables : public TestFixture { " return it;\n" "}\n"); ASSERT_EQUALS("[test.cpp:3:44] -> [test.cpp:2:22] -> [test.cpp:4:12]: (error) Returning iterator to local container 'x' that will be invalid when returning. [returnDanglingLifetime]\n", errout_str()); + + check("void f(std::vector& m) {\n" + " int x;\n" + " m.push_back(&x);\n" + "}\n"); + ASSERT_EQUALS("[test.cpp:3:17] -> [test.cpp:3:17] -> [test.cpp:2:9] -> [test.cpp:3:5]: (error) Non-local variable 'm' will use object that points to local variable 'x'. [danglingLifetime]\n", errout_str()); + + check("struct P {\n" + " int h() const;\n" + " int x;\n" + " int &r;\n" + "};\n" + "int f(const P &p) {\n" + " return p.h();\n" + "}\n" + "struct C {\n" + " void g() {\n" + " int i = 1;\n" + " P q(m, i);\n" + " f(q);\n" + " }\n" + " int m;\n" + "}\n"); + ASSERT_EQUALS("", errout_str()); } void danglingLifetimeContainerView()