Fix #11845 FP variableScope if buffer is passed to a conditionally called function (#5265)

Co-authored-by: chrchr-github <chrchr@github>
This commit is contained in:
chrchr-github 2023-07-27 22:18:34 +02:00 committed by GitHub
parent 99f7f88f39
commit bfaa7c075a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 34 additions and 2 deletions

View File

@ -991,7 +991,7 @@ void CheckOther::checkVariableScope()
} }
} }
bool CheckOther::checkInnerScope(const Token *tok, const Variable* var, bool& used) bool CheckOther::checkInnerScope(const Token *tok, const Variable* var, bool& used) const
{ {
const Scope* scope = tok->next()->scope(); const Scope* scope = tok->next()->scope();
bool loopVariable = scope->isLoopScope(); bool loopVariable = scope->isLoopScope();
@ -1071,6 +1071,16 @@ bool CheckOther::checkInnerScope(const Token *tok, const Variable* var, bool& us
if (scope->bodyStart && scope->bodyStart->isSimplifiedScope()) if (scope->bodyStart && scope->bodyStart->isSimplifiedScope())
return false; // simplified if/for/switch init statement return false; // simplified if/for/switch init statement
} }
if (var->isArrayOrPointer()) {
int argn{};
if (const Token* ftok = getTokenArgumentFunction(tok, argn)) { // var passed to function?
if (ftok->function() && Function::returnsPointer(ftok->function()))
return false;
const std::string ret = mSettings->library.returnValueType(ftok); // assume that var is returned
if (!ret.empty() && ret.back() == '*')
return false;
}
}
} }
} }

View File

@ -123,7 +123,7 @@ public:
/** @brief %Check scope of variables */ /** @brief %Check scope of variables */
void checkVariableScope(); void checkVariableScope();
static bool checkInnerScope(const Token *tok, const Variable* var, bool& used); bool checkInnerScope(const Token *tok, const Variable* var, bool& used) const;
/** @brief %Check for comma separated statements in return */ /** @brief %Check for comma separated statements in return */
void checkCommaSeparatedReturn(); void checkCommaSeparatedReturn();

View File

@ -106,6 +106,7 @@ private:
TEST_CASE(varScope32); // #11441 TEST_CASE(varScope32); // #11441
TEST_CASE(varScope33); TEST_CASE(varScope33);
TEST_CASE(varScope34); TEST_CASE(varScope34);
TEST_CASE(varScope35);
TEST_CASE(oldStylePointerCast); TEST_CASE(oldStylePointerCast);
TEST_CASE(invalidPointerCast); TEST_CASE(invalidPointerCast);
@ -1636,6 +1637,27 @@ private:
ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS("", errout.str());
} }
void varScope35() { // #11845
check("void f(int err, const char* src) {\n"
" const char* msg = \"Success\";\n"
" char buf[42];\n"
" if (err != 0)\n"
" msg = strcpy(buf, src);\n"
" printf(\"%d: %s\\n\", err, msg);\n"
"}\n");
ASSERT_EQUALS("", errout.str());
check("char* g(char* dst, const char* src);\n"
"void f(int err, const char* src) {\n"
" const char* msg = \"Success\";\n"
" char buf[42];\n"
" if (err != 0)\n"
" msg = g(buf, src);\n"
" printf(\"%d: %s\\n\", err, msg);\n"
"}\n");
ASSERT_EQUALS("", errout.str());
}
#define checkOldStylePointerCast(code) checkOldStylePointerCast_(code, __FILE__, __LINE__) #define checkOldStylePointerCast(code) checkOldStylePointerCast_(code, __FILE__, __LINE__)
void checkOldStylePointerCast_(const char code[], const char* file, int line) { void checkOldStylePointerCast_(const char code[], const char* file, int line) {
// Clear the error buffer.. // Clear the error buffer..