From d691450443875e21e48e200ff965f1dff57d5e3d Mon Sep 17 00:00:00 2001 From: Paul Fultz II Date: Sat, 19 Aug 2023 12:59:15 -0500 Subject: [PATCH] Improve knownArgument to check arguments to any nary function (#5348) --- lib/checkother.cpp | 30 ++++++++++++++++++++---------- test/testother.cpp | 8 ++++++++ 2 files changed, 28 insertions(+), 10 deletions(-) diff --git a/lib/checkother.cpp b/lib/checkother.cpp index 6b94c3484..deaadbf7c 100644 --- a/lib/checkother.cpp +++ b/lib/checkother.cpp @@ -3647,17 +3647,23 @@ void CheckOther::checkKnownArgument() const SymbolDatabase *symbolDatabase = mTokenizer->getSymbolDatabase(); for (const Scope *functionScope : symbolDatabase->functionScopes) { for (const Token *tok = functionScope->bodyStart; tok != functionScope->bodyEnd; tok = tok->next()) { - if (!Token::simpleMatch(tok->astParent(), "(")) - continue; - if (!Token::Match(tok->astParent()->previous(), "%name%")) - continue; - if (Token::Match(tok->astParent()->previous(), "if|while|switch|sizeof")) - continue; - if (tok == tok->astParent()->previous()) - continue; if (!tok->hasKnownIntValue()) continue; - if (tok->tokType() == Token::eIncDecOp) + if (Token::Match(tok, "++|--|%assign%")) + continue; + if (!Token::Match(tok->astParent(), "(|{|,")) + continue; + if (tok->astParent()->isCast()) + continue; + int argn = -1; + const Token* ftok = getTokenArgumentFunction(tok, argn); + if (!ftok) + continue; + if (ftok->isCast()) + continue; + if (Token::Match(ftok, "if|while|switch|sizeof")) + continue; + if (tok == tok->astParent()->previous()) continue; if (isConstVarExpression(tok)) continue; @@ -3668,6 +3674,10 @@ void CheckOther::checkKnownArgument() tok2 = tok2->astOperand2(); if (isVariableExpression(tok2)) continue; + if (tok->isComparisonOp() && + isSameExpression( + mTokenizer->isCPP(), true, tok->astOperand1(), tok->astOperand2(), mSettings->library, true, true)) + continue; // ensure that there is a integer variable in expression with unknown value std::string varexpr; bool isVariableExprHidden = false; // Is variable expression explicitly hidden @@ -3706,7 +3716,7 @@ void CheckOther::checkKnownArgument() strTolower(funcname); if (funcname.find("assert") != std::string::npos) continue; - knownArgumentError(tok, tok->astParent()->previous(), &tok->values().front(), varexpr, isVariableExprHidden); + knownArgumentError(tok, ftok, &tok->values().front(), varexpr, isVariableExprHidden); } } } diff --git a/test/testother.cpp b/test/testother.cpp index fe87e9d28..d789c3bb1 100644 --- a/test/testother.cpp +++ b/test/testother.cpp @@ -10905,6 +10905,14 @@ private: "}"); ASSERT_EQUALS("[test.cpp:3]: (style) Argument '(int)((x&0x01)>>7)' to function g is always 0. It does not matter what value 'x' has.\n", errout.str()); + check("void g(int, int);\n" + "void f(int x) {\n" + " g(x, (x & 0x01) >> 7);\n" + "}"); + ASSERT_EQUALS( + "[test.cpp:3]: (style) Argument '(x&0x01)>>7' to function g is always 0. It does not matter what value 'x' has.\n", + errout.str()); + check("void g(int);\n" "void f(int x) {\n" " g(0);\n"