56 logChecker(
"CheckBool::checkIncrementBoolean");
61 if (
astIsBool(tok) && tok->astParent() && tok->astParent()->str() ==
"++") {
74 "Incrementing a variable of type 'bool' with postfix operator++ is deprecated by the C++ Standard. You should assign it the value 'true' instead.\n"
75 "The operand of a postfix increment operator may be of type bool but it is deprecated by C++ Standard (Annex D-1) and the operand is always set to true. You should assign it the value 'true' instead.",
101 logChecker(
"CheckBool::checkBitwiseOnBoolean");
106 if (tok->isBinaryOp()) {
108 if (tok->str() ==
"&" || tok->str() ==
"|")
110 else if (tok->str() ==
"&=" || tok->str() ==
"|=")
114 const bool isBoolOp1 =
astIsBool(tok->astOperand1());
115 const bool isBoolOp2 =
astIsBool(tok->astOperand2());
116 if (!tok->astOperand1()->valueType() || !tok->astOperand2()->valueType())
118 if (!(isBoolOp1 || isBoolOp2))
120 if (isCompound && (!isBoolOp1 || isBoolOp2))
127 if (tok->astOperand2()->variable() && tok->astOperand2()->variable()->nameToken() == tok->astOperand2())
129 const std::string expression = (isBoolOp1 ? tok->astOperand1() : tok->astOperand2())->expressionString();
138 std::string msg =
"Boolean expression '" + expression +
"' is used in bitwise operation.";
140 msg +=
" Did you mean '" + op +
"'?";
158 logChecker(
"CheckBool::checkComparisonOfBoolWithInt");
163 if (!tok->isComparisonOp() || !tok->isBinaryOp())
168 if (tok->str() !=
"==" && tok->str() !=
"!=") {
172 if (tok->str() !=
"==" && tok->str() !=
"!=") {
183 "Comparison of a boolean value using relational operator (<, >, <= or >=).\n"
184 "The result of the expression '" + expression +
"' is of type 'bool'. "
185 "Comparing 'bool' value using relational (<, >, <= or >=)"
186 " operator could cause unexpected results.");
212 logChecker(
"CheckBool::checkComparisonOfFuncReturningBool");
215 auto getFunctionTok = [](
const Token* tok) ->
const Token* {
219 tok = tok->astOperand2();
221 return tok->previous();
227 if (!tok->isComparisonOp() || tok->str() ==
"==" || tok->str() ==
"!=")
230 const Token* firstToken = getFunctionTok(tok->astOperand1());
231 const Token* secondToken = getFunctionTok(tok->astOperand2());
232 if (!firstToken || !secondToken)
237 if (firstIsFunctionReturningBool && secondIsFunctionReturningBool) {
239 }
else if (firstIsFunctionReturningBool) {
241 }
else if (secondIsFunctionReturningBool) {
251 "Comparison of a function returning boolean value using relational (<, >, <= or >=) operator.\n"
252 "The return type of function '" + expression +
"' is 'bool' "
253 "and result is of type 'bool'. Comparing 'bool' value using relational (<, >, <= or >=)"
260 "Comparison of two functions returning boolean value using relational (<, >, <= or >=) operator.\n"
261 "The return type of function '" + expression1 +
"' and function '" + expression2 +
"' is 'bool' "
262 "and result is of type 'bool'. Comparing 'bool' value using relational (<, >, <= or >=)"
278 logChecker(
"CheckBool::checkComparisonOfBoolWithBool");
284 if (!tok->isComparisonOp() || tok->str() ==
"==" || tok->str() ==
"!=")
286 bool firstTokenBool =
false;
289 if (firstToken->
varId()) {
291 firstTokenBool =
true;
297 bool secondTokenBool =
false;
299 if (secondToken->
varId()) {
301 secondTokenBool =
true;
304 if (secondTokenBool) {
314 "Comparison of a variable having boolean value using relational (<, >, <= or >=) operator.\n"
315 "The variable '" + expression +
"' is of type 'bool' "
316 "and comparing 'bool' value using relational (<, >, <= or >=)"
323 logChecker(
"CheckBool::checkAssignBoolToPointer");
347 logChecker(
"CheckBool::checkComparisonOfBoolExpressionWithInt");
353 if (!tok->isComparisonOp())
356 const Token* numTok =
nullptr;
357 const Token* boolExpr =
nullptr;
363 }
else if (
astIsBool(tok->astOperand2())) {
371 if (!numTok || !boolExpr)
383 if (minval && minval->
intvalue == 0 &&
389 if (maxval && maxval->
intvalue == 1 &&
394 if (minval || maxval) {
395 const bool not0or1 = (minval && minval->
intvalue < 0) || (maxval && maxval->
intvalue > 1);
445 if (tok->
str() !=
"+" && tok->
str() !=
"-")
461 "Converting pointer arithmetic result to bool. The bool is always true unless there is undefined behaviour.\n"
462 "Converting pointer arithmetic result to bool. The boolean result is always true unless there is pointer arithmetic overflow, and overflow is undefined behaviour. Probably a dereference is forgotten.",
CWE571,
Certainty::normal);
471 logChecker(
"CheckBool::checkAssignBoolToFloat");
475 if (tok->str() ==
"=" &&
astIsFloat(tok->astOperand1(),
false) &&
astIsBool(tok->astOperand2())) {
493 logChecker(
"CheckBool::returnValueOfFunctionReturningBool");
506 else if (tok->scope() && tok->scope()->isClassOrStruct())
507 tok = tok->
scope()->bodyEnd;
509 (tok->astOperand1()->getValueGE(2, *
mSettings) || tok->astOperand1()->getValueLE(-1, *
mSettings)) &&
510 !(tok->astOperand1()->astOperand1() &&
Token::Match(tok->astOperand1(),
"&|%or%")))
518 reportError(tok,
Severity::style,
"returnNonBoolInBooleanFunction",
"Non-boolean value returned from function returning bool");
bool astIsPointer(const Token *tok)
bool astIsBool(const Token *tok)
Is expression of boolean type?
bool astIsFloat(const Token *tok, bool unknown)
Is expression of floating point type?
const Token * findLambdaEndToken(const Token *first)
find lambda function end token
bool isCPPCast(const Token *tok)
bool isConstExpression(const Token *tok, const Library &library)
static const CWE CWE571(571U)
static bool isConvertedToBool(const Token *tok)
static const CWE CWE398(398U)
static bool isBool(const Variable *var)
static const CWE CWE704(704U)
static bool tokenIsFunctionReturningBool(const Token *tok)
static const CWE CWE587(587U)
checks dealing with suspicious usage of boolean type (not for evaluating conditions)
void assignBoolToPointerError(const Token *tok)
void checkBitwiseOnBoolean()
Check for using bool in bitwise expression
void pointerArithBoolError(const Token *tok)
void comparisonOfFuncReturningBoolError(const Token *tok, const std::string &expression)
void pointerArithBool()
Check for 'if (p+1)' etc.
void checkComparisonOfBoolWithBool()
Check for comparison of variable of type bool
void incrementBooleanError(const Token *tok)
void checkComparisonOfBoolWithInt()
Check for suspicious comparison of a bool and a non-zero (and non-one) value (e.g.
void comparisonOfBoolWithBoolError(const Token *tok, const std::string &expression)
void pointerArithBoolCond(const Token *tok)
void checkAssignBoolToPointer()
assigning bool to pointer
void comparisonOfBoolExpressionWithIntError(const Token *tok, bool not0or1)
void bitwiseOnBooleanError(const Token *tok, const std::string &expression, const std::string &op, bool isCompound=false)
void returnValueBoolError(const Token *tok)
void checkComparisonOfFuncReturningBool()
Check for comparison of function returning bool
void comparisonOfBoolWithInvalidComparator(const Token *tok, const std::string &expression)
void checkComparisonOfBoolExpressionWithInt()
Check for comparing a bool expression with an integer other than 0 or 1
void checkIncrementBoolean()
Check for using postfix increment on bool
void returnValueOfFunctionReturningBool()
Check if a function returning bool returns an integer other than 0 or 1
void assignBoolToFloatError(const Token *tok)
void comparisonOfTwoFuncsReturningBoolError(const Token *tok, const std::string &expression1, const std::string &expression2)
void checkAssignBoolToFloat()
assigning bool to float
void reportError(const Token *tok, const Severity severity, const std::string &id, const std::string &msg)
report an error
const Settings *const mSettings
const Tokenizer *const mTokenizer
void logChecker(const char id[])
log checker
const Token * retDef
function return type token
const Token * tokenDef
function name token in class definition
Function * function
function info for this function
const Token * classDef
class/struct/union/namespace token
const Token * bodyStart
'{' token
const Token * bodyEnd
'}' token
bool isPremiumEnabled(const char id[]) const
Is checker id enabled by premiumArgs.
SimpleEnableGroup< Certainty > certainty
SimpleEnableGroup< Severity > severity
bool isEnabled(T flag) const
std::vector< const Scope * > functionScopes
Fast access to function scopes.
std::list< Scope > scopeList
Information about all namespaces/classes/structures.
The token list that the TokenList generates is a linked-list of this class.
static bool Match(const Token *tok, const char pattern[], nonneg int varid=0)
Match given token (or list of tokens) to a pattern list.
void astOperand1(Token *tok)
void function(const Function *f)
Associate this token with given function.
const ValueFlow::Value * getValueGE(const MathLib::bigint val, const Settings &settings) const
static const Token * findsimplematch(const Token *const startTok, const char(&pattern)[count])
const Token * tokAt(int index) const
void astOperand2(Token *tok)
void scope(const Scope *s)
Associate this token with given scope.
const ValueFlow::Value * getValueLE(const MathLib::bigint val, const Settings &settings) const
void variable(const Variable *v)
Associate this token with given variable.
static bool simpleMatch(const Token *tok, const char(&pattern)[count])
Match given token (or list of tokens) to a pattern list.
void astParent(Token *tok)
const SymbolDatabase * getSymbolDatabase() const
bool isCPP() const
Is the code CPP.
long long intvalue
int value (or sometimes bool value?)
Information about a member variable.
const Token * typeEndToken() const
Get type end token.
@ error
Programming error.