From 980b10bfc9fc98da8a00974f749903460e8bf1ca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Mon, 12 Jan 2009 17:12:14 +0000 Subject: [PATCH] errmsg: Added 'unsigned division' --- src/checkother.cpp | 50 +++++++++++++++++--------------- src/checkother.h | 3 +- src/cppcheck.cpp | 10 ++++--- src/errormessage.h | 18 ++++++++++++ test/testcharvar.cpp | 2 +- test/testdivision.cpp | 5 +++- test/testincompletestatement.cpp | 5 +++- test/testother.cpp | 4 +-- test/testredundantif.cpp | 2 +- test/testunusedvar.cpp | 4 +-- tools/errmsg.cpp | 2 ++ 11 files changed, 69 insertions(+), 36 deletions(-) diff --git a/src/checkother.cpp b/src/checkother.cpp index ded2ffe46..57b0495d6 100644 --- a/src/checkother.cpp +++ b/src/checkother.cpp @@ -35,7 +35,8 @@ // Warning on C-Style casts.. p = (kalle *)foo; //--------------------------------------------------------------------------- -CheckOther::CheckOther(const Tokenizer *tokenizer, ErrorLogger *errorLogger) +CheckOther::CheckOther(const Tokenizer *tokenizer, const Settings &settings, ErrorLogger *errorLogger) + : _settings(settings) { _tokenizer = tokenizer; _errorLogger = errorLogger; @@ -407,41 +408,44 @@ void CheckOther::CheckUnsignedDivision() else if (!Token::Match(tok, "[).]") && Token::Match(tok->next(), "%var% / %var%")) { - const char *varname1 = tok->strAt(1); - const char *varname2 = tok->strAt(3); - char sign1 = varsign[varname1]; - char sign2 = varsign[varname2]; - - if (sign1 && sign2 && sign1 != sign2) + if (ErrorMessage::udivWarning(_settings)) { - // One of the operands are signed, the other is unsigned.. - std::ostringstream ostr; - ostr << _tokenizer->fileLine(tok->next()) << ": Warning: Division with signed and unsigned operators"; - _errorLogger->reportErr(ostr.str()); + const char *varname1 = tok->strAt(1); + const char *varname2 = tok->strAt(3); + char sign1 = varsign[varname1]; + char sign2 = varsign[varname2]; + + if (sign1 && sign2 && sign1 != sign2) + { + // One of the operands are signed, the other is unsigned.. + _errorLogger->reportErr(ErrorMessage::udivWarning(_tokenizer, tok->next())); + } } } else if (!Token::Match(tok, "[).]") && Token::Match(tok->next(), "%var% / - %num%")) { - const char *varname1 = tok->strAt(1); - char sign1 = varsign[varname1]; - if (sign1 == 'u') + if (ErrorMessage::udivError(_settings)) { - std::ostringstream ostr; - ostr << _tokenizer->fileLine(tok->next()) << ": Unsigned division. The result will be wrong."; - _errorLogger->reportErr(ostr.str()); + const char *varname1 = tok->strAt(1); + char sign1 = varsign[varname1]; + if (sign1 == 'u') + { + _errorLogger->reportErr(ErrorMessage::udivError(_tokenizer, tok->next())); + } } } else if (Token::Match(tok, "[([=*/+-] - %num% / %var%")) { - const char *varname2 = tok->strAt(4); - char sign2 = varsign[varname2]; - if (sign2 == 'u') + if (ErrorMessage::udivError(_settings)) { - std::ostringstream ostr; - ostr << _tokenizer->fileLine(tok->next()) << ": Unsigned division. The result will be wrong."; - _errorLogger->reportErr(ostr.str()); + const char *varname2 = tok->strAt(4); + char sign2 = varsign[varname2]; + if (sign2 == 'u') + { + _errorLogger->reportErr(ErrorMessage::udivError(_tokenizer, tok->next())); + } } } } diff --git a/src/checkother.h b/src/checkother.h index b6c757431..d1d63aae2 100644 --- a/src/checkother.h +++ b/src/checkother.h @@ -29,7 +29,7 @@ class CheckOther { public: - CheckOther(const Tokenizer *tokenizer, ErrorLogger *errorLogger); + CheckOther(const Tokenizer *tokenizer, const Settings &settings, ErrorLogger *errorLogger); ~CheckOther(); // Casting @@ -83,6 +83,7 @@ private: const Tokenizer *_tokenizer; ErrorLogger *_errorLogger; + const Settings &_settings; }; //--------------------------------------------------------------------------- diff --git a/src/cppcheck.cpp b/src/cppcheck.cpp index edf43e118..fbb3f4b98 100644 --- a/src/cppcheck.cpp +++ b/src/cppcheck.cpp @@ -238,12 +238,14 @@ void CppCheck::checkFile(const std::string &code, const char FileName[]) // Coding style checks that must be run before the simplifyTokenList - CheckOther checkOther(&_tokenizer, this); - if (_settings._checkCodingStyle) - { - // Check for unsigned divisions where one operand is signed + CheckOther checkOther(&_tokenizer, _settings, this); + + // Check for unsigned divisions where one operand is signed + if (ErrorMessage::udivWarning(_settings) || ErrorMessage::udivError(_settings)) checkOther.CheckUnsignedDivision(); + if (_settings._checkCodingStyle) + { // Give warning when using char variable as array index checkOther.CheckCharVariable(); diff --git a/src/errormessage.h b/src/errormessage.h index b77958f9e..be2c002dd 100644 --- a/src/errormessage.h +++ b/src/errormessage.h @@ -201,5 +201,23 @@ public: return true; } + static std::string udivError(const Tokenizer *tokenizer, const Token *Location) + { + return msg1(tokenizer, Location) + "Unsigned division. The result will be wrong."; + } + static bool udivError(const Settings &s) + { + return true; + } + + static std::string udivWarning(const Tokenizer *tokenizer, const Token *Location) + { + return msg1(tokenizer, Location) + "Warning: Division with signed and unsigned operators"; + } + static bool udivWarning(const Settings &s) + { + return s._showAll; + } + }; #endif diff --git a/test/testcharvar.cpp b/test/testcharvar.cpp index a6e2a4162..6b5dbb058 100644 --- a/test/testcharvar.cpp +++ b/test/testcharvar.cpp @@ -53,7 +53,7 @@ private: errout.str(""); // Check char variable usage.. - CheckOther checkOther(&tokenizer, this); + CheckOther checkOther(&tokenizer, Settings(), this); checkOther.CheckCharVariable(); } diff --git a/test/testdivision.cpp b/test/testdivision.cpp index b1e09f610..8a346e8a0 100644 --- a/test/testdivision.cpp +++ b/test/testdivision.cpp @@ -47,8 +47,11 @@ private: // Clear the error buffer.. errout.str(""); + Settings settings; + settings._showAll = true; + // Check for unsigned divisions.. - CheckOther checkOther(&tokenizer, this); + CheckOther checkOther(&tokenizer, settings, this); checkOther.CheckUnsignedDivision(); } diff --git a/test/testincompletestatement.cpp b/test/testincompletestatement.cpp index 289bfedd4..6121be2d5 100644 --- a/test/testincompletestatement.cpp +++ b/test/testincompletestatement.cpp @@ -47,8 +47,11 @@ private: // Clear the error buffer.. errout.str(""); + Settings settings; + settings._showAll = true; + // Check for unused variables.. - CheckOther checkOther(&tokenizer, this); + CheckOther checkOther(&tokenizer, settings, this); checkOther.CheckIncompleteStatement(); } diff --git a/test/testother.cpp b/test/testother.cpp index 0ec1280d7..8a1e91f76 100644 --- a/test/testother.cpp +++ b/test/testother.cpp @@ -54,7 +54,7 @@ private: errout.str(""); // Check for redundant code.. - CheckOther checkOther(&tokenizer, this); + CheckOther checkOther(&tokenizer, Settings(), this); checkOther.WarningRedundantCode(); } @@ -106,7 +106,7 @@ private: errout.str(""); // Check for redundant code.. - CheckOther checkOther(&tokenizer, this); + CheckOther checkOther(&tokenizer, Settings(), this); checkOther.InvalidFunctionUsage(); } diff --git a/test/testredundantif.cpp b/test/testredundantif.cpp index 5861c6b13..095e34592 100644 --- a/test/testredundantif.cpp +++ b/test/testredundantif.cpp @@ -48,7 +48,7 @@ private: errout.str(""); // Check for redundant condition.. - CheckOther checkOther(&tokenizer, this); + CheckOther checkOther(&tokenizer, Settings(), this); checkOther.redundantCondition2(); } diff --git a/test/testunusedvar.cpp b/test/testunusedvar.cpp index 8a457fbdb..6edba1b9c 100644 --- a/test/testunusedvar.cpp +++ b/test/testunusedvar.cpp @@ -47,7 +47,7 @@ private: errout.str(""); // Check for unused variables.. - CheckOther checkOther(&tokenizer, this); + CheckOther checkOther(&tokenizer, Settings(), this); checkOther.CheckStructMemberUsage(); } @@ -182,7 +182,7 @@ private: errout.str(""); // Check for unused variables.. - CheckOther checkOther(&tokenizer, this); + CheckOther checkOther(&tokenizer, Settings(), this); checkOther.functionVariableUsage(); } diff --git a/tools/errmsg.cpp b/tools/errmsg.cpp index 9d4cb715a..b443491cf 100644 --- a/tools/errmsg.cpp +++ b/tools/errmsg.cpp @@ -81,6 +81,8 @@ int main() err.push_back(Message("dangerousUsageStrtol", 0, "Invalid radix in call to strtol or strtoul. Must be 0 or 2-36")); err.push_back(Message("ifNoAction", Message::STYLE, "Found redundant if condition - 'if (condition);'")); err.push_back(Message("sprintfOverlappingData", 0, "Overlapping data buffer %1", "varname")); + err.push_back(Message("udivError", 0, "Unsigned division. The result will be wrong.")); + err.push_back(Message("udivWarning", Message::ALL, "Warning: Division with signed and unsigned operators")); // Generate code.. std::cout << "Generate code.." << std::endl;