if (formatStringArgNr < 0 || formatStringArgNr >= args.size())
return var;
// 1st parameter..
if (Token::Match(&tok, "snprintf|vsnprintf|fnprintf|vfnprintf") && args.size() > 1 && !(args[1] && args[1]->hasKnownIntValue() && args[1]->getKnownIntValue() == 0)) // Only if length (second parameter) is not zero
var.push_back(args[0]);
if (args[formatStringArgNr]->tokType() != Token::eString)
for (size_t argnr = 0; argnr < args.size(); ++argnr) {
const Token *argtok = args[argnr];
if (!argtok->hasKnownIntValue())
continue;
if (argtok->getKnownIntValue() != 0)
continue;
if (mSettings.library.isnullargbad(tok, argnr+1))
nullPointerError(argtok);
}
}
elseif (Token::Match(tok->previous(), ">> 0|NULL|nullptr")) { // Only checking input stream operations is safe here, because otherwise 0 can be an integer as well
const Token* tok2 = tok->previous(); // Find start of statement
for (; tok2; tok2 = tok2->previous()) {
if (Token::Match(tok2->previous(), ";|{|}|:|("))
break;
}
if (tok2 && tok2->previous() && tok2->strAt(-1)=="(")
continue;
if (Token::simpleMatch(tok2, "std :: cin"))
nullPointerError(tok);
if (tok2 && tok2->varId() != 0) {
const Variable *var = tok2->variable();
if (var && var->isStlType(stl_istream))
nullPointerError(tok);
}
}
const Variable *ovar = nullptr;
const Token *tokNull = nullptr;
if (Token::Match(tok, "0|NULL|nullptr ==|!=|>|>=|<|<= %var%")) {