diff --git a/lib/checkautovariables.cpp b/lib/checkautovariables.cpp index a5bcd6101..1f261a611 100644 --- a/lib/checkautovariables.cpp +++ b/lib/checkautovariables.cpp @@ -159,6 +159,12 @@ void CheckAutoVariables::autoVariables() { errorReturnAddressToAutoVariable(tok); } + else if (Token::Match(tok, "return & %var% [") && + Token::Match(tok->tokAt(3)->link(), "] ;") && + isAutoVarArray(tok->tokAt(2)->varId())) + { + errorReturnAddressToAutoVariable(tok); + } // Invalid pointer deallocation else if (Token::Match(tok, "free ( %var% ) ;") && isAutoVarArray(tok->tokAt(2)->varId())) { diff --git a/test/testautovariables.cpp b/test/testautovariables.cpp index 89f34dfae..a7c833c60 100644 --- a/test/testautovariables.cpp +++ b/test/testautovariables.cpp @@ -78,6 +78,7 @@ private: TEST_CASE(testautovar_return1); TEST_CASE(testautovar_return2); TEST_CASE(testautovar_return3); + TEST_CASE(testautovar_return4); // ticket #3030 TEST_CASE(testautovar_extern); TEST_CASE(testinvaliddealloc); TEST_CASE(testassign1); // Ticket #1819 @@ -269,6 +270,17 @@ private: ASSERT_EQUALS("", errout.str()); } + void testautovar_return4() + { + // #3030 + check("char *foo()\n" + "{\n" + " char q[] = \"AAAAAAAAAAAA\";\n" + " return &q[1];\n" + "}"); + ASSERT_EQUALS("[test.cpp:4]: (error) Return of the address of an auto-variable\n", errout.str()); + } + void testautovar_extern() { check("struct foo *f()\n"