Rewrote the checking for "unsigned division" => less false positives

This commit is contained in:
Daniel Marjamäki 2008-03-20 07:23:01 +00:00
parent 506fc0e16d
commit 313d3dafa1
1 changed files with 37 additions and 36 deletions

View File

@ -476,50 +476,51 @@ void CheckCaseWithoutBreak()
void CheckUnsignedDivision() void CheckUnsignedDivision()
{ {
// TODO: Check that the scope is the same // Check for "ivar / uvar" and "uvar / ivar"
// Todo: Much better checking for declared variables
const char *pattern_declvar[] = { "unsigned", "int", "", NULL }; const char *div_pattern[] = {"", "/", "", NULL};
TOKEN *declvar = findtoken(tokens, pattern_declvar); for (const TOKEN *div_tok = findtoken(tokens, div_pattern); div_tok; div_tok = findtoken(div_tok->next, div_pattern))
while ( declvar )
{ {
const char *varname = getstr( declvar, 2 ); const char *varname1 = div_tok->str;
if ( ! IsName(varname) ) const char *varname2 = div_tok->next->next->str;
if ( IsName(varname1) && IsName(varname2) )
{ {
declvar = findtoken( declvar->next, pattern_declvar ); char var1_sign=0, var2_sign=0;
continue;
}
const char *pattern_div1[] = { "/", "", NULL }; // Check if any of the variables are unsigned..
pattern_div1[1] = varname; const char *pattern_declvar[] = { "unsigned", "", "", NULL };
TOKEN *tokdiv = findtoken(declvar, pattern_div1);
while ( tokdiv ) pattern_declvar[2] = varname1;
{ if ( findtoken(tokens, pattern_declvar) )
if ( strcmp(getstr(tokdiv,2), "->") ) var1_sign = 'u';
pattern_declvar[2] = varname2;
if ( findtoken(tokens, pattern_declvar) )
var2_sign = 'u';
if (var1_sign == var2_sign)
continue;
// Check if any of the variables are signed..
pattern_declvar[0] = ";";
pattern_declvar[1] = "int";
pattern_declvar[2] = varname1;
if ( findtoken(tokens, pattern_declvar) )
var1_sign = 's';
pattern_declvar[2] = varname2;
if ( findtoken(tokens, pattern_declvar) )
var2_sign = 's';
if ( var1_sign && var2_sign && var1_sign != var2_sign )
{ {
// One of the operands are signed, the other is unsigned..
std::ostringstream ostr; std::ostringstream ostr;
ostr << FileLine(tokdiv) << ": If the result is negative it will be wrong because an operand is unsigned."; ostr << FileLine(div_tok) << ": If the result is negative it will be wrong because an operand is unsigned.";
ReportErr(ostr.str()); ReportErr(ostr.str());
} }
tokdiv = findtoken(tokdiv->next, pattern_div1);
} }
const char *pattern_div2[] = { "", "", "/", NULL };
pattern_div2[1] = varname;
tokdiv = findtoken(declvar, pattern_div2);
while ( tokdiv )
{
if (!IsNumber(getstr(tokdiv,3)) &&
tokdiv->str[0] != ')' && // The ')' may indicate a cast
strcmp(tokdiv->str,"->"))
{
std::ostringstream ostr;
ostr << FileLine(tokdiv) << ": If the result is negative it will be wrong because an operand is unsigned.";
ReportErr(ostr.str());
}
tokdiv = findtoken(tokdiv->next, pattern_div2);
}
declvar = findtoken(declvar->next, pattern_declvar);
} }
} }
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------