Unified checks for unevaluated context (#5362)
This commit is contained in:
parent
499f566e9d
commit
8cd61941dc
|
@ -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__ (");
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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")) {
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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%|)|]|>");
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
Loading…
Reference in New Issue