Symbol database: fix some function prototype bugs that were found during check conversions. Ticket: #4266

This commit is contained in:
Robert Reif 2012-10-30 15:48:06 +01:00 committed by Daniel Marjamäki
parent e1dce66494
commit 8e14d7682c
3 changed files with 44 additions and 6 deletions

View File

@ -451,8 +451,10 @@ SymbolDatabase::SymbolDatabase(const Tokenizer *tokenizer, const Settings *setti
else if (Token::simpleMatch(argStart->link(), ") ;")) {
bool newFunc = true; // Is this function already in the database?
for (std::list<Function>::const_iterator i = scope->functionList.begin(); i != scope->functionList.end(); ++i) {
if (i->tokenDef->str() == tok->str() && Function::argsMatch(scope, i->argDef, argStart, "", 0))
if (i->tokenDef->str() == tok->str() && Function::argsMatch(scope, i->argDef->next(), argStart->next(), "", 0)) {
newFunc = false;
break;
}
}
// save function prototype in database
if (newFunc)
@ -1572,10 +1574,11 @@ void SymbolDatabase::printOut(const char *title) const
void Function::addArguments(const SymbolDatabase *symbolDatabase, const Scope *scope)
{
// check for non-empty argument list "( ... )"
if (arg && arg->link() != arg->next() && !Token::simpleMatch(arg, "( void )")) {
const Token * start = arg ? arg : argDef;
if (start && start->link() != start->next() && !Token::simpleMatch(start, "( void )")) {
unsigned int count = 0;
for (const Token* tok = arg->next(); tok; tok = tok->next()) {
for (const Token* tok = start->next(); tok; tok = tok->next()) {
const Token* startTok = tok;
const Token* endTok = NULL;
const Token* nameTok = NULL;
@ -2169,7 +2172,7 @@ const Function* SymbolDatabase::findFunctionByNameAndArgs(const Token *tok, cons
// check the arguments
unsigned int args = 0;
const Token *arg = tok->tokAt(2);
while (arg) {
while (arg && arg->str() != ")") {
/** @todo check argument type for match */
/** @todo check for default arguments */
args++;

View File

@ -2084,7 +2084,7 @@ private:
" foo(p);\n"
" if (p) { }\n"
"}");
TODO_ASSERT_EQUALS("[test.cpp:4] -> [test.cpp:6]: (error) Possible null pointer dereference: p - otherwise it is redundant to check it against null.\n", "", errout.str());
ASSERT_EQUALS("[test.cpp:4] -> [test.cpp:6]: (error) Possible null pointer dereference: p - otherwise it is redundant to check it against null.\n", errout.str());
// inconclusive
check("void f(int *p) {\n"
@ -2123,7 +2123,7 @@ private:
" foo(abc);\n"
" if (abc) { }\n"
"}");
TODO_ASSERT_EQUALS("[test.cpp:4] -> [test.cpp:6]: (error) Possible null pointer dereference: abc - otherwise it is redundant to check it against null.\n", "", errout.str());
ASSERT_EQUALS("[test.cpp:4] -> [test.cpp:6]: (error) Possible null pointer dereference: abc - otherwise it is redundant to check it against null.\n", errout.str());
// inconclusive
check("void f(struct ABC *abc) {\n"

View File

@ -19,6 +19,7 @@
#include "testsuite.h"
#include "testutils.h"
#include "symboldatabase.h"
#include <sstream>
#define GET_SYMBOL_DB(code) \
errout.str(""); \
@ -157,6 +158,8 @@ private:
TEST_CASE(isImplicitlyVirtual);
TEST_CASE(garbage);
TEST_CASE(findFunction1);
}
void array() {
@ -1406,6 +1409,38 @@ private:
GET_SYMBOL_DB("void f( { u = 1 ; } ) { }");
(void)db;
}
void findFunction1() {
GET_SYMBOL_DB("int foo(int x);\n" /* 1 */
"void foo();\n" /* 2 */
"void bar() {\n" /* 3 */
" foo();\n" /* 4 */
" foo(1);\n" /* 5 */
"}"); /* 6 */
ASSERT_EQUALS("", errout.str());
if (db) {
const Scope * bar = db->findScopeByName("bar");
ASSERT(bar);
if (bar) {
unsigned int linenrs[] = { 2, 1 };
unsigned int index = 0;
for (const Token * tok = bar->classStart->next(); tok != bar->classEnd; tok = tok->next()) {
if (Token::Match(tok, "%var% (") && !tok->varId() && Token::simpleMatch(tok->linkAt(1), ") ;")) {
const Function * function = db->findFunctionByNameAndArgs(tok, bar);
ASSERT(function);
if (function) {
std::stringstream expected;
expected << "Function call on line " << tok->linenr() << " calls function on line " << linenrs[index] << std::endl;
std::stringstream actual;
actual << "Function call on line " << tok->linenr() << " calls function on line " << function->tokenDef->linenr() << std::endl;
ASSERT_EQUALS(expected.str().c_str(), actual.str().c_str());
}
index++;
}
}
}
}
}
};
REGISTER_TEST(TestSymbolDatabase)