From e8d84bc6b48eaf6adc9965ba20e236e9626b475a Mon Sep 17 00:00:00 2001 From: Alexander Mai Date: Sat, 23 May 2015 11:56:11 +0200 Subject: [PATCH] #6700 const vs non-const inside assert() statement. Function matching in symboldatabase did not honor const'ness of a class instance variable --- lib/symboldatabase.cpp | 7 +++++-- lib/symboldatabase.h | 3 ++- test/testsymboldatabase.cpp | 21 +++++++++++++++++++++ 3 files changed, 28 insertions(+), 3 deletions(-) diff --git a/lib/symboldatabase.cpp b/lib/symboldatabase.cpp index 37712f4c4..06fed103a 100644 --- a/lib/symboldatabase.cpp +++ b/lib/symboldatabase.cpp @@ -3101,7 +3101,7 @@ void Scope::findFunctionInBase(const std::string & name, size_t args, std::vecto This can be difficult because of promotion and conversion operators and casts and because the argument can also be a function call. */ -const Function* Scope::findFunction(const Token *tok) const +const Function* Scope::findFunction(const Token *tok, bool requireConst) const { // make sure this is a function call const Token *end = tok->linkAt(1); @@ -3232,6 +3232,9 @@ const Function* Scope::findFunction(const Token *tok) const // check if all arguments matched if (same == args) { + if (requireConst && func->isConst()) + return func; + // get the function this call is in const Scope * scope = tok->scope(); @@ -3320,7 +3323,7 @@ const Function* SymbolDatabase::findFunction(const Token *tok) const if (Token::Match(tok1, "%var% .")) { const Variable *var = getVariableFromVarId(tok1->varId()); if (var && var->typeScope()) - return var->typeScope()->findFunction(tok); + return var->typeScope()->findFunction(tok, var->isConst()); } } diff --git a/lib/symboldatabase.h b/lib/symboldatabase.h index 3fd02e2f9..d9348893e 100644 --- a/lib/symboldatabase.h +++ b/lib/symboldatabase.h @@ -842,9 +842,10 @@ public: /** * @brief find a function * @param tok token of function call + * @param requireConst if const refers to a const variable only const methods should be matched * @return pointer to function if found or NULL if not found */ - const Function *findFunction(const Token *tok) const; + const Function *findFunction(const Token *tok, bool requireConst=false) const; /** * @brief find if name is in nested list diff --git a/test/testsymboldatabase.cpp b/test/testsymboldatabase.cpp index d5ad4a01b..cea84d455 100644 --- a/test/testsymboldatabase.cpp +++ b/test/testsymboldatabase.cpp @@ -240,6 +240,7 @@ private: TEST_CASE(findFunction4); TEST_CASE(findFunction5); // #6230 TEST_CASE(findFunction6); + TEST_CASE(findFunction7); // #6700 TEST_CASE(noexceptFunction1); TEST_CASE(noexceptFunction2); @@ -2517,6 +2518,26 @@ private: ASSERT_EQUALS(true, db && f && !f->function()); // regression value only } + void findFunction7() { + GET_SYMBOL_DB("class ResultEnsemble {\n" + "public:\n" + " std::vector &nodeResults() const;\n" + " std::vector &nodeResults();\n" + "};\n" + "class Simulator {\n" + " int generatePinchResultEnsemble(const ResultEnsemble &power, const ResultEnsemble &ground) {\n" + " power.nodeResults().size();\n" + " assert(power.nodeResults().size()==ground.nodeResults().size());\n" + " }\n" + "};") + const Token *callfunc = Token::findsimplematch(tokenizer.tokens(), "power . nodeResults ( ) . size ( ) ;"); + ASSERT_EQUALS("", errout.str()); + ASSERT_EQUALS(true, db != nullptr); // not null + ASSERT_EQUALS(true, callfunc != nullptr); // not null + ASSERT_EQUALS(true, callfunc && callfunc->tokAt(2)->function() && callfunc->tokAt(2)->function()->tokenDef->linenr() == 3); + } + + #define FUNC(x) const Function *x = findFunctionByName(#x, &db->scopeList.front()); \ ASSERT_EQUALS(true, x != nullptr); \