diff --git a/cli/threadexecutor.cpp b/cli/threadexecutor.cpp index 9e25fde1c..04e302d27 100644 --- a/cli/threadexecutor.cpp +++ b/cli/threadexecutor.cpp @@ -552,3 +552,7 @@ unsigned int STDCALL ThreadExecutor::threadProc(LogWriter* logWriter) return result; } #endif + +bool ThreadExecutor::isEnabled() { + return true; +} diff --git a/cli/threadexecutor.h b/cli/threadexecutor.h index e98b7ca13..60f09bb05 100644 --- a/cli/threadexecutor.h +++ b/cli/threadexecutor.h @@ -84,10 +84,7 @@ public: /** * @return true if support for threads exist. */ - static bool isEnabled() { - return true; - } - + static bool isEnabled(); }; /// @} diff --git a/lib/valueflow.cpp b/lib/valueflow.cpp index 2b8b92f09..fcafd6bb2 100644 --- a/lib/valueflow.cpp +++ b/lib/valueflow.cpp @@ -6972,7 +6972,15 @@ static bool isKnown(const Token * tok) static void valueFlowFunctionReturn(TokenList *tokenlist, ErrorLogger *errorLogger) { for (Token *tok = tokenlist->back(); tok; tok = tok->previous()) { - if (tok->str() != "(" || !tok->astOperand1() || !tok->astOperand1()->function()) + if (tok->str() != "(" || !tok->astOperand1()) + continue; + + const Function* function = nullptr; + if (Token::Match(tok->previous(), "%name% (")) + function = tok->previous()->function(); + else + function = tok->astOperand1()->function(); + if (!function) continue; if (tok->hasKnownValue()) @@ -6997,7 +7005,6 @@ static void valueFlowFunctionReturn(TokenList *tokenlist, ErrorLogger *errorLogg } // Get scope and args of function - const Function * const function = tok->astOperand1()->function(); const Scope * const functionScope = function->functionScope; if (!functionScope || !Token::simpleMatch(functionScope->bodyStart, "{ return")) { if (functionScope && tokenlist->getSettings()->debugwarnings && Token::findsimplematch(functionScope->bodyStart, "return", functionScope->bodyEnd)) diff --git a/test/testbufferoverrun.cpp b/test/testbufferoverrun.cpp index 7e86382e1..5b9528279 100644 --- a/test/testbufferoverrun.cpp +++ b/test/testbufferoverrun.cpp @@ -186,6 +186,7 @@ private: TEST_CASE(array_index_59); // #10413 TEST_CASE(array_index_60); // #10617, #9824 TEST_CASE(array_index_61); // #10621 + TEST_CASE(array_index_62); // #7684 TEST_CASE(array_index_multidim); TEST_CASE(array_index_switch_in_for); TEST_CASE(array_index_for_in_for); // FP: #2634 @@ -1766,6 +1767,21 @@ private: ASSERT_EQUALS("", errout.str()); } + void array_index_62() + { + check("struct X {\n" + " static int GetSize() {return 11;}\n" + "};\n" + "char f() {\n" + " char buf[10]= {0};\n" + " for(int i = 0; i < X::GetSize(); ++i) \n" + " buf[i] = 0;\n" + " return buf[0];\n" + "}\n"); + ASSERT_EQUALS("[test.cpp:7]: (error) Array 'buf[10]' accessed at index 10, which is out of bounds.\n", + errout.str()); + } + void array_index_multidim() { check("void f()\n" "{\n"