CheckUnsignedDivision: Refactoring
This commit is contained in:
parent
259e0ce238
commit
528deafe68
|
@ -3,6 +3,7 @@
|
||||||
#include "tokenize.h"
|
#include "tokenize.h"
|
||||||
#include "CommonCheck.h"
|
#include "CommonCheck.h"
|
||||||
#include <list>
|
#include <list>
|
||||||
|
#include <map>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <stdlib.h> // <- atoi
|
#include <stdlib.h> // <- atoi
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
@ -320,57 +321,27 @@ void CheckIfAssignment()
|
||||||
void CheckUnsignedDivision()
|
void CheckUnsignedDivision()
|
||||||
{
|
{
|
||||||
// Check for "ivar / uvar" and "uvar / ivar"
|
// Check for "ivar / uvar" and "uvar / ivar"
|
||||||
// Todo: Much better checking for declared variables
|
std::map<std::string, char> varsign;
|
||||||
const char *div_pattern[] = {"", "/", "", NULL};
|
for ( TOKEN *tok = tokens; tok; tok = tok->next )
|
||||||
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;
|
if ( Match(tok, "[{};(,] %type% %var% [;=,)]") )
|
||||||
const char *varname2 = div_tok->next->next->str;
|
varsign[getstr(tok,2)] = 's';
|
||||||
if ( IsName(varname1) && IsName(varname2) )
|
|
||||||
|
else if ( Match(tok, "[{};(,] unsigned %type% %var% [;=,)]") )
|
||||||
|
varsign[getstr(tok,3)] = 'u';
|
||||||
|
|
||||||
|
else if ( tok->str[0] != ')' && Match(tok->next, "%var% / %var%") )
|
||||||
{
|
{
|
||||||
char var1_sign=0, var2_sign=0;
|
const char *varname1 = getstr(tok,1);
|
||||||
|
const char *varname2 = getstr(tok,3);
|
||||||
|
char sign1 = varsign[varname1];
|
||||||
|
char sign2 = varsign[varname2];
|
||||||
|
|
||||||
// Check if any of the variables are unsigned..
|
if ( sign1 && sign2 && sign1 != sign2 )
|
||||||
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;
|
|
||||||
|
|
||||||
// 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';
|
|
||||||
|
|
||||||
pattern_declvar[0] = "{";
|
|
||||||
|
|
||||||
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..
|
// One of the operands are signed, the other is unsigned..
|
||||||
std::ostringstream ostr;
|
std::ostringstream ostr;
|
||||||
ostr << FileLine(div_tok) << ": Warning: Division with signed and unsigned operators";
|
ostr << FileLine(tok->next) << ": Warning: Division with signed and unsigned operators";
|
||||||
ReportErr(ostr.str());
|
ReportErr(ostr.str());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,6 +37,7 @@ public:
|
||||||
TEST_CASE( division1 );
|
TEST_CASE( division1 );
|
||||||
TEST_CASE( division2 );
|
TEST_CASE( division2 );
|
||||||
TEST_CASE( division3 );
|
TEST_CASE( division3 );
|
||||||
|
TEST_CASE( division4 );
|
||||||
}
|
}
|
||||||
|
|
||||||
void division1()
|
void division1()
|
||||||
|
@ -73,6 +74,21 @@ public:
|
||||||
"}\n" );
|
"}\n" );
|
||||||
ASSERT_EQUALS( std::string("[test.cpp:7]: Warning: Division with signed and unsigned operators\n"), errout.str() );
|
ASSERT_EQUALS( std::string("[test.cpp:7]: Warning: Division with signed and unsigned operators\n"), errout.str() );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void division4()
|
||||||
|
{
|
||||||
|
check( "void f1()\n"
|
||||||
|
"{\n"
|
||||||
|
" int i1;\n"
|
||||||
|
"}\n"
|
||||||
|
"\n"
|
||||||
|
"void f2(unsigned int i1)\n"
|
||||||
|
"{\n"
|
||||||
|
" unsigned int i2;\n"
|
||||||
|
" result = i2 / i1;\n"
|
||||||
|
);
|
||||||
|
ASSERT_EQUALS( std::string(""), errout.str() );
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
REGISTER_FIXTURE( TestDivision )
|
REGISTER_FIXTURE( TestDivision )
|
||||||
|
|
Loading…
Reference in New Issue