Fixed #2018 (Postfix Operators)
This commit is contained in:
commit
fb928b6778
|
@ -1012,7 +1012,7 @@ void CheckBufferOverrun::checkScope(const Token *tok, const ArrayInfo &arrayInfo
|
||||||
if (Token::Match(tok, "strcpy|strcat ( %varid% , %str% )", arrayInfo.varid))
|
if (Token::Match(tok, "strcpy|strcat ( %varid% , %str% )", arrayInfo.varid))
|
||||||
{
|
{
|
||||||
const unsigned long len = Token::getStrLength(tok->tokAt(4));
|
const unsigned long len = Token::getStrLength(tok->tokAt(4));
|
||||||
if (len >= total_size)
|
if (total_size > 0 && len >= total_size)
|
||||||
{
|
{
|
||||||
bufferOverrun(tok, arrayInfo.varname);
|
bufferOverrun(tok, arrayInfo.varname);
|
||||||
continue;
|
continue;
|
||||||
|
@ -1794,7 +1794,9 @@ bool CheckBufferOverrun::ArrayInfo::declare(const Token *tok, const Tokenizer &t
|
||||||
if (!tok->isName())
|
if (!tok->isName())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
while (tok && (tok->str() == "static" || tok->str() == "const"))
|
while (tok && (tok->str() == "static" ||
|
||||||
|
tok->str() == "const" ||
|
||||||
|
tok->str() == "extern"))
|
||||||
tok = tok->next();
|
tok = tok->next();
|
||||||
|
|
||||||
int ivar = 0;
|
int ivar = 0;
|
||||||
|
|
|
@ -2139,6 +2139,37 @@ bool CheckClass::isMemberVar(const SpaceInfo *info, const Token *tok)
|
||||||
return false;
|
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)
|
bool CheckClass::checkConstFunc(const SpaceInfo *info, const Token *tok)
|
||||||
{
|
{
|
||||||
// if the function doesn't have any assignment nor function call,
|
// 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..
|
// function call..
|
||||||
else if ((Token::Match(tok1, "%var% (") &&
|
else if (Token::Match(tok1, "%var% (") &&
|
||||||
!(Token::Match(tok1, "return|c_str|if|string") || tok1->isStandardType())) ||
|
!(Token::Match(tok1, "return|c_str|if|string") || tok1->isStandardType()))
|
||||||
Token::Match(tok1, "%var% < %any% > ("))
|
{
|
||||||
|
if (!isConstMemberFunc(info, tok1))
|
||||||
|
{
|
||||||
|
isconst = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (Token::Match(tok1, "%var% < %any% > ("))
|
||||||
{
|
{
|
||||||
isconst = false;
|
isconst = false;
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -305,6 +305,7 @@ private:
|
||||||
bool argsMatch(const Token *first, const Token *second, const std::string &path, unsigned int depth) const;
|
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 isMemberVar(const SpaceInfo *info, const Token *tok);
|
||||||
|
bool isConstMemberFunc(const SpaceInfo *info, const Token *tok);
|
||||||
bool checkConstFunc(const SpaceInfo *info, const Token *tok);
|
bool checkConstFunc(const SpaceInfo *info, const Token *tok);
|
||||||
|
|
||||||
const Token *initBaseInfo(SpaceInfo *info, const Token *tok);
|
const Token *initBaseInfo(SpaceInfo *info, const Token *tok);
|
||||||
|
|
|
@ -3884,8 +3884,8 @@ bool CheckOther::isIdentifierObjectType(const Token * const tok)
|
||||||
return found->second;
|
return found->second;
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::string classDef = std::string("class|struct ") + identifier;
|
const std::string classDefnOrDecl = std::string("class|struct ") + identifier + " [{:;]";
|
||||||
const bool result = Token::findmatch(_tokenizer->tokens(), classDef.c_str());
|
const bool result = Token::findmatch(_tokenizer->tokens(), classDefnOrDecl.c_str()) != NULL;
|
||||||
isClassResults.insert(std::make_pair(identifier, result));
|
isClassResults.insert(std::make_pair(identifier, result));
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -3895,7 +3895,6 @@ void CheckOther::checkMisusedScopedObject()
|
||||||
{
|
{
|
||||||
bool withinFunction = false;
|
bool withinFunction = false;
|
||||||
unsigned int depth = 0;
|
unsigned int depth = 0;
|
||||||
std::string className = "";
|
|
||||||
|
|
||||||
for (const Token *tok = _tokenizer->tokens(); tok; tok = tok->next())
|
for (const Token *tok = _tokenizer->tokens(); tok; tok = tok->next())
|
||||||
{
|
{
|
||||||
|
@ -3910,17 +3909,6 @@ void CheckOther::checkMisusedScopedObject()
|
||||||
{
|
{
|
||||||
--depth;
|
--depth;
|
||||||
withinFunction &= depth > 0;
|
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
|
if (withinFunction
|
||||||
|
|
|
@ -1594,28 +1594,33 @@ void Tokenizer::simplifyTypedef()
|
||||||
|
|
||||||
if (arrayStart && arrayEnd)
|
if (arrayStart && arrayEnd)
|
||||||
{
|
{
|
||||||
tok2 = tok2->next();
|
do
|
||||||
Token * nextArrTok;
|
|
||||||
std::stack<Token *> arrLinks;
|
|
||||||
for (nextArrTok = arrayStart; nextArrTok != arrayEnd->next(); nextArrTok = nextArrTok->next())
|
|
||||||
{
|
{
|
||||||
tok2->insertToken(nextArrTok->strAt(0));
|
|
||||||
tok2 = tok2->next();
|
tok2 = tok2->next();
|
||||||
|
Token * nextArrTok;
|
||||||
// Check for links and fix them up
|
std::stack<Token *> arrLinks;
|
||||||
if (tok2->str() == "(" || tok2->str() == "[")
|
for (nextArrTok = arrayStart; nextArrTok != arrayEnd->next(); nextArrTok = nextArrTok->next())
|
||||||
arrLinks.push(tok2);
|
|
||||||
if (tok2->str() == ")" || tok2->str() == "]")
|
|
||||||
{
|
{
|
||||||
Token * link = arrLinks.top();
|
tok2->insertToken(nextArrTok->strAt(0));
|
||||||
|
tok2 = tok2->next();
|
||||||
|
|
||||||
tok2->link(link);
|
// Check for links and fix them up
|
||||||
link->link(tok2);
|
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;
|
simplifyType = false;
|
||||||
|
@ -2095,6 +2100,12 @@ void Tokenizer::arraySize()
|
||||||
{
|
{
|
||||||
for (Token *tok = _tokens; tok; tok = tok->next())
|
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% [ ] = {"))
|
if (Token::Match(tok, "%var% [ ] = {"))
|
||||||
{
|
{
|
||||||
unsigned int sz = 1;
|
unsigned int sz = 1;
|
||||||
|
|
|
@ -1688,11 +1688,25 @@ private:
|
||||||
|
|
||||||
void buffer_overrun_16()
|
void buffer_overrun_16()
|
||||||
{
|
{
|
||||||
|
// unknown types
|
||||||
check("void f() {\n"
|
check("void f() {\n"
|
||||||
" struct Foo foo[5];\n"
|
" struct Foo foo[5];\n"
|
||||||
" memset(foo, 0, sizeof(foo));\n"
|
" memset(foo, 0, sizeof(foo));\n"
|
||||||
"}\n");
|
"}\n");
|
||||||
ASSERT_EQUALS("", errout.str());
|
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()
|
void sprintf1()
|
||||||
|
|
|
@ -4130,7 +4130,7 @@ private:
|
||||||
" void f() const { };\n"
|
" void f() const { };\n"
|
||||||
" void a() { f(); };\n"
|
" void a() { f(); };\n"
|
||||||
"};\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
|
// ticket #1593
|
||||||
checkConst("#include <vector>\n"
|
checkConst("#include <vector>\n"
|
||||||
|
|
|
@ -112,6 +112,7 @@ private:
|
||||||
TEST_CASE(testMisusedScopeObjectDoesNotPickLocalClassConstructors);
|
TEST_CASE(testMisusedScopeObjectDoesNotPickLocalClassConstructors);
|
||||||
TEST_CASE(testMisusedScopeObjectDoesNotPickUsedObject);
|
TEST_CASE(testMisusedScopeObjectDoesNotPickUsedObject);
|
||||||
TEST_CASE(trac2071);
|
TEST_CASE(trac2071);
|
||||||
|
TEST_CASE(trac2084);
|
||||||
|
|
||||||
TEST_CASE(assignmentInAssert);
|
TEST_CASE(assignmentInAssert);
|
||||||
}
|
}
|
||||||
|
@ -3060,6 +3061,21 @@ private:
|
||||||
ASSERT_EQUALS("", errout.str());
|
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()
|
void trac2071()
|
||||||
{
|
{
|
||||||
check("void f() {\n"
|
check("void f() {\n"
|
||||||
|
|
|
@ -217,6 +217,7 @@ private:
|
||||||
TEST_CASE(simplifyTypedef59); // ticket #2011
|
TEST_CASE(simplifyTypedef59); // ticket #2011
|
||||||
TEST_CASE(simplifyTypedef60); // ticket #2035
|
TEST_CASE(simplifyTypedef60); // ticket #2035
|
||||||
TEST_CASE(simplifyTypedef61); // ticket #2074 and 2075
|
TEST_CASE(simplifyTypedef61); // ticket #2074 and 2075
|
||||||
|
TEST_CASE(simplifyTypedef62); // ticket #2082
|
||||||
|
|
||||||
TEST_CASE(simplifyTypedefFunction1);
|
TEST_CASE(simplifyTypedefFunction1);
|
||||||
TEST_CASE(simplifyTypedefFunction2); // ticket #1685
|
TEST_CASE(simplifyTypedefFunction2); // ticket #1685
|
||||||
|
@ -934,6 +935,12 @@ private:
|
||||||
ASSERT_EQUALS("; const char str [ 1 ] = { '1' } ; 1 ;", sizeof_(code));
|
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
|
// ticket #716 - sizeof string
|
||||||
{
|
{
|
||||||
std::ostringstream expected;
|
std::ostringstream expected;
|
||||||
|
@ -4469,6 +4476,23 @@ private:
|
||||||
ASSERT_EQUALS("", errout.str());
|
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()
|
void simplifyTypedefFunction1()
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
|
|
|
@ -49,11 +49,13 @@
|
||||||
<Component Id='GuiHelp' Guid='*'>
|
<Component Id='GuiHelp' Guid='*'>
|
||||||
<File Id='onlinehelp.qhc' Name='online-help.qhc' DiskId='1' Source='$(var.HelpDir)\online-help.qhc' KeyPath='yes' />
|
<File Id='onlinehelp.qhc' Name='online-help.qhc' DiskId='1' Source='$(var.HelpDir)\online-help.qhc' KeyPath='yes' />
|
||||||
</Component>
|
</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'>
|
<Component Id='InnoSetupCleanup' Guid='4A3F299D-1EE1-468b-814B-D6577F0698CA'>
|
||||||
<RemoveFile Id="msvcp90.dll" On="install" Name="msvcp90.dll" />
|
<RemoveFile Id="msvcp90.dll" On="install" Name="msvcp90.dll" />
|
||||||
<RemoveFile Id="msvcr90.dll" On="install" Name="msvcr90.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="Microsoft.VC90.CRT.manifest" On="install" Name="Microsoft.VC90.CRT.manifest" />
|
||||||
|
<RemoveFile Id="gui.exe" On="install" Name="gui.exe" />
|
||||||
</Component>
|
</Component>
|
||||||
</Directory>
|
</Directory>
|
||||||
<Merge Id="CRT" Language="0" SourceFile="$(var.CrtMergeModule)" DiskId="1" />
|
<Merge Id="CRT" Language="0" SourceFile="$(var.CrtMergeModule)" DiskId="1" />
|
||||||
|
|
|
@ -25,11 +25,14 @@ Building installer
|
||||||
|
|
||||||
Before building the installer make sure all the components are build:
|
Before building the installer make sure all the components are build:
|
||||||
- CLI executable (cppcheck.exe)
|
- CLI executable (cppcheck.exe)
|
||||||
- GUI executable (gui.exe)
|
- GUI executable (cppcheck-gui.exe)
|
||||||
- Manual (manual.pdf)
|
- GUI translations (*.qm)
|
||||||
|
- Manual (onlinehelp.qhc)
|
||||||
|
|
||||||
And that runtime files are available:
|
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)
|
- MS CRT merge module (Microsoft_VC90_CRT_x86.msm)
|
||||||
|
|
||||||
Build installer by giving this command line in VS command prompt (or run
|
Build installer by giving this command line in VS command prompt (or run
|
||||||
|
|
Loading…
Reference in New Issue