diff --git a/lib/valueflow.cpp b/lib/valueflow.cpp index 04bddf20e..60446f315 100644 --- a/lib/valueflow.cpp +++ b/lib/valueflow.cpp @@ -4490,6 +4490,23 @@ static void valueFlowLifetimeFunction(Token *tok, TokenList *tokenlist, ErrorLog // Assume constructing the valueType valueFlowLifetimeConstructor(tok->next(), tokenlist, errorLogger, settings); valueFlowForwardLifetime(tok->next(), tokenlist, errorLogger, settings); + } else { + const std::string& retVal = settings->library.returnValue(tok); + if (retVal.compare(0, 3, "arg") == 0) { + std::size_t iArg{}; + try { + iArg = strToInt(retVal.substr(3)); + } catch (...) { + return; + } + std::vector args = getArguments(tok); + if (iArg > 0 && iArg <= args.size()) { + const Token* varTok = args[iArg - 1]; + if (varTok->variable() && varTok->variable()->isLocal()) + LifetimeStore{ varTok, "Passed to '" + tok->str() + "'.", ValueFlow::Value::LifetimeKind::Address }.byRef( + tok->next(), tokenlist, errorLogger, settings); + } + } } } diff --git a/test/testautovariables.cpp b/test/testautovariables.cpp index a05fca0c5..8694c14e7 100644 --- a/test/testautovariables.cpp +++ b/test/testautovariables.cpp @@ -4413,6 +4413,23 @@ private: " return 0;\n" "}"); ASSERT_EQUALS("[test.cpp:5] -> [test.cpp:4] -> [test.cpp:8]: (error) Using pointer to local variable 'x' that is out of scope.\n", errout.str()); + + // #11753 + check("int main(int argc, const char *argv[]) {\n" + " const char* s = \"\";\n" + " if (argc > 0) {\n" + " char buff[32]{};\n" + " s = std::strncpy(buff, argv[0], 31);\n" + " }\n" + " std::cout << s;\n" + "}\n"); + ASSERT_EQUALS("[test.cpp:5] -> [test.cpp:4] -> [test.cpp:7]: (error) Using pointer to local variable 'buff' that is out of scope.\n", errout.str()); + + check("char* f(char* dst) {\n" + " const char* src = \"abc\";\n" + " return strcpy(dst, src);\n" + "}\n"); + ASSERT_EQUALS("", errout.str()); } void splitNamespaceAuto() { // #10473