From 8a35c402a77b010b467f6206a0ca8388c917c609 Mon Sep 17 00:00:00 2001 From: chrchr-github Date: Wed, 26 Jul 2023 10:43:51 +0200 Subject: [PATCH] Fix #11845 FP variableScope if buffer is passed to a conditionally called function --- lib/checkother.cpp | 14 ++++++++++++++ lib/checkother.h | 2 +- test/testother.cpp | 22 ++++++++++++++++++++++ 3 files changed, 37 insertions(+), 1 deletion(-) diff --git a/lib/checkother.cpp b/lib/checkother.cpp index 2a167a068aa..15a8d89ec6a 100644 --- a/lib/checkother.cpp +++ b/lib/checkother.cpp @@ -1071,6 +1071,20 @@ bool CheckOther::checkInnerScope(const Token *tok, const Variable* var, bool& us if (scope->bodyStart && scope->bodyStart->isSimplifiedScope()) return false; // simplified if/for/switch init statement } + if (var->isArrayOrPointer()) { + const Token* parent = tok->astParent(); + while (parent && parent->isArithmeticalOp()) + parent = parent->astParent(); + while (Token::simpleMatch(parent, ",")) + parent = parent->astParent(); + if (parent && Token::Match(parent->previous(), "%name% (")) { // var passed to function? + if (parent->previous()->function() && Function::returnsPointer(parent->previous()->function())) + return false; + const std::string ret = mSettings->library.returnValueType(parent->previous()); // assume that var is returned + if (!ret.empty() && ret.back() == '*') + return false; + } + } } } diff --git a/lib/checkother.h b/lib/checkother.h index 14e0409145e..efae5459d2d 100644 --- a/lib/checkother.h +++ b/lib/checkother.h @@ -123,7 +123,7 @@ class CPPCHECKLIB CheckOther : public Check { /** @brief %Check scope of variables */ void checkVariableScope(); - static bool checkInnerScope(const Token *tok, const Variable* var, bool& used); + bool checkInnerScope(const Token *tok, const Variable* var, bool& used); /** @brief %Check for comma separated statements in return */ void checkCommaSeparatedReturn(); diff --git a/test/testother.cpp b/test/testother.cpp index 91d1beef558..8e3799f5251 100644 --- a/test/testother.cpp +++ b/test/testother.cpp @@ -106,6 +106,7 @@ class TestOther : public TestFixture { TEST_CASE(varScope32); // #11441 TEST_CASE(varScope33); TEST_CASE(varScope34); + TEST_CASE(varScope35); TEST_CASE(oldStylePointerCast); TEST_CASE(invalidPointerCast); @@ -1636,6 +1637,27 @@ class TestOther : public TestFixture { 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__) void checkOldStylePointerCast_(const char code[], const char* file, int line) { // Clear the error buffer..