This commit is contained in:
parent
dfd3e8ac55
commit
3076f9def1
|
@ -2833,8 +2833,10 @@ int numberOfArguments(const Token* ftok) {
|
||||||
|
|
||||||
int numberOfArgumentsWithoutAst(const Token* start)
|
int numberOfArgumentsWithoutAst(const Token* start)
|
||||||
{
|
{
|
||||||
int arguments=0;
|
int arguments = 0;
|
||||||
const Token* const openBracket = start->next();
|
const Token* openBracket = start->next();
|
||||||
|
while (Token::simpleMatch(openBracket, ")"))
|
||||||
|
openBracket = openBracket->next();
|
||||||
if (openBracket && openBracket->str()=="(" && openBracket->next() && openBracket->next()->str()!=")") {
|
if (openBracket && openBracket->str()=="(" && openBracket->next() && openBracket->next()->str()!=")") {
|
||||||
const Token* argument=openBracket->next();
|
const Token* argument=openBracket->next();
|
||||||
while (argument) {
|
while (argument) {
|
||||||
|
|
|
@ -982,7 +982,7 @@ std::string Library::getFunctionName(const Token *ftok, bool *error) const
|
||||||
|
|
||||||
std::string Library::getFunctionName(const Token *ftok) const
|
std::string Library::getFunctionName(const Token *ftok) const
|
||||||
{
|
{
|
||||||
if (!Token::Match(ftok, "%name% (") && (ftok->strAt(-1) != "&" || ftok->previous()->astOperand2()))
|
if (!Token::Match(ftok, "%name% )| (") && (ftok->strAt(-1) != "&" || ftok->previous()->astOperand2()))
|
||||||
return "";
|
return "";
|
||||||
|
|
||||||
// Lookup function name using AST..
|
// Lookup function name using AST..
|
||||||
|
@ -1228,6 +1228,8 @@ bool Library::isNotLibraryFunction(const Token *ftok) const
|
||||||
|
|
||||||
bool Library::matchArguments(const Token *ftok, const std::string &functionName) const
|
bool Library::matchArguments(const Token *ftok, const std::string &functionName) const
|
||||||
{
|
{
|
||||||
|
if (functionName.empty())
|
||||||
|
return false;
|
||||||
const int callargs = numberOfArgumentsWithoutAst(ftok);
|
const int callargs = numberOfArgumentsWithoutAst(ftok);
|
||||||
const std::unordered_map<std::string, Function>::const_iterator it = functions.find(functionName);
|
const std::unordered_map<std::string, Function>::const_iterator it = functions.find(functionName);
|
||||||
if (it == functions.cend())
|
if (it == functions.cend())
|
||||||
|
|
|
@ -8163,7 +8163,7 @@ void Tokenizer::simplifyDeclspec()
|
||||||
void Tokenizer::simplifyAttribute()
|
void Tokenizer::simplifyAttribute()
|
||||||
{
|
{
|
||||||
for (Token *tok = list.front(); tok; tok = tok->next()) {
|
for (Token *tok = list.front(); tok; tok = tok->next()) {
|
||||||
if (Token::Match(tok, "%type% (") && !mSettings->library.isNotLibraryFunction(tok)) {
|
if (!tok->isKeyword() && Token::Match(tok, "%type% (") && !mSettings->library.isNotLibraryFunction(tok)) {
|
||||||
if (mSettings->library.isFunctionConst(tok->str(), true))
|
if (mSettings->library.isFunctionConst(tok->str(), true))
|
||||||
tok->isAttributePure(true);
|
tok->isAttributePure(true);
|
||||||
if (mSettings->library.isFunctionConst(tok->str(), false))
|
if (mSettings->library.isFunctionConst(tok->str(), false))
|
||||||
|
|
|
@ -459,7 +459,7 @@ void combineValueProperties(const ValueFlow::Value &value1, const ValueFlow::Val
|
||||||
result->path = value1.path;
|
result->path = value1.path;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const Token *getCastTypeStartToken(const Token *parent)
|
static const Token *getCastTypeStartToken(const Token *parent, const Settings* settings)
|
||||||
{
|
{
|
||||||
// TODO: This might be a generic utility function?
|
// TODO: This might be a generic utility function?
|
||||||
if (!Token::Match(parent, "{|("))
|
if (!Token::Match(parent, "{|("))
|
||||||
|
@ -470,7 +470,8 @@ static const Token *getCastTypeStartToken(const Token *parent)
|
||||||
return parent->astOperand1();
|
return parent->astOperand1();
|
||||||
if (parent->str() != "(")
|
if (parent->str() != "(")
|
||||||
return nullptr;
|
return nullptr;
|
||||||
if (!parent->astOperand2() && Token::Match(parent,"( %name%"))
|
if (!parent->astOperand2() && Token::Match(parent, "( %name%") &&
|
||||||
|
(parent->next()->isStandardType() || settings->library.isNotLibraryFunction(parent->next())))
|
||||||
return parent->next();
|
return parent->next();
|
||||||
if (parent->astOperand2() && Token::Match(parent->astOperand1(), "const_cast|dynamic_cast|reinterpret_cast|static_cast <"))
|
if (parent->astOperand2() && Token::Match(parent->astOperand1(), "const_cast|dynamic_cast|reinterpret_cast|static_cast <"))
|
||||||
return parent->astOperand1()->tokAt(2);
|
return parent->astOperand1()->tokAt(2);
|
||||||
|
@ -603,7 +604,8 @@ static void setTokenValue(Token* tok,
|
||||||
return !Token::simpleMatch(p, ",");
|
return !Token::simpleMatch(p, ",");
|
||||||
});
|
});
|
||||||
// Ensure that the comma isn't a function call
|
// Ensure that the comma isn't a function call
|
||||||
if (!callParent || (!Token::Match(callParent->previous(), "%name%|> (") && !Token::simpleMatch(callParent, "{"))) {
|
if (!callParent || (!Token::Match(callParent->previous(), "%name%|> (") && !Token::simpleMatch(callParent, "{") &&
|
||||||
|
(!Token::Match(callParent, "( %name%") || settings->library.isNotLibraryFunction(callParent->next())))) {
|
||||||
setTokenValue(parent, std::move(value), settings);
|
setTokenValue(parent, std::move(value), settings);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -729,7 +731,7 @@ static void setTokenValue(Token* tok,
|
||||||
}
|
}
|
||||||
|
|
||||||
// cast..
|
// cast..
|
||||||
if (const Token *castType = getCastTypeStartToken(parent)) {
|
if (const Token *castType = getCastTypeStartToken(parent, settings)) {
|
||||||
if (contains({ValueFlow::Value::ValueType::INT, ValueFlow::Value::ValueType::SYMBOLIC}, value.valueType) &&
|
if (contains({ValueFlow::Value::ValueType::INT, ValueFlow::Value::ValueType::SYMBOLIC}, value.valueType) &&
|
||||||
Token::simpleMatch(parent->astOperand1(), "dynamic_cast"))
|
Token::simpleMatch(parent->astOperand1(), "dynamic_cast"))
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -2838,14 +2838,21 @@ private:
|
||||||
ASSERT_EQUALS("[test.cpp:7]: (warning) Possible null pointer dereference: p\n", errout.str());
|
ASSERT_EQUALS("[test.cpp:7]: (warning) Possible null pointer dereference: p\n", errout.str());
|
||||||
}
|
}
|
||||||
|
|
||||||
void nullpointer_cast() { // #4692
|
void nullpointer_cast() {
|
||||||
check("char *nasm_skip_spaces(const char *p) {\n"
|
check("char *nasm_skip_spaces(const char *p) {\n" // #4692
|
||||||
" if (p)\n"
|
" if (p)\n"
|
||||||
" while (*p && nasm_isspace(*p))\n"
|
" while (*p && nasm_isspace(*p))\n"
|
||||||
" p++;\n"
|
" p++;\n"
|
||||||
" return p;\n"
|
" return p;\n"
|
||||||
"}");
|
"}");
|
||||||
ASSERT_EQUALS("", errout.str());
|
ASSERT_EQUALS("", errout.str());
|
||||||
|
|
||||||
|
check("void f(char* origin) {\n" // #11449
|
||||||
|
" char* cp = (strchr)(origin, '\\0');\n"
|
||||||
|
" if (cp[-1] != '/')\n"
|
||||||
|
" *cp++ = '/';\n"
|
||||||
|
"}\n");
|
||||||
|
ASSERT_EQUALS("", errout.str());
|
||||||
}
|
}
|
||||||
|
|
||||||
void nullpointer_castToVoid() { // #3771
|
void nullpointer_castToVoid() { // #3771
|
||||||
|
|
Loading…
Reference in New Issue