char variable usage: Added checking

This commit is contained in:
Daniel Marjamäki 2008-08-28 06:36:30 +00:00
parent 0f036f622b
commit 778410ccbf
6 changed files with 139 additions and 17 deletions

View File

@ -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;
}
}
}
}
}
//---------------------------------------------------------------------------

View File

@ -40,6 +40,10 @@ void CheckConstantFunctionParameter();
// Check that all struct members are used // Check that all struct members are used
void CheckStructMemberUsage(); void CheckStructMemberUsage();
// Using char variable as array index / as operand in bit operation
void CheckCharVariable();
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
#endif #endif

View File

@ -1,6 +1,6 @@
SRCS=CheckBufferOverrun.cpp CheckClass.cpp CheckHeaders.cpp CheckMemoryLeak.cpp CheckOther.cpp CommonCheck.cpp tokenize.cpp SRCS=CheckBufferOverrun.cpp CheckClass.cpp CheckHeaders.cpp CheckMemoryLeak.cpp CheckOther.cpp CommonCheck.cpp tokenize.cpp
OBJS=$(SRCS:%.cpp=%.o) 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 %.o: %.cpp
g++ -Wall -pedantic -g -I. -o $@ -c $^ g++ -Wall -pedantic -g -I. -o $@ -c $^

View File

@ -10,12 +10,6 @@
* what the developer wanted to do (missing break after case). * what the developer wanted to do (missing break after case).
* It is safe to uncomment any of the checks. * 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 * Design
* The token list is a stringlist with the same contents and structure * The token list is a stringlist with the same contents and structure
* as the file. * as the file.
@ -230,6 +224,11 @@ static void CppCheck(const char FileName[], unsigned int FileId)
if ( ShowAll ) if ( ShowAll )
CheckUnsignedDivision(); 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) // Including header which is not needed (too many false positives)
//if ( CheckCodingStyle ) //if ( CheckCodingStyle )
@ -300,9 +299,9 @@ static void CppCheck(const char FileName[], unsigned int FileId)
CheckVariableScope(); CheckVariableScope();
// Check if a constant function parameter is passed by value // Check if a constant function parameter is passed by value
CheckConstantFunctionParameter(); CheckConstantFunctionParameter();
// Unused struct members.. // Unused struct members..
CheckStructMemberUsage(); CheckStructMemberUsage();
} }

62
testcharvar.cpp Normal file
View File

@ -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 )

View File

@ -18,15 +18,15 @@
<CfgParent>Base</CfgParent> <CfgParent>Base</CfgParent>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Base)'!=''"> <PropertyGroup Condition="'$(Base)'!=''">
<BCC_OptimizeForSpeed>true</BCC_OptimizeForSpeed>
<OutputExt>exe</OutputExt> <OutputExt>exe</OutputExt>
<Defines>NO_STRICT</Defines> <BCC_OptimizeForSpeed>true</BCC_OptimizeForSpeed>
<DCC_CBuilderOutput>JPHNE</DCC_CBuilderOutput> <DCC_CBuilderOutput>JPHNE</DCC_CBuilderOutput>
<Defines>NO_STRICT</Defines>
<DynamicRTL>true</DynamicRTL> <DynamicRTL>true</DynamicRTL>
<UsePackages>true</UsePackages>
<ILINK_ObjectSearchPath>C:\cppcheck</ILINK_ObjectSearchPath> <ILINK_ObjectSearchPath>C:\cppcheck</ILINK_ObjectSearchPath>
<ProjectType>CppConsoleApplication</ProjectType> <UsePackages>true</UsePackages>
<NoVCL>true</NoVCL> <NoVCL>true</NoVCL>
<ProjectType>CppConsoleApplication</ProjectType>
<FinalOutputDir>.</FinalOutputDir> <FinalOutputDir>.</FinalOutputDir>
<PackageImports>vclx.bpi;vcl.bpi;rtl.bpi;vclactnband.bpi</PackageImports> <PackageImports>vclx.bpi;vcl.bpi;rtl.bpi;vclactnband.bpi</PackageImports>
<BCC_wpar>false</BCC_wpar> <BCC_wpar>false</BCC_wpar>
@ -34,10 +34,10 @@
<ILINK_LibraryPath>$(BDS)\lib;$(BDS)\lib\obj;$(BDS)\lib\psdk;C:\cppcheck</ILINK_LibraryPath> <ILINK_LibraryPath>$(BDS)\lib;$(BDS)\lib\obj;$(BDS)\lib\psdk;C:\cppcheck</ILINK_LibraryPath>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Cfg_1)'!=''"> <PropertyGroup Condition="'$(Cfg_1)'!=''">
<DCC_Optimize>false</DCC_Optimize>
<BCC_OptimizeForSpeed>false</BCC_OptimizeForSpeed> <BCC_OptimizeForSpeed>false</BCC_OptimizeForSpeed>
<Defines>_DEBUG;$(Defines)</Defines> <DCC_Optimize>false</DCC_Optimize>
<DCC_DebugInfoInExe>true</DCC_DebugInfoInExe> <DCC_DebugInfoInExe>true</DCC_DebugInfoInExe>
<Defines>_DEBUG;$(Defines)</Defines>
<ILINK_FullDebugInfo>true</ILINK_FullDebugInfo> <ILINK_FullDebugInfo>true</ILINK_FullDebugInfo>
<BCC_InlineFunctionExpansion>false</BCC_InlineFunctionExpansion> <BCC_InlineFunctionExpansion>false</BCC_InlineFunctionExpansion>
<ILINK_DisableIncrementalLinking>true</ILINK_DisableIncrementalLinking> <ILINK_DisableIncrementalLinking>true</ILINK_DisableIncrementalLinking>
@ -47,8 +47,8 @@
<IntermediateOutputDir>Debug</IntermediateOutputDir> <IntermediateOutputDir>Debug</IntermediateOutputDir>
<TASM_DisplaySourceLines>true</TASM_DisplaySourceLines> <TASM_DisplaySourceLines>true</TASM_DisplaySourceLines>
<BCC_StackFrames>true</BCC_StackFrames> <BCC_StackFrames>true</BCC_StackFrames>
<ILINK_LibraryPath>$(BDS)\lib\debug;$(ILINK_LibraryPath)</ILINK_LibraryPath>
<BCC_DisableOptimizations>true</BCC_DisableOptimizations> <BCC_DisableOptimizations>true</BCC_DisableOptimizations>
<ILINK_LibraryPath>$(BDS)\lib\debug;$(ILINK_LibraryPath)</ILINK_LibraryPath>
<TASM_Debugging>Full</TASM_Debugging> <TASM_Debugging>Full</TASM_Debugging>
<BCC_SourceDebuggingOn>true</BCC_SourceDebuggingOn> <BCC_SourceDebuggingOn>true</BCC_SourceDebuggingOn>
</PropertyGroup> </PropertyGroup>
@ -95,6 +95,10 @@
<CppCompile Include="testbufferoverrun.cpp"> <CppCompile Include="testbufferoverrun.cpp">
<BuildOrder>7</BuildOrder> <BuildOrder>7</BuildOrder>
</CppCompile> </CppCompile>
<CppCompile Include="testcharvar.cpp">
<DependentOn>testcharvar.h</DependentOn>
<BuildOrder>12</BuildOrder>
</CppCompile>
<CppCompile Include="testconstructors.cpp"> <CppCompile Include="testconstructors.cpp">
<BuildOrder>8</BuildOrder> <BuildOrder>8</BuildOrder>
</CppCompile> </CppCompile>