Unified checks for unevaluated context (#5362)

This commit is contained in:
chrchr-github 2023-08-23 12:07:47 +02:00 committed by GitHub
parent 499f566e9d
commit 8cd61941dc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 18 additions and 27 deletions

View File

@ -1902,7 +1902,7 @@ static bool functionModifiesArguments(const Function* f)
bool isConstFunctionCall(const Token* ftok, const Library& library) bool isConstFunctionCall(const Token* ftok, const Library& library)
{ {
if (isSizeOfEtc(ftok)) if (isUnevaluated(ftok))
return true; return true;
if (!Token::Match(ftok, "%name% (")) if (!Token::Match(ftok, "%name% ("))
return false; return false;
@ -3382,7 +3382,7 @@ bool isGlobalData(const Token *expr, bool cpp)
return globalData || !var; return globalData || !var;
} }
bool isSizeOfEtc(const Token *tok) bool isUnevaluated(const Token *tok)
{ {
return Token::Match(tok, "sizeof|typeof|offsetof|decltype|__typeof__ ("); return Token::Match(tok, "alignof|_Alignof|_alignof|__alignof|__alignof__|decltype|offsetof|sizeof|typeid|typeof|__typeof__ (");
} }

View File

@ -427,6 +427,6 @@ CPPCHECKLIB bool isNullOperand(const Token *expr);
bool isGlobalData(const Token *expr, bool cpp); bool isGlobalData(const Token *expr, bool cpp);
bool isSizeOfEtc(const Token *tok); bool isUnevaluated(const Token *tok);
#endif // astutilsH #endif // astutilsH

View File

@ -150,11 +150,6 @@ bool CheckNullPointer::isPointerDeRef(const Token *tok, bool &unknown) const
return isPointerDeRef(tok, unknown, mSettings); return isPointerDeRef(tok, unknown, mSettings);
} }
static bool isUnevaluatedOperator(const Token* tok)
{
return Token::Match(tok, "sizeof|decltype|typeid|typeof|alignof|_Alignof|_alignof|__alignof|__alignof__ (");
}
bool CheckNullPointer::isPointerDeRef(const Token *tok, bool &unknown, const Settings *settings) bool CheckNullPointer::isPointerDeRef(const Token *tok, bool &unknown, const Settings *settings)
{ {
unknown = false; unknown = false;
@ -192,7 +187,7 @@ bool CheckNullPointer::isPointerDeRef(const Token *tok, bool &unknown, const Set
// Dereferencing pointer.. // Dereferencing pointer..
const Token* grandParent = parent->astParent(); const Token* grandParent = parent->astParent();
if (parent->isUnaryOp("*") && !(grandParent && isUnevaluatedOperator(grandParent->previous()))) { if (parent->isUnaryOp("*") && !(grandParent && isUnevaluated(grandParent->previous()))) {
// declaration of function pointer // declaration of function pointer
if (tok->variable() && tok->variable()->nameToken() == tok) if (tok->variable() && tok->variable()->nameToken() == tok)
return false; return false;
@ -290,7 +285,7 @@ void CheckNullPointer::nullPointerByDeRefAndChec()
const bool printInconclusive = (mSettings->certainty.isEnabled(Certainty::inconclusive)); const bool printInconclusive = (mSettings->certainty.isEnabled(Certainty::inconclusive));
for (const Token *tok = mTokenizer->tokens(); tok; tok = tok->next()) { for (const Token *tok = mTokenizer->tokens(); tok; tok = tok->next()) {
if (isUnevaluatedOperator(tok)) { if (isUnevaluated(tok)) {
tok = tok->next()->link(); tok = tok->next()->link();
continue; continue;
} }
@ -349,7 +344,7 @@ void CheckNullPointer::nullConstantDereference()
tok = scope->function->token; // Check initialization list tok = scope->function->token; // Check initialization list
for (; tok != scope->bodyEnd; tok = tok->next()) { for (; tok != scope->bodyEnd; tok = tok->next()) {
if (isUnevaluatedOperator(tok)) if (isUnevaluated(tok))
tok = tok->next()->link(); tok = tok->next()->link();
else if (Token::simpleMatch(tok, "* 0")) { else if (Token::simpleMatch(tok, "* 0")) {

View File

@ -607,7 +607,7 @@ bool CheckUninitVar::checkScopeForVariable(const Token *tok, const Variable& var
} }
// skip sizeof / offsetof // skip sizeof / offsetof
if (isSizeOfEtc(tok)) if (isUnevaluated(tok))
tok = tok->linkAt(1); tok = tok->linkAt(1);
// for/while.. // for/while..
@ -724,7 +724,7 @@ bool CheckUninitVar::checkScopeForVariable(const Token *tok, const Variable& var
return true; return true;
} }
if (isSizeOfEtc(tok)) if (isUnevaluated(tok))
tok = tok->linkAt(1); tok = tok->linkAt(1);
else if (tok->str() == "?") { else if (tok->str() == "?") {
@ -838,7 +838,7 @@ const Token* CheckUninitVar::checkExpr(const Token* tok, const Variable& var, co
{ {
if (!tok) if (!tok)
return nullptr; return nullptr;
if (isSizeOfEtc(tok->previous())) if (isUnevaluated(tok->previous()))
return nullptr; return nullptr;
if (tok->astOperand1()) { if (tok->astOperand1()) {
@ -891,7 +891,7 @@ bool CheckUninitVar::checkIfForWhileHead(const Token *startparentheses, const Va
return true; return true;
} }
// skip sizeof / offsetof // skip sizeof / offsetof
if (isSizeOfEtc(tok)) if (isUnevaluated(tok))
tok = tok->linkAt(1); tok = tok->linkAt(1);
if ((!isuninit || !membervar.empty()) && tok->str() == "&&") if ((!isuninit || !membervar.empty()) && tok->str() == "&&")
suppressErrors = true; suppressErrors = true;
@ -909,7 +909,7 @@ const Token* CheckUninitVar::checkLoopBodyRecursive(const Token *start, const Va
const Token *const end = start->link(); const Token *const end = start->link();
for (const Token *tok = start->next(); tok != end; tok = tok->next()) { for (const Token *tok = start->next(); tok != end; tok = tok->next()) {
// skip sizeof / offsetof // skip sizeof / offsetof
if (isSizeOfEtc(tok)) { if (isUnevaluated(tok)) {
tok = tok->linkAt(1); tok = tok->linkAt(1);
continue; continue;
} }
@ -1031,7 +1031,7 @@ const Token* CheckUninitVar::checkLoopBodyRecursive(const Token *start, const Va
varIsUsedInRhs = true; varIsUsedInRhs = true;
return ChildrenToVisit::done; return ChildrenToVisit::done;
} }
if (isSizeOfEtc(t->previous())) if (isUnevaluated(t->previous()))
return ChildrenToVisit::none; return ChildrenToVisit::none;
return ChildrenToVisit::op1_and_op2; return ChildrenToVisit::op1_and_op2;
}); });
@ -1096,7 +1096,7 @@ void CheckUninitVar::checkRhs(const Token *tok, const Variable &var, Alloc alloc
if (err) if (err)
uninitvarError(tok, var.nameToken()->str(), alloc); uninitvarError(tok, var.nameToken()->str(), alloc);
break; break;
} else if (isSizeOfEtc(tok)) } else if (isUnevaluated(tok))
tok = tok->linkAt(1); tok = tok->linkAt(1);
} }
@ -1599,7 +1599,7 @@ void CheckUninitVar::valueFlowUninit()
// check every executable scope // check every executable scope
for (const Scope* scope : symbolDatabase->functionScopes) { for (const Scope* scope : symbolDatabase->functionScopes) {
for (const Token* tok = scope->bodyStart; tok != scope->bodyEnd; tok = tok->next()) { for (const Token* tok = scope->bodyStart; tok != scope->bodyEnd; tok = tok->next()) {
if (isSizeOfEtc(tok)) { if (isUnevaluated(tok)) {
tok = tok->linkAt(1); tok = tok->linkAt(1);
continue; continue;
} }

View File

@ -143,7 +143,7 @@ struct ForwardTraversal {
// Traverse the parameters of the function before escaping // Traverse the parameters of the function before escaping
traverseRecursive(tok->next()->astOperand2(), f, traverseUnknown); traverseRecursive(tok->next()->astOperand2(), f, traverseUnknown);
return Break(Analyzer::Terminate::Escape); return Break(Analyzer::Terminate::Escape);
} else if (isUnevaluated(tok)) { } else if (isUnevaluated(tok->previous())) {
if (out) if (out)
*out = tok->link(); *out = tok->link();
return Progress::Skip; return Progress::Skip;
@ -825,10 +825,6 @@ struct ForwardTraversal {
return Progress::Continue; return Progress::Continue;
} }
static bool isUnevaluated(const Token* tok) {
return Token::Match(tok->previous(), "sizeof|decltype (");
}
static bool isFunctionCall(const Token* tok) static bool isFunctionCall(const Token* tok)
{ {
if (!Token::simpleMatch(tok, "(")) if (!Token::simpleMatch(tok, "("))
@ -839,7 +835,7 @@ struct ForwardTraversal {
return false; return false;
if (Token::simpleMatch(tok->link(), ") {")) if (Token::simpleMatch(tok->link(), ") {"))
return false; return false;
if (isUnevaluated(tok)) if (isUnevaluated(tok->previous()))
return false; return false;
return Token::Match(tok->previous(), "%name%|)|]|>"); return Token::Match(tok->previous(), "%name%|)|]|>");
} }

View File

@ -378,7 +378,7 @@ struct ReverseTraversal {
static Token* isUnevaluated(Token* tok) { static Token* isUnevaluated(Token* tok) {
if (Token::Match(tok, ")|>") && tok->link()) { if (Token::Match(tok, ")|>") && tok->link()) {
Token* start = tok->link(); Token* start = tok->link();
if (Token::Match(start->previous(), "sizeof|decltype (")) if (::isUnevaluated(start->previous()))
return start->previous(); return start->previous();
if (Token::simpleMatch(start, "<")) if (Token::simpleMatch(start, "<"))
return start; return start;