From d36ed9aff15e267f3f94f3e37432e0eb6380809a Mon Sep 17 00:00:00 2001 From: Robert Reif Date: Tue, 22 Mar 2011 19:23:36 -0400 Subject: [PATCH] fix #2670 (False positive: function can be const, overloaded functions) --- lib/checkclass.cpp | 34 +++++++++++++++++++++++++++++++++- test/testclass.cpp | 22 ++++++++++++++++++++++ 2 files changed, 55 insertions(+), 1 deletion(-) diff --git a/lib/checkclass.cpp b/lib/checkclass.cpp index 0672ad15b..0a0f7a3bb 100644 --- a/lib/checkclass.cpp +++ b/lib/checkclass.cpp @@ -1446,13 +1446,45 @@ bool CheckClass::isMemberVar(const Scope *scope, const Token *tok) return false; } +static int countParameters(const Token *tok) +{ + if (Token::Match(tok->tokAt(2), "void| )")) + return 0; + + int numpar = 1; + int parlevel = 0; + for (; tok; tok = tok->next()) + { + if (tok->str() == "(") + ++parlevel; + + else if (tok->str() == ")") + { + if (parlevel <= 1) + break; + --parlevel; + } + + else if (parlevel == 1 && tok->str() == ",") + { + ++numpar; + } + } + + return numpar; +} + bool CheckClass::isConstMemberFunc(const Scope *scope, const Token *tok) { + unsigned int args = countParameters(tok); + std::list::const_iterator func; for (func = scope->functionList.begin(); func != scope->functionList.end(); ++func) { - if (func->tokenDef->str() == tok->str() && func->isConst) + /** @todo we need to look at the argument types when there are overloaded functions + * with the same number of arguments */ + if (func->tokenDef->str() == tok->str() && func->argCount() == args && func->isConst) return true; } diff --git a/test/testclass.cpp b/test/testclass.cpp index f27d2a7a0..e4944addc 100644 --- a/test/testclass.cpp +++ b/test/testclass.cpp @@ -167,6 +167,7 @@ private: TEST_CASE(const44); // ticket #2595 TEST_CASE(const45); // ticket #2664 TEST_CASE(const46); // ticket #2636 + TEST_CASE(const47); // ticket #2670 TEST_CASE(assigningPointerToPointerIsNotAConstOperation); TEST_CASE(assigningArrayElementIsNotAConstOperation); TEST_CASE(constoperator1); // operator< can often be const @@ -5228,6 +5229,27 @@ private: "[test.cpp:7]: (information) Technically the member function 'Altren::fun2' can be const.\n", errout.str()); } + void const47() // ticket 2670 + { + checkConst("class Altren {\n" + "public:\n" + " void foo() { delete this; }\n" + " void foo(int i) const { }\n" + " void bar() { foo(); }\n" + "}\n"); + + ASSERT_EQUALS("", errout.str()); + + checkConst("class Altren {\n" + "public:\n" + " void foo() { delete this; }\n" + " void foo(int i) const { }\n" + " void bar() { foo(1); }\n" + "}\n"); + + ASSERT_EQUALS("[test.cpp:5]: (information) Technically the member function 'Altren::bar' can be const.\n", errout.str()); + } + void assigningPointerToPointerIsNotAConstOperation() { checkConst("struct s\n"