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
|
const Function* Scope::findFunction(const Token *tok, bool requireConst) const
|
||||||
{
|
{
|
||||||
// make sure this is a function call
|
// 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% ,|)")) {
|
if (Token::Match(arguments[j], "%var% ,|)")) {
|
||||||
const Variable * callarg = check->getVariableFromVarId(arguments[j]->varId());
|
const Variable * callarg = check->getVariableFromVarId(arguments[j]->varId());
|
||||||
|
|
||||||
if (callarg && callarg->isArrayOrPointer() == funcarg->isArrayOrPointer()) {
|
if (callarg) {
|
||||||
if (callarg->typeStartToken()->str() == funcarg->typeStartToken()->str() &&
|
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()->isUnsigned() == funcarg->typeStartToken()->isUnsigned() &&
|
||||||
callarg->typeStartToken()->isLong() == funcarg->typeStartToken()->isLong()) {
|
callarg->typeStartToken()->isLong() == funcarg->typeStartToken()->isLong()) {
|
||||||
same++;
|
same++;
|
||||||
} else if (callarg->isArrayOrPointer()) {
|
} else if (callarg->isArrayOrPointer()) {
|
||||||
if (funcarg->typeStartToken()->str() == "void")
|
if (ptrequals && constEquals && funcarg->typeStartToken()->str() == "void")
|
||||||
fallback1++;
|
fallback1++;
|
||||||
|
else if (constEquals && Token::Match(callarg->typeStartToken(), "char|wchar_t") && funcarg->isStlStringType())
|
||||||
|
fallback2++;
|
||||||
} else if ((Token::Match(funcarg->typeStartToken(), "char|short|int|long") &&
|
} else if ((Token::Match(funcarg->typeStartToken(), "char|short|int|long") &&
|
||||||
Token::Match(callarg->typeStartToken(), "char|short|int|long")) ||
|
Token::Match(callarg->typeStartToken(), "char|short|int|long") && ptrequals) ||
|
||||||
(Token::Match(funcarg->typeStartToken(), "float|double") &&
|
(Token::Match(funcarg->typeStartToken(), "float|double") &&
|
||||||
Token::Match(callarg->typeStartToken(), "float|double"))) {
|
Token::Match(callarg->typeStartToken(), "float|double") && ptrequals)) {
|
||||||
fallback1++;
|
fallback1++;
|
||||||
} else if ((Token::Match(funcarg->typeStartToken(), "char|short|int|long") &&
|
} else if ((Token::Match(funcarg->typeStartToken(), "char|short|int|long") &&
|
||||||
Token::Match(callarg->typeStartToken(), "float|double")) ||
|
Token::Match(callarg->typeStartToken(), "float|double") && ptrequals) ||
|
||||||
(Token::Match(funcarg->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++;
|
fallback2++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3925,11 +3926,15 @@ const Function* Scope::findFunction(const Token *tok, bool requireConst) const
|
||||||
}
|
}
|
||||||
|
|
||||||
// check for a match with a string literal
|
// check for a match with a string literal
|
||||||
else if (Token::Match(arguments[j], "%str% ,|)") &&
|
else if (Token::Match(arguments[j], "%str% ,|)")) {
|
||||||
funcarg->typeStartToken() != funcarg->typeEndToken() &&
|
if (funcarg->typeStartToken() != funcarg->typeEndToken() &&
|
||||||
((!arguments[j]->isLong() && Token::simpleMatch(funcarg->typeStartToken(), "char *")) ||
|
((!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++;
|
same++;
|
||||||
|
else if (Token::simpleMatch(funcarg->typeStartToken(), "void *"))
|
||||||
|
fallback1++;
|
||||||
|
else if (funcarg->isStlStringType())
|
||||||
|
fallback2++;
|
||||||
}
|
}
|
||||||
|
|
||||||
// check that function argument type is not mismatching
|
// check that function argument type is not mismatching
|
||||||
|
|
|
@ -282,6 +282,7 @@ private:
|
||||||
TEST_CASE(findFunction11);
|
TEST_CASE(findFunction11);
|
||||||
TEST_CASE(findFunction12);
|
TEST_CASE(findFunction12);
|
||||||
TEST_CASE(findFunction13);
|
TEST_CASE(findFunction13);
|
||||||
|
TEST_CASE(findFunction14);
|
||||||
|
|
||||||
TEST_CASE(noexceptFunction1);
|
TEST_CASE(noexceptFunction1);
|
||||||
TEST_CASE(noexceptFunction2);
|
TEST_CASE(noexceptFunction2);
|
||||||
|
@ -3494,11 +3495,13 @@ private:
|
||||||
void findFunction12() {
|
void findFunction12() {
|
||||||
GET_SYMBOL_DB("void foo(std::string a) { }\n"
|
GET_SYMBOL_DB("void foo(std::string a) { }\n"
|
||||||
"void foo(long long a) { }\n"
|
"void foo(long long a) { }\n"
|
||||||
"void foo() {\n"
|
"void func(char* cp) {\n"
|
||||||
" foo(0);\n"
|
" foo(0);\n"
|
||||||
" foo(0L);\n"
|
" foo(0L);\n"
|
||||||
" foo(0.f);\n"
|
" foo(0.f);\n"
|
||||||
" foo(bar());\n"
|
" foo(bar());\n"
|
||||||
|
" foo(cp);\n"
|
||||||
|
" foo(\"\");\n"
|
||||||
"}");
|
"}");
|
||||||
|
|
||||||
ASSERT_EQUALS("", errout.str());
|
ASSERT_EQUALS("", errout.str());
|
||||||
|
@ -3514,6 +3517,12 @@ private:
|
||||||
|
|
||||||
f = Token::findsimplematch(tokenizer.tokens(), "foo ( bar ( ) ) ;");
|
f = Token::findsimplematch(tokenizer.tokens(), "foo ( bar ( ) ) ;");
|
||||||
ASSERT_EQUALS(true, f && f->function() == nullptr);
|
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() {
|
void findFunction13() {
|
||||||
|
@ -3522,7 +3531,7 @@ private:
|
||||||
"void foo(long long a) { }\n"
|
"void foo(long long a) { }\n"
|
||||||
"void foo(int* a) { }\n"
|
"void foo(int* a) { }\n"
|
||||||
"void foo(void* 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(0);\n"
|
||||||
" foo(0L);\n"
|
" foo(0L);\n"
|
||||||
" foo(0.f);\n"
|
" foo(0.f);\n"
|
||||||
|
@ -3533,6 +3542,8 @@ private:
|
||||||
" foo(&f);\n"
|
" foo(&f);\n"
|
||||||
" foo(ip);\n"
|
" foo(ip);\n"
|
||||||
" foo(fp);\n"
|
" foo(fp);\n"
|
||||||
|
" foo(cp);\n"
|
||||||
|
" foo(\"\");\n"
|
||||||
"}");
|
"}");
|
||||||
|
|
||||||
ASSERT_EQUALS("", errout.str());
|
ASSERT_EQUALS("", errout.str());
|
||||||
|
@ -3566,6 +3577,43 @@ private:
|
||||||
|
|
||||||
f = Token::findsimplematch(tokenizer.tokens(), "foo ( fp ) ;");
|
f = Token::findsimplematch(tokenizer.tokens(), "foo ( fp ) ;");
|
||||||
ASSERT_EQUALS(true, f && f->function() && f->function()->tokenDef->linenr() == 5);
|
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()); \
|
#define FUNC(x) const Function *x = findFunctionByName(#x, &db->scopeList.front()); \
|
||||||
|
|
Loading…
Reference in New Issue