parent
6b260c481c
commit
8790f6d73f
|
@ -792,23 +792,25 @@ bool CheckIO::getArgumentInfo(const Token * tok, const Variable **var, const Tok
|
||||||
varTok = tok1->linkAt(-1)->previous();
|
varTok = tok1->linkAt(-1)->previous();
|
||||||
if (varTok->str() == ")" && varTok->link()->previous()->type() == Token::eFunction) {
|
if (varTok->str() == ")" && varTok->link()->previous()->type() == Token::eFunction) {
|
||||||
const Function * function = varTok->link()->previous()->function();
|
const Function * function = varTok->link()->previous()->function();
|
||||||
if (function) {
|
if (function && function->retDef) {
|
||||||
*var = 0;
|
*var = 0;
|
||||||
*typeTok = function->retDef;
|
*typeTok = function->retDef;
|
||||||
*func = function;
|
*func = function;
|
||||||
element = true;
|
element = true;
|
||||||
return true;
|
return true;
|
||||||
}
|
} else
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
} else if (tok1->previous()->str() == ")" && tok1->linkAt(-1)->previous()->type() == Token::eFunction) {
|
} else if (tok1->previous()->str() == ")" && tok1->linkAt(-1)->previous()->type() == Token::eFunction) {
|
||||||
const Function * function = tok1->linkAt(-1)->previous()->function();
|
const Function * function = tok1->linkAt(-1)->previous()->function();
|
||||||
if (function) {
|
if (function && function->retDef) {
|
||||||
*var = 0;
|
*var = 0;
|
||||||
*typeTok = function->retDef;
|
*typeTok = function->retDef;
|
||||||
*func = function;
|
*func = function;
|
||||||
element = false;
|
element = false;
|
||||||
return true;
|
return true;
|
||||||
}
|
} else
|
||||||
|
return false;
|
||||||
} else
|
} else
|
||||||
varTok = tok1->previous();
|
varTok = tok1->previous();
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -612,9 +612,10 @@ SymbolDatabase::SymbolDatabase(const Tokenizer *tokenizer, const Settings *setti
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// save function prototype in database
|
// save function prototype in database
|
||||||
if (newFunc)
|
if (newFunc)
|
||||||
addGlobalFunctionDecl(scope, argStart, funcStart);
|
addGlobalFunctionDecl(scope, tok, argStart, funcStart);
|
||||||
|
|
||||||
tok = argStart->link()->next();
|
tok = argStart->link()->next();
|
||||||
continue;
|
continue;
|
||||||
|
@ -630,7 +631,7 @@ SymbolDatabase::SymbolDatabase(const Tokenizer *tokenizer, const Settings *setti
|
||||||
}
|
}
|
||||||
// save function prototype in database
|
// save function prototype in database
|
||||||
if (newFunc) {
|
if (newFunc) {
|
||||||
Function* func = addGlobalFunctionDecl(scope, argStart, funcStart);
|
Function* func = addGlobalFunctionDecl(scope, tok, argStart, funcStart);
|
||||||
func->retFuncPtr = true;
|
func->retFuncPtr = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1243,25 +1244,12 @@ Function* SymbolDatabase::addGlobalFunction(Scope*& scope, const Token*& tok, co
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!function)
|
if (!function)
|
||||||
function = addGlobalFunctionDecl(scope, argStart, funcStart);
|
function = addGlobalFunctionDecl(scope, tok, argStart, funcStart);
|
||||||
|
|
||||||
function->arg = argStart;
|
function->arg = argStart;
|
||||||
function->token = funcStart;
|
function->token = funcStart;
|
||||||
function->hasBody = true;
|
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);
|
addNewFunction(&scope, &tok);
|
||||||
|
|
||||||
if (scope) {
|
if (scope) {
|
||||||
|
@ -1272,7 +1260,7 @@ Function* SymbolDatabase::addGlobalFunction(Scope*& scope, const Token*& tok, co
|
||||||
return 0;
|
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;
|
Function function;
|
||||||
|
|
||||||
|
@ -1290,6 +1278,19 @@ Function* SymbolDatabase::addGlobalFunctionDecl(Scope*& scope, const Token *argS
|
||||||
function.type = Function::eFunction;
|
function.type = Function::eFunction;
|
||||||
function.nestedIn = scope;
|
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);
|
scope->functionList.push_back(function);
|
||||||
return &scope->functionList.back();
|
return &scope->functionList.back();
|
||||||
}
|
}
|
||||||
|
|
|
@ -742,7 +742,7 @@ private:
|
||||||
friend class Scope;
|
friend class Scope;
|
||||||
|
|
||||||
void addClassFunction(Scope **info, const Token **tok, const Token *argStart);
|
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);
|
Function *addGlobalFunction(Scope*& scope, const Token*& tok, const Token *argStart, const Token* funcStart);
|
||||||
void addNewFunction(Scope **info, const Token **tok);
|
void addNewFunction(Scope **info, const Token **tok);
|
||||||
static bool isFunction(const Token *tok, const Scope* outerScope, const Token **funcStart, const Token **argStart);
|
static bool isFunction(const Token *tok, const Scope* outerScope, const Token **funcStart, const Token **argStart);
|
||||||
|
|
|
@ -9577,9 +9577,11 @@ void Tokenizer::createSymbolDatabase()
|
||||||
|
|
||||||
if (membertok) {
|
if (membertok) {
|
||||||
const Variable *var = tok->variable();
|
const Variable *var = tok->variable();
|
||||||
const Variable *membervar = var->typeScope()->getVariable(membertok->str());
|
if (var && var->typeScope()) {
|
||||||
if (membervar)
|
const Variable *membervar = var->typeScope()->getVariable(membertok->str());
|
||||||
membertok->variable(membervar);
|
if (membervar)
|
||||||
|
membertok->variable(membervar);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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"
|
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());
|
"[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
|
void testPosixPrintfScanfParameterPosition() { // #4900 - No support for parameters in format strings
|
||||||
|
|
Loading…
Reference in New Issue