Rewrote the checking for "unsigned division" => less false positives
This commit is contained in:
parent
506fc0e16d
commit
313d3dafa1
|
@ -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);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
|
Loading…
Reference in New Issue