@@ -1066,20 +1066,17 @@ void CheckOther::checkCatchExceptionByValue()
10661066 if (!_settings->isEnabled (" style" ))
10671067 return ;
10681068
1069- const char catchPattern[] = " } catch (" ;
1070- const Token *tok = Token::findmatch (_tokenizer->tokens (), catchPattern);
1071- const Token *endTok = tok ? tok->linkAt (2 ) : NULL ;
1069+ const SymbolDatabase* const symbolDatabase = _tokenizer->getSymbolDatabase ();
1070+
1071+ for (std::list<Scope>::const_iterator i = symbolDatabase->scopeList .begin (); i != symbolDatabase->scopeList .end (); ++i) {
1072+ if (i->type != Scope::eCatch)
1073+ continue ;
10721074
1073- while (tok && endTok) {
10741075 // Find a pass-by-value declaration in the catch(), excluding basic types
10751076 // e.g. catch (std::exception err)
1076- const Token *tokType = Token::findmatch (tok, " %type% %var% )" , endTok);
1077- if (tokType && !tokType->isStandardType ()) {
1078- catchExceptionByValueError (tokType);
1079- }
1080-
1081- tok = Token::findmatch (endTok->next (), catchPattern);
1082- endTok = tok ? tok->linkAt (2 ) : NULL ;
1077+ const Variable* var = symbolDatabase->getVariableFromVarId (i->classStart ->tokAt (-2 )->varId ());
1078+ if (var && var->isClass () && !var->isPointer () && !var->isReference ())
1079+ catchExceptionByValueError (i->classDef );
10831080 }
10841081}
10851082
@@ -1677,32 +1674,51 @@ void CheckOther::unreachableCodeError(const Token *tok)
16771674// ---------------------------------------------------------------------------
16781675static bool isUnsigned (const Variable* var)
16791676{
1680- return (var && var->typeStartToken ()->isUnsigned () && var->typeStartToken () == var->typeEndToken ());
1677+ return (var && var->typeStartToken ()->isUnsigned () && !var->isPointer () && !var->isArray ());
1678+ }
1679+ static bool isSigned (const Variable* var)
1680+ {
1681+ return (var && !var->typeStartToken ()->isUnsigned () && Token::Match (var->typeEndToken (), " int|char|short|long" ) && !var->isPointer () && !var->isArray ());
16811682}
16821683
16831684void CheckOther::checkUnsignedDivision ()
16841685{
16851686 const SymbolDatabase* symbolDatabase = _tokenizer->getSymbolDatabase ();
1687+ bool style = _settings->isEnabled (" style" );
16861688
1689+ const Token* ifTok = 0 ;
16871690 // Check for "ivar / uvar" and "uvar / ivar"
16881691 for (const Token *tok = _tokenizer->tokens (); tok; tok = tok->next ()) {
1689- if (!Token::Match (tok, " [).]" ) && Token::Match (tok->next (), " %var% / %num%" )) {
1692+ if (Token::Match (tok, " [).]" )) // Don't check members or casted variables
1693+ continue ;
1694+
1695+ if (Token::Match (tok->next (), " %var% / %num%" )) {
16901696 if (tok->strAt (3 )[0 ] == ' -' && isUnsigned (symbolDatabase->getVariableFromVarId (tok->next ()->varId ()))) {
1691- udivError (tok->next ());
1697+ udivError (tok->next (), false );
16921698 }
1693- }
1694-
1695- else if (Token::Match (tok, " (|[|=|%op% %num% / %var%" )) {
1699+ } else if (Token::Match (tok->next (), " %num% / %var%" )) {
16961700 if (tok->strAt (1 )[0 ] == ' -' && isUnsigned (symbolDatabase->getVariableFromVarId (tok->tokAt (3 )->varId ()))) {
1697- udivError (tok->next ());
1701+ udivError (tok->next (), false );
16981702 }
1699- }
1703+ } else if (Token::Match (tok->next (), " %var% / %var%" ) && _settings->inconclusive && style && !ifTok) {
1704+ const Variable* var1 = symbolDatabase->getVariableFromVarId (tok->next ()->varId ());
1705+ const Variable* var2 = symbolDatabase->getVariableFromVarId (tok->tokAt (3 )->varId ());
1706+ if ((isUnsigned (var1) && isSigned (var2)) || (isUnsigned (var2) && isSigned (var1))) {
1707+ udivError (tok->next (), true );
1708+ }
1709+ } else if (!ifTok && Token::Match (tok, " if (" ))
1710+ ifTok = tok->next ()->link ()->next ()->link ();
1711+ else if (ifTok == tok)
1712+ ifTok = 0 ;
17001713 }
17011714}
17021715
1703- void CheckOther::udivError (const Token *tok)
1716+ void CheckOther::udivError (const Token *tok, bool inconclusive )
17041717{
1705- reportError (tok, Severity::error, " udivError" , " Unsigned division. The result will be wrong." );
1718+ if (inconclusive)
1719+ reportError (tok, Severity::warning, " udivError" , " Division with signed and unsigned operators. The result might be wrong." );
1720+ else
1721+ reportError (tok, Severity::error, " udivError" , " Unsigned division. The result will be wrong." );
17061722}
17071723
17081724// ---------------------------------------------------------------------------
@@ -1956,9 +1972,14 @@ void CheckOther::passedByValueError(const Token *tok, const std::string &parname
19561972// ---------------------------------------------------------------------------
19571973// Check usage of char variables..
19581974// ---------------------------------------------------------------------------
1975+ static bool isChar (const Variable* var)
1976+ {
1977+ return (var && !var->isPointer () && !var->isArray () && (var->typeEndToken ()->str () == " char" || var->typeEndToken ()->previous ()->str () == " char" ));
1978+ }
1979+
19591980static bool isSignedChar (const Variable* var)
19601981{
1961- return (var && var->nameToken ()->previous ()-> str () == " char " && !var->nameToken ()->previous ()->isUnsigned () && var-> nameToken ()-> next ()-> str () != " [ " );
1982+ return (isChar ( var) && ! var->typeEndToken ()->isUnsigned () && !var->typeEndToken ()->previous ()->isUnsigned ());
19621983}
19631984
19641985void CheckOther::checkCharVariable ()
@@ -2092,10 +2113,6 @@ void CheckOther::constStatementError(const Token *tok, const std::string &type)
20922113// ---------------------------------------------------------------------------
20932114// str plus char
20942115// ---------------------------------------------------------------------------
2095- static bool isChar (const Variable* var)
2096- {
2097- return (var && var->nameToken ()->previous ()->str () == " char" && var->nameToken ()->next ()->str () != " [" );
2098- }
20992116
21002117void CheckOther::strPlusChar ()
21012118{
@@ -2159,7 +2176,9 @@ void CheckOther::checkMathFunctions()
21592176 continue ;
21602177
21612178 for (const Token *tok = scope->classStart ; tok && tok != scope->classEnd ; tok = tok->next ()) {
2162- if (tok->varId () == 0 && Token::Match (tok, " log|log10 ( %num% )" )) {
2179+ if (tok->varId ())
2180+ continue ;
2181+ if (Token::Match (tok, " log|log10 ( %num% )" )) {
21632182 bool isNegative = MathLib::isNegative (tok->strAt (2 ));
21642183 bool isInt = MathLib::isInt (tok->strAt (2 ));
21652184 bool isFloat = MathLib::isFloat (tok->strAt (2 ));
@@ -2175,33 +2194,29 @@ void CheckOther::checkMathFunctions()
21752194 }
21762195
21772196 // acos( x ), asin( x ) where x is defined for intervall [-1,+1], but not beyound
2178- else if (tok->varId () == 0 &&
2179- Token::Match (tok, " acos|asin ( %num% )" ) &&
2197+ else if (Token::Match (tok, " acos|asin ( %num% )" ) &&
21802198 std::fabs (MathLib::toDoubleNumber (tok->strAt (2 ))) > 1.0 ) {
21812199 mathfunctionCallError (tok);
21822200 }
21832201 // sqrt( x ): if x is negative the result is undefined
2184- else if (tok->varId () == 0 &&
2185- Token::Match (tok, " sqrt|sqrtf|sqrtl ( %num% )" ) &&
2202+ else if (Token::Match (tok, " sqrt|sqrtf|sqrtl ( %num% )" ) &&
21862203 MathLib::isNegative (tok->strAt (2 ))) {
21872204 mathfunctionCallError (tok);
21882205 }
21892206 // atan2 ( x , y): x and y can not be zero, because this is mathematically not defined
2190- else if (tok->varId () == 0 &&
2191- Token::Match (tok, " atan2 ( %num% , %num% )" ) &&
2207+ else if (Token::Match (tok, " atan2 ( %num% , %num% )" ) &&
21922208 MathLib::isNullValue (tok->strAt (2 )) &&
21932209 MathLib::isNullValue (tok->strAt (4 ))) {
21942210 mathfunctionCallError (tok, 2 );
21952211 }
21962212 // fmod ( x , y) If y is zero, then either a range error will occur or the function will return zero (implementation-defined).
2197- else if (tok-> varId () == 0 &&
2198- Token::Match ( tok, " fmod ( %num% , %num% ) " ) &&
2199- MathLib::isNullValue (tok-> strAt ( 4 ))) {
2200- mathfunctionCallError (tok, 2 );
2213+ else if (Token::Match (tok, " fmod ( %any% " )) {
2214+ const Token* nextArg = tok-> tokAt ( 2 )-> nextArgument ();
2215+ if (nextArg && nextArg-> isNumber () && MathLib::isNullValue (nextArg-> str ( )))
2216+ mathfunctionCallError (tok, 2 );
22012217 }
22022218 // pow ( x , y) If x is zero, and y is negative --> division by zero
2203- else if (tok->varId () == 0 &&
2204- Token::Match (tok, " pow ( %num% , %num% )" ) &&
2219+ else if (Token::Match (tok, " pow ( %num% , %num% )" ) &&
22052220 MathLib::isNullValue (tok->strAt (2 )) &&
22062221 MathLib::isNegative (tok->strAt (4 ))) {
22072222 mathfunctionCallError (tok, 2 );
0 commit comments