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()
{
// TODO: Check that the scope is the same
// Check for "ivar / uvar" and "uvar / ivar"
// Todo: Much better checking for declared variables
const char *div_pattern[] = {"", "/", "", NULL};
for (const TOKEN *div_tok = findtoken(tokens, div_pattern); div_tok; div_tok = findtoken(div_tok->next, div_pattern))
{
const char *varname1 = div_tok->str;
const char *varname2 = div_tok->next->next->str;
if ( IsName(varname1) && IsName(varname2) )
{
char var1_sign=0, var2_sign=0;
const char *pattern_declvar[] = { "unsigned", "int", "", NULL };
TOKEN *declvar = findtoken(tokens, pattern_declvar);
while ( declvar )
{
const char *varname = getstr( declvar, 2 );
if ( ! IsName(varname) )
{
declvar = findtoken( declvar->next, pattern_declvar );
// Check if any of the variables are unsigned..
const char *pattern_declvar[] = { "unsigned", "", "", NULL };
pattern_declvar[2] = varname1;
if ( findtoken(tokens, pattern_declvar) )
var1_sign = 'u';
pattern_declvar[2] = varname2;
if ( findtoken(tokens, pattern_declvar) )
var2_sign = 'u';
if (var1_sign == var2_sign)
continue;
}
const char *pattern_div1[] = { "/", "", NULL };
pattern_div1[1] = varname;
TOKEN *tokdiv = findtoken(declvar, pattern_div1);
while ( tokdiv )
{
if ( strcmp(getstr(tokdiv,2), "->") )
// 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;
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());
}
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);
}
}
//---------------------------------------------------------------------------