Skip to content

Commit 1ea062b

Browse files
committed
checkimpl
1 parent f97b07a commit 1ea062b

2 files changed

Lines changed: 110 additions & 106 deletions

File tree

lib/checkbool.cpp

Lines changed: 107 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
#include "checkbool.h"
2222

2323
#include "astutils.h"
24+
#include "checkimpl.h"
2425
#include "errortypes.h"
2526
#include "settings.h"
2627
#include "symboldatabase.h"
@@ -42,13 +43,65 @@ static const CWE CWE571(571U); // Expression is Always True
4243
static const CWE CWE587(587U); // Assignment of a Fixed Address to a Pointer
4344
static const CWE CWE704(704U); // Incorrect Type Conversion or Cast
4445

46+
class CheckBoolImpl: public CheckImpl
47+
{
48+
public:
49+
/** @brief This constructor is used when running checks. */
50+
CheckBoolImpl(const Tokenizer *tokenizer, const Settings *settings, ErrorLogger *errorLogger)
51+
: CheckImpl(tokenizer, settings, errorLogger) {}
52+
53+
/** @brief %Check for comparison of function returning bool*/
54+
void checkComparisonOfFuncReturningBool();
55+
56+
/** @brief %Check for comparison of variable of type bool*/
57+
void checkComparisonOfBoolWithBool();
58+
59+
/** @brief %Check for using postfix increment on bool */
60+
void checkIncrementBoolean();
61+
62+
/** @brief %Check for suspicious comparison of a bool and a non-zero (and non-one) value (e.g. "if (!x==4)") */
63+
void checkComparisonOfBoolWithInt();
64+
65+
/** @brief assigning bool to pointer */
66+
void checkAssignBoolToPointer();
67+
68+
/** @brief assigning bool to float */
69+
void checkAssignBoolToFloat();
70+
71+
/** @brief %Check for using bool in bitwise expression */
72+
void checkBitwiseOnBoolean();
73+
74+
/** @brief %Check for comparing a bool expression with an integer other than 0 or 1 */
75+
void checkComparisonOfBoolExpressionWithInt();
76+
77+
/** @brief %Check for 'if (p+1)' etc. either somebody forgot to dereference, or else somebody uses pointer overflow */
78+
void pointerArithBool();
79+
void pointerArithBoolCond(const Token *tok);
80+
81+
/** @brief %Check if a function returning bool returns an integer other than 0 or 1 */
82+
void returnValueOfFunctionReturningBool();
83+
84+
// Error messages..
85+
void comparisonOfFuncReturningBoolError(const Token *tok, const std::string &expression);
86+
void comparisonOfTwoFuncsReturningBoolError(const Token *tok, const std::string &expression1, const std::string &expression2);
87+
void comparisonOfBoolWithBoolError(const Token *tok, const std::string &expression);
88+
void incrementBooleanError(const Token *tok);
89+
void comparisonOfBoolWithInvalidComparator(const Token *tok, const std::string &expression);
90+
void assignBoolToPointerError(const Token *tok);
91+
void assignBoolToFloatError(const Token *tok);
92+
void bitwiseOnBooleanError(const Token* tok, const std::string& expression, const std::string& op, bool isCompound = false);
93+
void comparisonOfBoolExpressionWithIntError(const Token *tok, bool not0or1);
94+
void pointerArithBoolError(const Token *tok);
95+
void returnValueBoolError(const Token *tok);
96+
};
97+
4598
static bool isBool(const Variable* var)
4699
{
47100
return (var && Token::Match(var->typeEndToken(), "bool|_Bool"));
48101
}
49102

50103
//---------------------------------------------------------------------------
51-
void CheckBool::checkIncrementBoolean()
104+
void CheckBoolImpl::checkIncrementBoolean()
52105
{
53106
if (!mSettings->severity.isEnabled(Severity::style))
54107
return;
@@ -63,7 +116,7 @@ void CheckBool::checkIncrementBoolean()
63116
}
64117
}
65118

66-
void CheckBool::incrementBooleanError(const Token *tok)
119+
void CheckBoolImpl::incrementBooleanError(const Token *tok)
67120
{
68121
reportError(
69122
tok,
@@ -86,7 +139,7 @@ static bool isConvertedToBool(const Token* tok)
86139
// if (bool & bool) -> if (bool && bool)
87140
// if (bool | bool) -> if (bool || bool)
88141
//---------------------------------------------------------------------------
89-
void CheckBool::checkBitwiseOnBoolean()
142+
void CheckBoolImpl::checkBitwiseOnBoolean()
90143
{
91144
if (!mSettings->severity.isEnabled(Severity::style))
92145
return;
@@ -127,7 +180,7 @@ void CheckBool::checkBitwiseOnBoolean()
127180
}
128181
}
129182

130-
void CheckBool::bitwiseOnBooleanError(const Token* tok, const std::string& expression, const std::string& op, bool isCompound)
183+
void CheckBoolImpl::bitwiseOnBooleanError(const Token* tok, const std::string& expression, const std::string& op, bool isCompound)
131184
{
132185
std::string msg = "Boolean expression '" + expression + "' is used in bitwise operation.";
133186
if (!isCompound)
@@ -144,7 +197,7 @@ void CheckBool::bitwiseOnBooleanError(const Token* tok, const std::string& expre
144197
// if (!x==3) <- Probably meant to be "x!=3"
145198
//---------------------------------------------------------------------------
146199

147-
void CheckBool::checkComparisonOfBoolWithInt()
200+
void CheckBoolImpl::checkComparisonOfBoolWithInt()
148201
{
149202
if (!mSettings->severity.isEnabled(Severity::warning) || !mTokenizer->isCPP())
150203
return;
@@ -169,7 +222,7 @@ void CheckBool::checkComparisonOfBoolWithInt()
169222
}
170223
}
171224

172-
void CheckBool::comparisonOfBoolWithInvalidComparator(const Token *tok, const std::string &expression)
225+
void CheckBoolImpl::comparisonOfBoolWithInvalidComparator(const Token *tok, const std::string &expression)
173226
{
174227
reportError(tok, Severity::warning, "comparisonOfBoolWithInvalidComparator",
175228
"Comparison of a boolean value using relational operator (<, >, <= or >=).\n"
@@ -193,7 +246,7 @@ static bool tokenIsFunctionReturningBool(const Token* tok)
193246
return false;
194247
}
195248

196-
void CheckBool::checkComparisonOfFuncReturningBool()
249+
void CheckBoolImpl::checkComparisonOfFuncReturningBool()
197250
{
198251
if (!mSettings->severity.isEnabled(Severity::style))
199252
return;
@@ -235,7 +288,7 @@ void CheckBool::checkComparisonOfFuncReturningBool()
235288
}
236289
}
237290

238-
void CheckBool::comparisonOfFuncReturningBoolError(const Token *tok, const std::string &expression)
291+
void CheckBoolImpl::comparisonOfFuncReturningBoolError(const Token *tok, const std::string &expression)
239292
{
240293
reportError(tok, Severity::style, "comparisonOfFuncReturningBoolError",
241294
"Comparison of a function returning boolean value using relational (<, >, <= or >=) operator.\n"
@@ -244,7 +297,7 @@ void CheckBool::comparisonOfFuncReturningBoolError(const Token *tok, const std::
244297
" operator could cause unexpected results.", CWE398, Certainty::normal);
245298
}
246299

247-
void CheckBool::comparisonOfTwoFuncsReturningBoolError(const Token *tok, const std::string &expression1, const std::string &expression2)
300+
void CheckBoolImpl::comparisonOfTwoFuncsReturningBoolError(const Token *tok, const std::string &expression1, const std::string &expression2)
248301
{
249302
reportError(tok, Severity::style, "comparisonOfTwoFuncsReturningBoolError",
250303
"Comparison of two functions returning boolean value using relational (<, >, <= or >=) operator.\n"
@@ -257,7 +310,7 @@ void CheckBool::comparisonOfTwoFuncsReturningBoolError(const Token *tok, const s
257310
// Comparison of bool with bool
258311
//-------------------------------------------------------------------------------
259312

260-
void CheckBool::checkComparisonOfBoolWithBool()
313+
void CheckBoolImpl::checkComparisonOfBoolWithBool()
261314
{
262315
if (!mSettings->severity.isEnabled(Severity::style))
263316
return;
@@ -296,7 +349,7 @@ void CheckBool::checkComparisonOfBoolWithBool()
296349
}
297350
}
298351

299-
void CheckBool::comparisonOfBoolWithBoolError(const Token *tok, const std::string &expression)
352+
void CheckBoolImpl::comparisonOfBoolWithBoolError(const Token *tok, const std::string &expression)
300353
{
301354
reportError(tok, Severity::style, "comparisonOfBoolWithBoolError",
302355
"Comparison of a variable having boolean value using relational (<, >, <= or >=) operator.\n"
@@ -306,7 +359,7 @@ void CheckBool::comparisonOfBoolWithBoolError(const Token *tok, const std::strin
306359
}
307360

308361
//-----------------------------------------------------------------------------
309-
void CheckBool::checkAssignBoolToPointer()
362+
void CheckBoolImpl::checkAssignBoolToPointer()
310363
{
311364
const SymbolDatabase *symbolDatabase = mTokenizer->getSymbolDatabase();
312365
for (const Scope * scope : symbolDatabase->functionScopes) {
@@ -318,15 +371,15 @@ void CheckBool::checkAssignBoolToPointer()
318371
}
319372
}
320373

321-
void CheckBool::assignBoolToPointerError(const Token *tok)
374+
void CheckBoolImpl::assignBoolToPointerError(const Token *tok)
322375
{
323376
reportError(tok, Severity::error, "assignBoolToPointer",
324377
"Boolean value assigned to pointer.", CWE587, Certainty::normal);
325378
}
326379

327380
//-----------------------------------------------------------------------------
328381
//-----------------------------------------------------------------------------
329-
void CheckBool::checkComparisonOfBoolExpressionWithInt()
382+
void CheckBoolImpl::checkComparisonOfBoolExpressionWithInt()
330383
{
331384
if (!mSettings->severity.isEnabled(Severity::warning))
332385
return;
@@ -384,7 +437,7 @@ void CheckBool::checkComparisonOfBoolExpressionWithInt()
384437
}
385438
}
386439

387-
void CheckBool::comparisonOfBoolExpressionWithIntError(const Token *tok, bool not0or1)
440+
void CheckBoolImpl::comparisonOfBoolExpressionWithIntError(const Token *tok, bool not0or1)
388441
{
389442
if (not0or1)
390443
reportError(tok, Severity::warning, "compareBoolExpressionWithInt",
@@ -395,7 +448,7 @@ void CheckBool::comparisonOfBoolExpressionWithIntError(const Token *tok, bool no
395448
}
396449

397450

398-
void CheckBool::pointerArithBool()
451+
void CheckBoolImpl::pointerArithBool()
399452
{
400453
const SymbolDatabase* symbolDatabase = mTokenizer->getSymbolDatabase();
401454

@@ -416,7 +469,7 @@ void CheckBool::pointerArithBool()
416469
}
417470
}
418471

419-
void CheckBool::pointerArithBoolCond(const Token *tok)
472+
void CheckBoolImpl::pointerArithBoolCond(const Token *tok)
420473
{
421474
if (!tok)
422475
return;
@@ -436,7 +489,7 @@ void CheckBool::pointerArithBoolCond(const Token *tok)
436489
pointerArithBoolError(tok);
437490
}
438491

439-
void CheckBool::pointerArithBoolError(const Token *tok)
492+
void CheckBoolImpl::pointerArithBoolError(const Token *tok)
440493
{
441494
reportError(tok,
442495
Severity::error,
@@ -445,7 +498,7 @@ void CheckBool::pointerArithBoolError(const Token *tok)
445498
"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);
446499
}
447500

448-
void CheckBool::checkAssignBoolToFloat()
501+
void CheckBoolImpl::checkAssignBoolToFloat()
449502
{
450503
if (!mTokenizer->isCPP())
451504
return;
@@ -461,13 +514,13 @@ void CheckBool::checkAssignBoolToFloat()
461514
}
462515
}
463516

464-
void CheckBool::assignBoolToFloatError(const Token *tok)
517+
void CheckBoolImpl::assignBoolToFloatError(const Token *tok)
465518
{
466519
reportError(tok, Severity::style, "assignBoolToFloat",
467520
"Boolean value assigned to floating point variable.", CWE704, Certainty::normal);
468521
}
469522

470-
void CheckBool::returnValueOfFunctionReturningBool()
523+
void CheckBoolImpl::returnValueOfFunctionReturningBool()
471524
{
472525
if (!mSettings->severity.isEnabled(Severity::style))
473526
return;
@@ -493,7 +546,39 @@ void CheckBool::returnValueOfFunctionReturningBool()
493546
}
494547
}
495548

496-
void CheckBool::returnValueBoolError(const Token *tok)
549+
void CheckBoolImpl::returnValueBoolError(const Token *tok)
497550
{
498551
reportError(tok, Severity::style, "returnNonBoolInBooleanFunction", "Non-boolean value returned from function returning bool");
499552
}
553+
554+
void CheckBool::runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLogger)
555+
{
556+
CheckBoolImpl checkBool(&tokenizer, tokenizer.getSettings(), errorLogger);
557+
558+
checkBool.checkComparisonOfBoolExpressionWithInt();
559+
checkBool.checkComparisonOfBoolWithInt();
560+
checkBool.checkAssignBoolToFloat();
561+
checkBool.pointerArithBool();
562+
checkBool.returnValueOfFunctionReturningBool();
563+
checkBool.checkComparisonOfFuncReturningBool();
564+
checkBool.checkComparisonOfBoolWithBool();
565+
checkBool.checkIncrementBoolean();
566+
checkBool.checkAssignBoolToPointer();
567+
checkBool.checkBitwiseOnBoolean();
568+
}
569+
570+
void CheckBool::getErrorMessages(ErrorLogger *errorLogger, const Settings *settings) const
571+
{
572+
CheckBoolImpl c(nullptr, settings, errorLogger);
573+
c.assignBoolToPointerError(nullptr);
574+
c.assignBoolToFloatError(nullptr);
575+
c.comparisonOfFuncReturningBoolError(nullptr, "func_name");
576+
c.comparisonOfTwoFuncsReturningBoolError(nullptr, "func_name1", "func_name2");
577+
c.comparisonOfBoolWithBoolError(nullptr, "var_name");
578+
c.incrementBooleanError(nullptr);
579+
c.bitwiseOnBooleanError(nullptr, "expression", "&&");
580+
c.comparisonOfBoolExpressionWithIntError(nullptr, true);
581+
c.pointerArithBoolError(nullptr);
582+
c.comparisonOfBoolWithInvalidComparator(nullptr, "expression");
583+
c.returnValueBoolError(nullptr);
584+
}

0 commit comments

Comments
 (0)