diff --git a/lib/valueflow.cpp b/lib/valueflow.cpp index d6340fa14..527b004a7 100644 --- a/lib/valueflow.cpp +++ b/lib/valueflow.cpp @@ -1329,9 +1329,8 @@ static void valueFlowSubFunction(TokenList *tokenlist, ErrorLogger *errorLogger, // passing value(s) to function if (Token::Match(tok, "[(,] %var% [,)]") && !tok->next()->values.empty()) argvalues = tok->next()->values; - else if (Token::Match(tok, "[(,] %num% [,)]") && MathLib::isInt(tok->strAt(1))) { - argvalues.clear(); - argvalues.push_back(ValueFlow::Value(MathLib::toLongNumber(tok->next()->str()))); + else if (Token::Match(tok, "[(,] %num%|%str% [,)]") && !tok->next()->values.empty()) { + argvalues = tok->next()->values; } else { // bool operator => values 1/0 are passed to function.. const Token *op = tok->next(); @@ -1364,7 +1363,8 @@ static void valueFlowSubFunction(TokenList *tokenlist, ErrorLogger *errorLogger, // Get function argument, and check if parameter is passed by value const Function * const function = ftok->astOperand1()->function(); const Variable * const arg = function ? function->getArgumentVar(argnr) : nullptr; - if (!Token::Match(arg ? arg->typeStartToken() : nullptr, "%type% %var% ,|)")) + if (!Token::Match(arg ? arg->typeStartToken() : nullptr, "%type% %var% ,|)") && + !Token::Match(arg ? arg->typeStartToken() : nullptr, "const| struct| %type% * %var% ,|)")) continue; // Function scope.. diff --git a/test/testvalueflow.cpp b/test/testvalueflow.cpp index 625689728..67776de44 100644 --- a/test/testvalueflow.cpp +++ b/test/testvalueflow.cpp @@ -159,12 +159,21 @@ private: void valueFlowString() { const char *code; + // valueFlowAfterAssign code = "const char * f() {\n" " static const char *x;\n" " if (a) x = \"123\";\n" " return x;\n" "}"; ASSERT_EQUALS(true, testValueOfX(code, 4, "\"123\"")); + + // valueFlowSubFunction + code = "void dostuff(const char *x) {\n" + " f(x);\n" + "}\n" + "\n" + "void test() { dostuff(\"abc\"); }"; + ASSERT_EQUALS(true, testValueOfX(code, 2, "\"abc\"")); } void valueFlowPointerAlias() {