From 19eef2c5844d45e4ccc361939e1814c91bc58e5d Mon Sep 17 00:00:00 2001 From: chrchr-github <78114321+chrchr-github@users.noreply.github.com> Date: Sun, 19 Mar 2023 17:43:23 +0100 Subject: [PATCH] Partial fix for #11599 false negative: constParameter (#4901) --- lib/astutils.cpp | 2 +- lib/checkother.cpp | 10 ++++++++++ test/testother.cpp | 26 ++++++++++++++++++++++++-- 3 files changed, 35 insertions(+), 3 deletions(-) diff --git a/lib/astutils.cpp b/lib/astutils.cpp index 8da611712..434c25585 100644 --- a/lib/astutils.cpp +++ b/lib/astutils.cpp @@ -2412,7 +2412,7 @@ bool isVariableChangedByFunctionCall(const Token *tok, int indirect, const Setti // If const is applied to the pointer, then the value can still be modified if (Token::simpleMatch(arg->typeEndToken(), "* const")) return true; - if (!arg->isPointer()) + if (!arg->isPointer() && (!arg->valueType() || arg->valueType()->type == ValueType::UNKNOWN_TYPE)) return true; } if (!arg->isConst() && arg->isReference()) diff --git a/lib/checkother.cpp b/lib/checkother.cpp index 506be5fd2..6c232cb94 100644 --- a/lib/checkother.cpp +++ b/lib/checkother.cpp @@ -1590,6 +1590,16 @@ void CheckOther::checkConstPointer() continue; } else if (Token::simpleMatch(gparent, "[") && gparent->astOperand2() == parent) continue; + else if (Token::Match(gparent, "(|,")) { + const Token* ftok = gparent; + while (Token::simpleMatch(ftok, ",")) + ftok = ftok->astParent(); + if (ftok && Token::Match(ftok->astOperand1(), "%name% (")) { + bool inconclusive{}; + if (!isVariableChangedByFunctionCall(ftok->astOperand1(), vt->pointer, var->declarationId(), mSettings, &inconclusive) && !inconclusive) + continue; + } + } } else { if (Token::Match(parent, "%oror%|%comp%|&&|?|!|-")) continue; diff --git a/test/testother.cpp b/test/testother.cpp index 36fa2476c..e885945f0 100644 --- a/test/testother.cpp +++ b/test/testother.cpp @@ -3363,6 +3363,28 @@ private: " if (r == b) {}\n" "}\n"); ASSERT_EQUALS("", errout.str()); + + check("struct S {};\n" // #11599 + "void g(S);\n" + "void h(const S&);\n" + "void h(int, int, const S&);\n" + "void i(S&);\n" + "void f1(S* s) {\n" + " g(*s);\n" + "}\n" + "void f2(S* s) {\n" + " h(*s);\n" + "}\n" + "void f3(S* s) {\n" + " h(1, 2, *s);\n" + "}\n" + "void f4(S* s) {\n" + " i(*s);\n" + "}\n"); + ASSERT_EQUALS("[test.cpp:6]: (style) Parameter 's' can be declared as pointer to const\n" + "[test.cpp:9]: (style) Parameter 's' can be declared as pointer to const\n" + "[test.cpp:12]: (style) Parameter 's' can be declared as pointer to const\n", + errout.str()); } void switchRedundantAssignmentTest() { @@ -10464,7 +10486,7 @@ private: "}"); ASSERT_EQUALS("", errout.str()); - check("void foo(char *c) {\n" + check("void foo(const char *c) {\n" " if (*c == '+' && (operand || !isalnum(*c))) {}\n" "}"); ASSERT_EQUALS("", errout.str()); @@ -10482,7 +10504,7 @@ private: " int x[] = { 10, 10 };\n" " f(x[0]);\n" "}"); - ASSERT_EQUALS("", errout.str()); + ASSERT_EQUALS("[test.cpp:3]: (style) Variable 'x' can be declared as const array\n", errout.str()); check("struct A { int x; };" "void g(int);\n"