From a3dc2db77a7dcc32f297e23042e3716339b0c1e9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Wed, 31 Jul 2019 12:38:36 +0200 Subject: [PATCH] SymbolDatabase: Use ValueType::matchParameter for variable address parameters --- lib/symboldatabase.cpp | 57 +++++++++++++++++++++++++------------ lib/symboldatabase.h | 2 +- test/testsymboldatabase.cpp | 2 +- 3 files changed, 41 insertions(+), 20 deletions(-) diff --git a/lib/symboldatabase.cpp b/lib/symboldatabase.cpp index cb1a31e96..bac36db00 100644 --- a/lib/symboldatabase.cpp +++ b/lib/symboldatabase.cpp @@ -4185,23 +4185,39 @@ const Function* Scope::findFunction(const Token *tok, bool requireConst) const // check for a match with address of a variable else if (Token::Match(arguments[j], "& %var% ,|)")) { - const Variable * callarg = check->getVariableFromVarId(arguments[j]->next()->varId()); - if (callarg) { - const bool funcargptr = (funcarg->typeEndToken()->str() == "*"); - if (funcargptr && - (callarg->typeStartToken()->str() == funcarg->typeStartToken()->str() && - callarg->typeStartToken()->isUnsigned() == funcarg->typeStartToken()->isUnsigned() && - callarg->typeStartToken()->isLong() == funcarg->typeStartToken()->isLong())) { - same++; - } else if (funcargptr && funcarg->typeStartToken()->str() == "void") { - fallback1++; - } else { - // can't match so remove this function from possible matches - matches.erase(matches.begin() + i); - erased = true; - break; + ValueType::MatchResult res = ValueType::matchParameter(arguments[j]->valueType(), funcarg->valueType()); + if (res == ValueType::MatchResult::SAME) + ++same; + else if (res == ValueType::MatchResult::FALLBACK1) + ++fallback1; + else if (res == ValueType::MatchResult::FALLBACK2) + ++fallback2; + else if (res == ValueType::MatchResult::NOMATCH) { + // can't match so remove this function from possible matches + matches.erase(matches.begin() + i); + erased = true; + break; + } else { + // TODO: Remove this code + const Variable * callarg = check->getVariableFromVarId(arguments[j]->next()->varId()); + if (callarg) { + const bool funcargptr = (funcarg->typeEndToken()->str() == "*"); + if (funcargptr && + (callarg->typeStartToken()->str() == funcarg->typeStartToken()->str() && + callarg->typeStartToken()->isUnsigned() == funcarg->typeStartToken()->isUnsigned() && + callarg->typeStartToken()->isLong() == funcarg->typeStartToken()->isLong())) { + same++; + } else if (funcargptr && funcarg->typeStartToken()->str() == "void") { + fallback1++; + } else { + // can't match so remove this function from possible matches + matches.erase(matches.begin() + i); + erased = true; + break; + } } } + } // check for a match with a numeric literal @@ -5829,15 +5845,20 @@ ValueType::MatchResult ValueType::matchParameter(const ValueType *call, const Va { if (!call || !func) return ValueType::MatchResult::UNKNOWN; - if (call->pointer != func->pointer) + if (call->pointer != func->pointer) { + if (call->pointer < func->pointer && !call->isIntegral()) + return ValueType::MatchResult::NOMATCH; + if (func->pointer < call->pointer && !func->isIntegral()) + return ValueType::MatchResult::NOMATCH; return ValueType::MatchResult::UNKNOWN; // TODO + } if (call->pointer > 0 && func->type != ValueType::Type::VOID && ((call->constness | func->constness) != func->constness)) - return ValueType::MatchResult::UNKNOWN; + return ValueType::MatchResult::NOMATCH; if (call->type != func->type) { if (call->type == ValueType::Type::VOID || func->type == ValueType::Type::VOID) return ValueType::MatchResult::FALLBACK1; if (call->pointer > 0 && func->pointer > 0) - return ValueType::MatchResult::UNKNOWN; + return ValueType::MatchResult::NOMATCH; if (call->isIntegral() && func->isIntegral()) return call->type < func->type ? ValueType::MatchResult::FALLBACK1 : diff --git a/lib/symboldatabase.h b/lib/symboldatabase.h index badc74a7d..8de5a2f0d 100644 --- a/lib/symboldatabase.h +++ b/lib/symboldatabase.h @@ -1137,7 +1137,7 @@ public: static Type typeFromString(const std::string &typestr, bool longType); - enum class MatchResult { UNKNOWN, SAME, FALLBACK1, FALLBACK2 }; + enum class MatchResult { UNKNOWN, SAME, FALLBACK1, FALLBACK2, NOMATCH }; static MatchResult matchParameter(const ValueType *call, const ValueType *func); bool isIntegral() const { diff --git a/test/testsymboldatabase.cpp b/test/testsymboldatabase.cpp index 43baa147a..4ee018a54 100644 --- a/test/testsymboldatabase.cpp +++ b/test/testsymboldatabase.cpp @@ -5543,7 +5543,7 @@ private: ValueType vt_void_pointer(ValueType::Sign::SIGNED, ValueType::Type::VOID, 1); // compatible ValueType vt_int_pointer(ValueType::Sign::SIGNED, ValueType::Type::INT, 1); // not compatible ASSERT_EQUALS((int)ValueType::MatchResult::FALLBACK1, (int)ValueType::matchParameter(&vt_char_pointer, &vt_void_pointer)); - ASSERT_EQUALS((int)ValueType::MatchResult::UNKNOWN, (int)ValueType::matchParameter(&vt_char_pointer, &vt_int_pointer)); + ASSERT_EQUALS((int)ValueType::MatchResult::NOMATCH, (int)ValueType::matchParameter(&vt_char_pointer, &vt_int_pointer)); } #define FUNC(x) const Function *x = findFunctionByName(#x, &db->scopeList.front()); \