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;
//---------------------------------------------------------------------------
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()));
}
}
}
}

View File

@ -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;
};
//---------------------------------------------------------------------------

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
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();

View File

@ -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

View File

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

View File

@ -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();
}

View File

@ -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();
}

View File

@ -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();
}

View File

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

View File

@ -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();
}

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("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;