This commit is contained in:
Debrard Sebastien 2010-10-14 19:08:31 +02:00
commit bc6365a3b0
11 changed files with 138 additions and 39 deletions

View File

@ -1012,7 +1012,7 @@ void CheckBufferOverrun::checkScope(const Token *tok, const ArrayInfo &arrayInfo
if (Token::Match(tok, "strcpy|strcat ( %varid% , %str% )", arrayInfo.varid))
{
const unsigned long len = Token::getStrLength(tok->tokAt(4));
if (len >= total_size)
if (total_size > 0 && len >= total_size)
{
bufferOverrun(tok, arrayInfo.varname);
continue;
@ -1794,7 +1794,9 @@ bool CheckBufferOverrun::ArrayInfo::declare(const Token *tok, const Tokenizer &t
if (!tok->isName())
return false;
while (tok && (tok->str() == "static" || tok->str() == "const"))
while (tok && (tok->str() == "static" ||
tok->str() == "const" ||
tok->str() == "extern"))
tok = tok->next();
int ivar = 0;

View File

@ -2139,6 +2139,37 @@ bool CheckClass::isMemberVar(const SpaceInfo *info, const Token *tok)
return false;
}
bool CheckClass::isConstMemberFunc(const SpaceInfo *info, const Token *tok)
{
std::list<Func>::const_iterator func;
for (func = info->functionList.begin(); func != info->functionList.end(); ++func)
{
if (func->tokenDef->str() == tok->str() && func->isConst)
return true;
}
// not found in this class
if (!info->derivedFrom.empty())
{
// check each base class
for (unsigned int i = 0; i < info->derivedFrom.size(); ++i)
{
// find the base class
const SpaceInfo *spaceInfo = info->derivedFrom[i].spaceInfo;
// find the function in the base class
if (spaceInfo)
{
if (isConstMemberFunc(spaceInfo, tok))
return true;
}
}
}
return false;
}
bool CheckClass::checkConstFunc(const SpaceInfo *info, const Token *tok)
{
// if the function doesn't have any assignment nor function call,
@ -2200,9 +2231,16 @@ bool CheckClass::checkConstFunc(const SpaceInfo *info, const Token *tok)
}
// function call..
else if ((Token::Match(tok1, "%var% (") &&
!(Token::Match(tok1, "return|c_str|if|string") || tok1->isStandardType())) ||
Token::Match(tok1, "%var% < %any% > ("))
else if (Token::Match(tok1, "%var% (") &&
!(Token::Match(tok1, "return|c_str|if|string") || tok1->isStandardType()))
{
if (!isConstMemberFunc(info, tok1))
{
isconst = false;
break;
}
}
else if (Token::Match(tok1, "%var% < %any% > ("))
{
isconst = false;
break;

View File

@ -305,6 +305,7 @@ private:
bool argsMatch(const Token *first, const Token *second, const std::string &path, unsigned int depth) const;
bool isMemberVar(const SpaceInfo *info, const Token *tok);
bool isConstMemberFunc(const SpaceInfo *info, const Token *tok);
bool checkConstFunc(const SpaceInfo *info, const Token *tok);
const Token *initBaseInfo(SpaceInfo *info, const Token *tok);

View File

@ -3884,8 +3884,8 @@ bool CheckOther::isIdentifierObjectType(const Token * const tok)
return found->second;
}
const std::string classDef = std::string("class|struct ") + identifier;
const bool result = Token::findmatch(_tokenizer->tokens(), classDef.c_str());
const std::string classDefnOrDecl = std::string("class|struct ") + identifier + " [{:;]";
const bool result = Token::findmatch(_tokenizer->tokens(), classDefnOrDecl.c_str()) != NULL;
isClassResults.insert(std::make_pair(identifier, result));
return result;
}
@ -3895,7 +3895,6 @@ void CheckOther::checkMisusedScopedObject()
{
bool withinFunction = false;
unsigned int depth = 0;
std::string className = "";
for (const Token *tok = _tokenizer->tokens(); tok; tok = tok->next())
{
@ -3910,17 +3909,6 @@ void CheckOther::checkMisusedScopedObject()
{
--depth;
withinFunction &= depth > 0;
if (tok->strAt(1) == ";" && !className.empty())
{
isClassResults[className] = true;
className.clear();
}
}
else if (Token::Match(tok, "class|struct"))
{
className = tok->strAt(1);
isClassResults.insert(std::make_pair(className, false));
}
if (withinFunction

View File

@ -1594,28 +1594,33 @@ void Tokenizer::simplifyTypedef()
if (arrayStart && arrayEnd)
{
tok2 = tok2->next();
Token * nextArrTok;
std::stack<Token *> arrLinks;
for (nextArrTok = arrayStart; nextArrTok != arrayEnd->next(); nextArrTok = nextArrTok->next())
do
{
tok2->insertToken(nextArrTok->strAt(0));
tok2 = tok2->next();
// Check for links and fix them up
if (tok2->str() == "(" || tok2->str() == "[")
arrLinks.push(tok2);
if (tok2->str() == ")" || tok2->str() == "]")
Token * nextArrTok;
std::stack<Token *> arrLinks;
for (nextArrTok = arrayStart; nextArrTok != arrayEnd->next(); nextArrTok = nextArrTok->next())
{
Token * link = arrLinks.top();
tok2->insertToken(nextArrTok->strAt(0));
tok2 = tok2->next();
tok2->link(link);
link->link(tok2);
// Check for links and fix them up
if (tok2->str() == "(" || tok2->str() == "[")
arrLinks.push(tok2);
if (tok2->str() == ")" || tok2->str() == "]")
{
Token * link = arrLinks.top();
arrLinks.pop();
tok2->link(link);
link->link(tok2);
arrLinks.pop();
}
}
tok2 = tok2->next();
}
tok2 = tok2->next();
while (Token::Match(tok2, ", %var% ;|'"));
}
simplifyType = false;
@ -2095,6 +2100,12 @@ void Tokenizer::arraySize()
{
for (Token *tok = _tokens; tok; tok = tok->next())
{
if (Token::Match(tok, "%var% [ ] = { %str% }"))
{
tok->tokAt(4)->deleteThis();
tok->tokAt(5)->deleteThis();
}
if (Token::Match(tok, "%var% [ ] = {"))
{
unsigned int sz = 1;

View File

@ -1688,11 +1688,25 @@ private:
void buffer_overrun_16()
{
// unknown types
check("void f() {\n"
" struct Foo foo[5];\n"
" memset(foo, 0, sizeof(foo));\n"
"}\n");
ASSERT_EQUALS("", errout.str());
check("void f() {\n" // ticket #2093
" gchar x[3];\n"
" strcpy(x, \"12\");\n"
"}\n");
ASSERT_EQUALS("", errout.str());
check("extern char a[10];\n"
"void f() {\n"
" char b[25] = {0};\n"
" std::memcpy(b, a, sizeof(a));\n"
"}\n");
ASSERT_EQUALS("", errout.str());
}
void sprintf1()

View File

@ -4130,7 +4130,7 @@ private:
" void f() const { };\n"
" void a() { f(); };\n"
"};\n");
TODO_ASSERT_EQUALS("[test.cpp:3]: (style) The function 'Fred::a' can be const\n", errout.str());
ASSERT_EQUALS("[test.cpp:3]: (style) The function 'Fred::a' can be const\n", errout.str());
// ticket #1593
checkConst("#include <vector>\n"

View File

@ -112,6 +112,7 @@ private:
TEST_CASE(testMisusedScopeObjectDoesNotPickLocalClassConstructors);
TEST_CASE(testMisusedScopeObjectDoesNotPickUsedObject);
TEST_CASE(trac2071);
TEST_CASE(trac2084);
TEST_CASE(assignmentInAssert);
}
@ -3060,6 +3061,21 @@ private:
ASSERT_EQUALS("", errout.str());
}
void trac2084()
{
check("#include <signal.h>\n"
"\n"
"void f()\n"
"{\n"
" struct sigaction sa;\n"
"\n"
" { sigaction(SIGHUP, &sa, 0); };\n"
" { sigaction(SIGINT, &sa, 0); };\n"
"}\n"
);
ASSERT_EQUALS("", errout.str());
}
void trac2071()
{
check("void f() {\n"

View File

@ -217,6 +217,7 @@ private:
TEST_CASE(simplifyTypedef59); // ticket #2011
TEST_CASE(simplifyTypedef60); // ticket #2035
TEST_CASE(simplifyTypedef61); // ticket #2074 and 2075
TEST_CASE(simplifyTypedef62); // ticket #2082
TEST_CASE(simplifyTypedefFunction1);
TEST_CASE(simplifyTypedefFunction2); // ticket #1685
@ -934,6 +935,12 @@ private:
ASSERT_EQUALS("; const char str [ 1 ] = { '1' } ; 1 ;", sizeof_(code));
}
{
// Ticket #2087
const char code[] = "; const char str[] = {\"abc\"}; sizeof(str);";
ASSERT_EQUALS("; const char str [ 4 ] = \"abc\" ; 4 ;", sizeof_(code));
}
// ticket #716 - sizeof string
{
std::ostringstream expected;
@ -4469,6 +4476,23 @@ private:
ASSERT_EQUALS("", errout.str());
}
void simplifyTypedef62() // ticket #2082
{
const char code[] = "typedef char TString[256];\n"
"void f()\n"
"{\n"
" TString a, b;\n"
"}";
// The expected tokens..
const std::string expected("; void f ( ) { char a [ 256 ] ; char b [ 256 ] ; }");
ASSERT_EQUALS(expected, sizeof_(code, false));
// Check for output..
checkSimplifyTypedef(code);
ASSERT_EQUALS("", errout.str());
}
void simplifyTypedefFunction1()
{
{

View File

@ -49,11 +49,13 @@
<Component Id='GuiHelp' Guid='*'>
<File Id='onlinehelp.qhc' Name='online-help.qhc' DiskId='1' Source='$(var.HelpDir)\online-help.qhc' KeyPath='yes' />
</Component>
<!-- Cleanup runtime files installed by previous InnoSetup installer -->
<!-- Cleanup runtime files installed by previous InnoSetup installer
Also remove old gui.exe which is now cppcheck-gui.exe -->
<Component Id='InnoSetupCleanup' Guid='4A3F299D-1EE1-468b-814B-D6577F0698CA'>
<RemoveFile Id="msvcp90.dll" On="install" Name="msvcp90.dll" />
<RemoveFile Id="msvcr90.dll" On="install" Name="msvcr90.dll" />
<RemoveFile Id="Microsoft.VC90.CRT.manifest" On="install" Name="Microsoft.VC90.CRT.manifest" />
<RemoveFile Id="gui.exe" On="install" Name="gui.exe" />
</Component>
</Directory>
<Merge Id="CRT" Language="0" SourceFile="$(var.CrtMergeModule)" DiskId="1" />

View File

@ -25,11 +25,14 @@ Building installer
Before building the installer make sure all the components are build:
- CLI executable (cppcheck.exe)
- GUI executable (gui.exe)
- Manual (manual.pdf)
- GUI executable (cppcheck-gui.exe)
- GUI translations (*.qm)
- Manual (onlinehelp.qhc)
And that runtime files are available:
- Qt runtimes (qtcore4.dll, qtgui4.dll and qtxml4.dll)
- Qt runtimes:
QtCLucene4.dll, QtCore4.dll, QtGui4.dll, QtHelp4.dll, QtNetwork4.dll,
QtSql4.dll and QtXml4.dll
- MS CRT merge module (Microsoft_VC90_CRT_x86.msm)
Build installer by giving this command line in VS command prompt (or run