Skip to content

Commit

Permalink
char variable usage: Added checking
Browse files Browse the repository at this point in the history
  • Loading branch information
Daniel Marjamäki committed Aug 28, 2008
1 parent 0f036f6 commit 778410c
Show file tree
Hide file tree
Showing 6 changed files with 139 additions and 17 deletions.
53 changes: 53 additions & 0 deletions CheckOther.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -633,3 +633,56 @@ void CheckStructMemberUsage()
}
}





//---------------------------------------------------------------------------
// Check usage of char variables..
//---------------------------------------------------------------------------

void CheckCharVariable()
{
for (const TOKEN *tok = tokens; tok; tok = tok->next)
{
// Declaring the variable..
if ( Match(tok, "[{};] char %var% [;=,]") )
{
const char *varname[2] = {0};
varname[0] = getstr(tok, 2);

// Check usage of char variable..
int indentlevel = 0;
for ( const TOKEN *tok2 = tok->next; tok2; tok2 = tok2->next )
{
if ( tok2->str[0] == '{' )
++indentlevel;

else if ( tok2->str[0] == '}' )
{
--indentlevel;
if ( indentlevel < 0 )
break;
}

else if ( Match(tok2, "%var% [ %var1% ]", varname) )
{
std::ostringstream errmsg;
errmsg << FileLine(tok2) << ": Warning - using char variable as array index";
ReportErr(errmsg.str());
break;
}

else if ( Match(tok2, "[&|] %var1%") )
{
std::ostringstream errmsg;
errmsg << FileLine(tok2) << ": Warning - using char variable in bit operation";
ReportErr(errmsg.str());
break;
}
}
}
}
}
//---------------------------------------------------------------------------

4 changes: 4 additions & 0 deletions CheckOther.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,10 @@ void CheckConstantFunctionParameter();
// Check that all struct members are used
void CheckStructMemberUsage();

// Using char variable as array index / as operand in bit operation
void CheckCharVariable();


//---------------------------------------------------------------------------
#endif

2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
SRCS=CheckBufferOverrun.cpp CheckClass.cpp CheckHeaders.cpp CheckMemoryLeak.cpp CheckOther.cpp CommonCheck.cpp tokenize.cpp
OBJS=$(SRCS:%.cpp=%.o)
TESTS=testbufferoverrun.o testconstructors.o testdivision.o testmemleak.o
TESTS=testbufferoverrun.o testcharvar.o testconstructors.o testdivision.o testmemleak.o

%.o: %.cpp
g++ -Wall -pedantic -g -I. -o $@ -c $^
Expand Down
17 changes: 8 additions & 9 deletions main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,6 @@
* what the developer wanted to do (missing break after case).
* It is safe to uncomment any of the checks.
*
* Todo-list:
* - using 'char'-data as array index..
* char ch = 0xff;
* array[ch] = 0;
* => Dangerous. ch => -1 => 0xffffffff
*
* Design
* The token list is a stringlist with the same contents and structure
* as the file.
Expand Down Expand Up @@ -230,6 +224,11 @@ static void CppCheck(const char FileName[], unsigned int FileId)
if ( ShowAll )
CheckUnsignedDivision();

// Give warning when using char variable as array index
// Doesn't work on simplified token list ('unsigned')
if ( ShowAll )
CheckCharVariable();


// Including header which is not needed (too many false positives)
//if ( CheckCodingStyle )
Expand Down Expand Up @@ -300,9 +299,9 @@ static void CppCheck(const char FileName[], unsigned int FileId)
CheckVariableScope();

// Check if a constant function parameter is passed by value
CheckConstantFunctionParameter();

// Unused struct members..
CheckConstantFunctionParameter();

// Unused struct members..
CheckStructMemberUsage();
}

Expand Down
62 changes: 62 additions & 0 deletions testcharvar.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@



#include "tokenize.h"
#include "CommonCheck.h"
#include "CheckOther.h"
#include "MiniCppUnit.h"

#include <sstream>

extern std::ostringstream errout;
extern bool ShowAll;

class TestCharVar : public TestFixture<TestCharVar>
{
private:
void check( const char code[] )
{
// Tokenize..
tokens = tokens_back = NULL;
std::istringstream istr(code);
TokenizeCode( istr );

// Fill function list
FillFunctionList(0);

// Clear the error buffer..
errout.str("");

// Check for memory leaks..
ShowAll = true;
CheckCharVariable();
}

public:
TEST_FIXTURE( TestCharVar )
{
TEST_CASE( array_index );
}


void array_index()
{
check( "void foo()\n"
"{\n"
" unsigned char ch = 0x80;\n"
" buf[ch] = 0;\n"
"}\n" );
ASSERT_EQUALS( std::string(""), errout.str() );

check( "void foo()\n"
"{\n"
" char ch = 0x80;\n"
" buf[ch] = 0;\n"
"}\n" );
ASSERT_EQUALS( std::string("[test.cpp:4]: Warning - using char variable as array index\n"), errout.str() );
}

};

REGISTER_FIXTURE( TestCharVar )

18 changes: 11 additions & 7 deletions testrunner.cbproj
Original file line number Diff line number Diff line change
Expand Up @@ -18,26 +18,26 @@
<CfgParent>Base</CfgParent>
</PropertyGroup>
<PropertyGroup Condition="'$(Base)'!=''">
<BCC_OptimizeForSpeed>true</BCC_OptimizeForSpeed>
<OutputExt>exe</OutputExt>
<Defines>NO_STRICT</Defines>
<BCC_OptimizeForSpeed>true</BCC_OptimizeForSpeed>
<DCC_CBuilderOutput>JPHNE</DCC_CBuilderOutput>
<Defines>NO_STRICT</Defines>
<DynamicRTL>true</DynamicRTL>
<UsePackages>true</UsePackages>
<ILINK_ObjectSearchPath>C:\cppcheck</ILINK_ObjectSearchPath>
<ProjectType>CppConsoleApplication</ProjectType>
<UsePackages>true</UsePackages>
<NoVCL>true</NoVCL>
<ProjectType>CppConsoleApplication</ProjectType>
<FinalOutputDir>.</FinalOutputDir>
<PackageImports>vclx.bpi;vcl.bpi;rtl.bpi;vclactnband.bpi</PackageImports>
<BCC_wpar>false</BCC_wpar>
<IncludePath>$(BDS)\include;$(BDS)\include\dinkumware;$(BDS)\include\vcl;C:\cppcheck</IncludePath>
<ILINK_LibraryPath>$(BDS)\lib;$(BDS)\lib\obj;$(BDS)\lib\psdk;C:\cppcheck</ILINK_LibraryPath>
</PropertyGroup>
<PropertyGroup Condition="'$(Cfg_1)'!=''">
<DCC_Optimize>false</DCC_Optimize>
<BCC_OptimizeForSpeed>false</BCC_OptimizeForSpeed>
<Defines>_DEBUG;$(Defines)</Defines>
<DCC_Optimize>false</DCC_Optimize>
<DCC_DebugInfoInExe>true</DCC_DebugInfoInExe>
<Defines>_DEBUG;$(Defines)</Defines>
<ILINK_FullDebugInfo>true</ILINK_FullDebugInfo>
<BCC_InlineFunctionExpansion>false</BCC_InlineFunctionExpansion>
<ILINK_DisableIncrementalLinking>true</ILINK_DisableIncrementalLinking>
Expand All @@ -47,8 +47,8 @@
<IntermediateOutputDir>Debug</IntermediateOutputDir>
<TASM_DisplaySourceLines>true</TASM_DisplaySourceLines>
<BCC_StackFrames>true</BCC_StackFrames>
<ILINK_LibraryPath>$(BDS)\lib\debug;$(ILINK_LibraryPath)</ILINK_LibraryPath>
<BCC_DisableOptimizations>true</BCC_DisableOptimizations>
<ILINK_LibraryPath>$(BDS)\lib\debug;$(ILINK_LibraryPath)</ILINK_LibraryPath>
<TASM_Debugging>Full</TASM_Debugging>
<BCC_SourceDebuggingOn>true</BCC_SourceDebuggingOn>
</PropertyGroup>
Expand Down Expand Up @@ -95,6 +95,10 @@
<CppCompile Include="testbufferoverrun.cpp">
<BuildOrder>7</BuildOrder>
</CppCompile>
<CppCompile Include="testcharvar.cpp">
<DependentOn>testcharvar.h</DependentOn>
<BuildOrder>12</BuildOrder>
</CppCompile>
<CppCompile Include="testconstructors.cpp">
<BuildOrder>8</BuildOrder>
</CppCompile>
Expand Down

0 comments on commit 778410c

Please sign in to comment.