SymbolDatabase: Use ValueType::matchParameter for variable address parameters

This commit is contained in:
Daniel Marjamäki 2019-07-31 12:38:36 +02:00
parent 039d49bcb1
commit a3dc2db77a
3 changed files with 41 additions and 20 deletions

View File

@ -4185,23 +4185,39 @@ const Function* Scope::findFunction(const Token *tok, bool requireConst) const
// check for a match with address of a variable // check for a match with address of a variable
else if (Token::Match(arguments[j], "& %var% ,|)")) { else if (Token::Match(arguments[j], "& %var% ,|)")) {
const Variable * callarg = check->getVariableFromVarId(arguments[j]->next()->varId()); ValueType::MatchResult res = ValueType::matchParameter(arguments[j]->valueType(), funcarg->valueType());
if (callarg) { if (res == ValueType::MatchResult::SAME)
const bool funcargptr = (funcarg->typeEndToken()->str() == "*"); ++same;
if (funcargptr && else if (res == ValueType::MatchResult::FALLBACK1)
(callarg->typeStartToken()->str() == funcarg->typeStartToken()->str() && ++fallback1;
callarg->typeStartToken()->isUnsigned() == funcarg->typeStartToken()->isUnsigned() && else if (res == ValueType::MatchResult::FALLBACK2)
callarg->typeStartToken()->isLong() == funcarg->typeStartToken()->isLong())) { ++fallback2;
same++; else if (res == ValueType::MatchResult::NOMATCH) {
} else if (funcargptr && funcarg->typeStartToken()->str() == "void") { // can't match so remove this function from possible matches
fallback1++; matches.erase(matches.begin() + i);
} else { erased = true;
// can't match so remove this function from possible matches break;
matches.erase(matches.begin() + i); } else {
erased = true; // TODO: Remove this code
break; 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 // check for a match with a numeric literal
@ -5829,15 +5845,20 @@ ValueType::MatchResult ValueType::matchParameter(const ValueType *call, const Va
{ {
if (!call || !func) if (!call || !func)
return ValueType::MatchResult::UNKNOWN; 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 return ValueType::MatchResult::UNKNOWN; // TODO
}
if (call->pointer > 0 && func->type != ValueType::Type::VOID && ((call->constness | func->constness) != func->constness)) 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 != func->type) {
if (call->type == ValueType::Type::VOID || func->type == ValueType::Type::VOID) if (call->type == ValueType::Type::VOID || func->type == ValueType::Type::VOID)
return ValueType::MatchResult::FALLBACK1; return ValueType::MatchResult::FALLBACK1;
if (call->pointer > 0 && func->pointer > 0) if (call->pointer > 0 && func->pointer > 0)
return ValueType::MatchResult::UNKNOWN; return ValueType::MatchResult::NOMATCH;
if (call->isIntegral() && func->isIntegral()) if (call->isIntegral() && func->isIntegral())
return call->type < func->type ? return call->type < func->type ?
ValueType::MatchResult::FALLBACK1 : ValueType::MatchResult::FALLBACK1 :

View File

@ -1137,7 +1137,7 @@ public:
static Type typeFromString(const std::string &typestr, bool longType); 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); static MatchResult matchParameter(const ValueType *call, const ValueType *func);
bool isIntegral() const { bool isIntegral() const {

View File

@ -5543,7 +5543,7 @@ private:
ValueType vt_void_pointer(ValueType::Sign::SIGNED, ValueType::Type::VOID, 1); // compatible 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 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::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()); \ #define FUNC(x) const Function *x = findFunctionByName(#x, &db->scopeList.front()); \