SymbolDatabase: Better handling of pointers in findFunction(), supporting const pointers and std::string overloads
This commit is contained in:
parent
4a27376694
commit
c1d8fd7f13
|
@ -3715,10 +3715,6 @@ void Scope::findFunctionInBase(const std::string & name, size_t args, std::vecto
|
|||
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
/** @todo This function does not take into account argument types when they don't match.
|
||||
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, bool requireConst) const
|
||||
{
|
||||
// make sure this is a function call
|
||||
|
@ -3790,23 +3786,28 @@ const Function* Scope::findFunction(const Token *tok, bool requireConst) const
|
|||
if (Token::Match(arguments[j], "%var% ,|)")) {
|
||||
const Variable * callarg = check->getVariableFromVarId(arguments[j]->varId());
|
||||
|
||||
if (callarg && callarg->isArrayOrPointer() == funcarg->isArrayOrPointer()) {
|
||||
if (callarg->typeStartToken()->str() == funcarg->typeStartToken()->str() &&
|
||||
if (callarg) {
|
||||
bool ptrequals = callarg->isArrayOrPointer() == funcarg->isArrayOrPointer();
|
||||
bool constEquals = !callarg->isArrayOrPointer() || ((callarg->typeStartToken()->strAt(-1) == "const") == (funcarg->typeStartToken()->strAt(-1) == "const"));
|
||||
if (ptrequals && constEquals &&
|
||||
callarg->typeStartToken()->str() == funcarg->typeStartToken()->str() &&
|
||||
callarg->typeStartToken()->isUnsigned() == funcarg->typeStartToken()->isUnsigned() &&
|
||||
callarg->typeStartToken()->isLong() == funcarg->typeStartToken()->isLong()) {
|
||||
same++;
|
||||
} else if (callarg->isArrayOrPointer()) {
|
||||
if (funcarg->typeStartToken()->str() == "void")
|
||||
if (ptrequals && constEquals && funcarg->typeStartToken()->str() == "void")
|
||||
fallback1++;
|
||||
else if (constEquals && Token::Match(callarg->typeStartToken(), "char|wchar_t") && funcarg->isStlStringType())
|
||||
fallback2++;
|
||||
} else if ((Token::Match(funcarg->typeStartToken(), "char|short|int|long") &&
|
||||
Token::Match(callarg->typeStartToken(), "char|short|int|long") && ptrequals) ||
|
||||
(Token::Match(funcarg->typeStartToken(), "float|double") &&
|
||||
Token::Match(callarg->typeStartToken(), "float|double") && ptrequals)) {
|
||||
fallback1++;
|
||||
} else if ((Token::Match(funcarg->typeStartToken(), "char|short|int|long") &&
|
||||
Token::Match(callarg->typeStartToken(), "char|short|int|long")) ||
|
||||
Token::Match(callarg->typeStartToken(), "float|double") && ptrequals) ||
|
||||
(Token::Match(funcarg->typeStartToken(), "float|double") &&
|
||||
Token::Match(callarg->typeStartToken(), "float|double"))) {
|
||||
fallback1++;
|
||||
} else if ((Token::Match(funcarg->typeStartToken(), "char|short|int|long") &&
|
||||
Token::Match(callarg->typeStartToken(), "float|double")) ||
|
||||
(Token::Match(funcarg->typeStartToken(), "float|double") &&
|
||||
Token::Match(callarg->typeStartToken(), "char|short|int|long"))) {
|
||||
Token::Match(callarg->typeStartToken(), "char|short|int|long") && ptrequals)) {
|
||||
fallback2++;
|
||||
}
|
||||
}
|
||||
|
@ -3925,11 +3926,15 @@ const Function* Scope::findFunction(const Token *tok, bool requireConst) const
|
|||
}
|
||||
|
||||
// check for a match with a string literal
|
||||
else if (Token::Match(arguments[j], "%str% ,|)") &&
|
||||
funcarg->typeStartToken() != funcarg->typeEndToken() &&
|
||||
else if (Token::Match(arguments[j], "%str% ,|)")) {
|
||||
if (funcarg->typeStartToken() != funcarg->typeEndToken() &&
|
||||
((!arguments[j]->isLong() && Token::simpleMatch(funcarg->typeStartToken(), "char *")) ||
|
||||
(arguments[j]->isLong() && Token::simpleMatch(funcarg->typeStartToken(), "wchar_t *")))) {
|
||||
(arguments[j]->isLong() && Token::simpleMatch(funcarg->typeStartToken(), "wchar_t *"))))
|
||||
same++;
|
||||
else if (Token::simpleMatch(funcarg->typeStartToken(), "void *"))
|
||||
fallback1++;
|
||||
else if (funcarg->isStlStringType())
|
||||
fallback2++;
|
||||
}
|
||||
|
||||
// check that function argument type is not mismatching
|
||||
|
|
|
@ -282,6 +282,7 @@ private:
|
|||
TEST_CASE(findFunction11);
|
||||
TEST_CASE(findFunction12);
|
||||
TEST_CASE(findFunction13);
|
||||
TEST_CASE(findFunction14);
|
||||
|
||||
TEST_CASE(noexceptFunction1);
|
||||
TEST_CASE(noexceptFunction2);
|
||||
|
@ -3494,11 +3495,13 @@ private:
|
|||
void findFunction12() {
|
||||
GET_SYMBOL_DB("void foo(std::string a) { }\n"
|
||||
"void foo(long long a) { }\n"
|
||||
"void foo() {\n"
|
||||
"void func(char* cp) {\n"
|
||||
" foo(0);\n"
|
||||
" foo(0L);\n"
|
||||
" foo(0.f);\n"
|
||||
" foo(bar());\n"
|
||||
" foo(cp);\n"
|
||||
" foo(\"\");\n"
|
||||
"}");
|
||||
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
|
@ -3514,6 +3517,12 @@ private:
|
|||
|
||||
f = Token::findsimplematch(tokenizer.tokens(), "foo ( bar ( ) ) ;");
|
||||
ASSERT_EQUALS(true, f && f->function() == nullptr);
|
||||
|
||||
f = Token::findsimplematch(tokenizer.tokens(), "foo ( cp ) ;");
|
||||
ASSERT_EQUALS(true, f && f->function() && f->function()->tokenDef->linenr() == 1);
|
||||
|
||||
f = Token::findsimplematch(tokenizer.tokens(), "foo ( \"\" ) ;");
|
||||
ASSERT_EQUALS(true, f && f->function() && f->function()->tokenDef->linenr() == 1);
|
||||
}
|
||||
|
||||
void findFunction13() {
|
||||
|
@ -3522,7 +3531,7 @@ private:
|
|||
"void foo(long long a) { }\n"
|
||||
"void foo(int* a) { }\n"
|
||||
"void foo(void* a) { }\n"
|
||||
"void func(int i, float f, int* ip, float* fp) {\n"
|
||||
"void func(int i, const float f, int* ip, float* fp, char* cp) {\n"
|
||||
" foo(0);\n"
|
||||
" foo(0L);\n"
|
||||
" foo(0.f);\n"
|
||||
|
@ -3533,6 +3542,8 @@ private:
|
|||
" foo(&f);\n"
|
||||
" foo(ip);\n"
|
||||
" foo(fp);\n"
|
||||
" foo(cp);\n"
|
||||
" foo(\"\");\n"
|
||||
"}");
|
||||
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
|
@ -3566,6 +3577,43 @@ private:
|
|||
|
||||
f = Token::findsimplematch(tokenizer.tokens(), "foo ( fp ) ;");
|
||||
ASSERT_EQUALS(true, f && f->function() && f->function()->tokenDef->linenr() == 5);
|
||||
|
||||
f = Token::findsimplematch(tokenizer.tokens(), "foo ( cp ) ;");
|
||||
ASSERT_EQUALS(true, f && f->function() && f->function()->tokenDef->linenr() == 5);
|
||||
|
||||
f = Token::findsimplematch(tokenizer.tokens(), "foo ( \"\" ) ;");
|
||||
ASSERT_EQUALS(true, f && f->function() && f->function()->tokenDef->linenr() == 5);
|
||||
}
|
||||
|
||||
void findFunction14() {
|
||||
GET_SYMBOL_DB("void foo(int* a) { }\n"
|
||||
"void foo(const int* a) { }\n"
|
||||
"void foo(void* a) { }\n"
|
||||
"void foo(const float a) { }\n"
|
||||
"void func(int* ip, const int* cip, const char* ccp, char* cp, float f) {\n"
|
||||
" foo(ip);\n"
|
||||
" foo(cip);\n"
|
||||
" foo(cp);\n"
|
||||
" foo(ccp);\n"
|
||||
" foo(f);\n"
|
||||
"}");
|
||||
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
|
||||
const Token *f = Token::findsimplematch(tokenizer.tokens(), "foo ( ip ) ;");
|
||||
ASSERT_EQUALS(true, db && f && f->function() && f->function()->tokenDef->linenr() == 1);
|
||||
|
||||
f = Token::findsimplematch(tokenizer.tokens(), "foo ( cip ) ;");
|
||||
ASSERT_EQUALS(true, f && f->function() && f->function()->tokenDef->linenr() == 2);
|
||||
|
||||
f = Token::findsimplematch(tokenizer.tokens(), "foo ( cp ) ;");
|
||||
ASSERT_EQUALS(true, f && f->function() && f->function()->tokenDef->linenr() == 3);
|
||||
|
||||
f = Token::findsimplematch(tokenizer.tokens(), "foo ( ccp ) ;");
|
||||
ASSERT_EQUALS(true, f && f->function() == nullptr);
|
||||
|
||||
f = Token::findsimplematch(tokenizer.tokens(), "foo ( f ) ;");
|
||||
ASSERT_EQUALS(true, f && f->function() && f->function()->tokenDef->linenr() == 4);
|
||||
}
|
||||
|
||||
#define FUNC(x) const Function *x = findFunctionByName(#x, &db->scopeList.front()); \
|
||||
|
|
Loading…
Reference in New Issue