errmsg: Added 'unsigned division'

This commit is contained in:
Daniel Marjamäki 2009-01-12 17:12:14 +00:00
parent e70f68f266
commit 980b10bfc9
11 changed files with 69 additions and 36 deletions

View File

@ -35,7 +35,8 @@
// Warning on C-Style casts.. p = (kalle *)foo; // 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; _tokenizer = tokenizer;
_errorLogger = errorLogger; _errorLogger = errorLogger;
@ -406,6 +407,8 @@ void CheckOther::CheckUnsignedDivision()
varsign[tok->strAt(3)] = 'u'; varsign[tok->strAt(3)] = 'u';
else if (!Token::Match(tok, "[).]") && Token::Match(tok->next(), "%var% / %var%")) else if (!Token::Match(tok, "[).]") && Token::Match(tok->next(), "%var% / %var%"))
{
if (ErrorMessage::udivWarning(_settings))
{ {
const char *varname1 = tok->strAt(1); const char *varname1 = tok->strAt(1);
const char *varname2 = tok->strAt(3); const char *varname2 = tok->strAt(3);
@ -415,33 +418,34 @@ void CheckOther::CheckUnsignedDivision()
if (sign1 && sign2 && sign1 != sign2) if (sign1 && sign2 && sign1 != sign2)
{ {
// One of the operands are signed, the other is unsigned.. // One of the operands are signed, the other is unsigned..
std::ostringstream ostr; _errorLogger->reportErr(ErrorMessage::udivWarning(_tokenizer, tok->next()));
ostr << _tokenizer->fileLine(tok->next()) << ": Warning: Division with signed and unsigned operators"; }
_errorLogger->reportErr(ostr.str());
} }
} }
else if (!Token::Match(tok, "[).]") && Token::Match(tok->next(), "%var% / - %num%")) else if (!Token::Match(tok, "[).]") && Token::Match(tok->next(), "%var% / - %num%"))
{
if (ErrorMessage::udivError(_settings))
{ {
const char *varname1 = tok->strAt(1); const char *varname1 = tok->strAt(1);
char sign1 = varsign[varname1]; char sign1 = varsign[varname1];
if (sign1 == 'u') if (sign1 == 'u')
{ {
std::ostringstream ostr; _errorLogger->reportErr(ErrorMessage::udivError(_tokenizer, tok->next()));
ostr << _tokenizer->fileLine(tok->next()) << ": Unsigned division. The result will be wrong."; }
_errorLogger->reportErr(ostr.str());
} }
} }
else if (Token::Match(tok, "[([=*/+-] - %num% / %var%")) else if (Token::Match(tok, "[([=*/+-] - %num% / %var%"))
{
if (ErrorMessage::udivError(_settings))
{ {
const char *varname2 = tok->strAt(4); const char *varname2 = tok->strAt(4);
char sign2 = varsign[varname2]; char sign2 = varsign[varname2];
if (sign2 == 'u') if (sign2 == 'u')
{ {
std::ostringstream ostr; _errorLogger->reportErr(ErrorMessage::udivError(_tokenizer, tok->next()));
ostr << _tokenizer->fileLine(tok->next()) << ": Unsigned division. The result will be wrong."; }
_errorLogger->reportErr(ostr.str());
} }
} }
} }

View File

@ -29,7 +29,7 @@
class CheckOther class CheckOther
{ {
public: public:
CheckOther(const Tokenizer *tokenizer, ErrorLogger *errorLogger); CheckOther(const Tokenizer *tokenizer, const Settings &settings, ErrorLogger *errorLogger);
~CheckOther(); ~CheckOther();
// Casting // Casting
@ -83,6 +83,7 @@ private:
const Tokenizer *_tokenizer; const Tokenizer *_tokenizer;
ErrorLogger *_errorLogger; ErrorLogger *_errorLogger;
const Settings &_settings;
}; };
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------

View File

@ -238,12 +238,14 @@ void CppCheck::checkFile(const std::string &code, const char FileName[])
// Coding style checks that must be run before the simplifyTokenList // Coding style checks that must be run before the simplifyTokenList
CheckOther checkOther(&_tokenizer, this); CheckOther checkOther(&_tokenizer, _settings, this);
if (_settings._checkCodingStyle)
{
// Check for unsigned divisions where one operand is signed // Check for unsigned divisions where one operand is signed
if (ErrorMessage::udivWarning(_settings) || ErrorMessage::udivError(_settings))
checkOther.CheckUnsignedDivision(); checkOther.CheckUnsignedDivision();
if (_settings._checkCodingStyle)
{
// Give warning when using char variable as array index // Give warning when using char variable as array index
checkOther.CheckCharVariable(); checkOther.CheckCharVariable();

View File

@ -201,5 +201,23 @@ public:
return true; 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 #endif

View File

@ -53,7 +53,7 @@ private:
errout.str(""); errout.str("");
// Check char variable usage.. // Check char variable usage..
CheckOther checkOther(&tokenizer, this); CheckOther checkOther(&tokenizer, Settings(), this);
checkOther.CheckCharVariable(); checkOther.CheckCharVariable();
} }

View File

@ -47,8 +47,11 @@ private:
// Clear the error buffer.. // Clear the error buffer..
errout.str(""); errout.str("");
Settings settings;
settings._showAll = true;
// Check for unsigned divisions.. // Check for unsigned divisions..
CheckOther checkOther(&tokenizer, this); CheckOther checkOther(&tokenizer, settings, this);
checkOther.CheckUnsignedDivision(); checkOther.CheckUnsignedDivision();
} }

View File

@ -47,8 +47,11 @@ private:
// Clear the error buffer.. // Clear the error buffer..
errout.str(""); errout.str("");
Settings settings;
settings._showAll = true;
// Check for unused variables.. // Check for unused variables..
CheckOther checkOther(&tokenizer, this); CheckOther checkOther(&tokenizer, settings, this);
checkOther.CheckIncompleteStatement(); checkOther.CheckIncompleteStatement();
} }

View File

@ -54,7 +54,7 @@ private:
errout.str(""); errout.str("");
// Check for redundant code.. // Check for redundant code..
CheckOther checkOther(&tokenizer, this); CheckOther checkOther(&tokenizer, Settings(), this);
checkOther.WarningRedundantCode(); checkOther.WarningRedundantCode();
} }
@ -106,7 +106,7 @@ private:
errout.str(""); errout.str("");
// Check for redundant code.. // Check for redundant code..
CheckOther checkOther(&tokenizer, this); CheckOther checkOther(&tokenizer, Settings(), this);
checkOther.InvalidFunctionUsage(); checkOther.InvalidFunctionUsage();
} }

View File

@ -48,7 +48,7 @@ private:
errout.str(""); errout.str("");
// Check for redundant condition.. // Check for redundant condition..
CheckOther checkOther(&tokenizer, this); CheckOther checkOther(&tokenizer, Settings(), this);
checkOther.redundantCondition2(); checkOther.redundantCondition2();
} }

View File

@ -47,7 +47,7 @@ private:
errout.str(""); errout.str("");
// Check for unused variables.. // Check for unused variables..
CheckOther checkOther(&tokenizer, this); CheckOther checkOther(&tokenizer, Settings(), this);
checkOther.CheckStructMemberUsage(); checkOther.CheckStructMemberUsage();
} }
@ -182,7 +182,7 @@ private:
errout.str(""); errout.str("");
// Check for unused variables.. // Check for unused variables..
CheckOther checkOther(&tokenizer, this); CheckOther checkOther(&tokenizer, Settings(), this);
checkOther.functionVariableUsage(); checkOther.functionVariableUsage();
} }

View File

@ -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("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("ifNoAction", Message::STYLE, "Found redundant if condition - 'if (condition);'"));
err.push_back(Message("sprintfOverlappingData", 0, "Overlapping data buffer %1", "varname")); 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.. // Generate code..
std::cout << "Generate code.." << std::endl; std::cout << "Generate code.." << std::endl;