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
4243static const CWE CWE587 (587U ); // Assignment of a Fixed Address to a Pointer
4344static 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+
4598static 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