Fixed #4999 (Crash with simple code snipped in rev ab30fa3)

This commit is contained in:
Robert Reif 2013-08-31 18:58:55 +02:00 committed by Daniel Marjamäki
parent 6b260c481c
commit 8790f6d73f
5 changed files with 37 additions and 25 deletions

View File

@ -792,23 +792,25 @@ bool CheckIO::getArgumentInfo(const Token * tok, const Variable **var, const Tok
varTok = tok1->linkAt(-1)->previous();
if (varTok->str() == ")" && varTok->link()->previous()->type() == Token::eFunction) {
const Function * function = varTok->link()->previous()->function();
if (function) {
if (function && function->retDef) {
*var = 0;
*typeTok = function->retDef;
*func = function;
element = true;
return true;
}
} else
return false;
}
} else if (tok1->previous()->str() == ")" && tok1->linkAt(-1)->previous()->type() == Token::eFunction) {
const Function * function = tok1->linkAt(-1)->previous()->function();
if (function) {
if (function && function->retDef) {
*var = 0;
*typeTok = function->retDef;
*func = function;
element = false;
return true;
}
} else
return false;
} else
varTok = tok1->previous();
break;

View File

@ -612,9 +612,10 @@ SymbolDatabase::SymbolDatabase(const Tokenizer *tokenizer, const Settings *setti
break;
}
}
// save function prototype in database
if (newFunc)
addGlobalFunctionDecl(scope, argStart, funcStart);
addGlobalFunctionDecl(scope, tok, argStart, funcStart);
tok = argStart->link()->next();
continue;
@ -630,7 +631,7 @@ SymbolDatabase::SymbolDatabase(const Tokenizer *tokenizer, const Settings *setti
}
// save function prototype in database
if (newFunc) {
Function* func = addGlobalFunctionDecl(scope, argStart, funcStart);
Function* func = addGlobalFunctionDecl(scope, tok, argStart, funcStart);
func->retFuncPtr = true;
}
@ -1243,25 +1244,12 @@ Function* SymbolDatabase::addGlobalFunction(Scope*& scope, const Token*& tok, co
}
if (!function)
function = addGlobalFunctionDecl(scope, argStart, funcStart);
function = addGlobalFunctionDecl(scope, tok, argStart, funcStart);
function->arg = argStart;
function->token = funcStart;
function->hasBody = true;
const Token *tok1 = tok;
// look for end of previous statement
while (tok1->previous() && !Token::Match(tok1->previous(), ";|}|{"))
tok1 = tok1->previous();
// find the return type
while (tok1 && Token::Match(tok1->next(), "static|const"))
tok1 = tok1->next();
if (tok1)
function->retDef = tok1;
addNewFunction(&scope, &tok);
if (scope) {
@ -1272,7 +1260,7 @@ Function* SymbolDatabase::addGlobalFunction(Scope*& scope, const Token*& tok, co
return 0;
}
Function* SymbolDatabase::addGlobalFunctionDecl(Scope*& scope, const Token *argStart, const Token* funcStart)
Function* SymbolDatabase::addGlobalFunctionDecl(Scope*& scope, const Token *tok, const Token *argStart, const Token* funcStart)
{
Function function;
@ -1290,6 +1278,19 @@ Function* SymbolDatabase::addGlobalFunctionDecl(Scope*& scope, const Token *argS
function.type = Function::eFunction;
function.nestedIn = scope;
const Token *tok1 = tok;
// look for end of previous statement
while (tok1->previous() && !Token::Match(tok1->previous(), ";|}|{"))
tok1 = tok1->previous();
// find the return type
while (tok1 && Token::Match(tok1->next(), "static|const"))
tok1 = tok1->next();
if (tok1)
function.retDef = tok1;
scope->functionList.push_back(function);
return &scope->functionList.back();
}

View File

@ -742,7 +742,7 @@ private:
friend class Scope;
void addClassFunction(Scope **info, const Token **tok, const Token *argStart);
Function *addGlobalFunctionDecl(Scope*& scope, const Token *argStart, const Token* funcStart);
Function *addGlobalFunctionDecl(Scope*& scope, const Token* tok, const Token *argStart, const Token* funcStart);
Function *addGlobalFunction(Scope*& scope, const Token*& tok, const Token *argStart, const Token* funcStart);
void addNewFunction(Scope **info, const Token **tok);
static bool isFunction(const Token *tok, const Scope* outerScope, const Token **funcStart, const Token **argStart);

View File

@ -9577,9 +9577,11 @@ void Tokenizer::createSymbolDatabase()
if (membertok) {
const Variable *var = tok->variable();
const Variable *membervar = var->typeScope()->getVariable(membertok->str());
if (membervar)
membertok->variable(membervar);
if (var && var->typeScope()) {
const Variable *membervar = var->typeScope()->getVariable(membertok->str());
if (membervar)
membertok->variable(membervar);
}
}
}

View File

@ -1074,6 +1074,13 @@ private:
ASSERT_EQUALS("[test.cpp:3]: (warning) %u in format string (no. 2) requires an unsigned integer but the argument type is 'int'.\n"
"[test.cpp:3]: (warning) %f in format string (no. 3) requires a floating point number but the argument type is 'int'.\n", errout.str());
// #4999 (crash)
check("int bar(int a);\n"
"void foo() {\n"
" printf(\"%d\", bar(0));\n"
"}\n");
ASSERT_EQUALS("", errout.str());
}
void testPosixPrintfScanfParameterPosition() { // #4900 - No support for parameters in format strings