From 5f078da7adcb32385448df351cb7c557b959b780 Mon Sep 17 00:00:00 2001 From: Robert Reif Date: Fri, 7 Jan 2011 18:58:14 +0100 Subject: [PATCH 001/165] Fixed #2425 (segmentation fault of cppcheck) --- test/testclass.cpp | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/test/testclass.cpp b/test/testclass.cpp index 104f9fb36..d7acc25c7 100644 --- a/test/testclass.cpp +++ b/test/testclass.cpp @@ -184,6 +184,7 @@ private: TEST_CASE(symboldatabase6); // ticket #2221 TEST_CASE(symboldatabase7); // ticket #2230 TEST_CASE(symboldatabase8); // ticket #2252 + TEST_CASE(symboldatabase9); // ticket #2525 } // Check the operator Equal @@ -5408,6 +5409,21 @@ private: ASSERT_EQUALS("", errout.str()); } + void symboldatabase9() + { + // ticket #2425 - segmentation fault + checkConst("class CHyperlink : public CString\n" + "{\n" + "public:\n" + " const CHyperlink& operator=(LPCTSTR lpsz) {\n" + " CString::operator=(lpsz);\n" + " return *this;\n" + " }\n" + "};\n"); + + ASSERT_EQUALS("", errout.str()); + } + }; REGISTER_TEST(TestClass) From 989e0e7ccb7b77e5d5327d155128404649113e89 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Fri, 7 Jan 2011 19:48:51 +0100 Subject: [PATCH 002/165] Preprocessor: fix bug when determining location when there is a missing include. ticket: #2326 --- lib/preprocessor.cpp | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/lib/preprocessor.cpp b/lib/preprocessor.cpp index f95c4286c..43d026b16 100644 --- a/lib/preprocessor.cpp +++ b/lib/preprocessor.cpp @@ -1605,8 +1605,10 @@ void Preprocessor::handleIncludes(std::string &code, const std::string &filePath if (_errorLogger && _settings && _settings->isEnabled("missingInclude")) #endif { + std::string f = filePath; + // Determine line number of include - unsigned int linenr = 1; + unsigned int linenr = 0; unsigned int level = 0; for (std::string::size_type p = 1; p <= pos; ++p) { @@ -1620,13 +1622,16 @@ void Preprocessor::handleIncludes(std::string &code, const std::string &filePath { if (level == 0) { + const std::string::size_type pos1 = pos - p + 7; + const std::string::size_type pos2 = code.find_first_of("\"\n", pos1); + f = code.substr(pos1, (pos2 == std::string::npos) ? pos2 : (pos2 - pos1)); break; } --level; } } - missingInclude(Path::toNativeSeparators(filePath), + missingInclude(Path::toNativeSeparators(f), linenr, filename, headerType == UserHeader); From 14cbaebfe2bf898d43d20ecfebf90fbf0be08be4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Fri, 7 Jan 2011 20:45:33 +0100 Subject: [PATCH 003/165] Fixed #2428 (false alarm with code containing a throw clause) --- lib/checkexceptionsafety.cpp | 2 +- test/testexceptionsafety.cpp | 16 ++++++++++++++-- 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/lib/checkexceptionsafety.cpp b/lib/checkexceptionsafety.cpp index edee7221a..cdadcc66c 100644 --- a/lib/checkexceptionsafety.cpp +++ b/lib/checkexceptionsafety.cpp @@ -106,7 +106,7 @@ void CheckExceptionSafety::deallocThrow() bool globalVar = false; for (const Token *tok2 = _tokenizer->tokens(); tok2; tok2 = tok2->next()) { - if (tok->varId() == varid) + if (tok2->varId() == varid) { globalVar = true; break; diff --git a/test/testexceptionsafety.cpp b/test/testexceptionsafety.cpp index 52b93e1b2..9d05870c2 100644 --- a/test/testexceptionsafety.cpp +++ b/test/testexceptionsafety.cpp @@ -35,7 +35,8 @@ private: void run() { TEST_CASE(destructors); - TEST_CASE(deallocThrow); + TEST_CASE(deallocThrow1); + TEST_CASE(deallocThrow2); } void check(const std::string &code) @@ -66,7 +67,7 @@ private: ASSERT_EQUALS("[test.cpp:3]: (error) Throwing exception in destructor\n", errout.str()); } - void deallocThrow() + void deallocThrow1() { check("int * p;\n" "void f(int x)\n" @@ -78,6 +79,17 @@ private: "}\n"); ASSERT_EQUALS("[test.cpp:6]: (error) Throwing exception in invalid state, p points at deallocated memory\n", errout.str()); } + + void deallocThrow2() + { + check("void f() {\n" + " int* p = 0;\n" + " delete p;\n" + " throw 1;\n" + " p = new int;\n" + "}\n"); + ASSERT_EQUALS("", errout.str()); + } }; REGISTER_TEST(TestExceptionSafety) From d27b6a159893d89cefc40d872a16e25290273d14 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Fri, 7 Jan 2011 20:48:02 +0100 Subject: [PATCH 004/165] astyle formatting --- gui/erroritem.h | 2 +- lib/filelister_win32.cpp | 2 +- lib/preprocessor.cpp | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/gui/erroritem.h b/gui/erroritem.h index 6053aea1a..2048e2940 100644 --- a/gui/erroritem.h +++ b/gui/erroritem.h @@ -30,7 +30,7 @@ class ErrorLine; /** * @brief A class containing error data for one error. -* +* * The paths are stored with internal ("/") separators. Only when we show the * path or copy if for user (to clipboard) we convert to native separators. * Full path is stored instead of relative path for flexibility. It is easy diff --git a/lib/filelister_win32.cpp b/lib/filelister_win32.cpp index a9a8f895d..565bd579b 100644 --- a/lib/filelister_win32.cpp +++ b/lib/filelister_win32.cpp @@ -88,7 +88,7 @@ static BOOL MyIsDirectory(std::string path) return (GetFileAttributes(path.c_str()) & FILE_ATTRIBUTE_DIRECTORY); #else // See http://msdn.microsoft.com/en-us/library/bb773621(VS.85).aspx - return PathIsDirectory(path.c_str()); +return PathIsDirectory(path.c_str()); #endif } diff --git a/lib/preprocessor.cpp b/lib/preprocessor.cpp index 43d026b16..30504f218 100644 --- a/lib/preprocessor.cpp +++ b/lib/preprocessor.cpp @@ -1606,7 +1606,7 @@ void Preprocessor::handleIncludes(std::string &code, const std::string &filePath #endif { std::string f = filePath; - + // Determine line number of include unsigned int linenr = 0; unsigned int level = 0; From d7589294907f0fe12683dffc30ff24516ba95487 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Sat, 8 Jan 2011 09:23:51 +0100 Subject: [PATCH 005/165] Fixed #2433 (strtol: false positive when strtol isn't used in function call) --- lib/checkother.cpp | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/lib/checkother.cpp b/lib/checkother.cpp index 6e9101893..16528d006 100644 --- a/lib/checkother.cpp +++ b/lib/checkother.cpp @@ -338,19 +338,18 @@ void CheckOther::invalidFunctionUsage() // strtol and strtoul.. for (const Token *tok = _tokenizer->tokens(); tok; tok = tok->next()) { - if ((tok->str() != "strtol") && (tok->str() != "strtoul")) + if (!Token::Match(tok, "strtol|strtoul (")) continue; // Locate the third parameter of the function call.. - int parlevel = 0; int param = 1; - for (const Token *tok2 = tok->next(); tok2; tok2 = tok2->next()) + for (const Token *tok2 = tok->tokAt(2); tok2; tok2 = tok2->next()) { if (tok2->str() == "(") - ++parlevel; + tok2 = tok2->link(); else if (tok2->str() == ")") - --parlevel; - else if (parlevel == 1 && tok2->str() == ",") + break; + else if (tok2->str() == ",") { ++param; if (param == 3) From c39fab721db28cea94d561a900233fd099193c61 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Sat, 8 Jan 2011 10:20:29 +0100 Subject: [PATCH 006/165] Writing rules: Added one more example for the C++ intro --- man/writing-rules-3.docbook | 107 ++++++++++++++++++++++++++++++++++-- 1 file changed, 103 insertions(+), 4 deletions(-) diff --git a/man/writing-rules-3.docbook b/man/writing-rules-3.docbook index 787ff9910..29e369d98 100644 --- a/man/writing-rules-3.docbook +++ b/man/writing-rules-3.docbook @@ -73,7 +73,10 @@ void CheckOther::divisionByZero() // Report error void CheckOther::divisionByZeroError() { - reportError(tok, Severity::error, "divisionByZero", "Division by zero"); + reportError(tok, // location + Severity::error, // severity + "divisionByZero", // id + "Division by zero"); // message } The Token::Match matches tokens against @@ -111,7 +114,8 @@ void CheckOther::divisionByZeroError() if ( %var% ) { free ( %var% ) ; } - Any variable name is matched by %var%. + The %var% pattern is used to match any variable + name. Here is a C++ function: @@ -143,10 +147,105 @@ void CheckOther::dealloc() // Report warning void CheckOther::deallocWarning() { - reportError(tok, Severity::warning, "dealloc", "Redundant condition before deallocation"); + reportError(tok, // location + Severity::warning, // severity + "dealloc", // id + "Redundant condition"); // message } The strAt function is used to fetch strings from the token list. The - parameter specifies the token offset. + parameter specifies the token offset. The result for "tok->tokAt(1)" is + the same as for "tok->next()". + + +
+ Validate function parameters + + Sometimes it is known that a function can't handle certain + parameters. Here is an example rule that checks that the parameters for + strtol or strtoul are valid: + + //--------------------------------------------------------------------------- +// strtol(str, 0, radix) <- radix must be 0 or 2-36 +//--------------------------------------------------------------------------- + +void CheckOther::invalidFunctionUsage() +{ + // Loop through all tokens + for (const Token *tok = _tokenizer->tokens(); tok; tok = tok->next()) + { + // Is there a function call for strtol or strtoul? + if (!Token::Match(tok, "strtol|strtoul (")) + continue; + + // Locate the third parameter of the function call.. + + // Counter that counts the parameters. + int param = 1; + + // Scan the function call tokens. The "tok->tokAt(2)" returns + // the token after the "(" + for (const Token *tok2 = tok->tokAt(2); tok2; tok2 = tok2->next()) + { + // If a "(" is found then jump to the corresponding ")" + if (tok2->str() == "(") + tok2 = tok2->link(); + + // End of function call. + else if (tok2->str() == ")") + break; + + // Found a ",". increment param counter + else if (tok2->str() == ",") + { + ++param; + + // If the param is 3 then check if the parameter is valid + if (param == 3) + { + if (Token::Match(tok2, ", %num% )")) + { + // convert next token into a number + MathLib::bigint radix; + radix = MathLib::toLongNumber(tok2->strAt(1)); + + // invalid radix? + if (!(radix == 0 || (radix >= 2 && radix <= 36))) + { + dangerousUsageStrtolError(tok2); + } + } + break; + } + } + } + } +} + +void CheckOther::dangerousUsageStrtolError(const Token *tok) +{ + reportError(tok, // location + Severity::error, // severity + "dangerousUsageStrtol", // id + "Invalid radix"); // message +} + + The link() member function is used to find the corresponding ( ) [ ] + or { } token. + + The inner loop is not necessary if you just want to get the last + parameter. This code will check if the last parameter is + numerical.. + + .. + // Is there a function call? + if (!Token::Match(tok, "do_something (")) + continue; + + if (Token::Match(tok->next()->link()->tokAt(-2), "(|, %num% )")) + ... + + The pattern (|, can also be written as + [(,].
From 8715fef681c9452f4fbfd88d68b9d74340848ae1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Sat, 8 Jan 2011 11:10:10 +0100 Subject: [PATCH 007/165] Writing rules: minor tweak for the C++ intro --- man/writing-rules-3.docbook | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/man/writing-rules-3.docbook b/man/writing-rules-3.docbook index 29e369d98..73d35e44c 100644 --- a/man/writing-rules-3.docbook +++ b/man/writing-rules-3.docbook @@ -114,10 +114,8 @@ void CheckOther::divisionByZeroError() if ( %var% ) { free ( %var% ) ; } - The %var% pattern is used to match any variable - name. - - Here is a C++ function: + The %var% pattern match any variable name. Here + is a C++ function: // Find redundant condition before deallocation void CheckOther::dealloc() From 682aa57df4362682c0b52e182bb48a6b5d431b6e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Sat, 8 Jan 2011 11:10:33 +0100 Subject: [PATCH 008/165] buildman: build writing-rules-3.pdf --- man/buildman.sh | 3 +++ 1 file changed, 3 insertions(+) diff --git a/man/buildman.sh b/man/buildman.sh index 3f9f39a83..fec2efc4a 100755 --- a/man/buildman.sh +++ b/man/buildman.sh @@ -11,6 +11,9 @@ fop -pdf writing-rules-1.pdf -fo intermediate-fo-file.fo xsltproc --stringparam generate.toc "article nop" -o intermediate-fo-file.fo /usr/share/xml/docbook/stylesheet/nwalsh/fo/docbook.xsl writing-rules-2.docbook fop -pdf writing-rules-2.pdf -fo intermediate-fo-file.fo +xsltproc --stringparam generate.toc "article nop" -o intermediate-fo-file.fo /usr/share/xml/docbook/stylesheet/nwalsh/fo/docbook.xsl writing-rules-3.docbook +fop -pdf writing-rules-3.pdf -fo intermediate-fo-file.fo + xsltproc --stringparam generate.toc "article nop" -o intermediate-fo-file.fo /usr/share/xml/docbook/stylesheet/nwalsh/fo/docbook.xsl cppcheck-design.docbook fop -pdf cppcheck-design.pdf -fo intermediate-fo-file.fo From 67a1c6817bbbf6bc6ff48033717941f7da6f483a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Sat, 8 Jan 2011 14:35:09 +0100 Subject: [PATCH 009/165] Error message: Replace " with ' around variable name --- lib/checkmemoryleak.cpp | 2 +- test/testmemleak.cpp | 14 +++++++------- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/lib/checkmemoryleak.cpp b/lib/checkmemoryleak.cpp index b28113555..a41d56369 100644 --- a/lib/checkmemoryleak.cpp +++ b/lib/checkmemoryleak.cpp @@ -333,7 +333,7 @@ void CheckMemoryLeak::memleakError(const Token *tok, const std::string &varname) void CheckMemoryLeak::memleakUponReallocFailureError(const Token *tok, const std::string &varname) { - reportErr(tok, Severity::error, "memleakOnRealloc", "Common realloc mistake: \"" + varname + "\" nulled but not freed upon failure"); + reportErr(tok, Severity::error, "memleakOnRealloc", "Common realloc mistake: \'" + varname + "\' nulled but not freed upon failure"); } void CheckMemoryLeak::resourceLeakError(const Token *tok, const std::string &varname) diff --git a/test/testmemleak.cpp b/test/testmemleak.cpp index f94228523..9a702c135 100644 --- a/test/testmemleak.cpp +++ b/test/testmemleak.cpp @@ -1107,7 +1107,7 @@ private: " ;\n" " free(buf);\n" "}\n"); - ASSERT_EQUALS("[test.cpp:6]: (error) Common realloc mistake: \"buf\" nulled but not freed upon failure\n", errout.str()); + ASSERT_EQUALS("[test.cpp:6]: (error) Common realloc mistake: \'buf\' nulled but not freed upon failure\n", errout.str()); } void if11() @@ -1177,7 +1177,7 @@ private: " return a;\n" "}\n"); TODO_ASSERT_EQUALS("[test.cpp:10]: (error) Memory leak: a\n", errout.str()); - ASSERT_EQUALS("[test.cpp:8]: (error) Common realloc mistake: \"a\" nulled but not freed upon failure\n", errout.str()); + ASSERT_EQUALS("[test.cpp:8]: (error) Common realloc mistake: \'a\' nulled but not freed upon failure\n", errout.str()); } @@ -1198,7 +1198,7 @@ private: "\n" " return a;\n" "}\n", true); - ASSERT_EQUALS("[test.cpp:9]: (error) Common realloc mistake: \"a\" nulled but not freed upon failure\n", errout.str()); + ASSERT_EQUALS("[test.cpp:9]: (error) Common realloc mistake: \'a\' nulled but not freed upon failure\n", errout.str()); } @@ -1219,7 +1219,7 @@ private: "\n" " return a;\n" "}\n", true); - ASSERT_EQUALS("[test.cpp:9]: (error) Common realloc mistake: \"a\" nulled but not freed upon failure\n" + ASSERT_EQUALS("[test.cpp:9]: (error) Common realloc mistake: \'a\' nulled but not freed upon failure\n" "[test.cpp:11]: (error) Memory leak: a\n", errout.str()); } @@ -2033,7 +2033,7 @@ private: " char *a = (char *)malloc(10);\n" " a = realloc(a, 100);\n" "}\n"); - ASSERT_EQUALS("[test.cpp:4]: (error) Common realloc mistake: \"a\" nulled but not freed upon failure\n" + ASSERT_EQUALS("[test.cpp:4]: (error) Common realloc mistake: \'a\' nulled but not freed upon failure\n" "[test.cpp:5]: (error) Memory leak: a\n", errout.str()); } @@ -2046,7 +2046,7 @@ private: " free(a);\n" "}\n"); - ASSERT_EQUALS("[test.cpp:4]: (error) Common realloc mistake: \"a\" nulled but not freed upon failure\n", errout.str()); + ASSERT_EQUALS("[test.cpp:4]: (error) Common realloc mistake: \'a\' nulled but not freed upon failure\n", errout.str()); } void realloc3() @@ -2073,7 +2073,7 @@ private: "}\n"); TODO_ASSERT_EQUALS("[test.cpp:5]: (error) Memory leak: a\n", errout.str()); - ASSERT_EQUALS("[test.cpp:4]: (error) Common realloc mistake: \"a\" nulled but not freed upon failure\n", errout.str()); + ASSERT_EQUALS("[test.cpp:4]: (error) Common realloc mistake: \'a\' nulled but not freed upon failure\n", errout.str()); } void realloc5() From 68beffca043ba23114824ed46408e65cb0d653ec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Sat, 8 Jan 2011 17:16:52 +0100 Subject: [PATCH 010/165] Fixed #2437 (false positive: possible null pointer dereference: tok2) --- lib/checknullpointer.cpp | 2 +- test/testnullpointer.cpp | 8 ++++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/lib/checknullpointer.cpp b/lib/checknullpointer.cpp index 4bd058f45..c29c72897 100644 --- a/lib/checknullpointer.cpp +++ b/lib/checknullpointer.cpp @@ -461,7 +461,7 @@ void CheckNullPointer::nullPointerByDeRefAndChec() break; } - if (tok1->varId() == varid) + if (tok1->varId() == varid && !Token::Match(tok1->previous(), "[?:]")) { // unknown : this is set by isPointerDeRef if it is // uncertain diff --git a/test/testnullpointer.cpp b/test/testnullpointer.cpp index 7f5020339..e610ab618 100644 --- a/test/testnullpointer.cpp +++ b/test/testnullpointer.cpp @@ -397,6 +397,14 @@ private: " ;\n" "}\n"); ASSERT_EQUALS("", errout.str()); + + check("void foo(struct ABC *abc)\n" + "{\n" + " abc = abc ? abc->next : 0;\n" + " if (!abc)\n" + " ;\n" + "}\n"); + ASSERT_EQUALS("", errout.str()); } void nullpointer5() From d316f6005f289c5746a17062521a69bf16cd8f1c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Sun, 9 Jan 2011 09:29:38 +0100 Subject: [PATCH 011/165] Fixed #2409 (print a warning if provided path (commandline option -I [PATH]) does not exist) --- cli/cmdlineparser.cpp | 5 ++--- cli/cppcheckexecutor.cpp | 15 +++++++++++++++ lib/filelister.h | 5 +++++ lib/filelister_unix.cpp | 19 +++++++++++++++++++ lib/filelister_unix.h | 1 + lib/filelister_win32.cpp | 5 +++++ lib/filelister_win32.h | 1 + 7 files changed, 48 insertions(+), 3 deletions(-) diff --git a/cli/cmdlineparser.cpp b/cli/cmdlineparser.cpp index 53dc2054d..0736d356e 100644 --- a/cli/cmdlineparser.cpp +++ b/cli/cmdlineparser.cpp @@ -233,7 +233,7 @@ bool CmdLineParser::ParseFromArgs(int argc, const char* const argv[]) } // Include paths - else if (strcmp(argv[i], "-I") == 0 || strncmp(argv[i], "-I", 2) == 0) + else if (strncmp(argv[i], "-I", 2) == 0) { std::string path; @@ -252,8 +252,7 @@ bool CmdLineParser::ParseFromArgs(int argc, const char* const argv[]) // "-Ipath/" else { - path = argv[i]; - path = path.substr(2); + path = 2 + argv[i]; } // If path doesn't end with / or \, add it diff --git a/cli/cppcheckexecutor.cpp b/cli/cppcheckexecutor.cpp index ac33e8ecf..74c4e67d1 100644 --- a/cli/cppcheckexecutor.cpp +++ b/cli/cppcheckexecutor.cpp @@ -56,6 +56,21 @@ bool CppCheckExecutor::parseFromArgs(CppCheck *cppcheck, int argc, const char* c } } + // Check that all include paths exist + { + std::list::const_iterator iter; + for (iter = _settings._includePaths.begin(); + iter != _settings._includePaths.end(); + ++iter) + { + if (!getFileLister()->isDirectory(iter->c_str())) + { + std::cout << "cppcheck: error: Couldn't find path given by -I '" + *iter + "'" << std::endl; + return false; + } + } + } + std::vector pathnames = parser.GetPathNames(); std::vector filenames; diff --git a/lib/filelister.h b/lib/filelister.h index 7a09b1662..40432752a 100644 --- a/lib/filelister.h +++ b/lib/filelister.h @@ -66,6 +66,11 @@ public: */ virtual bool acceptFile(const std::string &filename); + /** + * @brief Is given path a directory? + * @return returns true if the path is a directory + */ + virtual bool isDirectory(const std::string &path) = 0; }; /** @brief get filelister (platform dependent implementation) */ diff --git a/lib/filelister_unix.cpp b/lib/filelister_unix.cpp index dc71425b3..f430417ad 100644 --- a/lib/filelister_unix.cpp +++ b/lib/filelister_unix.cpp @@ -103,4 +103,23 @@ bool FileListerUnix::sameFileName(const std::string &fname1, const std::string & #endif } +bool FileListerUnix::isDirectory(const std::string &path) +{ + bool ret = false; + + glob_t glob_results; + glob(path.c_str(), GLOB_MARK, 0, &glob_results); + if (glob_results.gl_pathc == 1) + { + const std::string glob_path = glob_results.gl_pathv[0]; + if (!glob_path.empty() && glob_path[glob_path.size() - 1] == '/') + { + ret = true; + } + } + globfree(&glob_results); + + return ret; +} + #endif // _WIN32 diff --git a/lib/filelister_unix.h b/lib/filelister_unix.h index 7effade0a..c04f9e8bf 100644 --- a/lib/filelister_unix.h +++ b/lib/filelister_unix.h @@ -33,6 +33,7 @@ public: virtual void recursiveAddFiles(std::vector &filenames, const std::string &path); virtual bool sameFileName(const std::string &fname1, const std::string &fname2); // virtual static bool acceptFile(const std::string &filename); + virtual bool isDirectory(const std::string &path); private: #ifndef _WIN32 void recursiveAddFiles2(std::vector &relative, diff --git a/lib/filelister_win32.cpp b/lib/filelister_win32.cpp index 565bd579b..c32ee4d0d 100644 --- a/lib/filelister_win32.cpp +++ b/lib/filelister_win32.cpp @@ -205,4 +205,9 @@ bool FileListerWin32::sameFileName(const std::string &fname1, const std::string #endif } +bool FileListerWin32::isDirectory(const std::string &path) +{ + return (MyIsDirectory(path) != FALSE); +} + #endif // _WIN32 diff --git a/lib/filelister_win32.h b/lib/filelister_win32.h index 9f0cb1264..21c7f48ab 100644 --- a/lib/filelister_win32.h +++ b/lib/filelister_win32.h @@ -32,6 +32,7 @@ class FileListerWin32 : public FileLister public: virtual void recursiveAddFiles(std::vector &filenames, const std::string &path); virtual bool sameFileName(const std::string &fname1, const std::string &fname2); + virtual bool isDirectory(const std::string &path); private: }; From 88abb32ddf65602eb9e9de38002acb8f0236d581 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Sun, 9 Jan 2011 10:09:54 +0100 Subject: [PATCH 012/165] Fixed #2429 (Tokenizer: Wrong simplification of 'sizeof .1250E+04') --- lib/tokenize.cpp | 5 +++++ test/testtokenize.cpp | 7 +++++++ 2 files changed, 12 insertions(+) diff --git a/lib/tokenize.cpp b/lib/tokenize.cpp index 6c963dbec..d00e70bcc 100644 --- a/lib/tokenize.cpp +++ b/lib/tokenize.cpp @@ -361,6 +361,11 @@ void Tokenizer::createTokens(std::istream &code) { // Don't separate doubles "4.2e+10" } + else if (CurrentToken.empty() && ch == '.' && std::isdigit(code.peek())) + { + // tokenize .125 into 0.125 + CurrentToken = "0"; + } else if (ch=='&' && CurrentToken.empty() && code.peek() == '&') { // && diff --git a/test/testtokenize.cpp b/test/testtokenize.cpp index 18db0f6fb..590d7ebb9 100644 --- a/test/testtokenize.cpp +++ b/test/testtokenize.cpp @@ -52,6 +52,7 @@ private: TEST_CASE(tokenize12); TEST_CASE(tokenize13); // bailout if the code contains "@" - that is not handled well. TEST_CASE(tokenize14); // tokenize "0X10" => 16 + TEST_CASE(tokenize15); // tokenize ".123" // don't freak out when the syntax is wrong TEST_CASE(wrong_syntax); @@ -490,6 +491,12 @@ private: ASSERT_EQUALS("; 16 ;", tokenizeAndStringify(";0x10;")); ASSERT_EQUALS("; 16 ;", tokenizeAndStringify(";0X10;")); } + + // Ticket #2429: 0.125 + void tokenize15() + { + ASSERT_EQUALS("0.125", tokenizeAndStringify(".125")); + } void wrong_syntax() { From 0b0c46e3732f7435df3d15219fcc0a8fda43a43e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Sun, 9 Jan 2011 18:39:59 +0100 Subject: [PATCH 013/165] astyle formatting --- test/testtokenize.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/testtokenize.cpp b/test/testtokenize.cpp index 590d7ebb9..d89875625 100644 --- a/test/testtokenize.cpp +++ b/test/testtokenize.cpp @@ -491,7 +491,7 @@ private: ASSERT_EQUALS("; 16 ;", tokenizeAndStringify(";0x10;")); ASSERT_EQUALS("; 16 ;", tokenizeAndStringify(";0X10;")); } - + // Ticket #2429: 0.125 void tokenize15() { From 79ef02812dd27c3502d8a763aa2dc08c5f715a66 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Sun, 9 Jan 2011 18:51:28 +0100 Subject: [PATCH 014/165] Fixed #2211 (false negative: buffer access out of bounds for(int i=0; i !=6;i++)) --- lib/checkbufferoverrun.cpp | 8 ++++++-- test/testbufferoverrun.cpp | 12 ++++++++++++ 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/lib/checkbufferoverrun.cpp b/lib/checkbufferoverrun.cpp index 3fecabf11..d117d77e6 100644 --- a/lib/checkbufferoverrun.cpp +++ b/lib/checkbufferoverrun.cpp @@ -289,7 +289,9 @@ static const Token *for_init(const Token *tok, unsigned int &varid, std::string /** Parse for condition */ static bool for_condition(const Token * const tok2, unsigned int varid, std::string &min_value, std::string &max_value, std::string &strindex, bool &maxMinFlipped) { - if (Token::Match(tok2, "%varid% < %num% ;", varid)) + if (Token::Match(tok2, "%varid% < %num% ;", varid) || + Token::Match(tok2, "%varid% != %num% ; ++ %varid%", varid) || + Token::Match(tok2, "%varid% != %num% ; %varid% ++", varid)) { maxMinFlipped = false; const MathLib::bigint value = MathLib::toLongNumber(tok2->strAt(2)); @@ -300,7 +302,9 @@ static bool for_condition(const Token * const tok2, unsigned int varid, std::str maxMinFlipped = false; max_value = tok2->strAt(2); } - else if (Token::Match(tok2, " %num% < %varid% ;", varid)) + else if (Token::Match(tok2, " %num% < %varid% ;", varid) || + Token::Match(tok2, "%num% != %varid% ; ++ %varid%", varid) || + Token::Match(tok2, "%num% != %varid% ; %varid% ++", varid)) { maxMinFlipped = true; const MathLib::bigint value = MathLib::toLongNumber(tok2->str()); diff --git a/test/testbufferoverrun.cpp b/test/testbufferoverrun.cpp index 34794dbb6..10d32105e 100644 --- a/test/testbufferoverrun.cpp +++ b/test/testbufferoverrun.cpp @@ -114,6 +114,7 @@ private: TEST_CASE(array_index_varnames); // FP: struct member. #1576 TEST_CASE(array_index_for_break); // FP: for,break TEST_CASE(array_index_for); // FN: for,if + TEST_CASE(array_index_for_neq); // #2211: Using != in condition TEST_CASE(buffer_overrun_1); TEST_CASE(buffer_overrun_2); @@ -1355,6 +1356,17 @@ private: ASSERT_EQUALS("", errout.str()); } + void array_index_for_neq() + { + // Ticket #2211 - for loop using != in the condition + check("void f() {\n" + " int a[5];\n" + " for (int i = 0; i != 10; ++i) {\n" + " a[i] = 0;\n" + " }\n" + "}"); + ASSERT_EQUALS("[test.cpp:4]: (error) Buffer access out-of-bounds: a\n", errout.str()); + } void buffer_overrun_1() { From 2848abbf368d9932354fb68fcc5856407d97c018 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Sun, 9 Jan 2011 20:16:16 +0100 Subject: [PATCH 015/165] Fixed #1219 (improve check: null pointer not detected 'if (p) return; *p = 0;') --- lib/checknullpointer.cpp | 17 ++++++++++++++++- test/testnullpointer.cpp | 9 +++++++++ 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/lib/checknullpointer.cpp b/lib/checknullpointer.cpp index c29c72897..e3f2a9341 100644 --- a/lib/checknullpointer.cpp +++ b/lib/checknullpointer.cpp @@ -526,6 +526,9 @@ void CheckNullPointer::nullPointerByCheckAndDeRef() vartok = tok->tokAt(4); else if (Token::Match(tok, "if ( %var% == NULL|0 ) {")) vartok = tok->tokAt(2); + else if (Token::Match(tok, "if|while ( %var% ) {") && + !Token::simpleMatch(tok->tokAt(4)->link(), "} else")) + vartok = tok->tokAt(2); else continue; @@ -541,12 +544,24 @@ void CheckNullPointer::nullPointerByCheckAndDeRef() // if this is true then it is known that the pointer is null bool null = true; + // start token = inside the if-body + const Token *tok1 = tok->next()->link()->tokAt(2); + + if (Token::Match(tok, "if|while ( %var% )")) + { + // pointer might be null + null = false; + + // start token = first token after the if/while body + tok1 = tok1->previous()->link()->next(); + } + // Name of the pointer const std::string &pointerName = vartok->str(); // Count { and } for tok2 unsigned int indentlevel = 1; - for (const Token *tok2 = tok->next()->link()->tokAt(2); tok2; tok2 = tok2->next()) + for (const Token *tok2 = tok1; tok2; tok2 = tok2->next()) { if (tok2->str() == "{") ++indentlevel; diff --git a/test/testnullpointer.cpp b/test/testnullpointer.cpp index e610ab618..c86ac8518 100644 --- a/test/testnullpointer.cpp +++ b/test/testnullpointer.cpp @@ -818,6 +818,15 @@ private: " }\n" "}\n"); ASSERT_EQUALS("", errout.str()); + + // ticket #1219 + check("void foo(char *p) {\n" + " if (p) {\n" + " return;\n" + " }\n" + " *p = 0;\n" + "}\n"); + ASSERT_EQUALS("[test.cpp:5]: (error) Possible null pointer dereference: p\n", errout.str()); } // Test CheckNullPointer::nullConstantDereference From 226b605774679c6155d805f73eb5901ef7748f49 Mon Sep 17 00:00:00 2001 From: Reijo Tomperi Date: Sun, 9 Jan 2011 21:33:36 +0200 Subject: [PATCH 016/165] Change year 2010 -> 2011 in license texts. --- cli/cmdlineparser.cpp | 2 +- cli/cmdlineparser.h | 2 +- cli/cppcheckexecutor.cpp | 2 +- cli/cppcheckexecutor.h | 2 +- cli/main.cpp | 2 +- cli/threadexecutor.cpp | 2 +- cli/threadexecutor.h | 2 +- gui/aboutdialog.cpp | 2 +- gui/aboutdialog.h | 2 +- gui/applicationdialog.cpp | 2 +- gui/applicationdialog.h | 2 +- gui/applicationlist.cpp | 2 +- gui/applicationlist.h | 2 +- gui/checkstatistics.cpp | 2 +- gui/checkstatistics.h | 2 +- gui/checkthread.cpp | 2 +- gui/checkthread.h | 2 +- gui/common.h | 2 +- gui/csvreport.cpp | 2 +- gui/csvreport.h | 2 +- gui/erroritem.cpp | 2 +- gui/erroritem.h | 2 +- gui/filelist.cpp | 2 +- gui/filelist.h | 2 +- gui/fileviewdialog.cpp | 2 +- gui/fileviewdialog.h | 2 +- gui/helpwindow.cpp | 2 +- gui/helpwindow.h | 2 +- gui/logview.cpp | 2 +- gui/logview.h | 2 +- gui/main.cpp | 2 +- gui/mainwindow.cpp | 2 +- gui/mainwindow.h | 2 +- gui/project.cpp | 2 +- gui/project.h | 2 +- gui/projectfile.cpp | 2 +- gui/projectfile.h | 2 +- gui/projectfiledialog.cpp | 2 +- gui/projectfiledialog.h | 2 +- gui/report.cpp | 2 +- gui/report.h | 2 +- gui/resultstree.cpp | 2 +- gui/resultstree.h | 2 +- gui/resultsview.cpp | 2 +- gui/resultsview.h | 2 +- gui/settingsdialog.cpp | 2 +- gui/settingsdialog.h | 2 +- gui/statsdialog.cpp | 2 +- gui/statsdialog.h | 2 +- gui/threadhandler.cpp | 2 +- gui/threadhandler.h | 2 +- gui/threadresult.cpp | 2 +- gui/threadresult.h | 2 +- gui/translationhandler.cpp | 2 +- gui/translationhandler.h | 2 +- gui/txtreport.cpp | 2 +- gui/txtreport.h | 2 +- gui/xmlreport.cpp | 2 +- gui/xmlreport.h | 2 +- lib/check.h | 2 +- lib/checkautovariables.cpp | 2 +- lib/checkautovariables.h | 2 +- lib/checkbufferoverrun.cpp | 2 +- lib/checkbufferoverrun.h | 2 +- lib/checkclass.cpp | 2 +- lib/checkclass.h | 2 +- lib/checkexceptionsafety.cpp | 2 +- lib/checkexceptionsafety.h | 2 +- lib/checkmemoryleak.cpp | 2 +- lib/checkmemoryleak.h | 2 +- lib/checknullpointer.cpp | 2 +- lib/checknullpointer.h | 2 +- lib/checkobsoletefunctions.cpp | 2 +- lib/checkobsoletefunctions.h | 2 +- lib/checkother.cpp | 2 +- lib/checkother.h | 2 +- lib/checkpostfixoperator.cpp | 2 +- lib/checkpostfixoperator.h | 2 +- lib/checkstl.cpp | 2 +- lib/checkstl.h | 2 +- lib/checkuninitvar.cpp | 2 +- lib/checkuninitvar.h | 2 +- lib/checkunusedfunctions.cpp | 2 +- lib/checkunusedfunctions.h | 2 +- lib/cppcheck.cpp | 2 +- lib/cppcheck.h | 2 +- lib/errorlogger.cpp | 2 +- lib/errorlogger.h | 2 +- lib/executionpath.cpp | 2 +- lib/executionpath.h | 2 +- lib/filelister.cpp | 2 +- lib/filelister.h | 2 +- lib/filelister_unix.cpp | 2 +- lib/filelister_unix.h | 2 +- lib/filelister_win32.cpp | 2 +- lib/filelister_win32.h | 2 +- lib/mathlib.cpp | 2 +- lib/mathlib.h | 2 +- lib/path.cpp | 2 +- lib/path.h | 2 +- lib/preprocessor.cpp | 2 +- lib/preprocessor.h | 2 +- lib/settings.cpp | 2 +- lib/settings.h | 2 +- lib/symboldatabase.cpp | 2 +- lib/symboldatabase.h | 2 +- lib/timer.cpp | 2 +- lib/timer.h | 2 +- lib/token.cpp | 2 +- lib/token.h | 2 +- lib/tokenize.cpp | 2 +- lib/tokenize.h | 2 +- man/cppcheck.1.xml | 2 +- test/testautovariables.cpp | 2 +- test/testbufferoverrun.cpp | 2 +- test/testcharvar.cpp | 2 +- test/testclass.cpp | 2 +- test/testcmdlineparser.cpp | 2 +- test/testconstructors.cpp | 2 +- test/testcppcheck.cpp | 2 +- test/testdivision.cpp | 2 +- test/testerrorlogger.cpp | 2 +- test/testexceptionsafety.cpp | 2 +- test/testfilelister_unix.cpp | 2 +- test/testincompletestatement.cpp | 2 +- test/testmathlib.cpp | 2 +- test/testmemleak.cpp | 2 +- test/testnullpointer.cpp | 2 +- test/testobsoletefunctions.cpp | 2 +- test/testother.cpp | 2 +- test/testpath.cpp | 2 +- test/testpostfixoperator.cpp | 2 +- test/testpreprocessor.cpp | 2 +- test/testrunner.cpp | 2 +- test/testsettings.cpp | 2 +- test/testsimplifytokens.cpp | 2 +- test/teststl.cpp | 2 +- test/testsuite.cpp | 2 +- test/testsuite.h | 2 +- test/testsymboldatabase.cpp | 2 +- test/testthreadexecutor.cpp | 2 +- test/testtoken.cpp | 2 +- test/testtokenize.cpp | 2 +- test/testuninitvar.cpp | 2 +- test/testunusedfunctions.cpp | 2 +- test/testunusedprivfunc.cpp | 2 +- test/testunusedvar.cpp | 2 +- test/testutils.h | 2 +- tools/dmake.cpp | 2 +- 149 files changed, 149 insertions(+), 149 deletions(-) diff --git a/cli/cmdlineparser.cpp b/cli/cmdlineparser.cpp index 0736d356e..b35a411e3 100644 --- a/cli/cmdlineparser.cpp +++ b/cli/cmdlineparser.cpp @@ -1,6 +1,6 @@ /* * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2010 Daniel Marjamäki and Cppcheck team. + * Copyright (C) 2007-2011 Daniel Marjamäki and Cppcheck team. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/cli/cmdlineparser.h b/cli/cmdlineparser.h index 7a1b428d7..60fccb93b 100644 --- a/cli/cmdlineparser.h +++ b/cli/cmdlineparser.h @@ -1,6 +1,6 @@ /* * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2010 Daniel Marjamäki and Cppcheck team. + * Copyright (C) 2007-2011 Daniel Marjamäki and Cppcheck team. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/cli/cppcheckexecutor.cpp b/cli/cppcheckexecutor.cpp index 74c4e67d1..661c1a9ab 100644 --- a/cli/cppcheckexecutor.cpp +++ b/cli/cppcheckexecutor.cpp @@ -1,6 +1,6 @@ /* * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2010 Daniel Marjamäki and Cppcheck team. + * Copyright (C) 2007-2011 Daniel Marjamäki and Cppcheck team. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/cli/cppcheckexecutor.h b/cli/cppcheckexecutor.h index 35ab42a31..b1cf6d48e 100644 --- a/cli/cppcheckexecutor.h +++ b/cli/cppcheckexecutor.h @@ -1,6 +1,6 @@ /* * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2010 Daniel Marjamäki and Cppcheck team. + * Copyright (C) 2007-2011 Daniel Marjamäki and Cppcheck team. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/cli/main.cpp b/cli/main.cpp index bef2ea0b8..1f1a31b0a 100644 --- a/cli/main.cpp +++ b/cli/main.cpp @@ -1,6 +1,6 @@ /* * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2010 Daniel Marjamäki and Cppcheck team. + * Copyright (C) 2007-2011 Daniel Marjamäki and Cppcheck team. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/cli/threadexecutor.cpp b/cli/threadexecutor.cpp index f1dd97aa5..c4119876d 100644 --- a/cli/threadexecutor.cpp +++ b/cli/threadexecutor.cpp @@ -1,6 +1,6 @@ /* * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2010 Daniel Marjamäki and Cppcheck team. + * Copyright (C) 2007-2011 Daniel Marjamäki and Cppcheck team. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/cli/threadexecutor.h b/cli/threadexecutor.h index a7122e27b..44238f5e9 100644 --- a/cli/threadexecutor.h +++ b/cli/threadexecutor.h @@ -1,6 +1,6 @@ /* * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2010 Daniel Marjamäki and Cppcheck team. + * Copyright (C) 2007-2011 Daniel Marjamäki and Cppcheck team. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/gui/aboutdialog.cpp b/gui/aboutdialog.cpp index 58e20c588..f21bc5495 100644 --- a/gui/aboutdialog.cpp +++ b/gui/aboutdialog.cpp @@ -1,6 +1,6 @@ /* * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2010 Daniel Marjamäki and Cppcheck team. + * Copyright (C) 2007-2011 Daniel Marjamäki and Cppcheck team. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/gui/aboutdialog.h b/gui/aboutdialog.h index 17d7021bc..6e08358a1 100644 --- a/gui/aboutdialog.h +++ b/gui/aboutdialog.h @@ -1,6 +1,6 @@ /* * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2010 Daniel Marjamäki and Cppcheck team. + * Copyright (C) 2007-2011 Daniel Marjamäki and Cppcheck team. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/gui/applicationdialog.cpp b/gui/applicationdialog.cpp index 4474de07f..ecaeb9691 100644 --- a/gui/applicationdialog.cpp +++ b/gui/applicationdialog.cpp @@ -1,6 +1,6 @@ /* * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2010 Daniel Marjamäki and Cppcheck team. + * Copyright (C) 2007-2011 Daniel Marjamäki and Cppcheck team. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/gui/applicationdialog.h b/gui/applicationdialog.h index 803b5b88e..0cb697fa8 100644 --- a/gui/applicationdialog.h +++ b/gui/applicationdialog.h @@ -1,6 +1,6 @@ /* * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2010 Daniel Marjamäki and Cppcheck team. + * Copyright (C) 2007-2011 Daniel Marjamäki and Cppcheck team. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/gui/applicationlist.cpp b/gui/applicationlist.cpp index 214a7b29e..090733c7a 100644 --- a/gui/applicationlist.cpp +++ b/gui/applicationlist.cpp @@ -1,6 +1,6 @@ /* * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2010 Daniel Marjamäki and Cppcheck team. + * Copyright (C) 2007-2011 Daniel Marjamäki and Cppcheck team. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/gui/applicationlist.h b/gui/applicationlist.h index 44f539ebe..2cbc19156 100644 --- a/gui/applicationlist.h +++ b/gui/applicationlist.h @@ -1,6 +1,6 @@ /* * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2010 Daniel Marjamäki and Cppcheck team. + * Copyright (C) 2007-2011 Daniel Marjamäki and Cppcheck team. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/gui/checkstatistics.cpp b/gui/checkstatistics.cpp index c9807c8c8..4f031e5c8 100644 --- a/gui/checkstatistics.cpp +++ b/gui/checkstatistics.cpp @@ -1,6 +1,6 @@ /* * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2010 Daniel Marjamäki and Cppcheck team. + * Copyright (C) 2007-2011 Daniel Marjamäki and Cppcheck team. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/gui/checkstatistics.h b/gui/checkstatistics.h index 38b5d5fcf..f21b84643 100644 --- a/gui/checkstatistics.h +++ b/gui/checkstatistics.h @@ -1,6 +1,6 @@ /* * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2010 Daniel Marjamäki and Cppcheck team. + * Copyright (C) 2007-2011 Daniel Marjamäki and Cppcheck team. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/gui/checkthread.cpp b/gui/checkthread.cpp index d0bfe7987..724228ded 100644 --- a/gui/checkthread.cpp +++ b/gui/checkthread.cpp @@ -1,6 +1,6 @@ /* * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2010 Daniel Marjamäki and Cppcheck team. + * Copyright (C) 2007-2011 Daniel Marjamäki and Cppcheck team. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/gui/checkthread.h b/gui/checkthread.h index 24ed0bd03..bb5d73c2d 100644 --- a/gui/checkthread.h +++ b/gui/checkthread.h @@ -1,6 +1,6 @@ /* * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2010 Daniel Marjamäki and Cppcheck team. + * Copyright (C) 2007-2011 Daniel Marjamäki and Cppcheck team. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/gui/common.h b/gui/common.h index 483eac7e0..7f3b5669b 100644 --- a/gui/common.h +++ b/gui/common.h @@ -1,6 +1,6 @@ /* * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2010 Daniel Marjamäki and Cppcheck team. + * Copyright (C) 2007-2011 Daniel Marjamäki and Cppcheck team. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/gui/csvreport.cpp b/gui/csvreport.cpp index 28b6ee3a2..a9016e42e 100644 --- a/gui/csvreport.cpp +++ b/gui/csvreport.cpp @@ -1,6 +1,6 @@ /* * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2010 Daniel Marjamäki and Cppcheck team. + * Copyright (C) 2007-2011 Daniel Marjamäki and Cppcheck team. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/gui/csvreport.h b/gui/csvreport.h index 5661a03d5..5994bba7e 100644 --- a/gui/csvreport.h +++ b/gui/csvreport.h @@ -1,6 +1,6 @@ /* * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2010 Daniel Marjamäki and Cppcheck team. + * Copyright (C) 2007-2011 Daniel Marjamäki and Cppcheck team. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/gui/erroritem.cpp b/gui/erroritem.cpp index 1fa03e43b..35506c697 100644 --- a/gui/erroritem.cpp +++ b/gui/erroritem.cpp @@ -1,6 +1,6 @@ /* * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2010 Daniel Marjamäki and Cppcheck team. + * Copyright (C) 2007-2011 Daniel Marjamäki and Cppcheck team. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/gui/erroritem.h b/gui/erroritem.h index 2048e2940..c6b36b7c3 100644 --- a/gui/erroritem.h +++ b/gui/erroritem.h @@ -1,6 +1,6 @@ /* * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2010 Daniel Marjamäki and Cppcheck team. + * Copyright (C) 2007-2011 Daniel Marjamäki and Cppcheck team. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/gui/filelist.cpp b/gui/filelist.cpp index d24b8fc52..cc1580904 100644 --- a/gui/filelist.cpp +++ b/gui/filelist.cpp @@ -1,6 +1,6 @@ /* * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2010 Daniel Marjamäki and Cppcheck team. + * Copyright (C) 2007-2011 Daniel Marjamäki and Cppcheck team. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/gui/filelist.h b/gui/filelist.h index b71589f6f..1a1818408 100644 --- a/gui/filelist.h +++ b/gui/filelist.h @@ -1,6 +1,6 @@ /* * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2010 Daniel Marjamäki and Cppcheck team. + * Copyright (C) 2007-2011 Daniel Marjamäki and Cppcheck team. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/gui/fileviewdialog.cpp b/gui/fileviewdialog.cpp index 5106ee9c2..066930704 100644 --- a/gui/fileviewdialog.cpp +++ b/gui/fileviewdialog.cpp @@ -1,6 +1,6 @@ /* * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2010 Daniel Marjamäki and Cppcheck team. + * Copyright (C) 2007-2011 Daniel Marjamäki and Cppcheck team. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/gui/fileviewdialog.h b/gui/fileviewdialog.h index 876bf3e00..4fe67b754 100644 --- a/gui/fileviewdialog.h +++ b/gui/fileviewdialog.h @@ -1,6 +1,6 @@ /* * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2010 Daniel Marjamäki and Cppcheck team. + * Copyright (C) 2007-2011 Daniel Marjamäki and Cppcheck team. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/gui/helpwindow.cpp b/gui/helpwindow.cpp index 484887c83..d3e3f249f 100644 --- a/gui/helpwindow.cpp +++ b/gui/helpwindow.cpp @@ -1,6 +1,6 @@ /* * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2010 Daniel Marjamäki and Cppcheck team. + * Copyright (C) 2007-2011 Daniel Marjamäki and Cppcheck team. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/gui/helpwindow.h b/gui/helpwindow.h index 1b9067477..8bb224bed 100644 --- a/gui/helpwindow.h +++ b/gui/helpwindow.h @@ -1,6 +1,6 @@ /* * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2010 Daniel Marjamäki and Cppcheck team. + * Copyright (C) 2007-2011 Daniel Marjamäki and Cppcheck team. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/gui/logview.cpp b/gui/logview.cpp index 817f55b7a..ca11929d7 100644 --- a/gui/logview.cpp +++ b/gui/logview.cpp @@ -1,6 +1,6 @@ /* * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2010 Daniel Marjamäki and Cppcheck team. + * Copyright (C) 2007-2011 Daniel Marjamäki and Cppcheck team. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/gui/logview.h b/gui/logview.h index 5f36b3540..c84ba6805 100644 --- a/gui/logview.h +++ b/gui/logview.h @@ -1,6 +1,6 @@ /* * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2010 Daniel Marjamäki and Cppcheck team. + * Copyright (C) 2007-2011 Daniel Marjamäki and Cppcheck team. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/gui/main.cpp b/gui/main.cpp index 93f60e006..fbc709744 100644 --- a/gui/main.cpp +++ b/gui/main.cpp @@ -1,6 +1,6 @@ /* * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2010 Daniel Marjamäki and Cppcheck team. + * Copyright (C) 2007-2011 Daniel Marjamäki and Cppcheck team. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/gui/mainwindow.cpp b/gui/mainwindow.cpp index 13d0f14a4..9eede6b97 100644 --- a/gui/mainwindow.cpp +++ b/gui/mainwindow.cpp @@ -1,6 +1,6 @@ /* * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2010 Daniel Marjamäki and Cppcheck team. + * Copyright (C) 2007-2011 Daniel Marjamäki and Cppcheck team. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/gui/mainwindow.h b/gui/mainwindow.h index c84cda2b6..781bd91ac 100644 --- a/gui/mainwindow.h +++ b/gui/mainwindow.h @@ -1,6 +1,6 @@ /* * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2010 Daniel Marjamäki and Cppcheck team. + * Copyright (C) 2007-2011 Daniel Marjamäki and Cppcheck team. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/gui/project.cpp b/gui/project.cpp index b8676bd3b..963fcfeee 100644 --- a/gui/project.cpp +++ b/gui/project.cpp @@ -1,6 +1,6 @@ /* * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2010 Daniel Marjamäki and Cppcheck team. + * Copyright (C) 2007-2011 Daniel Marjamäki and Cppcheck team. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/gui/project.h b/gui/project.h index 984764c7b..5d0945164 100644 --- a/gui/project.h +++ b/gui/project.h @@ -1,6 +1,6 @@ /* * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2010 Daniel Marjamäki and Cppcheck team. + * Copyright (C) 2007-2011 Daniel Marjamäki and Cppcheck team. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/gui/projectfile.cpp b/gui/projectfile.cpp index d6c6e5037..abd82ebcd 100644 --- a/gui/projectfile.cpp +++ b/gui/projectfile.cpp @@ -1,6 +1,6 @@ /* * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2010 Daniel Marjamäki and Cppcheck team. + * Copyright (C) 2007-2011 Daniel Marjamäki and Cppcheck team. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/gui/projectfile.h b/gui/projectfile.h index 2243a7c20..23496c90c 100644 --- a/gui/projectfile.h +++ b/gui/projectfile.h @@ -1,6 +1,6 @@ /* * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2010 Daniel Marjamäki and Cppcheck team. + * Copyright (C) 2007-2011 Daniel Marjamäki and Cppcheck team. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/gui/projectfiledialog.cpp b/gui/projectfiledialog.cpp index e24603983..2eaddf2d3 100644 --- a/gui/projectfiledialog.cpp +++ b/gui/projectfiledialog.cpp @@ -1,6 +1,6 @@ /* * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2010 Daniel Marjamäki and Cppcheck team. + * Copyright (C) 2007-2011 Daniel Marjamäki and Cppcheck team. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/gui/projectfiledialog.h b/gui/projectfiledialog.h index 440e58ddc..acfd45667 100644 --- a/gui/projectfiledialog.h +++ b/gui/projectfiledialog.h @@ -1,6 +1,6 @@ /* * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2010 Daniel Marjamäki and Cppcheck team. + * Copyright (C) 2007-2011 Daniel Marjamäki and Cppcheck team. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/gui/report.cpp b/gui/report.cpp index 34300a780..3ea7445f6 100644 --- a/gui/report.cpp +++ b/gui/report.cpp @@ -1,6 +1,6 @@ /* * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2010 Daniel Marjamäki and Cppcheck team. + * Copyright (C) 2007-2011 Daniel Marjamäki and Cppcheck team. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/gui/report.h b/gui/report.h index 83a22e148..681bdecf6 100644 --- a/gui/report.h +++ b/gui/report.h @@ -1,6 +1,6 @@ /* * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2010 Daniel Marjamäki and Cppcheck team. + * Copyright (C) 2007-2011 Daniel Marjamäki and Cppcheck team. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/gui/resultstree.cpp b/gui/resultstree.cpp index a46bedd59..a54f1757f 100644 --- a/gui/resultstree.cpp +++ b/gui/resultstree.cpp @@ -1,6 +1,6 @@ /* * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2010 Daniel Marjamäki and Cppcheck team. + * Copyright (C) 2007-2011 Daniel Marjamäki and Cppcheck team. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/gui/resultstree.h b/gui/resultstree.h index f6a1802e8..8dbd7e0a7 100644 --- a/gui/resultstree.h +++ b/gui/resultstree.h @@ -1,6 +1,6 @@ /* * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2010 Daniel Marjamäki and Cppcheck team. + * Copyright (C) 2007-2011 Daniel Marjamäki and Cppcheck team. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/gui/resultsview.cpp b/gui/resultsview.cpp index 47c56ff7b..ab1234f46 100644 --- a/gui/resultsview.cpp +++ b/gui/resultsview.cpp @@ -1,6 +1,6 @@ /* * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2010 Daniel Marjamäki and Cppcheck team. + * Copyright (C) 2007-2011 Daniel Marjamäki and Cppcheck team. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/gui/resultsview.h b/gui/resultsview.h index 3b70b5420..69973a07d 100644 --- a/gui/resultsview.h +++ b/gui/resultsview.h @@ -1,6 +1,6 @@ /* * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2010 Daniel Marjamäki and Cppcheck team. + * Copyright (C) 2007-2011 Daniel Marjamäki and Cppcheck team. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/gui/settingsdialog.cpp b/gui/settingsdialog.cpp index 9cdfa30c5..4563b2b27 100644 --- a/gui/settingsdialog.cpp +++ b/gui/settingsdialog.cpp @@ -1,6 +1,6 @@ /* * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2010 Daniel Marjamäki and Cppcheck team. + * Copyright (C) 2007-2011 Daniel Marjamäki and Cppcheck team. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/gui/settingsdialog.h b/gui/settingsdialog.h index 650cd30db..d97591f7c 100644 --- a/gui/settingsdialog.h +++ b/gui/settingsdialog.h @@ -1,6 +1,6 @@ /* * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2010 Daniel Marjamäki and Cppcheck team. + * Copyright (C) 2007-2011 Daniel Marjamäki and Cppcheck team. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/gui/statsdialog.cpp b/gui/statsdialog.cpp index 8ffa779a0..b33b3268b 100644 --- a/gui/statsdialog.cpp +++ b/gui/statsdialog.cpp @@ -1,6 +1,6 @@ /* * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2010 Daniel Marjamäki and Cppcheck team. + * Copyright (C) 2007-2011 Daniel Marjamäki and Cppcheck team. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/gui/statsdialog.h b/gui/statsdialog.h index 6bd4a0cb5..341a9d6f1 100644 --- a/gui/statsdialog.h +++ b/gui/statsdialog.h @@ -1,6 +1,6 @@ /* * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2010 Daniel Marjamäki and Cppcheck team. + * Copyright (C) 2007-2011 Daniel Marjamäki and Cppcheck team. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/gui/threadhandler.cpp b/gui/threadhandler.cpp index acb7ea90a..05529a544 100644 --- a/gui/threadhandler.cpp +++ b/gui/threadhandler.cpp @@ -1,6 +1,6 @@ /* * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2010 Daniel Marjamäki and Cppcheck team. + * Copyright (C) 2007-2011 Daniel Marjamäki and Cppcheck team. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/gui/threadhandler.h b/gui/threadhandler.h index 38a3c1da1..35ead6ed2 100644 --- a/gui/threadhandler.h +++ b/gui/threadhandler.h @@ -1,6 +1,6 @@ /* * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2010 Daniel Marjamäki and Cppcheck team. + * Copyright (C) 2007-2011 Daniel Marjamäki and Cppcheck team. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/gui/threadresult.cpp b/gui/threadresult.cpp index 5d8963096..7a92481c4 100644 --- a/gui/threadresult.cpp +++ b/gui/threadresult.cpp @@ -1,6 +1,6 @@ /* * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2010 Daniel Marjamäki and Cppcheck team. + * Copyright (C) 2007-2011 Daniel Marjamäki and Cppcheck team. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/gui/threadresult.h b/gui/threadresult.h index 27200efb5..170bc19f1 100644 --- a/gui/threadresult.h +++ b/gui/threadresult.h @@ -1,6 +1,6 @@ /* * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2010 Daniel Marjamäki and Cppcheck team. + * Copyright (C) 2007-2011 Daniel Marjamäki and Cppcheck team. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/gui/translationhandler.cpp b/gui/translationhandler.cpp index 17493d4bc..7b9e6e46d 100644 --- a/gui/translationhandler.cpp +++ b/gui/translationhandler.cpp @@ -1,6 +1,6 @@ /* * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2010 Daniel Marjamäki and Cppcheck team. + * Copyright (C) 2007-2011 Daniel Marjamäki and Cppcheck team. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/gui/translationhandler.h b/gui/translationhandler.h index 5b80fb867..e84fb67ab 100644 --- a/gui/translationhandler.h +++ b/gui/translationhandler.h @@ -1,6 +1,6 @@ /* * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2010 Daniel Marjamäki and Cppcheck team. + * Copyright (C) 2007-2011 Daniel Marjamäki and Cppcheck team. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/gui/txtreport.cpp b/gui/txtreport.cpp index 52b7efeba..a6f8dbe4b 100644 --- a/gui/txtreport.cpp +++ b/gui/txtreport.cpp @@ -1,6 +1,6 @@ /* * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2010 Daniel Marjamäki and Cppcheck team. + * Copyright (C) 2007-2011 Daniel Marjamäki and Cppcheck team. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/gui/txtreport.h b/gui/txtreport.h index 8dab58622..a42ac53a9 100644 --- a/gui/txtreport.h +++ b/gui/txtreport.h @@ -1,6 +1,6 @@ /* * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2010 Daniel Marjamäki and Cppcheck team. + * Copyright (C) 2007-2011 Daniel Marjamäki and Cppcheck team. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/gui/xmlreport.cpp b/gui/xmlreport.cpp index 31b92dc23..c82478055 100644 --- a/gui/xmlreport.cpp +++ b/gui/xmlreport.cpp @@ -1,6 +1,6 @@ /* * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2010 Daniel Marjamäki and Cppcheck team. + * Copyright (C) 2007-2011 Daniel Marjamäki and Cppcheck team. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/gui/xmlreport.h b/gui/xmlreport.h index f850707c3..0c8058dd0 100644 --- a/gui/xmlreport.h +++ b/gui/xmlreport.h @@ -1,6 +1,6 @@ /* * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2010 Daniel Marjamäki and Cppcheck team. + * Copyright (C) 2007-2011 Daniel Marjamäki and Cppcheck team. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/lib/check.h b/lib/check.h index 45bf07bf8..c11eb8f5d 100644 --- a/lib/check.h +++ b/lib/check.h @@ -1,6 +1,6 @@ /* * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2010 Daniel Marjamäki and Cppcheck team. + * Copyright (C) 2007-2011 Daniel Marjamäki and Cppcheck team. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/lib/checkautovariables.cpp b/lib/checkautovariables.cpp index b1f1e33f9..b24020435 100644 --- a/lib/checkautovariables.cpp +++ b/lib/checkautovariables.cpp @@ -1,6 +1,6 @@ /* * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2010 Daniel Marjamäki and Cppcheck team. + * Copyright (C) 2007-2011 Daniel Marjamäki and Cppcheck team. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/lib/checkautovariables.h b/lib/checkautovariables.h index 974659989..97df17ccf 100644 --- a/lib/checkautovariables.h +++ b/lib/checkautovariables.h @@ -1,6 +1,6 @@ /* * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2010 Daniel Marjamäki and Cppcheck team. + * Copyright (C) 2007-2011 Daniel Marjamäki and Cppcheck team. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/lib/checkbufferoverrun.cpp b/lib/checkbufferoverrun.cpp index d117d77e6..aa18d193d 100644 --- a/lib/checkbufferoverrun.cpp +++ b/lib/checkbufferoverrun.cpp @@ -1,6 +1,6 @@ /* * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2010 Daniel Marjamäki and Cppcheck team. + * Copyright (C) 2007-2011 Daniel Marjamäki and Cppcheck team. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/lib/checkbufferoverrun.h b/lib/checkbufferoverrun.h index 81006cc99..5f3b964b8 100644 --- a/lib/checkbufferoverrun.h +++ b/lib/checkbufferoverrun.h @@ -1,6 +1,6 @@ /* * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2010 Daniel Marjamäki and Cppcheck team. + * Copyright (C) 2007-2011 Daniel Marjamäki and Cppcheck team. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/lib/checkclass.cpp b/lib/checkclass.cpp index f1092b332..69e77ed48 100644 --- a/lib/checkclass.cpp +++ b/lib/checkclass.cpp @@ -1,6 +1,6 @@ /* * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2010 Daniel Marjamäki and Cppcheck team. + * Copyright (C) 2007-2011 Daniel Marjamäki and Cppcheck team. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/lib/checkclass.h b/lib/checkclass.h index 5ec791224..42603cf0e 100644 --- a/lib/checkclass.h +++ b/lib/checkclass.h @@ -1,6 +1,6 @@ /* * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2010 Daniel Marjamäki and Cppcheck team. + * Copyright (C) 2007-2011 Daniel Marjamäki and Cppcheck team. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/lib/checkexceptionsafety.cpp b/lib/checkexceptionsafety.cpp index cdadcc66c..0c3757dee 100644 --- a/lib/checkexceptionsafety.cpp +++ b/lib/checkexceptionsafety.cpp @@ -1,6 +1,6 @@ /* * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2010 Daniel Marjamäki and Cppcheck team. + * Copyright (C) 2007-2011 Daniel Marjamäki and Cppcheck team. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/lib/checkexceptionsafety.h b/lib/checkexceptionsafety.h index f17607d88..584cf78d6 100644 --- a/lib/checkexceptionsafety.h +++ b/lib/checkexceptionsafety.h @@ -1,6 +1,6 @@ /* * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2010 Daniel Marjamäki and Cppcheck team. + * Copyright (C) 2007-2011 Daniel Marjamäki and Cppcheck team. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/lib/checkmemoryleak.cpp b/lib/checkmemoryleak.cpp index a41d56369..c004edc05 100644 --- a/lib/checkmemoryleak.cpp +++ b/lib/checkmemoryleak.cpp @@ -1,6 +1,6 @@ /* * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2010 Daniel Marjamäki and Cppcheck team. + * Copyright (C) 2007-2011 Daniel Marjamäki and Cppcheck team. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/lib/checkmemoryleak.h b/lib/checkmemoryleak.h index 109b40316..75abc8bab 100644 --- a/lib/checkmemoryleak.h +++ b/lib/checkmemoryleak.h @@ -1,6 +1,6 @@ /* * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2010 Daniel Marjamäki and Cppcheck team. + * Copyright (C) 2007-2011 Daniel Marjamäki and Cppcheck team. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/lib/checknullpointer.cpp b/lib/checknullpointer.cpp index e3f2a9341..171af1cc3 100644 --- a/lib/checknullpointer.cpp +++ b/lib/checknullpointer.cpp @@ -1,6 +1,6 @@ /* * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2010 Daniel Marjamäki and Cppcheck team. + * Copyright (C) 2007-2011 Daniel Marjamäki and Cppcheck team. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/lib/checknullpointer.h b/lib/checknullpointer.h index 05c9b747d..70927e70f 100644 --- a/lib/checknullpointer.h +++ b/lib/checknullpointer.h @@ -1,6 +1,6 @@ /* * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2010 Daniel Marjamäki and Cppcheck team. + * Copyright (C) 2007-2011 Daniel Marjamäki and Cppcheck team. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/lib/checkobsoletefunctions.cpp b/lib/checkobsoletefunctions.cpp index f68d5eb78..f347fea34 100644 --- a/lib/checkobsoletefunctions.cpp +++ b/lib/checkobsoletefunctions.cpp @@ -1,6 +1,6 @@ /* * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2010 Daniel Marjamäki and Cppcheck team. + * Copyright (C) 2007-2011 Daniel Marjamäki and Cppcheck team. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/lib/checkobsoletefunctions.h b/lib/checkobsoletefunctions.h index 621db0a78..3ee4f88f3 100644 --- a/lib/checkobsoletefunctions.h +++ b/lib/checkobsoletefunctions.h @@ -1,6 +1,6 @@ /* * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2010 Daniel Marjamäki and Cppcheck team. + * Copyright (C) 2007-2011 Daniel Marjamäki and Cppcheck team. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/lib/checkother.cpp b/lib/checkother.cpp index 16528d006..ffae9e671 100644 --- a/lib/checkother.cpp +++ b/lib/checkother.cpp @@ -1,6 +1,6 @@ /* * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2010 Daniel Marjamäki and Cppcheck team. + * Copyright (C) 2007-2011 Daniel Marjamäki and Cppcheck team. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/lib/checkother.h b/lib/checkother.h index ee6909cdb..a26dc2ae9 100644 --- a/lib/checkother.h +++ b/lib/checkother.h @@ -1,6 +1,6 @@ /* * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2010 Daniel Marjamäki and Cppcheck team. + * Copyright (C) 2007-2011 Daniel Marjamäki and Cppcheck team. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/lib/checkpostfixoperator.cpp b/lib/checkpostfixoperator.cpp index 3503f33a7..2861926c2 100644 --- a/lib/checkpostfixoperator.cpp +++ b/lib/checkpostfixoperator.cpp @@ -1,6 +1,6 @@ /* * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2010 Daniel Marjamäki and Cppcheck team. + * Copyright (C) 2007-2011 Daniel Marjamäki and Cppcheck team. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/lib/checkpostfixoperator.h b/lib/checkpostfixoperator.h index eee5ad021..2840df19e 100644 --- a/lib/checkpostfixoperator.h +++ b/lib/checkpostfixoperator.h @@ -1,6 +1,6 @@ /* * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2010 Daniel Marjamäki and Cppcheck team. + * Copyright (C) 2007-2011 Daniel Marjamäki and Cppcheck team. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/lib/checkstl.cpp b/lib/checkstl.cpp index 10855cc44..91bfd0dfa 100644 --- a/lib/checkstl.cpp +++ b/lib/checkstl.cpp @@ -1,6 +1,6 @@ /* * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2010 Daniel Marjamäki and Cppcheck team. + * Copyright (C) 2007-2011 Daniel Marjamäki and Cppcheck team. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/lib/checkstl.h b/lib/checkstl.h index 896dfbdda..e232eedcd 100644 --- a/lib/checkstl.h +++ b/lib/checkstl.h @@ -1,6 +1,6 @@ /* * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2010 Daniel Marjamäki and Cppcheck team. + * Copyright (C) 2007-2011 Daniel Marjamäki and Cppcheck team. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/lib/checkuninitvar.cpp b/lib/checkuninitvar.cpp index 83e74f9d7..62b1ac33e 100644 --- a/lib/checkuninitvar.cpp +++ b/lib/checkuninitvar.cpp @@ -1,6 +1,6 @@ /* * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2010 Daniel Marjamäki and Cppcheck team. + * Copyright (C) 2007-2011 Daniel Marjamäki and Cppcheck team. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/lib/checkuninitvar.h b/lib/checkuninitvar.h index dd643c75c..78465d821 100644 --- a/lib/checkuninitvar.h +++ b/lib/checkuninitvar.h @@ -1,6 +1,6 @@ /* * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2010 Daniel Marjamäki and Cppcheck team. + * Copyright (C) 2007-2011 Daniel Marjamäki and Cppcheck team. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/lib/checkunusedfunctions.cpp b/lib/checkunusedfunctions.cpp index 1f0c01673..be2dce990 100644 --- a/lib/checkunusedfunctions.cpp +++ b/lib/checkunusedfunctions.cpp @@ -1,6 +1,6 @@ /* * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2010 Daniel Marjamäki and Cppcheck team. + * Copyright (C) 2007-2011 Daniel Marjamäki and Cppcheck team. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/lib/checkunusedfunctions.h b/lib/checkunusedfunctions.h index d64fa7944..066faafd6 100644 --- a/lib/checkunusedfunctions.h +++ b/lib/checkunusedfunctions.h @@ -1,6 +1,6 @@ /* * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2010 Daniel Marjamäki and Cppcheck team. + * Copyright (C) 2007-2011 Daniel Marjamäki and Cppcheck team. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/lib/cppcheck.cpp b/lib/cppcheck.cpp index 915ec0c44..fb2bebb6f 100644 --- a/lib/cppcheck.cpp +++ b/lib/cppcheck.cpp @@ -1,6 +1,6 @@ /* * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2010 Daniel Marjamäki and Cppcheck team. + * Copyright (C) 2007-2011 Daniel Marjamäki and Cppcheck team. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/lib/cppcheck.h b/lib/cppcheck.h index a5e8d3c20..18a81d1db 100644 --- a/lib/cppcheck.h +++ b/lib/cppcheck.h @@ -1,6 +1,6 @@ /* * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2010 Daniel Marjamäki and Cppcheck team. + * Copyright (C) 2007-2011 Daniel Marjamäki and Cppcheck team. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/lib/errorlogger.cpp b/lib/errorlogger.cpp index bd558f690..6f4baa90f 100644 --- a/lib/errorlogger.cpp +++ b/lib/errorlogger.cpp @@ -1,6 +1,6 @@ /* * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2010 Daniel Marjamäki and Cppcheck team. + * Copyright (C) 2007-2011 Daniel Marjamäki and Cppcheck team. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/lib/errorlogger.h b/lib/errorlogger.h index d1c756667..da68ba499 100644 --- a/lib/errorlogger.h +++ b/lib/errorlogger.h @@ -1,6 +1,6 @@ /* * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2010 Daniel Marjamäki and Cppcheck team. + * Copyright (C) 2007-2011 Daniel Marjamäki and Cppcheck team. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/lib/executionpath.cpp b/lib/executionpath.cpp index 02fcd79a6..fad18cc58 100644 --- a/lib/executionpath.cpp +++ b/lib/executionpath.cpp @@ -1,6 +1,6 @@ /* * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2010 Daniel Marjamäki and Cppcheck team. + * Copyright (C) 2007-2011 Daniel Marjamäki and Cppcheck team. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/lib/executionpath.h b/lib/executionpath.h index e501be1d1..bc296f4e7 100644 --- a/lib/executionpath.h +++ b/lib/executionpath.h @@ -1,6 +1,6 @@ /* * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2010 Daniel Marjamäki and Cppcheck team. + * Copyright (C) 2007-2011 Daniel Marjamäki and Cppcheck team. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/lib/filelister.cpp b/lib/filelister.cpp index 6f474c927..2c15d92dd 100644 --- a/lib/filelister.cpp +++ b/lib/filelister.cpp @@ -1,6 +1,6 @@ /* * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2010 Daniel Marjamäki and Cppcheck team. + * Copyright (C) 2007-2011 Daniel Marjamäki and Cppcheck team. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/lib/filelister.h b/lib/filelister.h index 40432752a..40eef61ea 100644 --- a/lib/filelister.h +++ b/lib/filelister.h @@ -1,6 +1,6 @@ /* * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2010 Daniel Marjamäki and Cppcheck team. + * Copyright (C) 2007-2011 Daniel Marjamäki and Cppcheck team. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/lib/filelister_unix.cpp b/lib/filelister_unix.cpp index f430417ad..12d179910 100644 --- a/lib/filelister_unix.cpp +++ b/lib/filelister_unix.cpp @@ -1,6 +1,6 @@ /* * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2010 Daniel Marjamäki and Cppcheck team. + * Copyright (C) 2007-2011 Daniel Marjamäki and Cppcheck team. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/lib/filelister_unix.h b/lib/filelister_unix.h index c04f9e8bf..7fab425b4 100644 --- a/lib/filelister_unix.h +++ b/lib/filelister_unix.h @@ -1,6 +1,6 @@ /* * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2010 Daniel Marjamäki and Cppcheck team. + * Copyright (C) 2007-2011 Daniel Marjamäki and Cppcheck team. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/lib/filelister_win32.cpp b/lib/filelister_win32.cpp index c32ee4d0d..9581d3fd3 100644 --- a/lib/filelister_win32.cpp +++ b/lib/filelister_win32.cpp @@ -1,6 +1,6 @@ /* * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2010 Daniel Marjamäki and Cppcheck team. + * Copyright (C) 2007-2011 Daniel Marjamäki and Cppcheck team. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/lib/filelister_win32.h b/lib/filelister_win32.h index 21c7f48ab..2d6948145 100644 --- a/lib/filelister_win32.h +++ b/lib/filelister_win32.h @@ -1,6 +1,6 @@ /* * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2010 Daniel Marjamäki and Cppcheck team. + * Copyright (C) 2007-2011 Daniel Marjamäki and Cppcheck team. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/lib/mathlib.cpp b/lib/mathlib.cpp index 353a0258a..a047718da 100644 --- a/lib/mathlib.cpp +++ b/lib/mathlib.cpp @@ -1,6 +1,6 @@ /* * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2010 Daniel Marjamäki and Cppcheck team. + * Copyright (C) 2007-2011 Daniel Marjamäki and Cppcheck team. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/lib/mathlib.h b/lib/mathlib.h index b4bf5d0d5..9c7f414fa 100644 --- a/lib/mathlib.h +++ b/lib/mathlib.h @@ -1,6 +1,6 @@ /* * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2010 Daniel Marjamäki and Cppcheck team. + * Copyright (C) 2007-2011 Daniel Marjamäki and Cppcheck team. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/lib/path.cpp b/lib/path.cpp index a0eceb852..cf8383116 100644 --- a/lib/path.cpp +++ b/lib/path.cpp @@ -1,6 +1,6 @@ /* * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2010 Daniel Marjamäki and Cppcheck team. + * Copyright (C) 2007-2011 Daniel Marjamäki and Cppcheck team. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/lib/path.h b/lib/path.h index 0c0c6ae04..ce8143a29 100644 --- a/lib/path.h +++ b/lib/path.h @@ -1,6 +1,6 @@ /* * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2010 Daniel Marjamäki and Cppcheck team. + * Copyright (C) 2007-2011 Daniel Marjamäki and Cppcheck team. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/lib/preprocessor.cpp b/lib/preprocessor.cpp index 30504f218..5f5b4ff44 100644 --- a/lib/preprocessor.cpp +++ b/lib/preprocessor.cpp @@ -1,6 +1,6 @@ /* * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2010 Daniel Marjamäki and Cppcheck team. + * Copyright (C) 2007-2011 Daniel Marjamäki and Cppcheck team. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/lib/preprocessor.h b/lib/preprocessor.h index 6cdaebb5f..2d9bc14cb 100644 --- a/lib/preprocessor.h +++ b/lib/preprocessor.h @@ -1,6 +1,6 @@ /* * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2010 Daniel Marjamäki and Cppcheck team. + * Copyright (C) 2007-2011 Daniel Marjamäki and Cppcheck team. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/lib/settings.cpp b/lib/settings.cpp index bb748aaed..e0fc89257 100644 --- a/lib/settings.cpp +++ b/lib/settings.cpp @@ -1,6 +1,6 @@ /* * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2010 Daniel Marjamäki and Cppcheck team. + * Copyright (C) 2007-2011 Daniel Marjamäki and Cppcheck team. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/lib/settings.h b/lib/settings.h index c89a44166..c6bec4336 100644 --- a/lib/settings.h +++ b/lib/settings.h @@ -1,6 +1,6 @@ /* * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2010 Daniel Marjamäki and Cppcheck team. + * Copyright (C) 2007-2011 Daniel Marjamäki and Cppcheck team. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/lib/symboldatabase.cpp b/lib/symboldatabase.cpp index 375c5df6a..78708c0c9 100644 --- a/lib/symboldatabase.cpp +++ b/lib/symboldatabase.cpp @@ -1,6 +1,6 @@ /* * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2010 Daniel Marjamäki and Cppcheck team. + * Copyright (C) 2007-2011 Daniel Marjamäki and Cppcheck team. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/lib/symboldatabase.h b/lib/symboldatabase.h index a13a4d53f..9cce2a422 100644 --- a/lib/symboldatabase.h +++ b/lib/symboldatabase.h @@ -1,6 +1,6 @@ /* * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2010 Daniel Marjamäki and Cppcheck team. + * Copyright (C) 2007-2011 Daniel Marjamäki and Cppcheck team. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/lib/timer.cpp b/lib/timer.cpp index 598fa3952..08ae011ef 100644 --- a/lib/timer.cpp +++ b/lib/timer.cpp @@ -1,6 +1,6 @@ /* * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2010 Daniel Marjamäki and Cppcheck team. + * Copyright (C) 2007-2011 Daniel Marjamäki and Cppcheck team. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/lib/timer.h b/lib/timer.h index a88a334d7..50a24ff60 100644 --- a/lib/timer.h +++ b/lib/timer.h @@ -1,6 +1,6 @@ /* * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2010 Daniel Marjamäki and Cppcheck team. + * Copyright (C) 2007-2011 Daniel Marjamäki and Cppcheck team. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/lib/token.cpp b/lib/token.cpp index 5e1ce97a6..f874d1f8e 100644 --- a/lib/token.cpp +++ b/lib/token.cpp @@ -1,6 +1,6 @@ /* * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2010 Daniel Marjamäki and Cppcheck team. + * Copyright (C) 2007-2011 Daniel Marjamäki and Cppcheck team. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/lib/token.h b/lib/token.h index eb61846ce..769ac4467 100644 --- a/lib/token.h +++ b/lib/token.h @@ -1,6 +1,6 @@ /* * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2010 Daniel Marjamäki and Cppcheck team. + * Copyright (C) 2007-2011 Daniel Marjamäki and Cppcheck team. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/lib/tokenize.cpp b/lib/tokenize.cpp index d00e70bcc..0ac6e1d63 100644 --- a/lib/tokenize.cpp +++ b/lib/tokenize.cpp @@ -1,6 +1,6 @@ /* * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2010 Daniel Marjamäki and Cppcheck team. + * Copyright (C) 2007-2011 Daniel Marjamäki and Cppcheck team. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/lib/tokenize.h b/lib/tokenize.h index 2ececdee8..749d836c2 100644 --- a/lib/tokenize.h +++ b/lib/tokenize.h @@ -1,6 +1,6 @@ /* * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2010 Daniel Marjamäki and Cppcheck team. + * Copyright (C) 2007-2011 Daniel Marjamäki and Cppcheck team. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/man/cppcheck.1.xml b/man/cppcheck.1.xml index ec4a810e0..4b3a5dde7 100644 --- a/man/cppcheck.1.xml +++ b/man/cppcheck.1.xml @@ -76,7 +76,7 @@ man(1), man(7), http://www.tldp.org/HOWTO/Man-Page/ - 2009 - 2010 + 2009 - 2011 &dhusername; diff --git a/test/testautovariables.cpp b/test/testautovariables.cpp index ba11a7d9c..1c0824526 100644 --- a/test/testautovariables.cpp +++ b/test/testautovariables.cpp @@ -1,6 +1,6 @@ /* * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2010 Daniel Marjamäki and Cppcheck team. + * Copyright (C) 2007-2011 Daniel Marjamäki and Cppcheck team. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/test/testbufferoverrun.cpp b/test/testbufferoverrun.cpp index 10d32105e..02aa9281d 100644 --- a/test/testbufferoverrun.cpp +++ b/test/testbufferoverrun.cpp @@ -1,6 +1,6 @@ /* * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2010 Daniel Marjamäki and Cppcheck team. + * Copyright (C) 2007-2011 Daniel Marjamäki and Cppcheck team. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/test/testcharvar.cpp b/test/testcharvar.cpp index d8d0d7236..eca41b59c 100644 --- a/test/testcharvar.cpp +++ b/test/testcharvar.cpp @@ -1,6 +1,6 @@ /* * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2010 Daniel Marjamäki and Cppcheck team. + * Copyright (C) 2007-2011 Daniel Marjamäki and Cppcheck team. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/test/testclass.cpp b/test/testclass.cpp index d7acc25c7..1d5d48f12 100644 --- a/test/testclass.cpp +++ b/test/testclass.cpp @@ -1,6 +1,6 @@ /* * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2010 Daniel Marjamäki and Cppcheck team. + * Copyright (C) 2007-2011 Daniel Marjamäki and Cppcheck team. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/test/testcmdlineparser.cpp b/test/testcmdlineparser.cpp index 70d83ccda..6d45d09bb 100644 --- a/test/testcmdlineparser.cpp +++ b/test/testcmdlineparser.cpp @@ -1,6 +1,6 @@ /* * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2010 Daniel Marjamäki and Cppcheck team. + * Copyright (C) 2007-2011 Daniel Marjamäki and Cppcheck team. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/test/testconstructors.cpp b/test/testconstructors.cpp index 2272a078d..826baff02 100644 --- a/test/testconstructors.cpp +++ b/test/testconstructors.cpp @@ -1,6 +1,6 @@ /* * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2010 Daniel Marjamäki and Cppcheck team. + * Copyright (C) 2007-2011 Daniel Marjamäki and Cppcheck team. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/test/testcppcheck.cpp b/test/testcppcheck.cpp index e9918265d..341d90bb9 100644 --- a/test/testcppcheck.cpp +++ b/test/testcppcheck.cpp @@ -1,6 +1,6 @@ /* * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2010 Daniel Marjamäki and Cppcheck team. + * Copyright (C) 2007-2011 Daniel Marjamäki and Cppcheck team. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/test/testdivision.cpp b/test/testdivision.cpp index 456bf877d..6757a4a2f 100644 --- a/test/testdivision.cpp +++ b/test/testdivision.cpp @@ -1,6 +1,6 @@ /* * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2010 Daniel Marjamäki and Cppcheck team. + * Copyright (C) 2007-2011 Daniel Marjamäki and Cppcheck team. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/test/testerrorlogger.cpp b/test/testerrorlogger.cpp index 69024baa6..e1064464b 100644 --- a/test/testerrorlogger.cpp +++ b/test/testerrorlogger.cpp @@ -1,6 +1,6 @@ /* * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2010 Daniel Marjamäki and Cppcheck team. + * Copyright (C) 2007-2011 Daniel Marjamäki and Cppcheck team. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/test/testexceptionsafety.cpp b/test/testexceptionsafety.cpp index 9d05870c2..a94f9b5b0 100644 --- a/test/testexceptionsafety.cpp +++ b/test/testexceptionsafety.cpp @@ -1,6 +1,6 @@ /* * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2010 Daniel Marjamäki and Cppcheck team. + * Copyright (C) 2007-2011 Daniel Marjamäki and Cppcheck team. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/test/testfilelister_unix.cpp b/test/testfilelister_unix.cpp index f68f5ba27..86b038cec 100644 --- a/test/testfilelister_unix.cpp +++ b/test/testfilelister_unix.cpp @@ -1,6 +1,6 @@ /* * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2010 Daniel Marjamäki and Cppcheck team. + * Copyright (C) 2007-2011 Daniel Marjamäki and Cppcheck team. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/test/testincompletestatement.cpp b/test/testincompletestatement.cpp index 6fe2a2a35..bd7a6d8cb 100644 --- a/test/testincompletestatement.cpp +++ b/test/testincompletestatement.cpp @@ -1,6 +1,6 @@ /* * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2010 Daniel Marjamäki and Cppcheck team. + * Copyright (C) 2007-2011 Daniel Marjamäki and Cppcheck team. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/test/testmathlib.cpp b/test/testmathlib.cpp index 155dec47c..f05a029bc 100644 --- a/test/testmathlib.cpp +++ b/test/testmathlib.cpp @@ -1,6 +1,6 @@ /* * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2010 Daniel Marjamäki and Cppcheck team. + * Copyright (C) 2007-2011 Daniel Marjamäki and Cppcheck team. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/test/testmemleak.cpp b/test/testmemleak.cpp index 9a702c135..05b04e3c4 100644 --- a/test/testmemleak.cpp +++ b/test/testmemleak.cpp @@ -1,6 +1,6 @@ /* * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2010 Daniel Marjamäki and Cppcheck team. + * Copyright (C) 2007-2011 Daniel Marjamäki and Cppcheck team. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/test/testnullpointer.cpp b/test/testnullpointer.cpp index c86ac8518..b1fcc4e7e 100644 --- a/test/testnullpointer.cpp +++ b/test/testnullpointer.cpp @@ -1,6 +1,6 @@ /* * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2010 Daniel Marjamäki and Cppcheck team. + * Copyright (C) 2007-2011 Daniel Marjamäki and Cppcheck team. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/test/testobsoletefunctions.cpp b/test/testobsoletefunctions.cpp index 7013d9816..760e46222 100644 --- a/test/testobsoletefunctions.cpp +++ b/test/testobsoletefunctions.cpp @@ -1,6 +1,6 @@ /* * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2010 Daniel Marjamäki and Cppcheck team. + * Copyright (C) 2007-2011 Daniel Marjamäki and Cppcheck team. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/test/testother.cpp b/test/testother.cpp index 7992a2849..35e4e5e2a 100644 --- a/test/testother.cpp +++ b/test/testother.cpp @@ -1,6 +1,6 @@ /* * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2010 Daniel Marjamäki and Cppcheck team. + * Copyright (C) 2007-2011 Daniel Marjamäki and Cppcheck team. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/test/testpath.cpp b/test/testpath.cpp index c21823cfb..c52251b41 100644 --- a/test/testpath.cpp +++ b/test/testpath.cpp @@ -1,6 +1,6 @@ /* * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2010 Daniel Marjamäki and Cppcheck team. + * Copyright (C) 2007-2011 Daniel Marjamäki and Cppcheck team. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/test/testpostfixoperator.cpp b/test/testpostfixoperator.cpp index 52d707df7..2970537eb 100644 --- a/test/testpostfixoperator.cpp +++ b/test/testpostfixoperator.cpp @@ -1,6 +1,6 @@ /* * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2010 Daniel Marjamäki and Cppcheck team. + * Copyright (C) 2007-2011 Daniel Marjamäki and Cppcheck team. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/test/testpreprocessor.cpp b/test/testpreprocessor.cpp index d67eb6c87..4a49ce42a 100644 --- a/test/testpreprocessor.cpp +++ b/test/testpreprocessor.cpp @@ -1,6 +1,6 @@ /* * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2010 Daniel Marjamäki and Cppcheck team. + * Copyright (C) 2007-2011 Daniel Marjamäki and Cppcheck team. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/test/testrunner.cpp b/test/testrunner.cpp index b47163821..83821f695 100644 --- a/test/testrunner.cpp +++ b/test/testrunner.cpp @@ -1,6 +1,6 @@ /* * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2010 Daniel Marjamäki and Cppcheck team. + * Copyright (C) 2007-2011 Daniel Marjamäki and Cppcheck team. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/test/testsettings.cpp b/test/testsettings.cpp index b09e1dced..28e242543 100644 --- a/test/testsettings.cpp +++ b/test/testsettings.cpp @@ -1,6 +1,6 @@ /* * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2010 Daniel Marjamäki and Cppcheck team. + * Copyright (C) 2007-2011 Daniel Marjamäki and Cppcheck team. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/test/testsimplifytokens.cpp b/test/testsimplifytokens.cpp index dc19bb1ab..17e6e6c7b 100644 --- a/test/testsimplifytokens.cpp +++ b/test/testsimplifytokens.cpp @@ -1,6 +1,6 @@ /* * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2010 Daniel Marjamäki and Cppcheck team. + * Copyright (C) 2007-2011 Daniel Marjamäki and Cppcheck team. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/test/teststl.cpp b/test/teststl.cpp index 700456a6f..aeabd69fa 100644 --- a/test/teststl.cpp +++ b/test/teststl.cpp @@ -1,6 +1,6 @@ /* * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2010 Daniel Marjamäki and Cppcheck team. + * Copyright (C) 2007-2011 Daniel Marjamäki and Cppcheck team. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/test/testsuite.cpp b/test/testsuite.cpp index 51a56fe60..9b7e62cfb 100644 --- a/test/testsuite.cpp +++ b/test/testsuite.cpp @@ -1,6 +1,6 @@ /* * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2010 Daniel Marjamäki and Cppcheck team. + * Copyright (C) 2007-2011 Daniel Marjamäki and Cppcheck team. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/test/testsuite.h b/test/testsuite.h index ec3524cce..edc8fcfeb 100644 --- a/test/testsuite.h +++ b/test/testsuite.h @@ -1,6 +1,6 @@ /* * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2010 Daniel Marjamäki and Cppcheck team. + * Copyright (C) 2007-2011 Daniel Marjamäki and Cppcheck team. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/test/testsymboldatabase.cpp b/test/testsymboldatabase.cpp index f3e6fd89b..4cb424096 100644 --- a/test/testsymboldatabase.cpp +++ b/test/testsymboldatabase.cpp @@ -1,6 +1,6 @@ /* * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2010 Daniel Marjamäki and Cppcheck team. + * Copyright (C) 2007-2011 Daniel Marjamäki and Cppcheck team. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/test/testthreadexecutor.cpp b/test/testthreadexecutor.cpp index f447144c2..77be42bfc 100644 --- a/test/testthreadexecutor.cpp +++ b/test/testthreadexecutor.cpp @@ -1,6 +1,6 @@ /* * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2010 Daniel Marjamäki and Cppcheck team. + * Copyright (C) 2007-2011 Daniel Marjamäki and Cppcheck team. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/test/testtoken.cpp b/test/testtoken.cpp index eed17fc60..7be587ff3 100644 --- a/test/testtoken.cpp +++ b/test/testtoken.cpp @@ -1,6 +1,6 @@ /* * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2010 Daniel Marjamäki and Cppcheck team. + * Copyright (C) 2007-2011 Daniel Marjamäki and Cppcheck team. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/test/testtokenize.cpp b/test/testtokenize.cpp index d89875625..621b88bca 100644 --- a/test/testtokenize.cpp +++ b/test/testtokenize.cpp @@ -1,6 +1,6 @@ /* * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2010 Daniel Marjamäki and Cppcheck team. + * Copyright (C) 2007-2011 Daniel Marjamäki and Cppcheck team. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/test/testuninitvar.cpp b/test/testuninitvar.cpp index 9a0894ff3..22e724ea2 100644 --- a/test/testuninitvar.cpp +++ b/test/testuninitvar.cpp @@ -1,6 +1,6 @@ /* * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2010 Daniel Marjamäki and Cppcheck team. + * Copyright (C) 2007-2011 Daniel Marjamäki and Cppcheck team. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/test/testunusedfunctions.cpp b/test/testunusedfunctions.cpp index 2dc338511..0f62c0816 100644 --- a/test/testunusedfunctions.cpp +++ b/test/testunusedfunctions.cpp @@ -1,6 +1,6 @@ /* * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2010 Daniel Marjamäki and Cppcheck team. + * Copyright (C) 2007-2011 Daniel Marjamäki and Cppcheck team. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/test/testunusedprivfunc.cpp b/test/testunusedprivfunc.cpp index 2c09d20fb..6260bd0bd 100644 --- a/test/testunusedprivfunc.cpp +++ b/test/testunusedprivfunc.cpp @@ -1,6 +1,6 @@ /* * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2010 Daniel Marjamäki and Cppcheck team. + * Copyright (C) 2007-2011 Daniel Marjamäki and Cppcheck team. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/test/testunusedvar.cpp b/test/testunusedvar.cpp index d73afa522..1c08bbc39 100644 --- a/test/testunusedvar.cpp +++ b/test/testunusedvar.cpp @@ -1,6 +1,6 @@ /* * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2010 Daniel Marjamäki and Cppcheck team. + * Copyright (C) 2007-2011 Daniel Marjamäki and Cppcheck team. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/test/testutils.h b/test/testutils.h index 5724a7a69..edc3b56d9 100644 --- a/test/testutils.h +++ b/test/testutils.h @@ -1,6 +1,6 @@ /* * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2010 Daniel Marjamäki and Cppcheck team. + * Copyright (C) 2007-2011 Daniel Marjamäki and Cppcheck team. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/tools/dmake.cpp b/tools/dmake.cpp index 1b34a109a..cae23376e 100644 --- a/tools/dmake.cpp +++ b/tools/dmake.cpp @@ -1,6 +1,6 @@ /* * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2010 Daniel Marjamäki and Cppcheck team. + * Copyright (C) 2007-2011 Daniel Marjamäki and Cppcheck team. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by From 29d6b443fac1caaa2900d3a09a68cc2a3793b7fd Mon Sep 17 00:00:00 2001 From: Kimmo Varis Date: Mon, 10 Jan 2011 00:21:51 +0200 Subject: [PATCH 017/165] GUI: Add language selection panel to settings-dialog. Settings-dialog is more natural place for language selection than the main menu. We also have more space and freedom there to have longer text etc to make the selection easier (menus are quite limited controls). --- gui/mainwindow.cpp | 6 +++++- gui/settings.ui | 14 ++++++++++++++ gui/settingsdialog.cpp | 16 ++++++++++++++++ gui/settingsdialog.h | 12 ++++++++++++ gui/translationhandler.cpp | 3 +-- 5 files changed, 48 insertions(+), 3 deletions(-) diff --git a/gui/mainwindow.cpp b/gui/mainwindow.cpp index 9eede6b97..01fc4356d 100644 --- a/gui/mainwindow.cpp +++ b/gui/mainwindow.cpp @@ -436,7 +436,7 @@ void MainWindow::CheckDone() void MainWindow::ProgramSettings() { - SettingsDialog dialog(mSettings, mApplications, this); + SettingsDialog dialog(mSettings, mApplications, mTranslation, this); if (dialog.exec() == QDialog::Accepted) { dialog.SaveSettingValues(); @@ -444,6 +444,10 @@ void MainWindow::ProgramSettings() dialog.SaveFullPath(), dialog.SaveAllErrors(), dialog.ShowNoErrorsMessage()); + const int currentLang = mTranslation->GetCurrentLanguage(); + const int newLang = mSettings->value(SETTINGS_LANGUAGE, 0).toInt(); + if (currentLang != newLang) + SetLanguage(newLang); } } diff --git a/gui/settings.ui b/gui/settings.ui index ea1ba274d..ac5f19f33 100644 --- a/gui/settings.ui +++ b/gui/settings.ui @@ -254,6 +254,20 @@ + + + Language + + + + + + QAbstractItemView::SelectRows + + + + + diff --git a/gui/settingsdialog.cpp b/gui/settingsdialog.cpp index 4563b2b27..71f0c34de 100644 --- a/gui/settingsdialog.cpp +++ b/gui/settingsdialog.cpp @@ -30,14 +30,17 @@ #include "settingsdialog.h" #include "applicationdialog.h" #include "applicationlist.h" +#include "translationhandler.h" #include "common.h" SettingsDialog::SettingsDialog(QSettings *programSettings, ApplicationList *list, + TranslationHandler *translator, QWidget *parent) : QDialog(parent), mSettings(programSettings), mApplications(list), + mTranslator(translator), mTempApplications(new ApplicationList(this)) { mUI.setupUi(this); @@ -78,6 +81,7 @@ SettingsDialog::SettingsDialog(QSettings *programSettings, mUI.mLblIdealThreads->setText(tr("N/A")); LoadSettings(); + InitTranslationsList(); } SettingsDialog::~SettingsDialog() @@ -85,6 +89,17 @@ SettingsDialog::~SettingsDialog() SaveSettings(); } +void SettingsDialog::InitTranslationsList() +{ + QStringList languages = mTranslator->GetNames(); + foreach(const QString lang, languages) + { + mUI.mListLanguages->addItem(lang); + } + const int current = mTranslator->GetCurrentLanguage(); + mUI.mListLanguages->setCurrentRow(current); +} + Qt::CheckState SettingsDialog::BoolToCheckState(bool yes) const { if (yes) @@ -133,6 +148,7 @@ void SettingsDialog::SaveSettingValues() SaveCheckboxValue(mUI.mShowDebugWarnings, SETTINGS_SHOW_DEBUG_WARNINGS); SaveCheckboxValue(mUI.mInlineSuppressions, SETTINGS_INLINE_SUPPRESSIONS); mSettings->setValue(SETTINGS_GLOBAL_INCLUDE_PATHS, mUI.mEditIncludePaths->text()); + mSettings->setValue(SETTINGS_LANGUAGE, mUI.mListLanguages->currentRow()); } void SettingsDialog::SaveCheckboxValue(QCheckBox *box, const QString &name) diff --git a/gui/settingsdialog.h b/gui/settingsdialog.h index d97591f7c..b99b5c294 100644 --- a/gui/settingsdialog.h +++ b/gui/settingsdialog.h @@ -27,6 +27,7 @@ class QSettings; class QWidget; class ApplicationList; +class TranslationHandler; /// @addtogroup GUI /// @{ @@ -41,6 +42,7 @@ class SettingsDialog : public QDialog public: SettingsDialog(QSettings *programSettings, ApplicationList *list, + TranslationHandler *translator, QWidget *parent = 0); virtual ~SettingsDialog(); @@ -163,6 +165,10 @@ protected: */ bool CheckStateToBool(Qt::CheckState state) const; + /** + * @brief Populate the translations list. + */ + void InitTranslationsList(); /** * @brief Settings @@ -183,6 +189,12 @@ protected: */ ApplicationList *mTempApplications; + /** + * @brief List of translations. + * + */ + TranslationHandler *mTranslator; + /** * @brief Dialog from UI designer * diff --git a/gui/translationhandler.cpp b/gui/translationhandler.cpp index 7b9e6e46d..d6b8e9dba 100644 --- a/gui/translationhandler.cpp +++ b/gui/translationhandler.cpp @@ -16,12 +16,11 @@ * along with this program. If not, see . */ -#include "translationhandler.h" - #include #include #include #include +#include "translationhandler.h" TranslationHandler::TranslationHandler(QObject *parent) : QObject(parent), From 85a700b49604c699a53a5bdf9106a640678b612b Mon Sep 17 00:00:00 2001 From: Kimmo Varis Date: Mon, 10 Jan 2011 00:50:32 +0200 Subject: [PATCH 018/165] GUI: Remove Language-menu. We now have language selection in Settings-dialog. --- gui/main.ui | 6 ------ gui/mainwindow.cpp | 47 ---------------------------------------------- gui/mainwindow.h | 12 ------------ 3 files changed, 65 deletions(-) diff --git a/gui/main.ui b/gui/main.ui index 8a8c09d9c..8ed52ff5c 100644 --- a/gui/main.ui +++ b/gui/main.ui @@ -113,11 +113,6 @@ - - - &Language - - &Help @@ -148,7 +143,6 @@ - diff --git a/gui/mainwindow.cpp b/gui/mainwindow.cpp index 01fc4356d..75a3f54b2 100644 --- a/gui/mainwindow.cpp +++ b/gui/mainwindow.cpp @@ -98,7 +98,6 @@ MainWindow::MainWindow() : connect(mUI.mActionHelpContents, SIGNAL(triggered()), this, SLOT(OpenHelpContents())); - CreateLanguageMenuItems(); LoadSettings(); mThread->Initialize(mUI.mResults); @@ -128,39 +127,6 @@ MainWindow::~MainWindow() delete mProject; } -void MainWindow::CreateLanguageMenuItems() -{ - QStringList languages = mTranslation->GetNames(); - - for (int i = 0; i < languages.size(); i++) - { - //Create an action for each language - //Language name is pre translated - QAction *temp = new QAction(languages[i], this); - - temp->setCheckable(true); - - //Add the action to menu - mUI.mMenuLanguage->addAction(temp); - - //Add action to the group - mLanguages->addAction(temp); - - //Check it if it's the value stored to settings - if (i == mSettings->value(SETTINGS_LANGUAGE, 0).toInt()) - { - temp->setChecked(true); - } - else - { - temp->setChecked(false); - } - } - - connect(mLanguages, SIGNAL(triggered(QAction *)), - this, SLOT(MapLanguage(QAction *))); -} - void MainWindow::LoadSettings() { if (mSettings->value(SETTINGS_WINDOW_MAXIMIZED, false).toBool()) @@ -715,19 +681,6 @@ void MainWindow::SetLanguage(int index) } } -void MainWindow::MapLanguage(QAction *action) -{ - //Find the action that has the language that user clicked - QList actions = mLanguages->actions(); - for (int i = 0; i < actions.size(); i++) - { - if (actions[i] == action) - { - SetLanguage(i); - } - } -} - void MainWindow::AboutToShowViewMenu() { mUI.mActionToolBarMain->setChecked(mUI.mToolBarMain->isVisible()); diff --git a/gui/mainwindow.h b/gui/mainwindow.h index 781bd91ac..e40f3ec51 100644 --- a/gui/mainwindow.h +++ b/gui/mainwindow.h @@ -212,12 +212,6 @@ protected slots: */ void ResultsAdded(); - /** - * @brief Slot for changing the program's language - * - */ - void MapLanguage(QAction *); - /** * @brief Slot for showing/hiding standard toolbar */ @@ -259,12 +253,6 @@ protected slots: protected: - /** - * @brief Create menu items to change language - * - */ - void CreateLanguageMenuItems(); - /** * @brief Set current language * @param index Index of the language to set From 03093cb8c419f6ddf41cd3ea74da7ac478d07eb4 Mon Sep 17 00:00:00 2001 From: Kimmo Varis Date: Mon, 10 Jan 2011 14:12:40 +0200 Subject: [PATCH 019/165] GUI: Update translation files. --- gui/cppcheck_de.ts | 275 +++++++++++++++++++++++--------------------- gui/cppcheck_en.ts | 275 +++++++++++++++++++++++--------------------- gui/cppcheck_fi.ts | 275 +++++++++++++++++++++++--------------------- gui/cppcheck_ja.ts | 275 +++++++++++++++++++++++--------------------- gui/cppcheck_nl.ts | 275 +++++++++++++++++++++++--------------------- gui/cppcheck_pl.ts | 277 ++++++++++++++++++++++++--------------------- gui/cppcheck_ru.ts | 275 +++++++++++++++++++++++--------------------- gui/cppcheck_se.ts | 275 +++++++++++++++++++++++--------------------- gui/cppcheck_sr.ts | 275 +++++++++++++++++++++++--------------------- 9 files changed, 1306 insertions(+), 1171 deletions(-) diff --git a/gui/cppcheck_de.ts b/gui/cppcheck_de.ts index 431ed818a..9b3ff31ea 100644 --- a/gui/cppcheck_de.ts +++ b/gui/cppcheck_de.ts @@ -220,17 +220,17 @@ kate -l(line) (file) MainWindow - - - - - - + + + + + + Cppcheck Cppcheck - + Standard Standard @@ -250,379 +250,374 @@ kate -l(line) (file) &Symbolleisten - + &Check &Prüfen - + &Edit &Bearbeiten - + &License... &Lizenz... - + A&uthors... &Autoren... - + &About... Ü&ber... - + &Files... &Dateien... - - + + Check files - + Ctrl+F Strg+F - + &Directory... &Verzeichnis... - - + + Check directory - + Ctrl+D Strg+D - + &Recheck files Dateien &neu prüfen - + Ctrl+R Strg+R - + &Stop &Stoppen - - + + Stop checking - + Esc Esc - + &Save results to file... Ergebnisse in Datei &speichern... - + Ctrl+S Strg+S - + &Quit &Beenden - + &Clear results Ergebnisse &leeren - + &Preferences &Einstellungen - + Errors - - + + Show errors - + Warnings - - + + Show warnings - + Performance warnings - - + + Show performance warnings - + Show &hidden - + Information - + Show information messages - + Portability - + Show portability warnings - + &Check all Alle &auswählen - + &Uncheck all Alle a&bwählen - + Collapse &all Alle &reduzieren - + &Expand all Alle &erweitern - + &Standard &Standard - + Standard items Standardeinträge - + Toolbar Symbolleiste - + &Categories &Kategorien - + Error categories Fehler-Kategorien - + &Open XML... - + Open P&roject File... - + &New Project File... - + &Log View - + Log View - + C&lose Project File - + &Edit Project File... - + &Statistics - + &Contents &Inhalte - + Categories Kategorien - + Style warnings - - + + Show style warnings - + Open the help contents Öffnet die Hilfe-Inhalte - + F1 F1 - &Language - &Sprache - - - &Help &Hilfe - + Select files to check Dateien zum Überprüfen auswählen - + Select directory to check Verzeichnis zum Überprüfen auswählen - + No suitable files found to check! Kein passenden Dateien zum Überprüfen gefunden! - + License Lizenz - + Authors Autoren - + XML files (*.xml);;Text files (*.txt);;CSV files (*.csv) XML-Dateien (*.xml);;Textdateien (*.txt);;CSV-Dateien (*.csv) - + Save the report file Speichert die Berichtdatei - - + + XML files (*.xml) XML-Dateien (*.xml) - + You must close the project file before selecting new files or directories! - - - + + + Project: - + Open the report file - + Checking is running. Do you want to stop the checking and exit Cppcheck?. - + Text files (*.txt) Textdateien (*.txt) - + CSV files (*.csv) CSV-Dateien (*.csv) - + Cppcheck - %1 Cppcheck - %1 - + Failed to change the language: %1 @@ -638,85 +633,85 @@ Do you want to stop the checking and exit Cppcheck?. - - + + Cppcheck Help - + Failed to load help file (not found) - + Failed to load help file - - + + Project files (*.cppcheck);;All files(*.*) - + Select Project File - + Select Project Filename - + No project file loaded - + Finnish Finnisch - + English Englisch - + Dutch Niederländisch - + Swedish Schwedisch - + German Deutsch - + Russian Russisch - + Polish Polnisch - + Japanese Japanease - + Serbian @@ -795,18 +790,18 @@ Do you want to stop the checking and exit Cppcheck?. QObject - + Incorrect language specified! Falsche Sprache angegeben! - + Language file %1 not found! Language file %1.qm not found! Sprachdatei %1 nicht gefunden! - + Failed to load translation for language %1 from file %2 Failed to load translation for language %1 from file %2.qm Die Übersetzungen der Sprache %1 konnten nicht aus der Datei %2 geladen werden @@ -1012,85 +1007,105 @@ Legen Sie unter dem Menü Ansicht fest, welche Art von Fehlern angezeigt werden Anzahl der Threads: - + + Ideal count: + + + + + TextLabel + + + + Check all #ifdef configurations Alle #ifdef-Konfigurationen überprüfen - + Show full path of files Vollständigen Dateipfad anzeigen - + Show "No errors found" message when no errors found "Keine Fehler gefunden"-Meldung anzeigen, wenn keine Fehler gefunden werden - + Show internal warnings in log - + Enable inline suppressions - + Applications Anwendungen - + Add application Anwendung hinzufügen - + Delete application Anwendung löschen - + Modify application Anwendung ändern - + Set as default application Als Standard-Anwendung verwenden - + Reports Berichte - + Save all errors when creating report Alle Fehler beim Erstellen von Berichten speichern - + Save full path to files in reports Vollständigen Dateipfad in Berichten speichern + + + Language + + SettingsDialog - + + N/A + + + + Add a new application Neue Anwendung hinzufügen - + Modify an application Anwendung ändern - + Select include directory diff --git a/gui/cppcheck_en.ts b/gui/cppcheck_en.ts index c042996b9..3a96b3c94 100644 --- a/gui/cppcheck_en.ts +++ b/gui/cppcheck_en.ts @@ -222,17 +222,17 @@ kate -l(line) (file) MainWindow - - - - - - + + + + + + Cppcheck Cppcheck - + Standard Standard @@ -252,379 +252,374 @@ kate -l(line) (file) - + &Check &Check - + &Edit &Edit - + &License... &License... - + A&uthors... A&uthors... - + &About... &About... - + &Files... &Files... - - + + Check files - + Ctrl+F Ctrl+F - + &Directory... &Directory... - - + + Check directory - + Ctrl+D Ctrl+D - + &Recheck files &Recheck files - + Ctrl+R Ctrl+R - + &Stop &Stop - - + + Stop checking - + Esc Esc - + &Save results to file... &Save results to file... - + Ctrl+S Ctrl+S - + &Quit &Quit - + &Clear results &Clear results - + &Preferences &Preferences - + Errors - - + + Show errors - + Warnings - - + + Show warnings - + Performance warnings - - + + Show performance warnings - + Show &hidden - + Information - + Show information messages - + Portability - + Show portability warnings - + &Check all &Check all - + &Uncheck all &Uncheck all - + Collapse &all Collapse &all - + &Expand all &Expand all - + &Standard - + Standard items - + Toolbar - + &Categories - + Error categories - + &Open XML... - + Open P&roject File... - + &New Project File... - + &Log View - + Log View - + C&lose Project File - + &Edit Project File... - + &Statistics - + &Contents - + Categories - + Style warnings - - + + Show style warnings - + Open the help contents - + F1 - &Language - &Language - - - &Help &Help - + Select files to check Select files to check - + Select directory to check Select directory to check - + No suitable files found to check! No suitable files found to check! - + License License - + Authors Authors - + XML files (*.xml);;Text files (*.txt);;CSV files (*.csv) XML files (*.xml);;Text files (*.txt);;CSV files (*.csv) - + Save the report file Save the report file - - + + XML files (*.xml) XML files (*.xml) - + You must close the project file before selecting new files or directories! - - - + + + Project: - + Open the report file - + Checking is running. Do you want to stop the checking and exit Cppcheck?. - + Text files (*.txt) Text files (*.txt) - + CSV files (*.csv) - + Cppcheck - %1 Cppcheck - %1 - + Failed to change the language: %1 @@ -638,85 +633,85 @@ Do you want to stop the checking and exit Cppcheck?. %1 - - + + Cppcheck Help - + Failed to load help file (not found) - + Failed to load help file - - + + Project files (*.cppcheck);;All files(*.*) - + Select Project File - + Select Project Filename - + No project file loaded - + Finnish Finnish - + English English - + Dutch - + Swedish Swedish - + German German - + Russian Russian - + Polish Polish - + Japanese Japanease - + Serbian Serbian @@ -795,18 +790,18 @@ Do you want to stop the checking and exit Cppcheck?. QObject - + Incorrect language specified! Incorrect language specified! - + Language file %1 not found! Language file %1.qm not found! Could not find the file: %1! - + Failed to load translation for language %1 from file %2 Failed to load translation for language %1 from file %2.qm Failed to load translation for language %1 from file %2 @@ -1012,85 +1007,105 @@ To toggle what kind of errors are shown, open view menu. Number of threads: - + + Ideal count: + + + + + TextLabel + + + + Check all #ifdef configurations Check all #ifdef configurations - + Show full path of files Show full path of files - + Show "No errors found" message when no errors found Show "No errors found" message when no errors found - + Show internal warnings in log - + Enable inline suppressions - + Applications Applications - + Add application Add application - + Delete application Delete application - + Modify application Modify application - + Set as default application Set as default application - + Reports Reports - + Save all errors when creating report Save all errors when creating report - + Save full path to files in reports Save full path to files in reports + + + Language + + SettingsDialog - + + N/A + + + + Add a new application Add a new application - + Modify an application Modify an application - + Select include directory diff --git a/gui/cppcheck_fi.ts b/gui/cppcheck_fi.ts index 7bd29e2a6..57924099c 100644 --- a/gui/cppcheck_fi.ts +++ b/gui/cppcheck_fi.ts @@ -224,17 +224,17 @@ kate -l(line) (file) MainWindow - - - - - - + + + + + + Cppcheck Cppcheck - + Standard Vakio @@ -254,379 +254,374 @@ kate -l(line) (file) - + &Check &Tarkista - + &Edit &Muokkaa - + &License... &Lisenssi... - + A&uthors... &Tekijät... - + &About... &Tietoa ohjelmasta Cppcheck... - + &Files... &Tiedostot... - - + + Check files - + Ctrl+F Ctrl+F - + &Directory... &Hakemisto... - - + + Check directory - + Ctrl+D Ctrl+D - + &Recheck files Tarkista tiedostot &uudelleen - + Ctrl+R Ctrl+R - + &Stop &Pysäytä - - + + Stop checking - + Esc Esc - + &Save results to file... &Tallenna tulokset tiedostoon... - + Ctrl+S Ctrl+S - + &Quit &Lopeta - + &Clear results &Tyhjennä tulokset - + &Preferences &Asetukset - + Errors - - + + Show errors - + Warnings - - + + Show warnings - + Performance warnings - - + + Show performance warnings - + Show &hidden - + Information - + Show information messages - + Portability - + Show portability warnings - + &Check all &Valitse kaikki - + &Uncheck all &Poista kaikista valinta - + Collapse &all &Pienennä kaikki - + &Expand all &Laajenna kaikki - + &Standard - + Standard items - + Toolbar - + &Categories - + Error categories - + &Open XML... - + Open P&roject File... - + &New Project File... - + &Log View - + Log View - + C&lose Project File - + &Edit Project File... - + &Statistics - + &Contents - + Categories - + Style warnings - - + + Show style warnings - + Open the help contents - + F1 - &Language - &Kieli - - - &Help &Ohje - + Select files to check Valitse tarkistettavat tiedostot - + Select directory to check Valitse tarkistettava hakemisto - + No suitable files found to check! Tarkistettavaksi sopivia tiedostoja ei löytynyt! - + License Lisenssi - + Authors Tekijät - + XML files (*.xml);;Text files (*.txt);;CSV files (*.csv) XML-tiedostot (*.xml);;Tekstitiedostot (*.txt);;CSV-tiedostot (*.csv) - + Save the report file Tallenna raportti - - + + XML files (*.xml) XML-tiedostot (*xml) - + You must close the project file before selecting new files or directories! - - - + + + Project: - + Open the report file - + Checking is running. Do you want to stop the checking and exit Cppcheck?. - + Text files (*.txt) Tekstitiedostot (*.txt) - + CSV files (*.csv) - + Cppcheck - %1 Cppcheck - %1 - + Failed to change the language: %1 @@ -642,85 +637,85 @@ Do you want to stop the checking and exit Cppcheck?. - - + + Cppcheck Help - + Failed to load help file (not found) - + Failed to load help file - - + + Project files (*.cppcheck);;All files(*.*) - + Select Project File - + Select Project Filename - + No project file loaded - + Finnish Suomi - + English Englanti - + Dutch - + Swedish Ruotsi - + German Saksa - + Russian Venäjä - + Polish Puola - + Japanese Japanease - + Serbian @@ -799,18 +794,18 @@ Do you want to stop the checking and exit Cppcheck?. QObject - + Incorrect language specified! Virheellinen kieli valittu! - + Language file %1 not found! Language file %1.qm not found! Käännöstiedostoa %1 ei löytynyt! - + Failed to load translation for language %1 from file %2 Failed to load translation for language %1 from file %2.qm Käänöksen lataaminen kielelle %1 tiedostosta %2 epäonnistui @@ -1016,85 +1011,105 @@ Määrittääksesi minkä tyyppisiä virheitä näytetään, avaa näkymä valik Säikeiden lukumäärä: - + + Ideal count: + + + + + TextLabel + + + + Check all #ifdef configurations Tarkista kaikki #ifdef kombinaatiot - + Show full path of files Näytä tiedostojen täysi polku - + Show "No errors found" message when no errors found Näytä "virheitä ei löytynyt"-viesti jos virheitä ei löydy - + Show internal warnings in log - + Enable inline suppressions - + Applications Ohjelmat - + Add application Lisää ohjelma - + Delete application Poista ohjelma - + Modify application Muokkaa ohjelmaa - + Set as default application Aseta oletusohjelmaksi - + Reports Raportit - + Save all errors when creating report Tallenna kaikki virheet raporttia luodessa - + Save full path to files in reports Tallenna tiedostojen koko polku raportteihin + + + Language + + SettingsDialog - + + N/A + + + + Add a new application Lisää uusi ohjelma - + Modify an application Muokkaa ohjelmaa - + Select include directory diff --git a/gui/cppcheck_ja.ts b/gui/cppcheck_ja.ts index d76a0646e..911b32756 100644 --- a/gui/cppcheck_ja.ts +++ b/gui/cppcheck_ja.ts @@ -208,12 +208,12 @@ kate -l(line) (file) MainWindow - - - - - - + + + + + + Cppcheck Cppcheck @@ -234,341 +234,336 @@ kate -l(line) (file) - &Language - 言語(&L) - - - &Help ヘルプ(&H) - + &Check 解析(&A) - + &Edit 編集(&E) - + Standard 標準(&S) - + Categories カテゴリ(&C) - + &License... ライセンス(&L)... - + A&uthors... 作者(&u)... - + &About... Cppcheckについて(&A)... - + &Files... ファイル選択(&F)... - - + + Check files - + Ctrl+F Ctrl+F - + &Directory... ディレクトリ選択(&D)... - - + + Check directory - + Ctrl+D Ctrl+D - + &Recheck files 再チェック(&R) - + Ctrl+R Ctrl+R - + &Stop 停止(&S) - - + + Stop checking - + Esc Esc - + &Save results to file... 結果をファイルに保存(&S)... - + Ctrl+S Ctrl+S - + &Quit 終了(&Q) - + &Clear results 結果をクリア(&C) - + &Preferences 設定(&P) - + Style warnings スタイル警告 - - + + Show style warnings スタイル警告を表示 - + Errors - - + + Show errors - + Information - + Show information messages - + Portability - + Show portability warnings - + C&lose Project File プロジェクトを閉じる(&l) - + &Edit Project File... プロジェクトの編集(&E)... - + &Statistics 統計情報(&S) - + Warnings 警告 - - + + Show warnings 警告を表示 - + Performance warnings パフォーマンス警告 - - + + Show performance warnings パフォーマンス警告を表示 - + Show &hidden 非表示を表示(&h) - + &Check all すべてのエラーを表示(&C) - + &Uncheck all すべてのエラーを非表示(&U) - + Collapse &all ツリーを折り畳む(&A) - + &Expand all ツリーを展開(&E) - + &Standard 標準(&S) - + Standard items 標準項目 - + &Contents コンテンツ(&C) - + Open the help contents ヘルプファイルを開く - + F1 F1 - + Toolbar ツールバー - + &Categories カテゴリ(&C) - + Error categories エラーカテゴリ - + &Open XML... XMLを開く(&O)... - + Open P&roject File... プロジェクトを開く(&R)... - + &New Project File... 新規プロジェクト(&N)... - + &Log View ログを表示(&L) - + Log View ログ表示 - + No suitable files found to check! 解析可能なファイルではありません - + You must close the project file before selecting new files or directories! 新しいファイル/ディレクトリを解析するには現在のプロジェクトを閉じてください - + Select files to check チェック対象のファイルを選択 - + Select directory to check チェック対象のディレクトリを選択 - - - + + + Project: プロジェクト: - - + + XML files (*.xml) XML ファイル (*.xml) - + Open the report file レポートを開く - + Checking is running. Do you want to stop the checking and exit Cppcheck?. @@ -577,42 +572,42 @@ Do you want to stop the checking and exit Cppcheck?. 解析を停止してCppcheckを終了しますか?. - + License ライセンス - + Authors 作者 - + XML files (*.xml);;Text files (*.txt);;CSV files (*.csv) XML ファイル (*.xml);;テキストファイル (*.txt);;CSV形式ファイル (*.csv) - + Save the report file レポートを保存 - + Text files (*.txt) テキストファイル (*.txt) - + CSV files (*.csv) CSV形式ファイル (*.csv) - + Cppcheck - %1 Cppcheck - %1 - + Failed to change the language: %1 @@ -625,85 +620,85 @@ Do you want to stop the checking and exit Cppcheck?. - - + + Cppcheck Help Cppcheck ヘルプ - + Failed to load help file (not found) ヘルプファイルが見つかりませんでした - + Failed to load help file ヘルプファイルの読み込みに失敗しました - - + + Project files (*.cppcheck);;All files(*.*) プロジェクトファイル (*.cppcheck);;All files(*.*) - + Select Project File プロジェクトファイルを選択 - + Select Project Filename プロジェクトファイル名を選択 - + No project file loaded プロジェクトファイルが読み込まれていません - + English - + Dutch - + Finnish - + Swedish - + German - + Russian - + Polish - + Japanese Japanease - + Serbian @@ -782,17 +777,17 @@ Do you want to stop the checking and exit Cppcheck?. QObject - + Incorrect language specified! - + Language file %1 not found! 言語ファイル %1 が見つかりません! - + Failed to load translation for language %1 from file %2 @@ -997,85 +992,105 @@ To toggle what kind of errors are shown, open view menu. 解析スレッド数: - + + Ideal count: + + + + + TextLabel + + + + Check all #ifdef configurations すべての #ifdef をチェックする - + Show full path of files ファイルのフルパスを表示 - + Show "No errors found" message when no errors found エラーが無いときは"エラーなし"を表示 - + Show internal warnings in log cppcheck内部警告をログに表示する - + Enable inline suppressions - + Applications アプリケーション - + Add application アプリケーションを追加 - + Delete application アプリケーションの削除 - + Modify application アプリケーション設定の変更 - + Set as default application デフォルトアプリケーションに設定 - + Reports レポート - + Save all errors when creating report すべての警告/エラーを保存 - + Save full path to files in reports ファイルのフルパスを保存 + + + Language + + SettingsDialog - + + N/A + + + + Add a new application 新しいアプリケーションの追加 - + Modify an application アプリケーションの変更 - + Select include directory include ディレクトリを選択 diff --git a/gui/cppcheck_nl.ts b/gui/cppcheck_nl.ts index edeff5d3c..c5e5e6747 100644 --- a/gui/cppcheck_nl.ts +++ b/gui/cppcheck_nl.ts @@ -222,17 +222,17 @@ kate -l(line) (file) MainWindow - - - - - - + + + + + + Cppcheck Cppcheck - + Standard Standaard @@ -252,379 +252,374 @@ kate -l(line) (file) - + &Check &Controleer - + &Edit Be&werken - + &License... &Licentie... - + A&uthors... A&uteurs... - + &About... &Over... - + &Files... &Bestanden... - - + + Check files - + Ctrl+F Ctrl+F - + &Directory... &Mappen... - - + + Check directory - + Ctrl+D Ctrl+D - + &Recheck files &Opnieuw controleren - + Ctrl+R Ctrl+R - + &Stop &Stop - - + + Stop checking - + Esc Esc - + &Save results to file... &Resultaten opslaan... - + Ctrl+S Ctrl+S - + &Quit &Afsluiten - + &Clear results &Resultaten wissen - + &Preferences &Voorkeuren - + Errors - - + + Show errors - + Warnings - - + + Show warnings - + Performance warnings - - + + Show performance warnings - + Show &hidden - + Information - + Show information messages - + Portability - + Show portability warnings - + &Check all &Selecteer alles - + &Uncheck all Selecteer &niets - + Collapse &all Alles Inkl&appen - + &Expand all Alles &Uitklappen - + &Standard - + Standard items - + Toolbar - + &Categories - + Error categories - + &Open XML... - + Open P&roject File... - + &New Project File... - + &Log View - + Log View - + C&lose Project File - + &Edit Project File... - + &Statistics - + &Contents - + Categories - + Style warnings - - + + Show style warnings - + Open the help contents - + F1 - &Language - &Taal - - - &Help &Help - + Select files to check Selecteer bestanden om te controleren - + Select directory to check Selecteer een map om te controleren - + No suitable files found to check! Geen geschikte bestanden gevonden om te controleren! - + License Licentie - + Authors Auteurs - + XML files (*.xml);;Text files (*.txt);;CSV files (*.csv) XML bestanden (*.xml);;Tekst bestanden (*.txt);;CSV bestanden (*.csv) - + Save the report file Rapport opslaan - - + + XML files (*.xml) XML bestanden (*.xml) - + You must close the project file before selecting new files or directories! - - - + + + Project: - + Open the report file - + Checking is running. Do you want to stop the checking and exit Cppcheck?. - + Text files (*.txt) Tekst bestanden (*.txt) - + CSV files (*.csv) - + Cppcheck - %1 Cppcheck - %1 - + Failed to change the language: %1 @@ -638,85 +633,85 @@ Do you want to stop the checking and exit Cppcheck?. %1 - - + + Cppcheck Help - + Failed to load help file (not found) - + Failed to load help file - - + + Project files (*.cppcheck);;All files(*.*) - + Select Project File - + Select Project Filename - + No project file loaded - + Finnish Fins - + English Engels - + Dutch Nederlands - + Swedish Zweeds - + German Duits - + Russian Russisch - + Polish Pools - + Japanese Japanease - + Serbian @@ -795,18 +790,18 @@ Do you want to stop the checking and exit Cppcheck?. QObject - + Incorrect language specified! Ongeldige taal gespecifieerd! - + Language file %1 not found! Language file %1.qm not found! Kon het taalbestand niet vinden: %1! - + Failed to load translation for language %1 from file %2 Failed to load translation for language %1 from file %2.qm Kon de vertaling voor taal %1 in bestand %2 niet laden @@ -1012,85 +1007,105 @@ Gebruik het uitzicht menu om te selecteren welke fouten getoond worden.Aantal threads: - + + Ideal count: + + + + + TextLabel + + + + Check all #ifdef configurations Controleer alle #ifdef combinaties - + Show full path of files Toon het volledige pad van bestanden - + Show "No errors found" message when no errors found Toon "Geen fouten gevonden" indien geen fouten gevonden werden - + Show internal warnings in log - + Enable inline suppressions - + Applications Applicaties - + Add application Applicatie toevoegen - + Delete application Applicatie verwijderen - + Modify application Applicatie wijzigen - + Set as default application Configureer als standaard applicatie - + Reports Rapporten - + Save all errors when creating report Alle fouten opslaan - + Save full path to files in reports Volledig pad opslaan + + + Language + + SettingsDialog - + + N/A + + + + Add a new application Nieuwe applicatie toevoegen - + Modify an application Applicatie wijzigen - + Select include directory diff --git a/gui/cppcheck_pl.ts b/gui/cppcheck_pl.ts index a3413a766..c35ddefb1 100644 --- a/gui/cppcheck_pl.ts +++ b/gui/cppcheck_pl.ts @@ -209,12 +209,12 @@ kate -l(line) (file) MainWindow - - - - - - + + + + + + Cppcheck @@ -235,409 +235,404 @@ kate -l(line) (file) - &Language - - - - &Help - + &Check - + &Edit - + Standard - + &License... - + A&uthors... - + &About... - + &Files... - - + + Check files - + Ctrl+F - + &Directory... - - + + Check directory - + Ctrl+D - + &Recheck files - + Ctrl+R - + &Stop - - + + Stop checking - + Esc - + &Save results to file... - + Ctrl+S - + &Quit - + &Clear results - + &Preferences - + Errors - - + + Show errors - + Warnings - - + + Show warnings - + Performance warnings - - + + Show performance warnings - + Show &hidden - + Information - + Show information messages - + Portability - + Show portability warnings - + &Check all - + &Uncheck all - + Collapse &all - + &Expand all - + &Standard - + Standard items - + Toolbar - + &Categories - + Error categories - + &Open XML... - + Open P&roject File... - + &New Project File... - + &Log View - + Log View - + C&lose Project File - + &Edit Project File... - + &Statistics - + &Contents - + Categories - + Style warnings - - + + Show style warnings - + Open the help contents - + F1 - + No suitable files found to check! - + You must close the project file before selecting new files or directories! - + Select files to check - + Select directory to check - - - + + + Project: - + Open the report file - + License - + Authors - + XML files (*.xml);;Text files (*.txt);;CSV files (*.csv) - + Save the report file - - + + Cppcheck Help - + Failed to load help file (not found) - + Failed to load help file - + Select Project Filename - + No project file loaded - - + + XML files (*.xml) - + Checking is running. Do you want to stop the checking and exit Cppcheck?. - + Text files (*.txt) - + CSV files (*.csv) - + Cppcheck - %1 - + Failed to change the language: %1 @@ -646,59 +641,59 @@ Do you want to stop the checking and exit Cppcheck?. - - + + Project files (*.cppcheck);;All files(*.*) - + Select Project File - + English - + Dutch - + Finnish - + Swedish - + German - + Russian - + Polish - + Japanese Japanease - + Serbian @@ -777,17 +772,17 @@ Do you want to stop the checking and exit Cppcheck?. QObject - + Incorrect language specified! - + Language file %1 not found! - + Failed to load translation for language %1 from file %2 @@ -988,85 +983,105 @@ To toggle what kind of errors are shown, open view menu. - - Check all #ifdef configurations + + Ideal count: - - Show full path of files + + TextLabel - Show "No errors found" message when no errors found + Check all #ifdef configurations - Show internal warnings in log + Show full path of files + Show "No errors found" message when no errors found + + + + + Show internal warnings in log + + + + Enable inline suppressions - + Applications - + Add application - + Delete application - + Modify application - + Set as default application - + Reports - + Save all errors when creating report - + Save full path to files in reports + + + Language + + SettingsDialog - + + N/A + + + + Add a new application - + Modify an application - + Select include directory diff --git a/gui/cppcheck_ru.ts b/gui/cppcheck_ru.ts index 4bab16b11..6c3d6d407 100644 --- a/gui/cppcheck_ru.ts +++ b/gui/cppcheck_ru.ts @@ -212,17 +212,17 @@ kate -l(line) (file) MainWindow - - - - - - + + + + + + Cppcheck Cppcheck - + Standard @@ -242,379 +242,374 @@ kate -l(line) (file) - + &Check Проверить - + &Edit Правка - + &License... Лицензия... - + A&uthors... Авторы... - + &About... О программе... - + &Files... Файлы... - - + + Check files - + Ctrl+F Ctrl+F - + &Directory... Каталог... - - + + Check directory - + Ctrl+D Ctrl+D - + &Recheck files - + Ctrl+R Ctrl+R - + &Stop Остановить - - + + Stop checking - + Esc Esc - + &Save results to file... Сохранить отчёт в файл... - + Ctrl+S Ctrl+S - + &Quit Выход - + &Clear results Очистить отчёт - + &Preferences Параметры - + Errors - - + + Show errors - + Warnings - - + + Show warnings - + Performance warnings - - + + Show performance warnings - + Show &hidden - + Information - + Show information messages - + Portability - + Show portability warnings - + &Check all Отметить все - + &Uncheck all Сбросить все - + Collapse &all Свернуть все - + &Expand all Развернуть все - + &Standard - + Standard items - + Toolbar - + &Categories - + Error categories - + &Open XML... - + Open P&roject File... - + &New Project File... - + &Log View - + Log View - + C&lose Project File - + &Edit Project File... - + &Statistics - + &Contents - + Categories - + Style warnings - - + + Show style warnings - + Open the help contents - + F1 - &Language - Язык - - - &Help Помощь - + Select files to check Выберите файлы для проверки - + Select directory to check Выберите каталог для проверки - + No suitable files found to check! - + License Лицензия - + Authors Авторы - + XML files (*.xml);;Text files (*.txt);;CSV files (*.csv) - + Save the report file - - + + XML files (*.xml) - + You must close the project file before selecting new files or directories! - - - + + + Project: - + Open the report file - + Checking is running. Do you want to stop the checking and exit Cppcheck?. - + Text files (*.txt) Текстовые файлы (*.txt) - + CSV files (*.csv) - + Cppcheck - %1 Cppcheck - %1 - + Failed to change the language: %1 @@ -630,85 +625,85 @@ Do you want to stop the checking and exit Cppcheck?. - - + + Cppcheck Help - + Failed to load help file (not found) - + Failed to load help file - - + + Project files (*.cppcheck);;All files(*.*) - + Select Project File - + Select Project Filename - + No project file loaded - + Finnish Финский - + English Английский - + Dutch - + Swedish Швецкий - + German Немецкий - + Russian Русский - + Polish - + Japanese Japanease - + Serbian @@ -787,18 +782,18 @@ Do you want to stop the checking and exit Cppcheck?. QObject - + Incorrect language specified! Выбран неверный язык! - + Language file %1 not found! Language file %1.qm not found! - + Failed to load translation for language %1 from file %2 Failed to load translation for language %1 from file %2.qm Ошибка загрузки переводов для языка %1 из файла %2 @@ -1001,85 +996,105 @@ To toggle what kind of errors are shown, open view menu. Количество потоков исполнения: - + + Ideal count: + + + + + TextLabel + + + + Check all #ifdef configurations Проверять все варианты #ifdef конфигураций - + Show full path of files Показывать полные пути к файлам - + Show "No errors found" message when no errors found Показывать сообщение, если ошибок не найдено - + Show internal warnings in log - + Enable inline suppressions - + Applications - + Add application - + Delete application - + Modify application - + Set as default application - + Reports Отчёты - + Save all errors when creating report Сохранять все ошибки при создании отчёта - + Save full path to files in reports Сохранять полные пути к файлам в отчётах + + + Language + + SettingsDialog - + + N/A + + + + Add a new application - + Modify an application - + Select include directory diff --git a/gui/cppcheck_se.ts b/gui/cppcheck_se.ts index 6190ebfe5..278a2de3f 100644 --- a/gui/cppcheck_se.ts +++ b/gui/cppcheck_se.ts @@ -222,17 +222,17 @@ kate -l(line) (file) MainWindow - - - - - - + + + + + + Cppcheck Cppcheck - + Standard Standard @@ -252,380 +252,375 @@ kate -l(line) (file) Verktygsfält - + &Check &Check - + &Edit &Redigera - + &License... &Licens... - + A&uthors... &Utvecklat av... - + &About... &Om... - + &Files... &Filer... - - + + Check files - + Ctrl+F Ctrl+F - + &Directory... &Katalog... - - + + Check directory - + Ctrl+D Ctrl+D - + &Recheck files Starta &om check - + Ctrl+R Ctrl+R - + &Stop &Stoppa - - + + Stop checking - + Esc Esc - + &Save results to file... &Spara resultat till fil... - + Ctrl+S Ctrl+S - + &Quit &Avsluta - + &Clear results &Töm resultat - + &Preferences &Inställningar - + Errors - - + + Show errors - + Warnings - - + + Show warnings - + Performance warnings - - + + Show performance warnings - + Show &hidden - + Information - + Show information messages - + Portability - + Show portability warnings - + &Check all &Kryssa alla - + &Uncheck all Kryssa &ur alla - + Collapse &all Ingen bra översättning! &Fäll ihop alla - + &Expand all &Expandera alla - + &Standard &Standard - + Standard items Standard poster - + Toolbar Verktygsfält - + &Categories &Kategorier - + Error categories Fel kategorier - + &Open XML... - + Open P&roject File... - + &New Project File... - + &Log View - + Log View - + C&lose Project File - + &Edit Project File... - + &Statistics - + &Contents &Innehåll - + Categories Kategorier - + Style warnings - - + + Show style warnings - + Open the help contents Öppna hjälp - + F1 F1 - &Language - &Språk - - - &Help &Hjälp - + Select files to check Välj filer att kontrollera - + Select directory to check Välj katalog som skall kontrolleras - + No suitable files found to check! Inga lämpliga filer hittades! - + License Licens - + Authors Utvecklare - + XML files (*.xml);;Text files (*.txt);;CSV files (*.csv) XML filer (*.xml);;Text filer (*.txt);;CSV filer (*.csv) - + Save the report file Spara rapport - - + + XML files (*.xml) XML filer (*.xml) - + You must close the project file before selecting new files or directories! - - - + + + Project: - + Open the report file - + Checking is running. Do you want to stop the checking and exit Cppcheck?. - + Text files (*.txt) Text filer (*.txt) - + CSV files (*.csv) CSV filer (*.csv) - + Cppcheck - %1 Cppcheck - %1 - + Failed to change the language: %1 @@ -641,85 +636,85 @@ Do you want to stop the checking and exit Cppcheck?. - - + + Cppcheck Help - + Failed to load help file (not found) - + Failed to load help file - - + + Project files (*.cppcheck);;All files(*.*) - + Select Project File - + Select Project Filename - + No project file loaded - + Finnish Finska - + English Engelska - + Dutch Nederländska - + Swedish Svenska - + German Tyska - + Russian Ryska - + Polish Polska - + Japanese Japanease - + Serbian @@ -798,18 +793,18 @@ Do you want to stop the checking and exit Cppcheck?. QObject - + Incorrect language specified! valt språk är ej korrekt! - + Language file %1 not found! Language file %1.qm not found! Språk filen %1 hittades ej! - + Failed to load translation for language %1 from file %2 Failed to load translation for language %1 from file %2.qm Misslyckades med att ladda översättningen för %1 från filen %2 @@ -1015,85 +1010,105 @@ För att ställa in vilka fel som skall visas använd visa menyn. Antal trådar: - + + Ideal count: + + + + + TextLabel + + + + Check all #ifdef configurations Kontrollera alla #ifdef konfigurationer - + Show full path of files Visa den fulla sökvägen för filer - + Show "No errors found" message when no errors found Visa "Inga fel hittades" meddelande när inga fel hittas - + Show internal warnings in log - + Enable inline suppressions - + Applications Program - + Add application Lägg till program - + Delete application Ta bort program - + Modify application Ändra program - + Set as default application Ange som standard program - + Reports Rapporter - + Save all errors when creating report Spara alla fel - + Save full path to files in reports Spara fulla sökvägar + + + Language + + SettingsDialog - + + N/A + + + + Add a new application Lägg till program - + Modify an application Ändra program - + Select include directory diff --git a/gui/cppcheck_sr.ts b/gui/cppcheck_sr.ts index a07961135..4beb61085 100644 --- a/gui/cppcheck_sr.ts +++ b/gui/cppcheck_sr.ts @@ -222,17 +222,17 @@ kate -l(line) (file) MainWindow - - - - - - + + + + + + Cppcheck Cppcheck - + Standard Standard @@ -252,379 +252,374 @@ kate -l(line) (file) - + &Check &Check - + &Edit &Edit - + &License... &License... - + A&uthors... A&uthors... - + &About... &About... - + &Files... &Files... - - + + Check files - + Ctrl+F Ctrl+F - + &Directory... &Directory... - - + + Check directory - + Ctrl+D Ctrl+D - + &Recheck files &Recheck files - + Ctrl+R Ctrl+R - + &Stop &Stop - - + + Stop checking - + Esc Esc - + &Save results to file... &Save results to file... - + Ctrl+S Ctrl+S - + &Quit &Quit - + &Clear results &Clear results - + &Preferences &Preferences - + Errors - - + + Show errors - + Warnings - - + + Show warnings - + Performance warnings - - + + Show performance warnings - + Show &hidden - + Information - + Show information messages - + Portability - + Show portability warnings - + &Check all &Check all - + &Uncheck all &Uncheck all - + Collapse &all Collapse &all - + &Expand all &Expand all - + &Standard - + Standard items - + Toolbar - + &Categories - + Error categories - + &Open XML... - + Open P&roject File... - + &New Project File... - + &Log View - + Log View - + C&lose Project File - + &Edit Project File... - + &Statistics - + &Contents - + Categories - + Style warnings - - + + Show style warnings - + Open the help contents - + F1 - &Language - &Language - - - &Help &Help - + Select files to check Select files to check - + Select directory to check Select directory to check - + No suitable files found to check! No suitable files found to check! - + License License - + Authors Authors - + XML files (*.xml);;Text files (*.txt);;CSV files (*.csv) XML files (*.xml);;Text files (*.txt);;CSV files (*.csv) - + Save the report file Save the report file - - + + XML files (*.xml) XML files (*.xml) - + You must close the project file before selecting new files or directories! - - - + + + Project: - + Open the report file - + Checking is running. Do you want to stop the checking and exit Cppcheck?. - + Text files (*.txt) Text files (*.txt) - + CSV files (*.csv) - + Cppcheck - %1 Cppcheck - %1 - + Failed to change the language: %1 @@ -638,85 +633,85 @@ Do you want to stop the checking and exit Cppcheck?. %1 - - + + Cppcheck Help - + Failed to load help file (not found) - + Failed to load help file - - + + Project files (*.cppcheck);;All files(*.*) - + Select Project File - + Select Project Filename - + No project file loaded - + Finnish Finski - + English Engleski - + Dutch Holandski - + Swedish Švedski - + German Nemački - + Russian Ruski - + Polish Poljski - + Japanese Japanease Japanski - + Serbian Srpski @@ -795,18 +790,18 @@ Do you want to stop the checking and exit Cppcheck?. QObject - + Incorrect language specified! Incorrect language specified! - + Language file %1 not found! Language file %1.qm not found! Could not find the file: %1! - + Failed to load translation for language %1 from file %2 Failed to load translation for language %1 from file %2.qm Failed to load translation for language %1 from file %2 @@ -1012,85 +1007,105 @@ To toggle what kind of errors are shown, open view menu. Number of threads: - + + Ideal count: + + + + + TextLabel + + + + Check all #ifdef configurations Check all #ifdef configurations - + Show full path of files Show full path of files - + Show "No errors found" message when no errors found Show "No errors found" message when no errors found - + Show internal warnings in log - + Enable inline suppressions - + Applications Applications - + Add application Add application - + Delete application Delete application - + Modify application Modify application - + Set as default application Set as default application - + Reports Reports - + Save all errors when creating report Save all errors when creating report - + Save full path to files in reports Save full path to files in reports + + + Language + + SettingsDialog - + + N/A + + + + Add a new application Add a new application - + Modify an application Modify an application - + Select include directory From 2d92f1ff6a48ce0a8645ba691c9e80199754a2be Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Mon, 10 Jan 2011 19:35:06 +0100 Subject: [PATCH 020/165] Fixed #2442 (False positive: Memory leak when function returns in 'if' instead of 'else if') --- lib/checkmemoryleak.cpp | 22 +++++++++++++++++++++- test/testmemleak.cpp | 4 ++++ 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/lib/checkmemoryleak.cpp b/lib/checkmemoryleak.cpp index c004edc05..278653877 100644 --- a/lib/checkmemoryleak.cpp +++ b/lib/checkmemoryleak.cpp @@ -838,6 +838,10 @@ Token *CheckMemoryLeakInFunction::getcode(const Token *tok, std::list extravar; + // The first token should be ";" rethead = new Token(0); rethead->str(";"); @@ -1084,10 +1088,22 @@ Token *CheckMemoryLeakInFunction::getcode(const Token *tok, std::listtokAt(2), varid, true)) { addtoken(&rettail, tok, "if(!var)"); + + // parse the if-body. + // if a variable is assigned then add variable to "extravar". + for (const Token *tok2 = tok->next()->link()->tokAt(2); tok2; tok2 = tok2->next()) + { + if (tok2->str() == "{") + tok2 = tok2->link(); + else if (tok2->str() == "}") + break; + else if (Token::Match(tok2, "%var% =")) + extravar.insert(tok2->varId()); + } } else { - // Check if the condition depends on var somehow.. + // Check if the condition depends on var or extravar somehow.. bool dep = false; int innerParlevel = 0; for (const Token *tok2 = tok->next(); tok2; tok2 = tok2->next()) @@ -1138,6 +1154,10 @@ Token *CheckMemoryLeakInFunction::getcode(const Token *tok, std::listvarId() && extravar.find(tok2->varId()) != extravar.end()) + { + dep = true; + } } if (Token::Match(tok, "if ( ! %varid% &&", varid)) diff --git a/test/testmemleak.cpp b/test/testmemleak.cpp index 05b04e3c4..ef900c103 100644 --- a/test/testmemleak.cpp +++ b/test/testmemleak.cpp @@ -425,6 +425,10 @@ private: ASSERT_EQUALS(";;use;if{}", getcode("char *s; if (x(&s)) { }", "s")); ASSERT_EQUALS(";;use;if{}", getcode("char *s; if (!s || x(&s)) { }", "s")); + // if (ticket #2442) + ASSERT_EQUALS(";;;;if(!var){;}ifv{}", getcode("char *s; int x = 0; if (!s) { x = 2; } if (x) { }", "s")); + ASSERT_EQUALS(";;;;if(!var){;}if{}", getcode("char *s; int x = 0; if (!s) { x = 2; } if (y) { }", "s")); + // switch.. ASSERT_EQUALS(";;switch{case;;break;};", getcode("char *s; switch(a){case 1: break;};", "s")); From 9658e2299d56cb566bd71c1ab8cda1754ad46f37 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Mon, 10 Jan 2011 19:57:26 +0100 Subject: [PATCH 021/165] Fixed #2443 (Possible null pointer dereference: xxx - otherwise it is redundant to check if xxx is null at line) --- lib/checknullpointer.cpp | 5 +++++ test/testnullpointer.cpp | 12 ++++++++++++ 2 files changed, 17 insertions(+) diff --git a/lib/checknullpointer.cpp b/lib/checknullpointer.cpp index 171af1cc3..0a327f372 100644 --- a/lib/checknullpointer.cpp +++ b/lib/checknullpointer.cpp @@ -461,6 +461,11 @@ void CheckNullPointer::nullPointerByDeRefAndChec() break; } + if (tok1->str() == ")" && Token::Match(tok1->link()->previous(), "while ( %varid%", varid)) + { + break; + } + if (tok1->varId() == varid && !Token::Match(tok1->previous(), "[?:]")) { // unknown : this is set by isPointerDeRef if it is diff --git a/test/testnullpointer.cpp b/test/testnullpointer.cpp index b1fcc4e7e..63550e950 100644 --- a/test/testnullpointer.cpp +++ b/test/testnullpointer.cpp @@ -405,6 +405,18 @@ private: " ;\n" "}\n"); ASSERT_EQUALS("", errout.str()); + + check("BOOL GotoFlyAnchor()\n" // #2243 + "{\n" + " const SwFrm* pFrm = GetCurrFrm();\n" + " do {\n" + " pFrm = pFrm->GetUpper();\n" + " } while( pFrm && !pFrm->IsFlyFrm() );\n" + "\n" + " if( !pFrm )\n" + " return FALSE;\n" + "}\n"); + ASSERT_EQUALS("", errout.str()); } void nullpointer5() From a5cf06f616f587b9cfd12e1a5db48c0ebead57a7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Mon, 10 Jan 2011 20:16:10 +0100 Subject: [PATCH 022/165] removed unused htdocs/build.bat --- htdocs/build.bat | 7 ------- 1 file changed, 7 deletions(-) delete mode 100755 htdocs/build.bat diff --git a/htdocs/build.bat b/htdocs/build.bat deleted file mode 100755 index 1b44c5c68..000000000 --- a/htdocs/build.bat +++ /dev/null @@ -1,7 +0,0 @@ - -cd.. - -msbuild cppcheck.cbproj /target:clean -msbuild cppcheck.cbproj /target:build /property:"config=release" > htdocs\bcb.txt - -cppcheck --all --style --unused-functions src 2> htdocs\cppcheck-results.txt From 98e77bda10078c114e82ad518ac2d2f09e9e8074 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Mon, 10 Jan 2011 22:24:02 +0100 Subject: [PATCH 023/165] scripts: Added define.pl that warns if #define is used. Related with ticket #689 --- scripts/define.pl | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100755 scripts/define.pl diff --git a/scripts/define.pl b/scripts/define.pl new file mode 100755 index 000000000..a6b7c0296 --- /dev/null +++ b/scripts/define.pl @@ -0,0 +1,35 @@ +#!/usr/bin/perl +# warn if there are #define in the code. it is often preferred with "const" +# usage: +# scripts/define.pl lib/checkstl.cpp + +sub checkfile +{ + my $filename = $_[0]; + + # parse file + open(FILE, $filename); + my @lines = ; + close(FILE); + + # check comments.. + my $linenr = 0; + foreach $line (@lines) + { + $linenr = $linenr + 1; + + # is there a define? + if ($line =~ /^#define\s+[A-Za-z0-9_]+\s+[^\s]/) + { + print "[$filename:$linenr] found #define\n"; + } + } +} + + +foreach $filename (@ARGV) +{ + checkfile($filename) +} + + From 79e52a8c45c817cd97f35a9af30870b5432733ff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Tue, 11 Jan 2011 19:34:35 +0100 Subject: [PATCH 024/165] Fixed #2296 (Tokenizer: simplifyKnownVariable doesn't simplify pointer properly 'delete [] p;') --- lib/tokenize.cpp | 11 +++++++++++ test/testtokenize.cpp | 22 ++++++++++++++++++++++ 2 files changed, 33 insertions(+) diff --git a/lib/tokenize.cpp b/lib/tokenize.cpp index 0ac6e1d63..0b31557d2 100644 --- a/lib/tokenize.cpp +++ b/lib/tokenize.cpp @@ -6504,6 +6504,17 @@ bool Tokenizer::simplifyKnownVariables() ret = true; } + // Delete pointer alias + if (pointeralias && tok3->str() == "delete" && + (Token::Match(tok3, "delete %varid% ;", varid) || + Token::Match(tok3, "delete [ ] %varid%", varid))) + { + tok3 = (tok3->strAt(1) == "[") ? tok3->tokAt(3) : tok3->next(); + tok3->str(value); + tok3->varId(valueVarId); + ret = true; + } + // Variable is used in function call.. if (Token::Match(tok3, ("%var% ( " + structname + " %varid% ,").c_str(), varid)) { diff --git a/test/testtokenize.cpp b/test/testtokenize.cpp index 621b88bca..304026cfe 100644 --- a/test/testtokenize.cpp +++ b/test/testtokenize.cpp @@ -128,6 +128,7 @@ private: TEST_CASE(simplifyKnownVariables36); // ticket #2304 - known value for strcpy parameter TEST_CASE(simplifyKnownVariables37); // ticket #2398 - false positive caused by no simplification in for loop TEST_CASE(simplifyKnownVariables38); // ticket #2399 - simplify conditions + TEST_CASE(simplifyKnownVariables39); TEST_CASE(simplifyKnownVariablesBailOutAssign); TEST_CASE(simplifyKnownVariablesBailOutFor1); TEST_CASE(simplifyKnownVariablesBailOutFor2); @@ -1965,6 +1966,27 @@ private: ASSERT_EQUALS(expected, tokenizeAndStringify(code, true)); } + void simplifyKnownVariables39() + { + // Ticket #2296 - simplify pointer alias 'delete p;' + { + const char code[] = "void f() {\n" + " int *x;\n" + " int *y = x;\n" + " delete y;\n" + "}"; + ASSERT_EQUALS("void f ( ) {\nint * x ;\n\ndelete x ;\n}", tokenizeAndStringify(code, true)); + } + { + const char code[] = "void f() {\n" + " int *x;\n" + " int *y = x;\n" + " delete [] y;\n" + "}"; + ASSERT_EQUALS("void f ( ) {\nint * x ;\n\ndelete [ ] x ;\n}", tokenizeAndStringify(code, true)); + } + } + void simplifyKnownVariablesBailOutAssign() { const char code[] = "int foo() {\n" From 846d3dae992523c1fa769e07297f0f58f5e5cd22 Mon Sep 17 00:00:00 2001 From: Kimmo Varis Date: Tue, 11 Jan 2011 21:03:18 +0200 Subject: [PATCH 025/165] Accept include paths ending with backslash. Convert include path to use internal path separators when parsing command line. Convert back to native separators when using paths. Ticket #2448 (Error in handling -I command line parameter) --- cli/cmdlineparser.cpp | 4 +++- cli/cppcheckexecutor.cpp | 6 ++++-- lib/preprocessor.cpp | 5 +++-- test/testcmdlineparser.cpp | 33 +++++++++++++++++++++++++++++++++ 4 files changed, 43 insertions(+), 5 deletions(-) diff --git a/cli/cmdlineparser.cpp b/cli/cmdlineparser.cpp index b35a411e3..6ef6b578f 100644 --- a/cli/cmdlineparser.cpp +++ b/cli/cmdlineparser.cpp @@ -25,6 +25,7 @@ #include "timer.h" #include "settings.h" #include "cmdlineparser.h" +#include "path.h" // xml is used in rules #include "tinyxml/tinyxml.h" @@ -254,9 +255,10 @@ bool CmdLineParser::ParseFromArgs(int argc, const char* const argv[]) { path = 2 + argv[i]; } + path = Path::fromNativeSeparators(path); // If path doesn't end with / or \, add it - if (path[path.length()-1] != '/' && path[path.length()-1] != '\\') + if (path[path.length()-1] != '/') path += '/'; _settings->_includePaths.push_back(path); diff --git a/cli/cppcheckexecutor.cpp b/cli/cppcheckexecutor.cpp index 661c1a9ab..c4d5b9f97 100644 --- a/cli/cppcheckexecutor.cpp +++ b/cli/cppcheckexecutor.cpp @@ -24,6 +24,7 @@ #include // EXIT_SUCCESS and EXIT_FAILURE #include "cmdlineparser.h" #include "filelister.h" +#include "path.h" CppCheckExecutor::CppCheckExecutor() { @@ -63,9 +64,10 @@ bool CppCheckExecutor::parseFromArgs(CppCheck *cppcheck, int argc, const char* c iter != _settings._includePaths.end(); ++iter) { - if (!getFileLister()->isDirectory(iter->c_str())) + const std::string path(Path::toNativeSeparators(*iter)); + if (!getFileLister()->isDirectory(path.c_str())) { - std::cout << "cppcheck: error: Couldn't find path given by -I '" + *iter + "'" << std::endl; + std::cout << "cppcheck: error: Couldn't find path given by -I '" + path + "'" << std::endl; return false; } } diff --git a/lib/preprocessor.cpp b/lib/preprocessor.cpp index 5f5b4ff44..467ad7f58 100644 --- a/lib/preprocessor.cpp +++ b/lib/preprocessor.cpp @@ -1537,10 +1537,11 @@ void Preprocessor::handleIncludes(std::string &code, const std::string &filePath includePaths2.push_front(""); for (std::list::const_iterator iter = includePaths2.begin(); iter != includePaths2.end(); ++iter) { - fin.open((*iter + filename).c_str()); + const std::string path(Path::toNativeSeparators(*iter)); + fin.open((path + filename).c_str()); if (fin.is_open()) { - filename = *iter + filename; + filename = path + filename; fileOpened = true; break; } diff --git a/test/testcmdlineparser.cpp b/test/testcmdlineparser.cpp index 6d45d09bb..3caba1749 100644 --- a/test/testcmdlineparser.cpp +++ b/test/testcmdlineparser.cpp @@ -51,6 +51,9 @@ private: TEST_CASE(defines3); TEST_CASE(includesnopath); TEST_CASE(includes); + TEST_CASE(includesslash); + TEST_CASE(includesbackslash); + TEST_CASE(includesnospace); TEST_CASE(includes2); TEST_CASE(enabledAll); TEST_CASE(enabledStyle); @@ -276,6 +279,36 @@ private: ASSERT_EQUALS(" include/", settings._includePaths.front()); } + void includesslash() + { + REDIRECT; + const char *argv[] = {"cppcheck", "-I include/", "file.cpp"}; + Settings settings; + CmdLineParser parser(&settings); + ASSERT(parser.ParseFromArgs(3, argv)); + ASSERT_EQUALS(" include/", settings._includePaths.front()); + } + + void includesbackslash() + { + REDIRECT; + const char *argv[] = {"cppcheck", "-I include\\", "file.cpp"}; + Settings settings; + CmdLineParser parser(&settings); + ASSERT(parser.ParseFromArgs(3, argv)); + ASSERT_EQUALS(" include/", settings._includePaths.front()); + } + + void includesnospace() + { + REDIRECT; + const char *argv[] = {"cppcheck", "-Iinclude", "file.cpp"}; + Settings settings; + CmdLineParser parser(&settings); + ASSERT(parser.ParseFromArgs(3, argv)); + ASSERT_EQUALS("include/", settings._includePaths.front()); + } + void includes2() { REDIRECT; From 09f900ce7990d36eff483bf0d08b59bcabdeb461 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Tue, 11 Jan 2011 20:14:15 +0100 Subject: [PATCH 026/165] Fixed #2440 (False negative: basic memory leak) --- lib/checkmemoryleak.cpp | 18 +++++++++++++++++- lib/checkmemoryleak.h | 3 +++ test/testmemleak.cpp | 10 ++++++++++ 3 files changed, 30 insertions(+), 1 deletion(-) diff --git a/lib/checkmemoryleak.cpp b/lib/checkmemoryleak.cpp index 278653877..c24421cfa 100644 --- a/lib/checkmemoryleak.cpp +++ b/lib/checkmemoryleak.cpp @@ -587,12 +587,18 @@ void CheckMemoryLeakInFunction::parse_noreturn() if (indentlevel == 0) break; } - if (Token::Match(tok2, "[;{}] exit (")) + if (Token::Match(tok2->previous(), "[;{}] exit (")) { noreturn.insert(info->className); break; } } + + // This function is not a noreturn function + if (indentlevel == 0) + { + notnoreturn.insert(info->className); + } } } @@ -733,7 +739,17 @@ const char * CheckMemoryLeakInFunction::call_func(const Token *tok, std::list it is not a noreturn function + if (tok->strAt(-1) == "=") + return NULL; + + // Function is not noreturn + if (notnoreturn.find(funcname) != notnoreturn.end()) + return NULL; + return (tok->previous()->str() != "=") ? "callfunc" : NULL; + } unsigned int par = 1; unsigned int parlevel = 0; diff --git a/lib/checkmemoryleak.h b/lib/checkmemoryleak.h index 75abc8bab..ecce46cb2 100644 --- a/lib/checkmemoryleak.h +++ b/lib/checkmemoryleak.h @@ -349,6 +349,9 @@ public: /** Function names for functions that are "noreturn" */ std::set noreturn; + /** Function names for functions that are not "noreturn" */ + std::set notnoreturn; + SymbolDatabase *symbolDatabase; }; diff --git a/test/testmemleak.cpp b/test/testmemleak.cpp index ef900c103..2c7503fd2 100644 --- a/test/testmemleak.cpp +++ b/test/testmemleak.cpp @@ -2619,6 +2619,16 @@ private: " fatal_error();\n" "}\n"); ASSERT_EQUALS("", errout.str()); + + check("void fatal_error()\n" // #2440 + "{ }\n" + "\n" + "void f()\n" + "{\n" + " char *p = malloc(100);\n" + " fatal_error();\n" + "}\n"); + ASSERT_EQUALS("[test.cpp:8]: (error) Memory leak: p\n", errout.str()); } From 38be7056b02366073c7771668aebac519be26826 Mon Sep 17 00:00:00 2001 From: Zachary Blair Date: Wed, 12 Jan 2011 22:33:46 -0800 Subject: [PATCH 027/165] Fixed #2434 (FP memleakOnRealloc) --- lib/checkmemoryleak.cpp | 19 +++++++++++++++---- test/testmemleak.cpp | 13 +++++++++++++ 2 files changed, 28 insertions(+), 4 deletions(-) diff --git a/lib/checkmemoryleak.cpp b/lib/checkmemoryleak.cpp index c24421cfa..5e6efda33 100644 --- a/lib/checkmemoryleak.cpp +++ b/lib/checkmemoryleak.cpp @@ -2451,14 +2451,25 @@ void CheckMemoryLeakInFunction::checkReallocUsage() } if (tok->varId() > 0 && - Token::Match(tok, "%var% = realloc|g_try_realloc ( %var% ,") && + Token::Match(tok, "%var% = realloc|g_try_realloc ( %var% , %any% ) ;|}") && tok->varId() == tok->tokAt(4)->varId() && parameterVarIds.find(tok->varId()) == parameterVarIds.end()) { // Check that another copy of the pointer wasn't saved earlier in the function - if (!Token::findmatch(startOfFunction, "%var% = %varid% ;", tok->varId()) && - !Token::findmatch(startOfFunction, "[{};] %varid% = %var% [;=]", tok->varId())) - memleakUponReallocFailureError(tok, tok->str()); + if (Token::findmatch(startOfFunction, "%var% = %varid% ;", tok->varId()) || + Token::findmatch(startOfFunction, "[{};] %varid% = %var% [;=]", tok->varId())) + continue; + + // Check that the allocation isn't followed immediately by an 'if (!var) { error(); }' that might handle failure + if (Token::Match(tok->tokAt(9), "if ( ! %varid% ) {", tok->varId())) + { + const Token* tokEndBrace = tok->tokAt(14)->link(); + if (tokEndBrace && Token::simpleMatch(tokEndBrace->tokAt(-2), ") ;") && + Token::Match(tokEndBrace->tokAt(-2)->link()->tokAt(-2), "{|}|; %var% (")) + continue; + } + + memleakUponReallocFailureError(tok, tok->str()); } } } diff --git a/test/testmemleak.cpp b/test/testmemleak.cpp index 2c7503fd2..cba61fb40 100644 --- a/test/testmemleak.cpp +++ b/test/testmemleak.cpp @@ -253,6 +253,7 @@ private: TEST_CASE(realloc8); TEST_CASE(realloc9); TEST_CASE(realloc10); + TEST_CASE(realloc11); TEST_CASE(assign); @@ -2150,6 +2151,18 @@ private: ASSERT_EQUALS("", errout.str()); } + void realloc11() + { + check("void foo() {\n" + " char *p;\n" + " p = realloc(p, size);\n" + " if (!p)\n" + " error();\n" + " usep(p);\n" + "}\n", false); + ASSERT_EQUALS("", errout.str()); + } + void assign() { check("void foo()\n" From 36c18072280d71e49d4d2a38d011666f792d6283 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Thu, 13 Jan 2011 20:12:57 +0100 Subject: [PATCH 028/165] Fixed #2458 (false positive: (warning) Redundant code: Found a statement that begins with numeric constant) --- lib/checkother.cpp | 51 +++++++++----------------------- test/testincompletestatement.cpp | 8 +++++ 2 files changed, 22 insertions(+), 37 deletions(-) diff --git a/lib/checkother.cpp b/lib/checkother.cpp index ffae9e671..dbd4e5686 100644 --- a/lib/checkother.cpp +++ b/lib/checkother.cpp @@ -2342,52 +2342,29 @@ void CheckOther::checkIncompleteStatement() if (!_settings->_checkCodingStyle) return; - int parlevel = 0; - for (const Token *tok = _tokenizer->tokens(); tok; tok = tok->next()) { if (tok->str() == "(") - ++parlevel; - else if (tok->str() == ")") - --parlevel; + tok = tok->link(); - if (parlevel != 0) - continue; + else if (Token::simpleMatch(tok, "= {")) + tok = tok->next()->link(); - if (Token::simpleMatch(tok, "= {")) + else if (Token::Match(tok, "[;{}] %str%") || Token::Match(tok, "[;{}] %num%")) { - /* We are in an assignment, so it's not a statement. - * Skip until ";" */ - - while (tok->str() != ";") + // bailout if there is a "? :" in this statement + bool bailout = false; + for (const Token *tok2 = tok->tokAt(2); tok2; tok2 = tok2->next()) { - int level = 0; - do - { - if (tok->str() == "(" || tok->str() == "{") - ++level; - else if (tok->str() == ")" || tok->str() == "}") - --level; - - tok = tok->next(); - - if (tok == NULL) - return; - } - while (level > 0); + if (tok2->str() == "?") + bailout = true; + else if (tok2->str() == ";") + break; } + if (bailout) + continue; - continue; - } - - if (Token::Match(tok, "[;{}] %str%") && !Token::Match(tok->tokAt(2), "[,}]")) - { - constStatementError(tok->next(), "string"); - } - - if (Token::Match(tok, "[;{}] %num%") && !Token::Match(tok->tokAt(2), "[,}]")) - { - constStatementError(tok->next(), "numeric"); + constStatementError(tok->next(), tok->next()->isNumber() ? "numeric" : "string"); } } } diff --git a/test/testincompletestatement.cpp b/test/testincompletestatement.cpp index bd7a6d8cb..622a0cd9f 100644 --- a/test/testincompletestatement.cpp +++ b/test/testincompletestatement.cpp @@ -66,6 +66,7 @@ private: TEST_CASE(intarray); TEST_CASE(structarraynull); TEST_CASE(structarray); + TEST_CASE(conditionalcall); // ; 0==x ? X() : Y(); } void test1() @@ -170,6 +171,13 @@ private: ASSERT_EQUALS("", errout.str()); } + void conditionalcall() + { + check("void f() {\n" + " 0==x ? X() : Y();\n" + "}\n"); + ASSERT_EQUALS("", errout.str()); + } }; REGISTER_TEST(TestIncompleteStatement) From b247d7d56e5a1f7359697c175333ce8a84eb526b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Thu, 13 Jan 2011 20:57:44 +0100 Subject: [PATCH 029/165] Fixed #2450 (False positive when iterator reused) --- lib/checkstl.cpp | 2 +- test/teststl.cpp | 10 ++++++++++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/lib/checkstl.cpp b/lib/checkstl.cpp index 91bfd0dfa..96f736b4f 100644 --- a/lib/checkstl.cpp +++ b/lib/checkstl.cpp @@ -968,7 +968,7 @@ void CheckStl::missingComparison() incrementToken = tok3; else if (tok3->varId() == iteratorId && Token::Match(tok3->next(), "!=|==")) incrementToken = 0; - else if (tok3->str() == "break") + else if (tok3->str() == "break" || tok3->str() == "return") incrementToken = 0; } if (incrementToken) diff --git a/test/teststl.cpp b/test/teststl.cpp index aeabd69fa..354907310 100644 --- a/test/teststl.cpp +++ b/test/teststl.cpp @@ -1118,6 +1118,16 @@ private: " }\n" "}"); ASSERT_EQUALS("", errout.str()); + + check("function f1(std::list &l1) {\n" + " for(std::list::iterator i = l1.begin(); i != l1.end(); i++) {\n" + " if (*i == 44) {\n" + " l1.insert(++i, 55);\n" + " return;\n" + " }\n" + " }\n" + "}"); + ASSERT_EQUALS("", errout.str()); } void missingInnerComparison5() From 4668e19060394f2a04dd91aec27022c743fb16d1 Mon Sep 17 00:00:00 2001 From: Kimmo Varis Date: Thu, 13 Jan 2011 23:18:04 +0200 Subject: [PATCH 030/165] Modify Cppcheck::addFile() only take one file as a parameter. CLI and GUI already do the directory walking for us and we have list of files to check. So we were duplicating this directory walking. Practically doing check again for each file if it is a directory. Which can take some time with large amount of files. --- lib/cppcheck.cpp | 6 +++--- lib/cppcheck.h | 4 +--- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/lib/cppcheck.cpp b/lib/cppcheck.cpp index fb2bebb6f..c2711bd60 100644 --- a/lib/cppcheck.cpp +++ b/lib/cppcheck.cpp @@ -56,14 +56,14 @@ void CppCheck::settings(const Settings ¤tSettings) _settings = currentSettings; } -void CppCheck::addFile(const std::string &path) +void CppCheck::addFile(const std::string &filepath) { - getFileLister()->recursiveAddFiles(_filenames, path.c_str()); + _filenames.push_back(Path::fromNativeSeparators(filepath)); } void CppCheck::addFile(const std::string &path, const std::string &content) { - _filenames.push_back(path); + _filenames.push_back(Path::fromNativeSeparators(path)); _fileContents[ path ] = content; } diff --git a/lib/cppcheck.h b/lib/cppcheck.h index 18a81d1db..8d8417c83 100644 --- a/lib/cppcheck.h +++ b/lib/cppcheck.h @@ -77,10 +77,8 @@ public: * @param path Relative or absolute path to the file to be checked, * e.g. "cppcheck.cpp". Note that only source files (.c, .cc or .cpp) * should be added to the list. Include files are gathered automatically. - * You can also give path, e.g. "src/" which will be scanned for source - * files recursively. */ - void addFile(const std::string &path); + void addFile(const std::string &filepath); /** * @brief Add new unreal file to be checked. From 420099588fffc73eb3706a3057136e95b1acb2cc Mon Sep 17 00:00:00 2001 From: Kimmo Varis Date: Thu, 13 Jan 2011 23:20:58 +0200 Subject: [PATCH 031/165] Add couple of missing path separator conversions. --- cli/cmdlineparser.cpp | 2 +- cli/cppcheckexecutor.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/cli/cmdlineparser.cpp b/cli/cmdlineparser.cpp index 6ef6b578f..50a65992d 100644 --- a/cli/cmdlineparser.cpp +++ b/cli/cmdlineparser.cpp @@ -459,7 +459,7 @@ bool CmdLineParser::ParseFromArgs(int argc, const char* const argv[]) } else - _pathnames.push_back(argv[i]); + _pathnames.push_back(Path::fromNativeSeparators(argv[i])); } if (_settings->isEnabled("unusedFunctions") && _settings->_jobs > 1) diff --git a/cli/cppcheckexecutor.cpp b/cli/cppcheckexecutor.cpp index c4d5b9f97..ef9277d64 100644 --- a/cli/cppcheckexecutor.cpp +++ b/cli/cppcheckexecutor.cpp @@ -81,7 +81,7 @@ bool CppCheckExecutor::parseFromArgs(CppCheck *cppcheck, int argc, const char* c // Execute recursiveAddFiles() to each given file parameter std::vector::const_iterator iter; for (iter = pathnames.begin(); iter != pathnames.end(); ++iter) - getFileLister()->recursiveAddFiles(filenames, iter->c_str()); + getFileLister()->recursiveAddFiles(filenames, Path::toNativeSeparators(iter->c_str())); for (iter = filenames.begin(); iter != filenames.end(); ++iter) cppcheck->addFile(*iter); From dffe1a0acd55788482d925368829dcd3ec037726 Mon Sep 17 00:00:00 2001 From: Kimmo Varis Date: Thu, 13 Jan 2011 23:25:17 +0200 Subject: [PATCH 032/165] Fix doxgen comment. --- lib/cppcheck.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/cppcheck.h b/lib/cppcheck.h index 8d8417c83..9f00c86b2 100644 --- a/lib/cppcheck.h +++ b/lib/cppcheck.h @@ -74,7 +74,7 @@ public: /** * @brief Add new file to be checked. * - * @param path Relative or absolute path to the file to be checked, + * @param filepath Relative or absolute path to the file to be checked, * e.g. "cppcheck.cpp". Note that only source files (.c, .cc or .cpp) * should be added to the list. Include files are gathered automatically. */ From 012b07023b7e448c006e635e171345c10ffb653b Mon Sep 17 00:00:00 2001 From: Kimmo Varis Date: Thu, 13 Jan 2011 23:38:08 +0200 Subject: [PATCH 033/165] GUI: Fix compiler warning from GCC. Thanks for vBm for reporting this! --- gui/settingsdialog.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gui/settingsdialog.cpp b/gui/settingsdialog.cpp index 71f0c34de..28fcf4773 100644 --- a/gui/settingsdialog.cpp +++ b/gui/settingsdialog.cpp @@ -40,8 +40,8 @@ SettingsDialog::SettingsDialog(QSettings *programSettings, QDialog(parent), mSettings(programSettings), mApplications(list), - mTranslator(translator), - mTempApplications(new ApplicationList(this)) + mTempApplications(new ApplicationList(this)), + mTranslator(translator) { mUI.setupUi(this); mTempApplications->Copy(list); From 708a75e36330d0f8d329c6a7ddb3bf1008eda1b5 Mon Sep 17 00:00:00 2001 From: Robert Reif Date: Fri, 14 Jan 2011 07:41:22 +0100 Subject: [PATCH 034/165] Fixed #2452 (syntax error when 'void f(typedef int x)' is used. causes segmentation fault.) --- lib/tokenize.cpp | 7 +++++++ test/testsimplifytokens.cpp | 9 +++++++++ 2 files changed, 16 insertions(+) diff --git a/lib/tokenize.cpp b/lib/tokenize.cpp index 0b31557d2..5d6117132 100644 --- a/lib/tokenize.cpp +++ b/lib/tokenize.cpp @@ -856,6 +856,13 @@ void Tokenizer::simplifyTypedef() else if (tok->str() != "typedef") continue; + // check for syntax errors + if (tok->previous() && tok->previous()->str() == "(") + { + syntaxError(tok); + continue; + } + // pull struct, union, enum or class definition out of typedef // use typedef name for unnamed struct, union, enum or class if (Token::Match(tok->next(), "const| struct|enum|union|class %type% {") || diff --git a/test/testsimplifytokens.cpp b/test/testsimplifytokens.cpp index 17e6e6c7b..0723e03af 100644 --- a/test/testsimplifytokens.cpp +++ b/test/testsimplifytokens.cpp @@ -233,6 +233,7 @@ private: TEST_CASE(simplifyTypedef73); // ticket #2412 TEST_CASE(simplifyTypedef74); // ticket #2414 TEST_CASE(simplifyTypedef75); // ticket #2426 + TEST_CASE(simplifyTypedef76); // ticket #2453 TEST_CASE(simplifyTypedefFunction1); TEST_CASE(simplifyTypedefFunction2); // ticket #1685 @@ -4795,6 +4796,14 @@ private: ASSERT_EQUALS("", errout.str()); } + void simplifyTypedef76() // ticket #2453 segmentation fault + { + const char code[] = "void f1(typedef int x) {}\n"; + const std::string expected = "void f1 ( typedef int x ) { }"; + ASSERT_EQUALS(expected, sizeof_(code)); + ASSERT_EQUALS("[test.cpp:1]: (error) syntax error\n", errout.str()); + } + void simplifyTypedefFunction1() { { From 00b49a51daa7d50e50adface231e46155938dc6f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Fri, 14 Jan 2011 19:50:07 +0100 Subject: [PATCH 035/165] Fixed #2451 (False positive when incrementing map value via iterator) --- lib/checkstl.cpp | 6 +++--- test/teststl.cpp | 7 +++++++ 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/lib/checkstl.cpp b/lib/checkstl.cpp index 96f736b4f..e87c0d076 100644 --- a/lib/checkstl.cpp +++ b/lib/checkstl.cpp @@ -962,11 +962,11 @@ void CheckStl::missingComparison() break; --indentlevel; } - else if (tok3->varId() == iteratorId && Token::simpleMatch(tok3->next(), "++")) + else if (Token::Match(tok3, "%varid% ++", iteratorId)) incrementToken = tok3; - else if (tok3->str() == "++" && tok3->next() && tok3->next()->varId() == iteratorId) + else if (Token::Match(tok3->previous(), "++ %varid% !!.", iteratorId)) incrementToken = tok3; - else if (tok3->varId() == iteratorId && Token::Match(tok3->next(), "!=|==")) + else if (Token::Match(tok3, "%varid% !=|==", iteratorId)) incrementToken = 0; else if (tok3->str() == "break" || tok3->str() == "return") incrementToken = 0; diff --git a/test/teststl.cpp b/test/teststl.cpp index 354907310..1c9a9e869 100644 --- a/test/teststl.cpp +++ b/test/teststl.cpp @@ -1080,6 +1080,13 @@ private: " }\n" "}\n"); ASSERT_EQUALS("[test.cpp:4]: (warning) Missing bounds check for extra iterator increment in loop.\n", errout.str()); + + check("void f(std::map &ints) {\n" + " for (std::map::iterator it = ints.begin(); it != ints.end(); ++it) {\n" + " ++it->second;\n" + " }\n" + "}\n"); + ASSERT_EQUALS("", errout.str()); } void missingInnerComparison2() From 79b993961016b5e68266b103ab5b921c1b84ae51 Mon Sep 17 00:00:00 2001 From: Robert Reif Date: Sat, 15 Jan 2011 07:59:37 +0100 Subject: [PATCH 036/165] Fixed #2465 (False positive: not initialised variable, but there is default constructor for it.) --- lib/symboldatabase.cpp | 45 +++++++++++++++++++++++++++++++++++++++++- lib/symboldatabase.h | 3 +++ test/testclass.cpp | 32 ++++++++++++++++++++++++++++++ 3 files changed, 79 insertions(+), 1 deletion(-) diff --git a/lib/symboldatabase.cpp b/lib/symboldatabase.cpp index 78708c0c9..e541101f7 100644 --- a/lib/symboldatabase.cpp +++ b/lib/symboldatabase.cpp @@ -411,12 +411,18 @@ SymbolDatabase::SymbolDatabase(const Tokenizer *tokenizer, const Settings *setti if (func->type == SymbolDatabase::Func::Constructor) { // check for no arguments: func ( ) - /** @todo check for arguments with default values someday */ if (func->argDef->next() == func->argDef->link()) { hasDefaultConstructor = true; break; } + + /** check for arguments with default values */ + else if (func->argCount() == func->initializedArgCount()) + { + hasDefaultConstructor = true; + break; + } } } @@ -908,6 +914,43 @@ const Token *SymbolDatabase::initBaseInfo(SpaceInfo *info, const Token *tok) return tok2; } + +//--------------------------------------------------------------------------- + +unsigned int SymbolDatabase::Func::argCount() const +{ + unsigned int count = 0; + + if (argDef->link() != argDef->next()) + { + count++; + + for (const Token *tok = argDef->next(); tok && tok->next() && tok->next() != argDef->link(); tok = tok->next()) + { + if (tok->str() == ",") + count++; + } + } + + return count; +} + +unsigned int SymbolDatabase::Func::initializedArgCount() const +{ + unsigned int count = 0; + + if (argDef->link() != argDef->next()) + { + for (const Token *tok = argDef->next(); tok && tok->next() && tok->next() != argDef->link(); tok = tok->next()) + { + if (tok->str() == "=") + count++; + } + } + + return count; +} + //--------------------------------------------------------------------------- SymbolDatabase::SpaceInfo::SpaceInfo(SymbolDatabase *check_, const Token *classDef_, SymbolDatabase::SpaceInfo *nestedIn_) : diff --git a/lib/symboldatabase.h b/lib/symboldatabase.h index 9cce2a422..0445b35ba 100644 --- a/lib/symboldatabase.h +++ b/lib/symboldatabase.h @@ -117,6 +117,9 @@ public: { } + unsigned int argCount() const; + unsigned int initializedArgCount() const; + const Token *tokenDef; // function name token in class definition const Token *argDef; // function argument start '(' in class definition const Token *token; // function name token in implementation diff --git a/test/testclass.cpp b/test/testclass.cpp index 1d5d48f12..f683dc502 100644 --- a/test/testclass.cpp +++ b/test/testclass.cpp @@ -61,6 +61,7 @@ private: TEST_CASE(uninitVar15); TEST_CASE(uninitVar16); TEST_CASE(uninitVar17); + TEST_CASE(uninitVar18); // ticket #2465 TEST_CASE(uninitVarEnum); TEST_CASE(uninitVarStream); TEST_CASE(uninitVarTypedef); @@ -2026,6 +2027,37 @@ private: ASSERT_EQUALS("[test.cpp:9]: (warning) Member variable 'Bar::foo' is not initialised in the constructor.\n", errout.str()); } + void uninitVar18() // ticket #2465 + { + checkUninitVar("struct Altren\n" + "{\n" + " Altren(int _a = 0) : value(0) { }\n" + " int value;\n" + "};\n" + "class A\n" + "{\n" + "public:\n" + " A() { }\n" + "private:\n" + " Altren value;\n" + "};\n"); + ASSERT_EQUALS("", errout.str()); + + checkUninitVar("struct Altren\n" + "{\n" + " Altren(int _a) : value(0) { }\n" + " int value;\n" + "};\n" + "class A\n" + "{\n" + "public:\n" + " A() { }\n" + "private:\n" + " Altren value;\n" + "};\n"); + ASSERT_EQUALS("[test.cpp:9]: (warning) Member variable 'A::value' is not initialised in the constructor.\n", errout.str()); + } + void uninitVarArray1() { checkUninitVar("class John\n" From 8ecba0af90c5cd800f261d57999a2906d90f6d1e Mon Sep 17 00:00:00 2001 From: Robert Reif Date: Sat, 15 Jan 2011 08:04:50 +0100 Subject: [PATCH 037/165] Fixed #2464 (False positive: not initialised/not assigned Static variable in copy constructors.) --- lib/tokenize.cpp | 7 +++++++ test/testsimplifytokens.cpp | 7 +++++++ 2 files changed, 14 insertions(+) diff --git a/lib/tokenize.cpp b/lib/tokenize.cpp index 5d6117132..5f77ffb84 100644 --- a/lib/tokenize.cpp +++ b/lib/tokenize.cpp @@ -8668,6 +8668,7 @@ void Tokenizer::simplifyStructDecl() // check for named struct/union if (Token::Match(tok, "struct|union %type% :|{")) { + Token *isStatic = tok->previous() && tok->previous()->str() == "static" ? tok->previous() : NULL; Token *type = tok->next(); Token *next = tok->tokAt(2); @@ -8684,6 +8685,12 @@ void Tokenizer::simplifyStructDecl() { tok->insertToken(";"); tok = tok->next(); + if (isStatic) + { + isStatic->deleteThis(); + tok->insertToken("static"); + tok = tok->next(); + } tok->insertToken(type->str().c_str()); } diff --git a/test/testsimplifytokens.cpp b/test/testsimplifytokens.cpp index 0723e03af..68ab73a0f 100644 --- a/test/testsimplifytokens.cpp +++ b/test/testsimplifytokens.cpp @@ -6271,6 +6271,13 @@ private: const char expected[] = ";"; ASSERT_EQUALS(expected, tok(code, false)); } + + // ticket 2464 + { + const char code[] = "static struct ABC { } abc ;"; + const char expected[] = "struct ABC { } ; static ABC abc ;"; + ASSERT_EQUALS(expected, tok(code, false)); + } } void removeUnwantedKeywords() From 5920dbb7e710f8db1bfd47724c2cacf82103775b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Sat, 15 Jan 2011 08:21:06 +0100 Subject: [PATCH 038/165] Fixed #2466 (Tokenizer: simplification of enum) --- lib/tokenize.cpp | 10 +++++++--- test/testsimplifytokens.cpp | 8 ++++++++ 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/lib/tokenize.cpp b/lib/tokenize.cpp index 5f77ffb84..882faeee4 100644 --- a/lib/tokenize.cpp +++ b/lib/tokenize.cpp @@ -7613,7 +7613,9 @@ void Tokenizer::simplifyEnum() // find all uses of this enumerator and substitute it's value for it's name if (enumName && (enumValue || (enumValueStart && enumValueEnd))) { - const std::string pattern(className.empty() ? "" : (className + " :: " + enumName->str()).c_str()); + const std::string pattern(className.empty() ? + std::string("") : + (className + " :: " + enumName->str())); int level = 1; bool inScope = true; @@ -7666,9 +7668,11 @@ void Tokenizer::simplifyEnum() else if (inScope && !exitThisScope && tok2->str() == enumName->str()) { if (Token::simpleMatch(tok2->previous(), "::") || - Token::simpleMatch(tok2->next(), "::")) + Token::Match(tok2->next(), "::|[")) { - // Don't replace this enum if it's preceded or followed by "::" + // Don't replace this enum if: + // * it's preceded or followed by "::" + // * it's followed by "[" } else if (!duplicateDefinition(&tok2, enumName)) { diff --git a/test/testsimplifytokens.cpp b/test/testsimplifytokens.cpp index 68ab73a0f..b9ad1f26e 100644 --- a/test/testsimplifytokens.cpp +++ b/test/testsimplifytokens.cpp @@ -276,6 +276,7 @@ private: TEST_CASE(enum15); TEST_CASE(enum16); // ticket #1988 TEST_CASE(enum17); // ticket #2381 (duplicate enums) + TEST_CASE(enum18); // #2466 (array with same name as enum constant) // remove "std::" on some standard functions TEST_CASE(removestd); @@ -6050,6 +6051,13 @@ private: ASSERT_EQUALS("", errout.str()); } + void enum18() // ticket #2466 - array with same name as enum constant + { + const char code[] = "enum ab { a=0, b };\n" + "void f() { a[0]; }\n"; + ASSERT_EQUALS("; void f ( ) { a [ 0 ] ; }", tok(code, false)); + } + void removestd() { ASSERT_EQUALS("; strcpy ( a , b ) ;", tok("; std::strcpy(a,b);")); From cf3201644452338f929795033c0565eba6c708aa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Sat, 15 Jan 2011 08:30:54 +0100 Subject: [PATCH 039/165] removed old comment --- test/testtokenize.cpp | 4 ---- 1 file changed, 4 deletions(-) diff --git a/test/testtokenize.cpp b/test/testtokenize.cpp index 304026cfe..5d010aee3 100644 --- a/test/testtokenize.cpp +++ b/test/testtokenize.cpp @@ -17,10 +17,6 @@ */ -// The preprocessor that Cppcheck uses is a bit special. Instead of generating -// the code for a known configuration, it generates the code for each configuration. - - #include "testsuite.h" #include "tokenize.h" #include "token.h" From 97d0755750901236eddb86ee4b0f8f0a56625a2f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Sat, 15 Jan 2011 08:48:42 +0100 Subject: [PATCH 040/165] Fixed #2454 (Tokenizer::simplifyKnownVariables: problem with float/double variables) --- lib/tokenize.cpp | 18 ++++++++++++++++++ test/testtokenize.cpp | 16 ++++++++++++++++ 2 files changed, 34 insertions(+) diff --git a/lib/tokenize.cpp b/lib/tokenize.cpp index 882faeee4..fd3d414f7 100644 --- a/lib/tokenize.cpp +++ b/lib/tokenize.cpp @@ -6206,6 +6206,9 @@ bool Tokenizer::simplifyKnownVariables() } } + // variable id for float/double variables + std::set floatvars; + // auto variables.. for (Token *tok = _tokens; tok; tok = tok->next()) { @@ -6218,6 +6221,11 @@ bool Tokenizer::simplifyKnownVariables() Token *tok2 = tok; for (; tok2; tok2 = tok2->next()) { + if (Token::Match(tok2, "[;{}] float|double %var% ;")) + { + floatvars.insert(tok2->tokAt(2)->varId()); + } + if (tok2->str() == "{") ++indentlevel; @@ -6325,8 +6333,18 @@ bool Tokenizer::simplifyKnownVariables() if (tok2->strAt(4) == ";") valueIsPointer = true; } + + // float value should contain a "." + else if (tok2->tokAt(2)->isNumber() && + floatvars.find(tok2->varId()) != floatvars.end() && + value.find(".") == std::string::npos) + { + value += ".0"; + } + if (Token::simpleMatch(tok2->next(), "= &")) tok2 = tok2->tokAt(3); + tok3 = tok2->next(); } Token* bailOutFromLoop = 0; diff --git a/test/testtokenize.cpp b/test/testtokenize.cpp index 5d010aee3..25089a374 100644 --- a/test/testtokenize.cpp +++ b/test/testtokenize.cpp @@ -132,6 +132,7 @@ private: TEST_CASE(simplifyKnownVariablesBailOutMemberFunction); TEST_CASE(simplifyKnownVariablesBailOutConditionalIncrement); TEST_CASE(simplifyKnownVariablesBailOutSwitchBreak); // ticket #2324 + TEST_CASE(simplifyKnownVariablesFloat); // #2454 - float variable TEST_CASE(varid1); TEST_CASE(varid2); @@ -2104,6 +2105,21 @@ private: ASSERT_EQUALS(expected, tokenizeAndStringify(code,true)); } + void simplifyKnownVariablesFloat() + { + // Ticket #2454 + const char code[] = "void f() {\n" + " float a = 40;\n" + " x(10 / a);\n" + "}\n"; + + const char expected[] = "void f ( ) {\n;\nx ( 0.25 ) ;\n}"; + + ASSERT_EQUALS(expected, tokenizeAndStringify(code,true)); + } + + + std::string tokenizeDebugListing(const std::string &code, bool simplify = false) { errout.str(""); From 6edf35ebf56305766fb50582c85d980bf819fdcf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Sat, 15 Jan 2011 12:09:36 +0100 Subject: [PATCH 041/165] Fixed #2463 (false positive: possible nullpointer dereference) --- lib/checknullpointer.cpp | 3 +++ test/testnullpointer.cpp | 20 ++++++++++++++++++++ 2 files changed, 23 insertions(+) diff --git a/lib/checknullpointer.cpp b/lib/checknullpointer.cpp index 0a327f372..e5f03cdf2 100644 --- a/lib/checknullpointer.cpp +++ b/lib/checknullpointer.cpp @@ -466,6 +466,9 @@ void CheckNullPointer::nullPointerByDeRefAndChec() break; } + if (tok1->str() == "break") + break; + if (tok1->varId() == varid && !Token::Match(tok1->previous(), "[?:]")) { // unknown : this is set by isPointerDeRef if it is diff --git a/test/testnullpointer.cpp b/test/testnullpointer.cpp index 63550e950..cd485e920 100644 --- a/test/testnullpointer.cpp +++ b/test/testnullpointer.cpp @@ -417,6 +417,26 @@ private: " return FALSE;\n" "}\n"); ASSERT_EQUALS("", errout.str()); + + // Ticket #2463 + check("struct A \n" + "{\n" + " B* W;\n" + "\n" + " void f() {\n" + " switch (InData) {\n" + " case 2:\n" + " if (!W) return;\n" + " W->foo();\n" + " break;\n" + " case 3:\n" + " f();\n" + " if (!W) return;\n" + " break;\n" + " }\n" + " }\n" + "}\n"); + ASSERT_EQUALS("", errout.str()); } void nullpointer5() From 94ebb24d3dc6153f0198949f865aa774e56733ec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Sat, 15 Jan 2011 20:55:51 +0100 Subject: [PATCH 042/165] Optimising: about 5% improvement with Visual Studio executable --- lib/checkother.cpp | 28 +++++++++------------------- lib/checkother.h | 10 ---------- 2 files changed, 9 insertions(+), 29 deletions(-) diff --git a/lib/checkother.cpp b/lib/checkother.cpp index dbd4e5686..d9ac6dfc8 100644 --- a/lib/checkother.cpp +++ b/lib/checkother.cpp @@ -2519,24 +2519,6 @@ void CheckOther::checkMathFunctions() } } - -bool CheckOther::isIdentifierObjectType(const Token * const tok) -{ - const std::string identifier = tok->tokAt(1)->str(); - - const std::map::const_iterator found = isClassResults.find(identifier); - if (found != isClassResults.end()) - { - return found->second; - } - - 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; -} - - void CheckOther::checkMisusedScopedObject() { // Skip this check for .c files @@ -2551,6 +2533,14 @@ void CheckOther::checkMisusedScopedObject() std::list::iterator i; + // list of classes / structs + std::set identifiers; + for (const Token *tok = _tokenizer->tokens(); tok; tok = tok->next()) + { + if (Token::Match(tok, "class|struct %var% [:{]")) + identifiers.insert(tok->next()->str()); + } + for (i = symbolDatabase->spaceInfoList.begin(); i != symbolDatabase->spaceInfoList.end(); ++i) { SymbolDatabase::SpaceInfo *info = *i; @@ -2576,7 +2566,7 @@ void CheckOther::checkMisusedScopedObject() if (Token::Match(tok, "[;{}] %var% (") && Token::Match(tok->tokAt(2)->link(), ") ;") - && isIdentifierObjectType(tok) + && identifiers.find(tok->next()->str()) != identifiers.end() ) { tok = tok->next(); diff --git a/lib/checkother.h b/lib/checkother.h index a26dc2ae9..9e49d8dce 100644 --- a/lib/checkother.h +++ b/lib/checkother.h @@ -293,16 +293,6 @@ private: return varname; } - - /** - * @brief query type of identifier - * @param tok Token of the identifier - * @return true if the identifier is of type 'class' or 'struct', - * false otherwise. - */ - bool isIdentifierObjectType(const Token* const tok); - - std::map isClassResults; }; /// @} //--------------------------------------------------------------------------- From bb2862bc97c6f29041bfe59884accb53c6ce559a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Sat, 15 Jan 2011 21:04:20 +0100 Subject: [PATCH 043/165] fixed unit test --- lib/checkother.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/checkother.cpp b/lib/checkother.cpp index d9ac6dfc8..3f47fe7b1 100644 --- a/lib/checkother.cpp +++ b/lib/checkother.cpp @@ -2537,7 +2537,7 @@ void CheckOther::checkMisusedScopedObject() std::set identifiers; for (const Token *tok = _tokenizer->tokens(); tok; tok = tok->next()) { - if (Token::Match(tok, "class|struct %var% [:{]")) + if (Token::Match(tok, "class|struct %var% [:{;]")) identifiers.insert(tok->next()->str()); } From 433ae8abf427a54d517c31d9125ef8771a2a7b4c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Sat, 15 Jan 2011 22:38:05 +0100 Subject: [PATCH 044/165] STL: Optimised checking --- lib/checkstl.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/lib/checkstl.cpp b/lib/checkstl.cpp index e87c0d076..4743bc173 100644 --- a/lib/checkstl.cpp +++ b/lib/checkstl.cpp @@ -684,10 +684,9 @@ void CheckStl::stlBoundries() for (const Token *tok = _tokenizer->tokens(); tok; tok = tok->next()) { // Declaring iterator.. - const std::string checkStr = (std::string(STL_CONTAINER_LIST) + " <"); - if (Token::Match(tok, checkStr.c_str())) + if (tok->str() == "<" && Token::Match(tok->previous(), STL_CONTAINER_LIST)) { - const std::string container_name(tok->strAt(0)); + const std::string container_name(tok->strAt(-1)); while (tok && tok->str() != ">") tok = tok->next(); if (!tok) From 8fa26fbd28d975b03408ba7880d56e2f4d5ff5a3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Sun, 16 Jan 2011 09:56:04 +0100 Subject: [PATCH 045/165] Memory leaks: Optimised and refactored --- lib/checkmemoryleak.cpp | 111 +++++++++++++++++++++++++++++++++------- 1 file changed, 93 insertions(+), 18 deletions(-) diff --git a/lib/checkmemoryleak.cpp b/lib/checkmemoryleak.cpp index 5e6efda33..b137eb0ca 100644 --- a/lib/checkmemoryleak.cpp +++ b/lib/checkmemoryleak.cpp @@ -865,8 +865,6 @@ Token *CheckMemoryLeakInFunction::getcode(const Token *tok, std::listfileIndex(tok->fileIndex()); rettail = rethead; - bool isloop = false; - int indentlevel = 0; int parlevel = 0; for (; tok; tok = tok->next()) @@ -884,15 +882,59 @@ Token *CheckMemoryLeakInFunction::getcode(const Token *tok, std::liststr() == "(") + else if (tok->str() == "(") ++parlevel; else if (tok->str() == ")") --parlevel; - isloop &= (parlevel > 0); if (parlevel == 0 && tok->str() == ";") addtoken(&rettail, tok, ";"); + // Start of new statement.. check if the statement has anything interesting + if (Token::Match(tok, "[;{}]") && varid > 0 && parlevel == 0) + { + if (Token::Match(tok->next(), "[{};]")) + continue; + + // function calls are interesting.. + const Token *tok2 = tok; + while (Token::Match(tok2->next(), "%var% .")) + tok2 = tok2->tokAt(2); + if (Token::Match(tok2->next(), "%var% (")) + ; + + else if (Token::Match(tok->next(), "continue|break|return|throw|goto|do|else")) + ; + + else + { + const Token *skipToToken = 0; + + // scan statement for interesting keywords / varid + for (tok2 = tok->next(); tok2; tok2 = tok2->next()) + { + if (tok2->str() == ";") + { + // nothing interesting found => skip this statement + skipToToken = tok2->previous(); + break; + } + + if (tok2->varId() == varid || + tok2->str() == ":") + { + break; + } + } + + if (skipToToken) + { + tok = skipToToken; + continue; + } + } + } + if (varid == 0) { if (!callstack.empty() && Token::Match(tok, "[;{}] __cppcheck_lock|__cppcheck_unlock ( ) ;")) @@ -967,6 +1009,8 @@ Token *CheckMemoryLeakInFunction::getcode(const Token *tok, std::listtokAt(2); + if (Token::Match(tok, "%var% (")) + tok = tok->next()->link(); continue; } } @@ -1047,8 +1091,7 @@ Token *CheckMemoryLeakInFunction::getcode(const Token *tok, std::listprevious(), "[;{})=] %var%") || - Token::Match(tok->previous(), "| %var%")) + if (Token::Match(tok->previous(), "[;{})=|] %var%")) { AllocType dealloc = getDeallocationType(tok, varid); @@ -1069,6 +1112,9 @@ Token *CheckMemoryLeakInFunction::getcode(const Token *tok, std::liststrAt(2) == "(") + tok = tok->tokAt(2)->link(); continue; } } @@ -1100,6 +1146,7 @@ Token *CheckMemoryLeakInFunction::getcode(const Token *tok, std::listnext()->link(); + continue; } else if (Token::simpleMatch(tok, "if (") && notvar(tok->tokAt(2), varid, true)) { @@ -1116,6 +1163,9 @@ Token *CheckMemoryLeakInFunction::getcode(const Token *tok, std::listnext(); - if (tok->link()) - tok = tok->link(); + tok = tok->next()->link(); + continue; } } } @@ -1201,25 +1250,30 @@ Token *CheckMemoryLeakInFunction::getcode(const Token *tok, std::liststr() == "else") || (tok->str() == "switch")) { addtoken(&rettail, tok, tok->str()); + if (tok->str() == "switch") + tok = tok->next()->link(); + continue; } - else if ((tok->str() == "case")) + if ((tok->str() == "case")) { addtoken(&rettail, tok, "case"); addtoken(&rettail, tok, ";"); + if (Token::Match(tok, "case %any% :")) + tok = tok->tokAt(2); + continue; } - else if ((tok->str() == "default")) + if ((tok->str() == "default")) { addtoken(&rettail, tok, "default"); addtoken(&rettail, tok, ";"); + continue; } // Loops.. else if ((tok->str() == "for") || (tok->str() == "while")) { - isloop = true; - if (Token::simpleMatch(tok, "while ( true )") || Token::simpleMatch(tok, "for ( ; ; )")) { @@ -1266,14 +1320,35 @@ Token *CheckMemoryLeakInFunction::getcode(const Token *tok, std::list 0) + { + unsigned int parlevel2 = 0; + for (const Token *tok2 = tok->tokAt(2); tok2; tok2 = tok2->next()) + { + if (tok2->str() == "(") + ++parlevel2; + else if (tok2->str() == ")") + { + if (parlevel2 > 0) + --parlevel2; + else + break; + } + if (notvar(tok2, varid)) + { + addtoken(&rettail, tok2, "!var"); + break; + } + } + } + + continue; } - else if ((tok->str() == "do")) + if ((tok->str() == "do")) { addtoken(&rettail, tok, "do"); - } - if (varid > 0 && isloop && notvar(tok, varid)) - { - addtoken(&rettail, tok, "!var"); + continue; } // continue / break.. From 8ef47dc576dce7d14adcc102630cca31da38efc8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Sun, 16 Jan 2011 09:57:56 +0100 Subject: [PATCH 046/165] astyle formatting --- lib/checkmemoryleak.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/lib/checkmemoryleak.cpp b/lib/checkmemoryleak.cpp index b137eb0ca..4ce6a918e 100644 --- a/lib/checkmemoryleak.cpp +++ b/lib/checkmemoryleak.cpp @@ -920,13 +920,13 @@ Token *CheckMemoryLeakInFunction::getcode(const Token *tok, std::listvarId() == varid || + if (tok2->varId() == varid || tok2->str() == ":") { break; } } - + if (skipToToken) { tok = skipToToken; @@ -1112,9 +1112,9 @@ Token *CheckMemoryLeakInFunction::getcode(const Token *tok, std::liststrAt(2) == "(") - tok = tok->tokAt(2)->link(); + tok = tok->tokAt(2)->link(); continue; } } @@ -1320,7 +1320,7 @@ Token *CheckMemoryLeakInFunction::getcode(const Token *tok, std::list 0) { unsigned int parlevel2 = 0; @@ -1342,7 +1342,7 @@ Token *CheckMemoryLeakInFunction::getcode(const Token *tok, std::liststr() == "do")) From 0f6644e1eaeed3bf7b9b1d5821b3aff7bfcfa0a8 Mon Sep 17 00:00:00 2001 From: Robert Reif Date: Sun, 16 Jan 2011 11:18:12 +0100 Subject: [PATCH 047/165] Symbol database: Refactorings --- lib/checkclass.cpp | 249 ++++++++++++++++++++++++++++++++++++++++- lib/checkclass.h | 7 +- lib/symboldatabase.cpp | 244 ---------------------------------------- lib/symboldatabase.h | 14 +-- test/testclass.cpp | 6 +- 5 files changed, 257 insertions(+), 263 deletions(-) diff --git a/lib/checkclass.cpp b/lib/checkclass.cpp index 69e77ed48..ffcc55633 100644 --- a/lib/checkclass.cpp +++ b/lib/checkclass.cpp @@ -811,7 +811,7 @@ void CheckClass::virtualDestructor() for (unsigned int j = 0; j < info->derivedFrom.size(); ++j) { // Check if base class is public and exists in database - if (info->derivedFrom[j].access == SymbolDatabase::Public && info->derivedFrom[j].spaceInfo) + if (info->derivedFrom[j].access != SymbolDatabase::Private && info->derivedFrom[j].spaceInfo) { const SymbolDatabase::SpaceInfo *spaceInfo = info->derivedFrom[j].spaceInfo; @@ -977,12 +977,12 @@ void CheckClass::checkConst() // check if base class function is virtual if (!info->derivedFrom.empty()) { - if (symbolDatabase->isVirtualFunc(info, func->tokenDef)) + if (isVirtualFunc(info, func->tokenDef)) continue; } // if nothing non-const was found. write error.. - if (symbolDatabase->checkConstFunc(info, paramEnd)) + if (checkConstFunc(info, paramEnd)) { std::string classname = info->className; SymbolDatabase::SpaceInfo *nest = info->nestedIn; @@ -1010,6 +1010,249 @@ void CheckClass::checkConst() } } +bool CheckClass::isMemberVar(const SymbolDatabase::SpaceInfo *info, const Token *tok) +{ + const Token *tok1 = tok; + + while (tok->previous() && !Token::Match(tok->previous(), "}|{|;|public:|protected:|private:|return|:|?")) + { + if (Token::Match(tok->previous(), "* this")) + return true; + + tok = tok->previous(); + } + + if (tok->str() == "this") + return true; + + if (Token::Match(tok, "( * %var% ) [") || (Token::Match(tok, "( * %var% ) <<") && tok1->next()->str() == "<<")) + tok = tok->tokAt(2); + + // ignore class namespace + if (tok->str() == info->className && tok->next()->str() == "::") + tok = tok->tokAt(2); + + std::list::const_iterator var; + for (var = info->varlist.begin(); var != info->varlist.end(); ++var) + { + if (var->token->str() == tok->str()) + { + return !var->isMutable; + } + } + + // 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 SymbolDatabase::SpaceInfo *spaceInfo = info->derivedFrom[i].spaceInfo; + + // find the function in the base class + if (spaceInfo) + { + if (isMemberVar(spaceInfo, tok)) + return true; + } + } + } + + return false; +} + +bool CheckClass::isConstMemberFunc(const SymbolDatabase::SpaceInfo *info, const Token *tok) +{ + std::list::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 SymbolDatabase::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 SymbolDatabase::SpaceInfo *info, const Token *tok) +{ + // if the function doesn't have any assignment nor function call, + // it can be a const function.. + unsigned int indentlevel = 0; + bool isconst = true; + for (const Token *tok1 = tok; tok1; tok1 = tok1->next()) + { + if (tok1->str() == "{") + ++indentlevel; + else if (tok1->str() == "}") + { + if (indentlevel <= 1) + break; + --indentlevel; + } + + // assignment.. = += |= .. + else if (tok1->str() == "=" || + (tok1->str().find("=") == 1 && + tok1->str().find_first_of("") == std::string::npos)) + { + if (tok1->previous()->varId() == 0 && !info->derivedFrom.empty()) + { + isconst = false; + break; + } + else if (isMemberVar(info, tok1->previous())) + { + isconst = false; + break; + } + else if (tok1->previous()->str() == "]") + { + // TODO: I assume that the assigned variable is a member variable + // don't assume it + isconst = false; + break; + } + else if (tok1->next()->str() == "this") + { + isconst = false; + break; + } + + // FIXME: I assume that a member union/struct variable is assigned. + else if (Token::Match(tok1->tokAt(-2), ". %var%")) + { + isconst = false; + break; + } + } + + // streaming: << + else if (tok1->str() == "<<" && isMemberVar(info, tok1->previous())) + { + isconst = false; + break; + } + + // increment/decrement (member variable?).. + else if (Token::Match(tok1, "++|--")) + { + isconst = false; + break; + } + + // function call.. + 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; + } + + // delete.. + else if (tok1->str() == "delete") + { + isconst = false; + break; + } + } + + return isconst; +} + +//--------------------------------------------------------------------------- + +// check if this function is defined virtual in the base classes +bool CheckClass::isVirtualFunc(const SymbolDatabase::SpaceInfo *info, const Token *functionToken) const +{ + // check each base class + for (unsigned int i = 0; i < info->derivedFrom.size(); ++i) + { + // check if base class exists in database + if (info->derivedFrom[i].spaceInfo) + { + const SymbolDatabase::SpaceInfo *derivedFrom = info->derivedFrom[i].spaceInfo; + + std::list::const_iterator func; + + // check if function defined in base class + for (func = derivedFrom->functionList.begin(); func != derivedFrom->functionList.end(); ++func) + { + if (func->isVirtual) + { + const Token *tok = func->tokenDef; + + if (tok->str() == functionToken->str()) + { + const Token *temp1 = tok->previous(); + const Token *temp2 = functionToken->previous(); + bool returnMatch = true; + + // check for matching return parameters + while (temp1->str() != "virtual") + { + if (temp1->str() != temp2->str()) + { + returnMatch = false; + break; + } + + temp1 = temp1->previous(); + temp2 = temp2->previous(); + } + + // check for matching function parameters + if (returnMatch && symbolDatabase->argsMatch(info, tok->tokAt(2), functionToken->tokAt(2), std::string(""), 0)) + { + return true; + } + } + } + } + + if (!derivedFrom->derivedFrom.empty()) + { + if (isVirtualFunc(derivedFrom, functionToken)) + return true; + } + } + else + { + // unable to find base class so assume it has a virtual function + return true; + } + } + + return false; +} + void CheckClass::checkConstError(const Token *tok, const std::string &classname, const std::string &funcname) { reportError(tok, Severity::information, "functionConst", diff --git a/lib/checkclass.h b/lib/checkclass.h index 42603cf0e..c87b4fdd9 100644 --- a/lib/checkclass.h +++ b/lib/checkclass.h @@ -169,7 +169,12 @@ private: bool hasDeallocation(const Token *first, const Token *last); bool hasAssignSelf(const Token *first, const Token *last, const Token *rhs); - + // checkConst helper functions + bool isMemberVar(const SymbolDatabase::SpaceInfo *info, const Token *tok); + bool isConstMemberFunc(const SymbolDatabase::SpaceInfo *info, const Token *tok); + bool checkConstFunc(const SymbolDatabase::SpaceInfo *info, const Token *tok); + /** @brief check if this function is virtual in the base classes */ + bool isVirtualFunc(const SymbolDatabase::SpaceInfo *info, const Token *functionToken) const; }; /// @} //--------------------------------------------------------------------------- diff --git a/lib/symboldatabase.cpp b/lib/symboldatabase.cpp index e541101f7..2319c945f 100644 --- a/lib/symboldatabase.cpp +++ b/lib/symboldatabase.cpp @@ -1784,247 +1784,3 @@ void SymbolDatabase::SpaceInfo::initializeVarList(const Func &func, std::listprevious() && !Token::Match(tok->previous(), "}|{|;|public:|protected:|private:|return|:|?")) - { - if (Token::Match(tok->previous(), "* this")) - return true; - - tok = tok->previous(); - } - - if (tok->str() == "this") - return true; - - if (Token::Match(tok, "( * %var% ) [") || (Token::Match(tok, "( * %var% ) <<") && tok1->next()->str() == "<<")) - tok = tok->tokAt(2); - - // ignore class namespace - if (tok->str() == info->className && tok->next()->str() == "::") - tok = tok->tokAt(2); - - std::list::const_iterator var; - for (var = info->varlist.begin(); var != info->varlist.end(); ++var) - { - if (var->token->str() == tok->str()) - { - return !var->isMutable; - } - } - - // 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 (isMemberVar(spaceInfo, tok)) - return true; - } - } - } - - return false; -} - -bool SymbolDatabase::isConstMemberFunc(const SymbolDatabase::SpaceInfo *info, const Token *tok) -{ - std::list::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 SymbolDatabase::SpaceInfo *spaceInfo = info->derivedFrom[i].spaceInfo; - - // find the function in the base class - if (spaceInfo) - { - if (isConstMemberFunc(spaceInfo, tok)) - return true; - } - } - } - - return false; -} - -bool SymbolDatabase::checkConstFunc(const SymbolDatabase::SpaceInfo *info, const Token *tok) -{ - // if the function doesn't have any assignment nor function call, - // it can be a const function.. - unsigned int indentlevel = 0; - bool isconst = true; - for (const Token *tok1 = tok; tok1; tok1 = tok1->next()) - { - if (tok1->str() == "{") - ++indentlevel; - else if (tok1->str() == "}") - { - if (indentlevel <= 1) - break; - --indentlevel; - } - - // assignment.. = += |= .. - else if (tok1->str() == "=" || - (tok1->str().find("=") == 1 && - tok1->str().find_first_of("") == std::string::npos)) - { - if (tok1->previous()->varId() == 0 && !info->derivedFrom.empty()) - { - isconst = false; - break; - } - else if (isMemberVar(info, tok1->previous())) - { - isconst = false; - break; - } - else if (tok1->previous()->str() == "]") - { - // TODO: I assume that the assigned variable is a member variable - // don't assume it - isconst = false; - break; - } - else if (tok1->next()->str() == "this") - { - isconst = false; - break; - } - - // FIXME: I assume that a member union/struct variable is assigned. - else if (Token::Match(tok1->tokAt(-2), ". %var%")) - { - isconst = false; - break; - } - } - - // streaming: << - else if (tok1->str() == "<<" && isMemberVar(info, tok1->previous())) - { - isconst = false; - break; - } - - // increment/decrement (member variable?).. - else if (Token::Match(tok1, "++|--")) - { - isconst = false; - break; - } - - // function call.. - 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; - } - - // delete.. - else if (tok1->str() == "delete") - { - isconst = false; - break; - } - } - - return isconst; -} - -//--------------------------------------------------------------------------- - -// check if this function is defined virtual in the base classes -bool SymbolDatabase::isVirtualFunc(const SymbolDatabase::SpaceInfo *info, const Token *functionToken) const -{ - // check each base class - for (unsigned int i = 0; i < info->derivedFrom.size(); ++i) - { - // check if base class exists in database - if (info->derivedFrom[i].spaceInfo) - { - const SymbolDatabase::SpaceInfo *derivedFrom = info->derivedFrom[i].spaceInfo; - - std::list::const_iterator func; - - // check if function defined in base class - for (func = derivedFrom->functionList.begin(); func != derivedFrom->functionList.end(); ++func) - { - if (func->isVirtual) - { - const Token *tok = func->tokenDef; - - if (tok->str() == functionToken->str()) - { - const Token *temp1 = tok->previous(); - const Token *temp2 = functionToken->previous(); - bool returnMatch = true; - - // check for matching return parameters - while (temp1->str() != "virtual") - { - if (temp1->str() != temp2->str()) - { - returnMatch = false; - break; - } - - temp1 = temp1->previous(); - temp2 = temp2->previous(); - } - - // check for matching function parameters - if (returnMatch && argsMatch(info, tok->tokAt(2), functionToken->tokAt(2), std::string(""), 0)) - { - return true; - } - } - } - } - - if (!derivedFrom->derivedFrom.empty()) - { - if (isVirtualFunc(derivedFrom, functionToken)) - return true; - } - } - else - { - // unable to find base class so assume it has a virtual function - return true; - } - } - - return false; -} - diff --git a/lib/symboldatabase.h b/lib/symboldatabase.h index 0445b35ba..268aa3a95 100644 --- a/lib/symboldatabase.h +++ b/lib/symboldatabase.h @@ -249,15 +249,6 @@ public: bool isVariableDeclaration(const Token* tok, const Token*& vartok, const Token*& typetok) 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); - - /** @brief check if this function is virtual in the base classes */ - bool isVirtualFunc(const SymbolDatabase::SpaceInfo *info, const Token *functionToken) const; - /** @brief Information about all namespaces/classes/structrues */ std::list spaceInfoList; @@ -269,6 +260,8 @@ public: */ const SpaceInfo *findVarType(const SpaceInfo *start, const Token *type) const; + bool argsMatch(const SpaceInfo *info, const Token *first, const Token *second, const std::string &path, unsigned int depth) const; + private: // Needed by Borland C++: @@ -276,9 +269,8 @@ private: void addFunction(SpaceInfo **info, const Token **tok, const Token *argStart); void addNewFunction(SpaceInfo **info, const Token **tok); - + const Token *initBaseInfo(SpaceInfo *info, const Token *tok); bool isFunction(const Token *tok, const Token **funcStart, const Token **argStart) const; - bool argsMatch(const SpaceInfo *info, const Token *first, const Token *second, const std::string &path, unsigned int depth) const; const Tokenizer *_tokenizer; const Settings *_settings; diff --git a/test/testclass.cpp b/test/testclass.cpp index f683dc502..a36dcd13a 100644 --- a/test/testclass.cpp +++ b/test/testclass.cpp @@ -1316,8 +1316,7 @@ private: checkVirtualDestructor("class Base { };\n" "class Derived : protected Base { public: ~Derived() { (void)11; } };"); - TODO_ASSERT_EQUALS("[test.cpp:1]: (error) Class Base which is inherited by class Derived does not have a virtual destructor\n", errout.str()); - ASSERT_EQUALS("", errout.str()); + ASSERT_EQUALS("[test.cpp:1]: (error) Class Base which is inherited by class Derived does not have a virtual destructor\n", errout.str()); checkVirtualDestructor("class Base { };\n" "class Derived : private Base { public: ~Derived() { (void)11; } };"); @@ -1338,8 +1337,7 @@ private: checkVirtualDestructor("class Base { public: ~Base(); };\n" "class Derived : protected Base { public: ~Derived() { (void)11; } };"); - TODO_ASSERT_EQUALS("[test.cpp:1]: (error) Class Base which is inherited by class Derived does not have a virtual destructor\n", errout.str()); - ASSERT_EQUALS("", errout.str()); + ASSERT_EQUALS("[test.cpp:1]: (error) Class Base which is inherited by class Derived does not have a virtual destructor\n", errout.str()); checkVirtualDestructor("class Base { public: ~Base(); };\n" "class Derived : private Fred, public Base { public: ~Derived() { (void)11; } };"); From beb2db82a2539a3e5bc0bd3b832a342701c38377 Mon Sep 17 00:00:00 2001 From: Robert Reif Date: Sun, 16 Jan 2011 11:24:58 +0100 Subject: [PATCH 048/165] Fixed #980 (false negative: division by zero when using enum) --- lib/tokenize.cpp | 29 ++++++++++++++++++++++++++++- test/testsimplifytokens.cpp | 7 +++++++ 2 files changed, 35 insertions(+), 1 deletion(-) diff --git a/lib/tokenize.cpp b/lib/tokenize.cpp index fd3d414f7..b856fa6dd 100644 --- a/lib/tokenize.cpp +++ b/lib/tokenize.cpp @@ -2430,6 +2430,9 @@ bool Tokenizer::tokenize(std::istream &code, // struct initialization (must be used before simplifyVarDecl) simplifyStructInit(); + // Change initialisation of variable to assignment + simplifyInitVar(); + // Split up variable declarations. simplifyVarDecl(); @@ -2467,7 +2470,8 @@ bool Tokenizer::tokenize(std::istream &code, // Change initialisation of variable to assignment simplifyInitVar(); - + // Split up variable declarations. + simplifyVarDecl(); if (!preprocessorCondition) { @@ -6083,6 +6087,7 @@ bool Tokenizer::simplifyLogicalOperators() } // int i(0); => int i; i = 0; +// int i(0), j; => int i; i = 0; int j; void Tokenizer::simplifyInitVar() { for (Token *tok = _tokens; tok; tok = tok->next()) @@ -6095,6 +6100,28 @@ void Tokenizer::simplifyInitVar() { tok = initVar(tok); } + else if (Token::Match(tok, "class|struct|union| %type% *| %var% ( &| %any% ) ,")) + { + Token *tok1 = tok; + while (tok1->str() != ",") + tok1 = tok1->next(); + tok1->str(";"); + Token *tok2 = tok; + if (Token::Match(tok2, "class|struct|union")) + { + tok1->insertToken(tok2->str()); + tok1 = tok1->next(); + tok2 = tok2->next(); + } + tok1->insertToken(tok2->str()); + tok1 = tok1->next(); + tok2 = tok2->next(); + if (tok2->str() == "*") + { + tok1->insertToken("*"); + } + tok = initVar(tok); + } } } diff --git a/test/testsimplifytokens.cpp b/test/testsimplifytokens.cpp index b9ad1f26e..6410774aa 100644 --- a/test/testsimplifytokens.cpp +++ b/test/testsimplifytokens.cpp @@ -6286,6 +6286,13 @@ private: const char expected[] = "struct ABC { } ; static ABC abc ;"; ASSERT_EQUALS(expected, tok(code, false)); } + + // ticket #980 + { + const char code[] = "void f() { int A(1),B(2),C=3,D,E(5),F=6; }"; + const char expected[] = "void f ( ) { int A ; A = 1 ; int B ; B = 2 ; int C ; C = 3 ; int D ; int E ; E = 5 ; int F ; F = 6 ; }"; + ASSERT_EQUALS(expected, tok(code, false)); + } } void removeUnwantedKeywords() From da998fec68106d1f7245a906fe5ab9055670e8dc Mon Sep 17 00:00:00 2001 From: Raphael Geissert Date: Sun, 16 Jan 2011 11:37:03 +0100 Subject: [PATCH 049/165] Tokenizer: simplify restrict --- lib/tokenize.cpp | 14 +++++++------- test/testsimplifytokens.cpp | 3 ++- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/lib/tokenize.cpp b/lib/tokenize.cpp index b856fa6dd..7b7951af9 100644 --- a/lib/tokenize.cpp +++ b/lib/tokenize.cpp @@ -2379,6 +2379,12 @@ bool Tokenizer::tokenize(std::istream &code, // remove Borland stuff.. simplifyBorland(); + // Remove "volatile", "inline", "register", and "restrict" + simplifyKeyword(); + + // Remove __builtin_expect, likely and unlikely + simplifyBuiltinExpect(); + // typedef.. simplifyTypedef(); @@ -2400,12 +2406,6 @@ bool Tokenizer::tokenize(std::istream &code, } } - // Remove "volatile", "inline", "register", and "restrict" - simplifyKeyword(); - - // Remove __builtin_expect, likely and unlikely - simplifyBuiltinExpect(); - // collapse compound standard types into a single token // unsigned long long int => long _isUnsigned=true,_isLong=true simplifyStdType(); @@ -8899,7 +8899,7 @@ void Tokenizer::simplifyAttribute() // Remove "volatile", "inline", "register", and "restrict" void Tokenizer::simplifyKeyword() { - const char pattern[] = "volatile|inline|__inline|__forceinline|register|restrict|__restrict__"; + const char pattern[] = "volatile|inline|__inline|__forceinline|register|restrict|__restrict|__restrict__"; while (Token::Match(_tokens, pattern)) { _tokens->deleteThis(); diff --git a/test/testsimplifytokens.cpp b/test/testsimplifytokens.cpp index 6410774aa..631c331c5 100644 --- a/test/testsimplifytokens.cpp +++ b/test/testsimplifytokens.cpp @@ -6304,12 +6304,13 @@ private: ASSERT_EQUALS("int foo ( ) { }", tok("__forceinline int foo ( ) { }", true)); ASSERT_EQUALS("if ( a ) { }", tok("if ( likely ( a ) ) { }", true)); ASSERT_EQUALS("if ( a ) { }", tok("if ( unlikely ( a ) ) { }", true)); - ASSERT_EQUALS("int * p ;", tok("int * __restrict__ p;", true)); + ASSERT_EQUALS("int * p ;", tok("int * __restrict p;", true)); ASSERT_EQUALS("int * * p ;", tok("int * __restrict__ * p;", true)); ASSERT_EQUALS("void foo ( float * a , float * b ) ;", tok("void foo(float * __restrict__ a, float * __restrict__ b);", true)); ASSERT_EQUALS("int * p ;", tok("int * restrict p;", true)); ASSERT_EQUALS("int * * p ;", tok("int * restrict * p;", true)); ASSERT_EQUALS("void foo ( float * a , float * b ) ;", tok("void foo(float * restrict a, float * restrict b);", true)); + ASSERT_EQUALS("; int * p ;", tok("typedef int * __restrict__ rint; rint p;", true)); } void simplifyCallingConvention() From f72fd6960e5093efaedd32e9d28ce6645fc8b040 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Sun, 16 Jan 2011 11:54:28 +0100 Subject: [PATCH 050/165] Fixed #2449 (segfault in tokenize.cpp, incorrect parsing) --- lib/tokenize.cpp | 21 +++++++++++++++++++++ test/testtokenize.cpp | 7 +++++++ 2 files changed, 28 insertions(+) diff --git a/lib/tokenize.cpp b/lib/tokenize.cpp index 7b7951af9..249ebc656 100644 --- a/lib/tokenize.cpp +++ b/lib/tokenize.cpp @@ -2385,6 +2385,27 @@ bool Tokenizer::tokenize(std::istream &code, // Remove __builtin_expect, likely and unlikely simplifyBuiltinExpect(); + // #2449: syntax error: enum with typedef in it + for (const Token *tok = _tokens; tok; tok = tok->next()) + { + if (Token::Match(tok, "enum %var% {")) + { + for (const Token *tok2 = tok->tokAt(3); tok2; tok2 = tok2->next()) + { + if (tok2->str() == "typedef") + { + syntaxError(tok2); + deallocateTokens(); + return false; + } + else if (tok2->str() == "}") + { + break; + } + } + } + } + // typedef.. simplifyTypedef(); diff --git a/test/testtokenize.cpp b/test/testtokenize.cpp index 25089a374..ee5207b96 100644 --- a/test/testtokenize.cpp +++ b/test/testtokenize.cpp @@ -511,6 +511,13 @@ private: ASSERT_EQUALS("", tokenizeAndStringify(code.c_str(), true)); ASSERT_EQUALS("[test.cpp:1]: (error) syntax error\n", errout.str()); } + + { + errout.str(""); + const std::string code("enum ABC { A,B, typedef enum { C } };"); + tokenizeAndStringify(code.c_str(), true); + ASSERT_EQUALS("[test.cpp:1]: (error) syntax error\n", errout.str()); + } } void minus() From a97e28491fd634686f5c59e10f4fa32bd4cd45bb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Sun, 16 Jan 2011 12:16:31 +0100 Subject: [PATCH 051/165] Fixed #2407 (False positive: unused private function) --- lib/checkclass.cpp | 5 +++++ test/testunusedprivfunc.cpp | 33 +++++++++++++++++++++++++++++++++ 2 files changed, 38 insertions(+) diff --git a/lib/checkclass.cpp b/lib/checkclass.cpp index ffcc55633..9b211cc34 100644 --- a/lib/checkclass.cpp +++ b/lib/checkclass.cpp @@ -199,6 +199,11 @@ void CheckClass::privateFunctions() if (Token::findmatch(_tokenizer->tokens(), "; __property ;")) return; + // #2407 calls from operator() is not detected + // TODO: Don't bailout. Detect the call. + if (Token::findmatch(_tokenizer->tokens(), "operator ( )")) + return; + createSymbolDatabase(); std::list::iterator i; diff --git a/test/testunusedprivfunc.cpp b/test/testunusedprivfunc.cpp index 6260bd0bd..d3474daa0 100644 --- a/test/testunusedprivfunc.cpp +++ b/test/testunusedprivfunc.cpp @@ -57,6 +57,9 @@ private: // No false positives when there are "unused" templates that are removed in the simplified token list TEST_CASE(template1); + + // #2407 - FP when called from operator() + TEST_CASE(fp_operator); } @@ -414,6 +417,36 @@ private: "};\n"); ASSERT_EQUALS("", errout.str()); } + + void fp_operator() + { + // #2407 - FP when function is called from operator() + check("class Fred\n" + "{\n" + "public:\n" + " void operator()(int x) {\n" + " startListening();\n" + " }\n" + "\n" + "private:\n" + " void startListening() {\n" + " }\n" + "};\n"); + ASSERT_EQUALS("", errout.str()); + + check("class Fred\n" + "{\n" + "public:\n" + " void operator()(int x) {\n" + " }\n" + "\n" + "private:\n" + " void startListening() {\n" + " }\n" + "};\n"); + TODO_ASSERT_EQUALS("[test.cpp:8]: (style) Unused private function 'Fred::startListening'\n", errout.str()); + ASSERT_EQUALS("", errout.str()); + } }; REGISTER_TEST(TestUnusedPrivateFunction) From 03ddfcb5b326cdcd5939ac7787501f16e63de864 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Sun, 16 Jan 2011 16:17:53 +0100 Subject: [PATCH 052/165] testcppcheck: parsing templates is tested in testcmdlineparser.cpp --- test/testcppcheck.cpp | 39 --------------------------------------- 1 file changed, 39 deletions(-) diff --git a/test/testcppcheck.cpp b/test/testcppcheck.cpp index 341d90bb9..8645b92ca 100644 --- a/test/testcppcheck.cpp +++ b/test/testcppcheck.cpp @@ -68,7 +68,6 @@ private: //TEST_CASE(parseOutputtingArgs); //TEST_CASE(parseOutputtingInvalidArgs); //TEST_CASE(parseArgsAndCheck); - //TEST_CASE(parseArgsAndCheckSettings); //TEST_CASE(userdefines); } @@ -135,44 +134,6 @@ private: return result; } - void parseArgsAndCheckSettings() - { - { - const char *argv[] = {"cppcheck", "--template", "gcc"}; - Settings settings; - ASSERT_EQUALS(true, argCheckReturnSettings(3, argv, settings)); - ASSERT_EQUALS("{file}:{line}: {severity}: {message}", settings._outputFormat); - ASSERT_EQUALS("", errout.str()); - ASSERT_EQUALS("", output.str()); - } - - { - const char *argv[] = {"cppcheck", "--template", "vs"}; - Settings settings; - ASSERT_EQUALS(true, argCheckReturnSettings(3, argv, settings)); - ASSERT_EQUALS("{file}({line}): {severity}: {message}", settings._outputFormat); - ASSERT_EQUALS("", errout.str()); - ASSERT_EQUALS("", output.str()); - } - - { - const char *argv[] = {"cppcheck", "--template", "{file}<->{line}"}; - Settings settings; - ASSERT_EQUALS(true, argCheckReturnSettings(3, argv, settings)); - ASSERT_EQUALS("{file}<->{line}", settings._outputFormat); - ASSERT_EQUALS("", errout.str()); - ASSERT_EQUALS("", output.str()); - } - - { - const char *argv[] = {"cppcheck", "--template"}; - Settings settings; - ASSERT_EQUALS(false, argCheckReturnSettings(2, argv, settings)); - ASSERT_EQUALS("", errout.str()); - ASSERT_EQUALS("cppcheck: argument to '--template' is missing\n", output.str()); - } - } - void parseArgsAndCheck() { { From c84190814926102172f916191e562691340b5279 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Sun, 16 Jan 2011 16:19:40 +0100 Subject: [PATCH 053/165] testcppcheck: command line parsing of -D is tested in testcmdlineparser.cpp --- test/testcppcheck.cpp | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/test/testcppcheck.cpp b/test/testcppcheck.cpp index 8645b92ca..93bf2b9aa 100644 --- a/test/testcppcheck.cpp +++ b/test/testcppcheck.cpp @@ -68,8 +68,6 @@ private: //TEST_CASE(parseOutputtingArgs); //TEST_CASE(parseOutputtingInvalidArgs); //TEST_CASE(parseArgsAndCheck); - - //TEST_CASE(userdefines); } #if 0 @@ -388,19 +386,6 @@ private: cppCheck.getErrorMessages(); } -#if 0 - void userdefines() - { - { - const char *argv[] = {"cppcheck", "-DA", "-DB"}; - Settings settings; - ASSERT_EQUALS(true, argCheckReturnSettings(3, argv, settings)); - ASSERT_EQUALS("A;B", settings.userDefines); - ASSERT_EQUALS("", errout.str()); - ASSERT_EQUALS("", output.str()); - } - } -#endif }; REGISTER_TEST(TestCppcheck) From 4661e38c658b16ac5792e9afa76e07136afca920 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Sun, 16 Jan 2011 16:21:34 +0100 Subject: [PATCH 054/165] testcppcheck: linenumbers are tested in the other tests --- test/testcppcheck.cpp | 33 --------------------------------- 1 file changed, 33 deletions(-) diff --git a/test/testcppcheck.cpp b/test/testcppcheck.cpp index 93bf2b9aa..03964a7ab 100644 --- a/test/testcppcheck.cpp +++ b/test/testcppcheck.cpp @@ -57,8 +57,6 @@ private: void run() { TEST_CASE(nonexistingpath); - TEST_CASE(linenumbers); - // TEST_CASE(linenumbers2); TEST_CASE(xml); @@ -312,37 +310,6 @@ private: ASSERT_EQUALS(retval, EXIT_FAILURE); } - void linenumbers() - { - const char filedata[] = "void f()\n" - "{\n" - " char *foo = new char[10];\n" - " delete [] foo;\n" - " foo[3] = 0;\n" - "}\n"; - check(filedata); - - // Compare results.. - ASSERT_EQUALS("Checking file.cpp...\n", output.str()); - ASSERT_EQUALS("[file.cpp:5]: (error) Dereferencing 'foo' after it is deallocated / released\n", errout.str()); - } - - void linenumbers2() - { - const char filedata[] = "void f()\n" - "{\n" - " char *string;\n" - " string = new char[20];\n" - " string = new char[30];\n" - " delete [] string;\n" - "}\n"; - check(filedata); - - // Compare results.. - ASSERT_EQUALS("[file.cpp:5]: (error) Memory leak: string\n", errout.str()); - } - - void xml() { // Test the errorlogger.. From e3e32de22e59fc3adca18d5b74070ce39b7721d2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Sun, 16 Jan 2011 16:22:46 +0100 Subject: [PATCH 055/165] testcppcheck: the testcmdlineparser tests invalid command line arguments --- test/testcppcheck.cpp | 81 ------------------------------------------- 1 file changed, 81 deletions(-) diff --git a/test/testcppcheck.cpp b/test/testcppcheck.cpp index 03964a7ab..fe2625b3d 100644 --- a/test/testcppcheck.cpp +++ b/test/testcppcheck.cpp @@ -64,7 +64,6 @@ private: TEST_CASE(templateFormat); //TEST_CASE(getErrorMessages); //TEST_CASE(parseOutputtingArgs); - //TEST_CASE(parseOutputtingInvalidArgs); //TEST_CASE(parseArgsAndCheck); } @@ -219,86 +218,6 @@ private: ASSERT_EQUALS(true, output.str().find("===Unused functions===") != std::string::npos); } } - - void parseOutputtingInvalidArgs() - { - { - const char *argv[] = {"cppcheck", "--invalidArg"}; - ASSERT_EQUALS(false, argCheck(2, argv)); - ASSERT_EQUALS("", errout.str()); - ASSERT_EQUALS("cppcheck: error: unrecognized command line option \"--invalidArg\"\n", output.str()); - } - - { - const char *argv[] = {"cppcheck", "--suppressions"}; - ASSERT_EQUALS(false, argCheck(2, argv)); - ASSERT_EQUALS("", errout.str()); - ASSERT_EQUALS("cppcheck: No file specified for the --suppressions option\n", output.str()); - } - - { - const char *argv[] = {"cppcheck", "--exitcode-suppressions"}; - ASSERT_EQUALS(false, argCheck(2, argv)); - ASSERT_EQUALS("", errout.str()); - ASSERT_EQUALS("cppcheck: No file specified for the --exitcode-suppressions option\n", output.str()); - } - - { - const char *argv[] = {"cppcheck", "--enable"}; - ASSERT_EQUALS(false, argCheck(2, argv)); - ASSERT_EQUALS("", errout.str()); - ASSERT_EQUALS("cppcheck: error: unrecognized command line option \"--enable\"\n", output.str()); - } - - { - const char *argv[] = {"cppcheck", "--append"}; - ASSERT_EQUALS(false, argCheck(2, argv)); - ASSERT_EQUALS("", errout.str()); - ASSERT_EQUALS("cppcheck: error: unrecognized command line option \"--append\"\n", output.str()); - } - - { - const char *argv[] = {"cppcheck", "--error-exitcode"}; - ASSERT_EQUALS(false, argCheck(2, argv)); - ASSERT_EQUALS("", errout.str()); - ASSERT_EQUALS("cppcheck: error: unrecognized command line option \"--error-exitcode\"\n", output.str()); - } - - { - const char *argv[] = {"cppcheck", "--file-list"}; - ASSERT_EQUALS(false, argCheck(2, argv)); - ASSERT_EQUALS("", errout.str()); - ASSERT_EQUALS("cppcheck: error: unrecognized command line option \"--file-list\"\n", output.str()); - } - - { - const char *argv[] = {"cppcheck", "--showtime"}; - ASSERT_EQUALS(false, argCheck(2, argv)); - ASSERT_EQUALS("", errout.str()); - ASSERT_EQUALS("cppcheck: error: unrecognized command line option \"--showtime\"\n", output.str()); - } - - { - const char *argv[] = {"cppcheck", "-I"}; - ASSERT_EQUALS(false, argCheck(2, argv)); - ASSERT_EQUALS("", errout.str()); - ASSERT_EQUALS("cppcheck: argument to '-I' is missing\n", output.str()); - } - - { - const char *argv[] = {"cppcheck", "-j"}; - ASSERT_EQUALS(false, argCheck(2, argv)); - ASSERT_EQUALS("", errout.str()); - ASSERT_EQUALS("cppcheck: argument to '-j' is missing\n", output.str()); - } - - { - const char *argv[] = {"cppcheck", "--template"}; - ASSERT_EQUALS(false, argCheck(2, argv)); - ASSERT_EQUALS("", errout.str()); - ASSERT_EQUALS("cppcheck: argument to '--template' is missing\n", output.str()); - } - } #endif void nonexistingpath() From f862b37c7148fcb23bb4499299e7eb0ac52b4444 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Sun, 16 Jan 2011 16:26:33 +0100 Subject: [PATCH 056/165] testcppcheck: the xml and template output is tested in testerrorlogger instead --- test/testcppcheck.cpp | 28 ---------------------------- 1 file changed, 28 deletions(-) diff --git a/test/testcppcheck.cpp b/test/testcppcheck.cpp index fe2625b3d..f5ede8866 100644 --- a/test/testcppcheck.cpp +++ b/test/testcppcheck.cpp @@ -58,10 +58,7 @@ private: { TEST_CASE(nonexistingpath); - TEST_CASE(xml); - TEST_CASE(include); - TEST_CASE(templateFormat); //TEST_CASE(getErrorMessages); //TEST_CASE(parseOutputtingArgs); //TEST_CASE(parseArgsAndCheck); @@ -229,15 +226,6 @@ private: ASSERT_EQUALS(retval, EXIT_FAILURE); } - void xml() - { - // Test the errorlogger.. - ErrorLogger::ErrorMessage errorMessage; - errorMessage.setmsg("abef"); - ASSERT_EQUALS("", errorMessage.toXML(false,1)); - } - - void include() { ErrorLogger::ErrorMessage errorMessage; @@ -249,22 +237,6 @@ private: ASSERT_EQUALS("[" + fname + ":0]: ", errorMessage.toString(false)); } - void templateFormat() - { - ErrorLogger::ErrorMessage errorMessage; - ErrorLogger::ErrorMessage::FileLocation loc; - loc.setfile("some/{file}file.cpp"); - loc.line = 10; - errorMessage._callStack.push_back(loc); - errorMessage._id = "testId"; - errorMessage._severity = Severity::fromString("error"); - errorMessage.setmsg("long testMessage"); - const std::string fname(Path::toNativeSeparators("some/{file}file.cpp")); - ASSERT_EQUALS("", errorMessage.toXML(false,1)); - ASSERT_EQUALS("[" + fname + ":10]: (error) long testMessage", errorMessage.toString(false)); - ASSERT_EQUALS("testId-" + fname + ",error.10?{long testMessage}", errorMessage.toString(false, "{id}-{file},{severity}.{line}?{{message}}")); - } - void getErrorMessages() { errout.str(""); From 206565c837630878361f49425dfd71764c40cf32 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Sun, 16 Jan 2011 16:32:05 +0100 Subject: [PATCH 057/165] testcppcheck: removed nonexistingpath and include tests. The Cppcheck class doesn't handle this. --- test/testcppcheck.cpp | 23 ----------------------- 1 file changed, 23 deletions(-) diff --git a/test/testcppcheck.cpp b/test/testcppcheck.cpp index f5ede8866..72dd4953a 100644 --- a/test/testcppcheck.cpp +++ b/test/testcppcheck.cpp @@ -56,9 +56,6 @@ private: void run() { - TEST_CASE(nonexistingpath); - - TEST_CASE(include); //TEST_CASE(getErrorMessages); //TEST_CASE(parseOutputtingArgs); //TEST_CASE(parseArgsAndCheck); @@ -217,26 +214,6 @@ private: } #endif - void nonexistingpath() - { - CppCheckExecutor exec; - const char *argv[] = { "", "idontexist" }; - int retval = exec.check(2, argv); - - ASSERT_EQUALS(retval, EXIT_FAILURE); - } - - void include() - { - ErrorLogger::ErrorMessage errorMessage; - ErrorLogger::ErrorMessage::FileLocation loc; - loc.setfile("ab/cd/../ef.h"); - errorMessage._callStack.push_back(loc); - const std::string fname(Path::toNativeSeparators("ab/ef.h")); - ASSERT_EQUALS("", errorMessage.toXML(false,1)); - ASSERT_EQUALS("[" + fname + ":0]: ", errorMessage.toString(false)); - } - void getErrorMessages() { errout.str(""); From 483e50d5bc7f53bfa9cafb5c46bbd93ea49715c0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Sun, 16 Jan 2011 16:34:29 +0100 Subject: [PATCH 058/165] testcppcheck: removed 'parseArgsAndCheck' and 'parseOutputtingArgs'. Such tests belong to testcmdlineparser --- test/testcppcheck.cpp | 61 ------------------------------------------- 1 file changed, 61 deletions(-) diff --git a/test/testcppcheck.cpp b/test/testcppcheck.cpp index 72dd4953a..d7a099478 100644 --- a/test/testcppcheck.cpp +++ b/test/testcppcheck.cpp @@ -57,8 +57,6 @@ private: void run() { //TEST_CASE(getErrorMessages); - //TEST_CASE(parseOutputtingArgs); - //TEST_CASE(parseArgsAndCheck); } #if 0 @@ -122,17 +120,6 @@ private: return result; } - - void parseArgsAndCheck() - { - { - const char *argv[] = {"cppcheck", "--showtime=top5"}; - const char *data = "void foo(){}"; - ASSERT_EQUALS(true, argCheckWithCheck(2, argv, data)); - ASSERT_EQUALS("", errout.str()); -// ASSERT_EQUALS(true, output.str().find("Overall time:") != std::string::npos); - } - } #endif void parseErrorList(const char* xmlData) @@ -166,54 +153,6 @@ private: } } -#if 0 - void parseOutputtingArgs() - { - { - const char *argv[] = { "cppcheck", "--errorlist" }; - ASSERT_EQUALS(true, argCheckWithCoutCerrRedirect(2, argv)); - ASSERT_EQUALS("", errout.str()); - parseErrorList(output.str().c_str()); - } - - { - const char *argv[] = {"cppcheck", "--help"}; - ASSERT_EQUALS(true, argCheck(2, argv)); - ASSERT_EQUALS("", errout.str()); - ASSERT_EQUALS(true, output.str().find("Example usage") != std::string::npos); - } - - { - const char *argv[] = {"cppcheck", "-h"}; - ASSERT_EQUALS(true, argCheck(2, argv)); - ASSERT_EQUALS("", errout.str()); - ASSERT_EQUALS(true, output.str().find("Example usage") != std::string::npos); - } - - { - const char *argv[] = {"cppcheck"}; - ASSERT_EQUALS(true, argCheck(1, argv)); - ASSERT_EQUALS("", errout.str()); - ASSERT_EQUALS(true, output.str().find("Example usage") != std::string::npos); - } - - { - const char *argv[] = {"cppcheck", "--version"}; - ASSERT_EQUALS(true, argCheck(2, argv)); - ASSERT_EQUALS("", errout.str()); - ASSERT_EQUALS(std::string("Cppcheck ") + CppCheck::version() + "\n", output.str()); - } - - { - const char *argv[] = {"cppcheck", "--doc"}; - ASSERT_EQUALS(true, argCheck(2, argv)); - ASSERT_EQUALS("", errout.str()); - ASSERT_EQUALS(true, output.str().find("===Bounds checking===") != std::string::npos); - ASSERT_EQUALS(true, output.str().find("===Unused functions===") != std::string::npos); - } - } -#endif - void getErrorMessages() { errout.str(""); From 66be74a5afcc0077823e5e52683788fa514d44c8 Mon Sep 17 00:00:00 2001 From: Robert Reif Date: Sun, 16 Jan 2011 16:37:11 +0100 Subject: [PATCH 059/165] Symbol database: Refactorings. Move check-specific code to check. Ticket: #2468 --- lib/checkclass.cpp | 371 ++++++++++++++++++++++++++++++++++++++++- lib/checkclass.h | 52 ++++++ lib/symboldatabase.cpp | 367 ---------------------------------------- lib/symboldatabase.h | 41 +---- 4 files changed, 420 insertions(+), 411 deletions(-) diff --git a/lib/checkclass.cpp b/lib/checkclass.cpp index 9b211cc34..bc9b6be7a 100644 --- a/lib/checkclass.cpp +++ b/lib/checkclass.cpp @@ -94,6 +94,7 @@ void CheckClass::constructors() } std::list::const_iterator func; + std::vector usage(info->varlist.size()); for (func = info->functionList.begin(); func != info->functionList.end(); ++func) { @@ -103,16 +104,17 @@ void CheckClass::constructors() continue; // Mark all variables not used - info->clearAllVar(); + clearAllVar(usage); std::list callstack; - info->initializeVarList(*func, callstack); + initializeVarList(*func, callstack, info, usage); // Check if any variables are uninitialized std::list::const_iterator var; - for (var = info->varlist.begin(); var != info->varlist.end(); ++var) + unsigned int count = 0; + for (var = info->varlist.begin(); var != info->varlist.end(); ++var, ++count) { - if (var->assign || var->init || var->isStatic) + if (usage[count].assign || usage[count].init || var->isStatic) continue; if (var->isConst && var->token->previous()->str() != "*") @@ -160,6 +162,367 @@ void CheckClass::constructors() } } +void CheckClass::assignVar(const std::string &varname, const SymbolDatabase::SpaceInfo *info, std::vector &usage) +{ + std::list::const_iterator var; + unsigned int count = 0; + + for (var = info->varlist.begin(); var != info->varlist.end(); ++var, ++count) + { + if (var->token->str() == varname) + { + usage[count].assign = true; + return; + } + } +} + +void CheckClass::initVar(const std::string &varname, const SymbolDatabase::SpaceInfo *info, std::vector &usage) +{ + std::list::const_iterator var; + unsigned int count = 0; + + for (var = info->varlist.begin(); var != info->varlist.end(); ++var, ++count) + { + if (var->token->str() == varname) + { + usage[count].init = true; + return; + } + } +} + +void CheckClass::assignAllVar(std::vector &usage) +{ + for (size_t i = 0; i < usage.size(); ++i) + usage[i].assign = true; +} + +void CheckClass::clearAllVar(std::vector &usage) +{ + for (size_t i = 0; i < usage.size(); ++i) + { + usage[i].assign = false; + usage[i].init = false; + } +} + +bool CheckClass::isBaseClassFunc(const Token *tok, const SymbolDatabase::SpaceInfo *info) +{ + // Iterate through each base class... + for (size_t i = 0; i < info->derivedFrom.size(); ++i) + { + const SymbolDatabase::SpaceInfo *derivedFrom = info->derivedFrom[i].spaceInfo; + + // Check if base class exists in database + if (derivedFrom) + { + std::list::const_iterator func; + + for (func = derivedFrom->functionList.begin(); func != derivedFrom->functionList.end(); ++func) + { + if (func->tokenDef->str() == tok->str()) + return true; + } + } + + // Base class not found so assume it is in it. + else + return true; + } + + return false; +} + +void CheckClass::initializeVarList(const SymbolDatabase::Func &func, std::list &callstack, const SymbolDatabase::SpaceInfo *info, std::vector &usage) +{ + bool Assign = false; + unsigned int indentlevel = 0; + const Token *ftok = func.token; + + for (; ftok; ftok = ftok->next()) + { + if (!ftok->next()) + break; + + // Class constructor.. initializing variables like this + // clKalle::clKalle() : var(value) { } + if (indentlevel == 0) + { + if (Assign && Token::Match(ftok, "%var% (")) + { + initVar(ftok->str(), info, usage); + + // assignment in the initializer.. + // : var(value = x) + if (Token::Match(ftok->tokAt(2), "%var% =")) + assignVar(ftok->strAt(2), info, usage); + } + + Assign |= (ftok->str() == ":"); + } + + + if (ftok->str() == "{") + { + ++indentlevel; + Assign = false; + } + + else if (ftok->str() == "}") + { + if (indentlevel <= 1) + break; + --indentlevel; + } + + if (indentlevel < 1) + continue; + + // Variable getting value from stream? + if (Token::Match(ftok, ">> %var%")) + { + assignVar(ftok->strAt(1), info, usage); + } + + // Before a new statement there is "[{};)=]" + if (! Token::Match(ftok, "[{};()=]")) + continue; + + if (Token::simpleMatch(ftok, "( !")) + ftok = ftok->next(); + + // Using the operator= function to initialize all variables.. + if (Token::simpleMatch(ftok->next(), "* this = ")) + { + assignAllVar(usage); + break; + } + + // Calling member variable function? + if (Token::Match(ftok->next(), "%var% . %var% (")) + { + std::list::const_iterator var; + for (var = info->varlist.begin(); var != info->varlist.end(); ++var) + { + if (var->token->varId() == ftok->next()->varId()) + { + /** @todo false negative: we assume function changes variable state */ + assignVar(ftok->next()->str(), info, usage); + continue; + } + } + + ftok = ftok->tokAt(2); + } + + if (!Token::Match(ftok->next(), "%var%") && + !Token::Match(ftok->next(), "this . %var%") && + !Token::Match(ftok->next(), "* %var% =") && + !Token::Match(ftok->next(), "( * this ) . %var%")) + continue; + + // Goto the first token in this statement.. + ftok = ftok->next(); + + // Skip "( * this )" + if (Token::simpleMatch(ftok, "( * this ) .")) + { + ftok = ftok->tokAt(5); + } + + // Skip "this->" + if (Token::simpleMatch(ftok, "this .")) + ftok = ftok->tokAt(2); + + // Skip "classname :: " + if (Token::Match(ftok, "%var% ::")) + ftok = ftok->tokAt(2); + + // Clearing all variables.. + if (Token::simpleMatch(ftok, "memset ( this ,")) + { + assignAllVar(usage); + return; + } + + // Clearing array.. + else if (Token::Match(ftok, "memset ( %var% ,")) + { + assignVar(ftok->strAt(2), info, usage); + ftok = ftok->next()->link(); + continue; + } + + // Calling member function? + else if (Token::simpleMatch(ftok, "operator = (") && + ftok->previous()->str() != "::") + { + // check if member function exists + std::list::const_iterator it; + for (it = info->functionList.begin(); it != info->functionList.end(); ++it) + { + if (ftok->next()->str() == it->tokenDef->str() && it->type != SymbolDatabase::Func::Constructor) + break; + } + + // member function found + if (it != info->functionList.end()) + { + // member function has implementation + if (it->hasBody) + { + // initialize variable use list using member function + callstack.push_back(ftok->str()); + initializeVarList(*it, callstack, info, usage); + callstack.pop_back(); + } + + // there is a called member function, but it has no implementation, so we assume it initializes everything + else + { + assignAllVar(usage); + } + } + + // using default operator =, assume everything initialized + else + { + assignAllVar(usage); + } + } + else if (Token::Match(ftok, "%var% (") && ftok->str() != "if") + { + // Passing "this" => assume that everything is initialized + for (const Token *tok2 = ftok->next()->link(); tok2 && tok2 != ftok; tok2 = tok2->previous()) + { + if (tok2->str() == "this") + { + assignAllVar(usage); + return; + } + } + + // recursive call / calling overloaded function + // assume that all variables are initialized + if (std::find(callstack.begin(), callstack.end(), ftok->str()) != callstack.end()) + { + assignAllVar(usage); + return; + } + + // check if member function + std::list::const_iterator it; + for (it = info->functionList.begin(); it != info->functionList.end(); ++it) + { + if (ftok->str() == it->tokenDef->str() && it->type != SymbolDatabase::Func::Constructor) + break; + } + + // member function found + if (it != info->functionList.end()) + { + // member function has implementation + if (it->hasBody) + { + // initialize variable use list using member function + callstack.push_back(ftok->str()); + initializeVarList(*it, callstack, info, usage); + callstack.pop_back(); + } + + // there is a called member function, but it has no implementation, so we assume it initializes everything + else + { + assignAllVar(usage); + } + } + + // not member function + else + { + // could be a base class virtual function, so we assume it initializes everything + if (func.type != SymbolDatabase::Func::Constructor && isBaseClassFunc(ftok, info)) + { + /** @todo False Negative: we should look at the base class functions to see if they + * call any derived class virtual functions that change the derived class state + */ + assignAllVar(usage); + } + + // has friends, so we assume it initializes everything + if (!info->friendList.empty()) + assignAllVar(usage); + + // the function is external and it's neither friend nor inherited virtual function. + // assume all variables that are passed to it are initialized.. + else + { + unsigned int indentlevel2 = 0; + for (const Token *tok = ftok->tokAt(2); tok; tok = tok->next()) + { + if (tok->str() == "(") + ++indentlevel2; + else if (tok->str() == ")") + { + if (indentlevel2 == 0) + break; + --indentlevel2; + } + if (tok->isName()) + { + assignVar(tok->str(), info, usage); + } + } + } + } + } + + // Assignment of member variable? + else if (Token::Match(ftok, "%var% =")) + { + assignVar(ftok->str(), info, usage); + } + + // Assignment of array item of member variable? + else if (Token::Match(ftok, "%var% [ %any% ] =")) + { + assignVar(ftok->str(), info, usage); + } + + // Assignment of member of array item of member variable? + else if (Token::Match(ftok, "%var% [ %any% ] . %var% =") || + Token::Match(ftok, "%var% [ %any% ] . %var% . %var% =")) + { + assignVar(ftok->str(), info, usage); + } + + // Assignment of array item of member variable? + else if (Token::Match(ftok, "%var% [ %any% ] [ %any% ] =")) + { + assignVar(ftok->str(), info, usage); + } + + // Assignment of array item of member variable? + else if (Token::Match(ftok, "* %var% =")) + { + assignVar(ftok->next()->str(), info, usage); + } + + // Assignment of struct member of member variable? + else if (Token::Match(ftok, "%var% . %any% =")) + { + assignVar(ftok->str(), info, usage); + } + + // The functions 'clear' and 'Clear' are supposed to initialize variable. + if (Token::Match(ftok, "%var% . clear|Clear (")) + { + assignVar(ftok->str(), info, usage); + } + } +} + void CheckClass::noConstructorError(const Token *tok, const std::string &classname, bool isStruct) { // For performance reasons the constructor might be intentionally missing. Therefore this is not a "warning" diff --git a/lib/checkclass.h b/lib/checkclass.h index c87b4fdd9..23edb4dc0 100644 --- a/lib/checkclass.h +++ b/lib/checkclass.h @@ -175,6 +175,58 @@ private: bool checkConstFunc(const SymbolDatabase::SpaceInfo *info, const Token *tok); /** @brief check if this function is virtual in the base classes */ bool isVirtualFunc(const SymbolDatabase::SpaceInfo *info, const Token *functionToken) const; + + // constructors helper function + /** @brief Information about a member variable. Used when checking for uninitialized variables */ + struct Usage + { + Usage() : assign(false), init(false) { } + + /** @brief has this variable been assigned? */ + bool assign; + + /** @brief has this variable been initialized? */ + bool init; + }; + + bool isBaseClassFunc(const Token *tok, const SymbolDatabase::SpaceInfo *info); + + /** + * @brief assign a variable in the varlist + * @param varname name of variable to mark assigned + * @param info pointer to variable SpaceInfo + * @param usage reference to usage vector + */ + void assignVar(const std::string &varname, const SymbolDatabase::SpaceInfo *info, std::vector &usage); + + /** + * @brief initialize a variable in the varlist + * @param varname name of variable to mark initialized + * @param info pointer to variable SpaceInfo + * @param usage reference to usage vector + */ + void initVar(const std::string &varname, const SymbolDatabase::SpaceInfo *info, std::vector &usage); + + /** + * @brief set all variables in list assigned + * @param usage reference to usage vector + */ + void assignAllVar(std::vector &usage); + + /** + * @brief set all variables in list not assigned and not initialized + * @param usage reference to usage vector + */ + void clearAllVar(std::vector &usage); + + /** + * @brief parse a scope for a constructor or member function and set the "init" flags in the provided varlist + * @param func reference to the function that should be checked + * @param callstack the function doesn't look into recursive function calls. + * @param info pointer to variable SpaceInfo + * @param usage reference to usage vector + */ + void initializeVarList(const SymbolDatabase::Func &func, std::list &callstack, const SymbolDatabase::SpaceInfo *info, std::vector &usage); }; /// @} //--------------------------------------------------------------------------- diff --git a/lib/symboldatabase.cpp b/lib/symboldatabase.cpp index 2319c945f..ea1401e7c 100644 --- a/lib/symboldatabase.cpp +++ b/lib/symboldatabase.cpp @@ -1417,370 +1417,3 @@ unsigned int SymbolDatabase::SpaceInfo::getNestedNonFunctions() const } return nested; } - -//--------------------------------------------------------------------------- - -void SymbolDatabase::SpaceInfo::assignVar(const std::string &varname) -{ - std::list::iterator i; - - for (i = varlist.begin(); i != varlist.end(); ++i) - { - if (i->token->str() == varname) - { - i->assign = true; - return; - } - } -} - -void SymbolDatabase::SpaceInfo::initVar(const std::string &varname) -{ - std::list::iterator i; - - for (i = varlist.begin(); i != varlist.end(); ++i) - { - if (i->token->str() == varname) - { - i->init = true; - return; - } - } -} - -void SymbolDatabase::SpaceInfo::assignAllVar() -{ - std::list::iterator i; - - for (i = varlist.begin(); i != varlist.end(); ++i) - i->assign = true; -} - -void SymbolDatabase::SpaceInfo::clearAllVar() -{ - std::list::iterator i; - - for (i = varlist.begin(); i != varlist.end(); ++i) - { - i->assign = false; - i->init = false; - } -} - -//--------------------------------------------------------------------------- - -bool SymbolDatabase::SpaceInfo::isBaseClassFunc(const Token *tok) -{ - // Iterate through each base class... - for (unsigned int i = 0; i < derivedFrom.size(); ++i) - { - const SpaceInfo *info = derivedFrom[i].spaceInfo; - - // Check if base class exists in database - if (info) - { - std::list::const_iterator it; - - for (it = info->functionList.begin(); it != info->functionList.end(); ++it) - { - if (it->tokenDef->str() == tok->str()) - return true; - } - } - - // Base class not found so assume it is in it. - else - return true; - } - - return false; -} - -void SymbolDatabase::SpaceInfo::initializeVarList(const Func &func, std::list &callstack) -{ - bool Assign = false; - unsigned int indentlevel = 0; - const Token *ftok = func.token; - - for (; ftok; ftok = ftok->next()) - { - if (!ftok->next()) - break; - - // Class constructor.. initializing variables like this - // clKalle::clKalle() : var(value) { } - if (indentlevel == 0) - { - if (Assign && Token::Match(ftok, "%var% (")) - { - initVar(ftok->str()); - - // assignment in the initializer.. - // : var(value = x) - if (Token::Match(ftok->tokAt(2), "%var% =")) - assignVar(ftok->strAt(2)); - } - - Assign |= (ftok->str() == ":"); - } - - - if (ftok->str() == "{") - { - ++indentlevel; - Assign = false; - } - - else if (ftok->str() == "}") - { - if (indentlevel <= 1) - break; - --indentlevel; - } - - if (indentlevel < 1) - continue; - - // Variable getting value from stream? - if (Token::Match(ftok, ">> %var%")) - { - assignVar(ftok->strAt(1)); - } - - // Before a new statement there is "[{};)=]" - if (! Token::Match(ftok, "[{};()=]")) - continue; - - if (Token::simpleMatch(ftok, "( !")) - ftok = ftok->next(); - - // Using the operator= function to initialize all variables.. - if (Token::simpleMatch(ftok->next(), "* this = ")) - { - assignAllVar(); - break; - } - - // Calling member variable function? - if (Token::Match(ftok->next(), "%var% . %var% (")) - { - std::list::const_iterator var; - for (var = varlist.begin(); var != varlist.end(); ++var) - { - if (var->token->varId() == ftok->next()->varId()) - { - /** @todo false negative: we assume function changes variable state */ - assignVar(ftok->next()->str()); - continue; - } - } - - ftok = ftok->tokAt(2); - } - - if (!Token::Match(ftok->next(), "%var%") && - !Token::Match(ftok->next(), "this . %var%") && - !Token::Match(ftok->next(), "* %var% =") && - !Token::Match(ftok->next(), "( * this ) . %var%")) - continue; - - // Goto the first token in this statement.. - ftok = ftok->next(); - - // Skip "( * this )" - if (Token::simpleMatch(ftok, "( * this ) .")) - { - ftok = ftok->tokAt(5); - } - - // Skip "this->" - if (Token::simpleMatch(ftok, "this .")) - ftok = ftok->tokAt(2); - - // Skip "classname :: " - if (Token::Match(ftok, "%var% ::")) - ftok = ftok->tokAt(2); - - // Clearing all variables.. - if (Token::simpleMatch(ftok, "memset ( this ,")) - { - assignAllVar(); - return; - } - - // Clearing array.. - else if (Token::Match(ftok, "memset ( %var% ,")) - { - assignVar(ftok->strAt(2)); - ftok = ftok->next()->link(); - continue; - } - - // Calling member function? - else if (Token::simpleMatch(ftok, "operator = (") && - ftok->previous()->str() != "::") - { - // check if member function exists - std::list::const_iterator it; - for (it = functionList.begin(); it != functionList.end(); ++it) - { - if (ftok->next()->str() == it->tokenDef->str() && it->type != Func::Constructor) - break; - } - - // member function found - if (it != functionList.end()) - { - // member function has implementation - if (it->hasBody) - { - // initialize variable use list using member function - callstack.push_back(ftok->str()); - initializeVarList(*it, callstack); - callstack.pop_back(); - } - - // there is a called member function, but it has no implementation, so we assume it initializes everything - else - { - assignAllVar(); - } - } - - // using default operator =, assume everything initialized - else - { - assignAllVar(); - } - } - else if (Token::Match(ftok, "%var% (") && ftok->str() != "if") - { - // Passing "this" => assume that everything is initialized - for (const Token *tok2 = ftok->next()->link(); tok2 && tok2 != ftok; tok2 = tok2->previous()) - { - if (tok2->str() == "this") - { - assignAllVar(); - return; - } - } - - // recursive call / calling overloaded function - // assume that all variables are initialized - if (std::find(callstack.begin(), callstack.end(), ftok->str()) != callstack.end()) - { - assignAllVar(); - return; - } - - // check if member function - std::list::const_iterator it; - for (it = functionList.begin(); it != functionList.end(); ++it) - { - if (ftok->str() == it->tokenDef->str() && it->type != Func::Constructor) - break; - } - - // member function found - if (it != functionList.end()) - { - // member function has implementation - if (it->hasBody) - { - // initialize variable use list using member function - callstack.push_back(ftok->str()); - initializeVarList(*it, callstack); - callstack.pop_back(); - } - - // there is a called member function, but it has no implementation, so we assume it initializes everything - else - { - assignAllVar(); - } - } - - // not member function - else - { - // could be a base class virtual function, so we assume it initializes everything - if (func.type != Func::Constructor && isBaseClassFunc(ftok)) - { - /** @todo False Negative: we should look at the base class functions to see if they - * call any derived class virtual functions that change the derived class state - */ - assignAllVar(); - } - - // has friends, so we assume it initializes everything - if (!friendList.empty()) - assignAllVar(); - - // the function is external and it's neither friend nor inherited virtual function. - // assume all variables that are passed to it are initialized.. - else - { - unsigned int indentlevel2 = 0; - for (const Token *tok = ftok->tokAt(2); tok; tok = tok->next()) - { - if (tok->str() == "(") - ++indentlevel2; - else if (tok->str() == ")") - { - if (indentlevel2 == 0) - break; - --indentlevel2; - } - if (tok->isName()) - { - assignVar(tok->str()); - } - } - } - } - } - - // Assignment of member variable? - else if (Token::Match(ftok, "%var% =")) - { - assignVar(ftok->str()); - } - - // Assignment of array item of member variable? - else if (Token::Match(ftok, "%var% [ %any% ] =")) - { - assignVar(ftok->str()); - } - - // Assignment of member of array item of member variable? - else if (Token::Match(ftok, "%var% [ %any% ] . %var% =") || - Token::Match(ftok, "%var% [ %any% ] . %var% . %var% =")) - { - assignVar(ftok->str()); - } - - // Assignment of array item of member variable? - else if (Token::Match(ftok, "%var% [ %any% ] [ %any% ] =")) - { - assignVar(ftok->str()); - } - - // Assignment of array item of member variable? - else if (Token::Match(ftok, "* %var% =")) - { - assignVar(ftok->next()->str()); - } - - // Assignment of struct member of member variable? - else if (Token::Match(ftok, "%var% . %any% =")) - { - assignVar(ftok->str()); - } - - // The functions 'clear' and 'Clear' are supposed to initialize variable. - if (Token::Match(ftok, "%var% . clear|Clear (")) - { - assignVar(ftok->str()); - } - } -} diff --git a/lib/symboldatabase.h b/lib/symboldatabase.h index 268aa3a95..177c981be 100644 --- a/lib/symboldatabase.h +++ b/lib/symboldatabase.h @@ -43,15 +43,13 @@ public: class SpaceInfo; - /** @brief Information about a member variable. Used when checking for uninitialized variables */ + /** @brief Information about a member variable. */ class Var { public: Var(const Token *token_, std::size_t index_, AccessControl access_, bool mutable_, bool static_, bool const_, bool class_, const SpaceInfo *type_) : token(token_), index(index_), - assign(false), - init(false), access(access_), isMutable(mutable_), isStatic(static_), @@ -67,12 +65,6 @@ public: /** @brief order declared */ std::size_t index; - /** @brief has this variable been assigned? */ - bool assign; - - /** @brief has this variable been initialized? */ - bool init; - /** @brief what section is this variable declared in? */ AccessControl access; // public/protected/private @@ -187,43 +179,14 @@ public: */ SpaceInfo * findInNestedList(const std::string & name); - /** - * @brief assign a variable in the varlist - * @param varname name of variable to mark assigned - */ - void assignVar(const std::string &varname); - - /** - * @brief initialize a variable in the varlist - * @param varname name of variable to mark initialized - */ - void initVar(const std::string &varname); - void addVar(const Token *token_, AccessControl access_, bool mutable_, bool static_, bool const_, bool class_, const SpaceInfo *type_) { varlist.push_back(Var(token_, varlist.size(), access_, mutable_, static_, const_, class_, type_)); } - /** - * @brief set all variables in list assigned - */ - void assignAllVar(); - - /** - * @brief set all variables in list not assigned and not initialized - */ - void clearAllVar(); - /** @brief initialize varlist */ void getVarList(); - /** - * @brief parse a scope for a constructor or member function and set the "init" flags in the provided varlist - * @param func reference to the function that should be checked - * @param callstack the function doesn't look into recursive function calls. - */ - void initializeVarList(const Func &func, std::list &callstack); - const Func *getDestructor() const; /** @@ -234,8 +197,6 @@ public: */ unsigned int getNestedNonFunctions() const; - bool isBaseClassFunc(const Token *tok); - bool hasDefaultConstructor() const; private: From 615c92c83b7f472d71d1ea636898f4c2761828be Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Sun, 16 Jan 2011 16:45:00 +0100 Subject: [PATCH 060/165] testcppcheck: cleanup --- test/testcppcheck.cpp | 43 ------------------------------------------- 1 file changed, 43 deletions(-) diff --git a/test/testcppcheck.cpp b/test/testcppcheck.cpp index d7a099478..ec1d061cb 100644 --- a/test/testcppcheck.cpp +++ b/test/testcppcheck.cpp @@ -45,29 +45,12 @@ public: private: - void check(const std::string &data) - { - errout.str(""); - output.str(""); - CppCheck cppCheck(*this); - cppCheck.addFile("file.cpp", data); - cppCheck.check(); - } - void run() { //TEST_CASE(getErrorMessages); } #if 0 - bool argCheck(int argc, const char *argv[]) - { - errout.str(""); - output.str(""); - CppCheck cppCheck(*this); - return cppCheck.parseFromArgs(argc, argv); - } - bool argCheckWithCoutCerrRedirect(int argc, const char * argv[]) { // redirect cout and cerr @@ -94,32 +77,6 @@ private: return result; } - - bool argCheckWithCheck(int argc, const char *argv[], const std::string &data) - { - errout.str(""); - output.str(""); - CppCheck cppCheck(*this); - cppCheck.addFile("file.cpp", data); - bool result = cppCheck.parseFromArgs(argc, argv); - if (result) - cppCheck.check(); - - return result; - } - - bool argCheckReturnSettings(int argc, const char *argv[], Settings &settings) - { - errout.str(""); - output.str(""); - CppCheck cppCheck(*this); - cppCheck.addFile("file.cpp", "void foo(){}"); - bool result = cppCheck.parseFromArgs(argc, argv); - if (result) - settings = cppCheck.settings(); - - return result; - } #endif void parseErrorList(const char* xmlData) From f50971a65aa1921622cfd4883b40d0380cf73055 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Sun, 16 Jan 2011 17:06:07 +0100 Subject: [PATCH 061/165] testcppcheck: test Cppcheck::getErrorMessages --- test/testcppcheck.cpp | 88 ++++++++++++------------------------------- 1 file changed, 24 insertions(+), 64 deletions(-) diff --git a/test/testcppcheck.cpp b/test/testcppcheck.cpp index ec1d061cb..838b54e6f 100644 --- a/test/testcppcheck.cpp +++ b/test/testcppcheck.cpp @@ -45,78 +45,38 @@ public: private: + class ErrorLogger2 : public ErrorLogger + { + public: + std::list id; + + void reportOut(const std::string & /*outmsg*/) + { + } + + void reportErr(const ErrorLogger::ErrorMessage &msg) + { + id.push_back(msg._id); + } + + void reportStatus(unsigned int /*index*/, unsigned int /*max*/) + { + } + }; + void run() { - //TEST_CASE(getErrorMessages); - } - -#if 0 - bool argCheckWithCoutCerrRedirect(int argc, const char * argv[]) - { - // redirect cout and cerr - std::stringstream out, err; - std::streambuf* oldCout, *oldCerr; - - // flush all old output - std::cout.flush(); - std::cerr.flush(); - - oldCout = std::cout.rdbuf(); // back up cout's streambuf - oldCerr = std::cerr.rdbuf(); // back up cerr's streambuf - - std::cout.rdbuf(out.rdbuf()); // assign streambuf to cout - std::cerr.rdbuf(err.rdbuf()); // assign streambuf to cerr - - bool result = argCheck(argc, argv); - - std::cout.rdbuf(oldCout); // restore cout's original streambuf - std::cerr.rdbuf(oldCerr); // restore cerrs's original streambuf - - errout << err.str(); - output << out.str(); - - return result; - } -#endif - - void parseErrorList(const char* xmlData) - { - TiXmlDocument doc; - doc.Parse(xmlData); - // parsing must be successful - ASSERT_EQUALS(false, doc.Error()); - // root element must be "results" - TiXmlElement* root = doc.FirstChildElement(); - ASSERT_EQUALS("results", root->Value()); - - TiXmlElement* error = root->FirstChildElement(); - std::list idList; - - while (error) - { - // only childs of type "error" - ASSERT_EQUALS("error", error->Value()); - // attributes id, msg, severity - ASSERT_EQUALS(error->Attribute("msg") == NULL, false); - ASSERT_EQUALS(error->Attribute("severity") == NULL, false); - const char* id = error->Attribute("id"); - ASSERT_EQUALS(id == NULL, false); - // no duplicate ids - std::stringstream msg; - msg << "Duplicate id " << id; - ASSERT_EQUALS_MSG(idList.end() == std::find(idList.begin(), idList.end(), id), true, msg.str()); - idList.push_back(id); - error = error->NextSiblingElement(); - } + TEST_CASE(getErrorMessages); } void getErrorMessages() { - errout.str(""); - CppCheck cppCheck(*this); + ErrorLogger2 errorLogger; + CppCheck cppCheck(errorLogger); cppCheck.getErrorMessages(); - } + // TODO: check if there are duplicate error ids in errorLogger.id + } }; REGISTER_TEST(TestCppcheck) From 61aa86f20198dc4c73d71913daab1750da6580b8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Sun, 16 Jan 2011 17:07:12 +0100 Subject: [PATCH 062/165] testcppcheck: check that Cppcheck::getErrorMessages output is not empty --- test/testcppcheck.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/test/testcppcheck.cpp b/test/testcppcheck.cpp index 838b54e6f..582a6376d 100644 --- a/test/testcppcheck.cpp +++ b/test/testcppcheck.cpp @@ -74,6 +74,7 @@ private: ErrorLogger2 errorLogger; CppCheck cppCheck(errorLogger); cppCheck.getErrorMessages(); + ASSERT(!errorLogger.id.empty()); // TODO: check if there are duplicate error ids in errorLogger.id } From 657c22d23b0de3f37d88d26b13499a765d6eb130 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Sun, 16 Jan 2011 17:18:09 +0100 Subject: [PATCH 063/165] cppcheck: output errorlist to stdout --- cli/cppcheckexecutor.cpp | 10 +++++++++- cli/cppcheckexecutor.h | 5 +++++ lib/cppcheck.cpp | 3 --- 3 files changed, 14 insertions(+), 4 deletions(-) diff --git a/cli/cppcheckexecutor.cpp b/cli/cppcheckexecutor.cpp index ef9277d64..4885357e6 100644 --- a/cli/cppcheckexecutor.cpp +++ b/cli/cppcheckexecutor.cpp @@ -29,6 +29,7 @@ CppCheckExecutor::CppCheckExecutor() { time1 = 0; + errorlist = false; } CppCheckExecutor::~CppCheckExecutor() @@ -52,7 +53,10 @@ bool CppCheckExecutor::parseFromArgs(CppCheck *cppcheck, int argc, const char* c if (parser.GetShowErrorMessages()) { + errorlist = true; + std::cout << ErrorLogger::ErrorMessage::getXMLHeader(_settings._xml_version); cppcheck->getErrorMessages(); + std::cout << ErrorLogger::ErrorMessage::getXMLFooter() << std::endl; std::exit(0); } } @@ -199,7 +203,11 @@ void CppCheckExecutor::reportStatus(unsigned int index, unsigned int max) void CppCheckExecutor::reportErr(const ErrorLogger::ErrorMessage &msg) { - if (_settings._xml) + if (errorlist) + { + reportOut(msg.toXML(false, _settings._xml_version)); + } + else if (_settings._xml) { reportErr(msg.toXML(_settings._verbose, _settings._xml_version)); } diff --git a/cli/cppcheckexecutor.h b/cli/cppcheckexecutor.h index b1cf6d48e..339d16959 100644 --- a/cli/cppcheckexecutor.h +++ b/cli/cppcheckexecutor.h @@ -102,6 +102,11 @@ private: * Report progress time */ std::time_t time1; + + /** + * Has --errorlist been given? + */ + bool errorlist; }; #endif // CPPCHECKEXECUTOR_H diff --git a/lib/cppcheck.cpp b/lib/cppcheck.cpp index c2711bd60..471887fb1 100644 --- a/lib/cppcheck.cpp +++ b/lib/cppcheck.cpp @@ -440,7 +440,6 @@ void CppCheck::reportStatus(unsigned int /*index*/, unsigned int /*max*/) void CppCheck::getErrorMessages() { // call all "getErrorMessages" in all registered Check classes - std::cout << ErrorLogger::ErrorMessage::getXMLHeader(_settings._xml_version); for (std::list::iterator it = Check::instances().begin(); it != Check::instances().end(); ++it) (*it)->getErrorMessages(this, &_settings); @@ -448,6 +447,4 @@ void CppCheck::getErrorMessages() tokenizer.getErrorMessages(this, &_settings); Preprocessor::getErrorMessages(this, &_settings); - - std::cout << ErrorLogger::ErrorMessage::getXMLFooter() << std::endl; } From d341b42b0c78be2f6387f2819ed6d11d8dbd65ba Mon Sep 17 00:00:00 2001 From: Robert Reif Date: Sun, 16 Jan 2011 18:13:54 +0100 Subject: [PATCH 064/165] Symbol database: increased constness. ticket: #2468 --- lib/checkclass.cpp | 14 +++++++------- lib/checkclass.h | 2 +- lib/checkmemoryleak.cpp | 12 ++++++------ lib/checkmemoryleak.h | 2 +- lib/checkother.cpp | 14 +++++++------- lib/tokenize.cpp | 6 +++--- lib/tokenize.h | 4 ++-- 7 files changed, 27 insertions(+), 27 deletions(-) diff --git a/lib/checkclass.cpp b/lib/checkclass.cpp index bc9b6be7a..4c71a0bf7 100644 --- a/lib/checkclass.cpp +++ b/lib/checkclass.cpp @@ -68,11 +68,11 @@ void CheckClass::constructors() createSymbolDatabase(); - std::list::iterator i; + std::list::const_iterator i; for (i = symbolDatabase->spaceInfoList.begin(); i != symbolDatabase->spaceInfoList.end(); ++i) { - SymbolDatabase::SpaceInfo *info = *i; + const SymbolDatabase::SpaceInfo *info = *i; // only check classes and structures if (!info->isClassOrStruct()) @@ -569,11 +569,11 @@ void CheckClass::privateFunctions() createSymbolDatabase(); - std::list::iterator i; + std::list::const_iterator i; for (i = symbolDatabase->spaceInfoList.begin(); i != symbolDatabase->spaceInfoList.end(); ++i) { - SymbolDatabase::SpaceInfo *info = *i; + const SymbolDatabase::SpaceInfo *info = *i; // only check classes and structures if (!info->isClassOrStruct()) @@ -1270,11 +1270,11 @@ void CheckClass::checkConst() createSymbolDatabase(); - std::list::iterator it; + std::list::const_iterator it; for (it = symbolDatabase->spaceInfoList.begin(); it != symbolDatabase->spaceInfoList.end(); ++it) { - SymbolDatabase::SpaceInfo *info = *it; + const SymbolDatabase::SpaceInfo *info = *it; // only check classes and structures if (!info->isClassOrStruct()) @@ -1353,7 +1353,7 @@ void CheckClass::checkConst() if (checkConstFunc(info, paramEnd)) { std::string classname = info->className; - SymbolDatabase::SpaceInfo *nest = info->nestedIn; + const SymbolDatabase::SpaceInfo *nest = info->nestedIn; while (nest && nest->type != SymbolDatabase::SpaceInfo::Global) { classname = std::string(nest->className + "::" + classname); diff --git a/lib/checkclass.h b/lib/checkclass.h index 23edb4dc0..9a8717720 100644 --- a/lib/checkclass.h +++ b/lib/checkclass.h @@ -110,7 +110,7 @@ private: */ void createSymbolDatabase(); - SymbolDatabase *symbolDatabase; + const SymbolDatabase *symbolDatabase; // Reporting errors.. void noConstructorError(const Token *tok, const std::string &classname, bool isStruct); diff --git a/lib/checkmemoryleak.cpp b/lib/checkmemoryleak.cpp index 4ce6a918e..62d883e11 100644 --- a/lib/checkmemoryleak.cpp +++ b/lib/checkmemoryleak.cpp @@ -569,7 +569,7 @@ void CheckMemoryLeakInFunction::parse_noreturn() for (i = symbolDatabase->spaceInfoList.begin(); i != symbolDatabase->spaceInfoList.end(); ++i) { - SymbolDatabase::SpaceInfo *info = *i; + const SymbolDatabase::SpaceInfo *info = *i; // only check functions if (info->type != SymbolDatabase::SpaceInfo::Function) @@ -2495,7 +2495,7 @@ void CheckMemoryLeakInFunction::checkReallocUsage() for (i = symbolDatabase->spaceInfoList.begin(); i != symbolDatabase->spaceInfoList.end(); ++i) { - SymbolDatabase::SpaceInfo *info = *i; + const SymbolDatabase::SpaceInfo *info = *i; // only check functions if (info->type != SymbolDatabase::SpaceInfo::Function) @@ -2648,7 +2648,7 @@ void CheckMemoryLeakInFunction::check() for (i = symbolDatabase->spaceInfoList.begin(); i != symbolDatabase->spaceInfoList.end(); ++i) { - SymbolDatabase::SpaceInfo *info = *i; + const SymbolDatabase::SpaceInfo *info = *i; // only check functions if (info->type != SymbolDatabase::SpaceInfo::Function) @@ -2699,9 +2699,9 @@ void CheckMemoryLeakInFunction::check() void CheckMemoryLeakInClass::check() { - SymbolDatabase *symbolDatabase = _tokenizer->getSymbolDatabase(); + const SymbolDatabase *symbolDatabase = _tokenizer->getSymbolDatabase(); - std::list::iterator i; + std::list::const_iterator i; for (i = symbolDatabase->spaceInfoList.begin(); i != symbolDatabase->spaceInfoList.end(); ++i) { @@ -3164,7 +3164,7 @@ void CheckMemoryLeakNoVar::check() c.analyse(_tokenizer->tokens(), uvarFunctions); } - SymbolDatabase *symbolDatabase = _tokenizer->getSymbolDatabase(); + const SymbolDatabase *symbolDatabase = _tokenizer->getSymbolDatabase(); std::list::const_iterator i; diff --git a/lib/checkmemoryleak.h b/lib/checkmemoryleak.h index ecce46cb2..961b0d258 100644 --- a/lib/checkmemoryleak.h +++ b/lib/checkmemoryleak.h @@ -352,7 +352,7 @@ public: /** Function names for functions that are not "noreturn" */ std::set notnoreturn; - SymbolDatabase *symbolDatabase; + const SymbolDatabase *symbolDatabase; }; diff --git a/lib/checkother.cpp b/lib/checkother.cpp index 3f47fe7b1..1a17e0d2e 100644 --- a/lib/checkother.cpp +++ b/lib/checkother.cpp @@ -1234,13 +1234,13 @@ void CheckOther::functionVariableUsage() return; // Parse all executing scopes.. - SymbolDatabase *symbolDatabase = _tokenizer->getSymbolDatabase(); + const SymbolDatabase *symbolDatabase = _tokenizer->getSymbolDatabase(); std::list::const_iterator i; for (i = symbolDatabase->spaceInfoList.begin(); i != symbolDatabase->spaceInfoList.end(); ++i) { - SymbolDatabase::SpaceInfo *info = *i; + const SymbolDatabase::SpaceInfo *info = *i; // only check functions if (info->type != SymbolDatabase::SpaceInfo::Function) @@ -1902,13 +1902,13 @@ void CheckOther::checkVariableScope() if (!_settings->isEnabled("information")) return; - SymbolDatabase *symbolDatabase = _tokenizer->getSymbolDatabase(); + const SymbolDatabase *symbolDatabase = _tokenizer->getSymbolDatabase(); std::list::const_iterator i; for (i = symbolDatabase->spaceInfoList.begin(); i != symbolDatabase->spaceInfoList.end(); ++i) { - SymbolDatabase::SpaceInfo *info = *i; + const SymbolDatabase::SpaceInfo *info = *i; // only check functions if (info->type != SymbolDatabase::SpaceInfo::Function) @@ -2529,9 +2529,9 @@ void CheckOther::checkMisusedScopedObject() return; } - SymbolDatabase *symbolDatabase = _tokenizer->getSymbolDatabase(); + const SymbolDatabase *symbolDatabase = _tokenizer->getSymbolDatabase(); - std::list::iterator i; + std::list::const_iterator i; // list of classes / structs std::set identifiers; @@ -2543,7 +2543,7 @@ void CheckOther::checkMisusedScopedObject() for (i = symbolDatabase->spaceInfoList.begin(); i != symbolDatabase->spaceInfoList.end(); ++i) { - SymbolDatabase::SpaceInfo *info = *i; + const SymbolDatabase::SpaceInfo *info = *i; // only check functions if (info->type != SymbolDatabase::SpaceInfo::Function) diff --git a/lib/tokenize.cpp b/lib/tokenize.cpp index 249ebc656..6e7441daa 100644 --- a/lib/tokenize.cpp +++ b/lib/tokenize.cpp @@ -7954,11 +7954,11 @@ const Token *Tokenizer::getFunctionTokenByName(const char funcname[]) const if (_symbolDatabase == NULL) getSymbolDatabase(); - std::list::iterator i; + std::list::const_iterator i; for (i = _symbolDatabase->spaceInfoList.begin(); i != _symbolDatabase->spaceInfoList.end(); ++i) { - SymbolDatabase::SpaceInfo *info = *i; + const SymbolDatabase::SpaceInfo *info = *i; if (info->type == SymbolDatabase::SpaceInfo::Function) { @@ -9235,7 +9235,7 @@ void Tokenizer::simplifyQtSignalsSlots() } } -SymbolDatabase *Tokenizer::getSymbolDatabase() const +const SymbolDatabase *Tokenizer::getSymbolDatabase() const { if (!_symbolDatabase) _symbolDatabase = new SymbolDatabase(this, _settings, _errorLogger); diff --git a/lib/tokenize.h b/lib/tokenize.h index 749d836c2..318bdf4c4 100644 --- a/lib/tokenize.h +++ b/lib/tokenize.h @@ -572,9 +572,9 @@ public: _settings = settings; } - SymbolDatabase * getSymbolDatabase() const; + const SymbolDatabase *getSymbolDatabase() const; - Token * deleteInvalidTypedef(Token *typeDef); + Token *deleteInvalidTypedef(Token *typeDef); private: /** Disable copy constructor, no implementation */ From e6a1efa13b8828c99fa38945952d97fc22ea1100 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Sun, 16 Jan 2011 18:45:05 +0100 Subject: [PATCH 065/165] Fixed #2302 (Duplicate id 'unusedVariable') --- lib/checkother.cpp | 2 +- test/testcppcheck.cpp | 12 ++++++++++++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/lib/checkother.cpp b/lib/checkother.cpp index 1a17e0d2e..2caf92f66 100644 --- a/lib/checkother.cpp +++ b/lib/checkother.cpp @@ -1875,7 +1875,7 @@ void CheckOther::unusedVariableError(const Token *tok, const std::string &varnam void CheckOther::allocatedButUnusedVariableError(const Token *tok, const std::string &varname) { - reportError(tok, Severity::style, "unusedVariable", "Variable '" + varname + "' is allocated memory that is never used"); + reportError(tok, Severity::style, "unusedAllocatedMemory", "Variable '" + varname + "' is allocated memory that is never used"); } void CheckOther::unreadVariableError(const Token *tok, const std::string &varname) diff --git a/test/testcppcheck.cpp b/test/testcppcheck.cpp index 582a6376d..af6e33883 100644 --- a/test/testcppcheck.cpp +++ b/test/testcppcheck.cpp @@ -77,6 +77,18 @@ private: ASSERT(!errorLogger.id.empty()); // TODO: check if there are duplicate error ids in errorLogger.id + std::string duplicate; + for (std::list::iterator it = errorLogger.id.begin(); + it != errorLogger.id.end(); + ++it) + { + if (std::find(errorLogger.id.begin(), it, *it) != it) + { + duplicate = "Duplicate ID: " + *it; + break; + } + } + ASSERT_EQUALS("", duplicate); } }; From 93d1313186941bfdf38b40a173e0341fad90a115 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Sun, 16 Jan 2011 19:57:29 +0100 Subject: [PATCH 066/165] Refactoring: Check if type is class/struct through symbol database --- lib/checkautovariables.cpp | 5 ++++- lib/checkother.cpp | 17 +++++------------ lib/symboldatabase.cpp | 7 +++++++ lib/symboldatabase.h | 9 +++++++++ 4 files changed, 25 insertions(+), 13 deletions(-) diff --git a/lib/checkautovariables.cpp b/lib/checkautovariables.cpp index b24020435..414ae527e 100644 --- a/lib/checkautovariables.cpp +++ b/lib/checkautovariables.cpp @@ -21,6 +21,7 @@ //--------------------------------------------------------------------------- #include "checkautovariables.h" +#include "symboldatabase.h" #include #include @@ -140,6 +141,8 @@ void CheckAutoVariables::autoVariables() // Which variables have an unknown type? std::set unknown_type; + const SymbolDatabase * const symbolDatabase = _tokenizer->getSymbolDatabase(); + for (const Token *tok = _tokenizer->tokens(); tok; tok = tok->next()) { @@ -192,7 +195,7 @@ void CheckAutoVariables::autoVariables() { addVD(tok->next()->varId()); if (!tok->isStandardType() && - NULL == Token::findmatch(_tokenizer->tokens(), ("struct|class " + tok->str()).c_str())) + !symbolDatabase->isClassOrStruct(tok->str())) { unknown_type.insert(tok->next()->varId()); } diff --git a/lib/checkother.cpp b/lib/checkother.cpp index 2caf92f66..a7e955484 100644 --- a/lib/checkother.cpp +++ b/lib/checkother.cpp @@ -2100,6 +2100,8 @@ void CheckOther::checkConstantFunctionParameter() if (!_settings->_checkCodingStyle) return; + const SymbolDatabase * const symbolDatabase = _tokenizer->getSymbolDatabase(); + for (const Token *tok = _tokenizer->tokens(); tok; tok = tok->next()) { if (Token::Match(tok, "[,(] const std :: %type% %var% [,)]")) @@ -2140,8 +2142,7 @@ void CheckOther::checkConstantFunctionParameter() else if (Token::Match(tok, "[,(] const %type% %var% [,)]")) { // Check if type is a struct or class. - const std::string pattern(std::string("class|struct ") + tok->strAt(2)); - if (Token::findmatch(_tokenizer->tokens(), pattern.c_str())) + if (symbolDatabase->isClassOrStruct(tok->strAt(2))) { passedByValueError(tok, tok->strAt(3)); } @@ -2529,18 +2530,10 @@ void CheckOther::checkMisusedScopedObject() return; } - const SymbolDatabase *symbolDatabase = _tokenizer->getSymbolDatabase(); + const SymbolDatabase * const symbolDatabase = _tokenizer->getSymbolDatabase(); std::list::const_iterator i; - // list of classes / structs - std::set identifiers; - for (const Token *tok = _tokenizer->tokens(); tok; tok = tok->next()) - { - if (Token::Match(tok, "class|struct %var% [:{;]")) - identifiers.insert(tok->next()->str()); - } - for (i = symbolDatabase->spaceInfoList.begin(); i != symbolDatabase->spaceInfoList.end(); ++i) { const SymbolDatabase::SpaceInfo *info = *i; @@ -2566,7 +2559,7 @@ void CheckOther::checkMisusedScopedObject() if (Token::Match(tok, "[;{}] %var% (") && Token::Match(tok->tokAt(2)->link(), ") ;") - && identifiers.find(tok->next()->str()) != identifiers.end() + && symbolDatabase->isClassOrStruct(tok->next()->str()) ) { tok = tok->next(); diff --git a/lib/symboldatabase.cpp b/lib/symboldatabase.cpp index ea1401e7c..f7db79018 100644 --- a/lib/symboldatabase.cpp +++ b/lib/symboldatabase.cpp @@ -38,6 +38,13 @@ SymbolDatabase::SymbolDatabase(const Tokenizer *tokenizer, const Settings *settings, ErrorLogger *errorLogger) : _tokenizer(tokenizer), _settings(settings), _errorLogger(errorLogger) { + // fill the classAndStructTypes set.. + for (const Token *tok = _tokenizer->tokens(); tok; tok = tok->next()) + { + if (Token::Match(tok, "class|struct %var% [:{;]")) + classAndStructTypes.insert(tok->next()->str()); + } + // find all namespaces (class,struct and namespace) SpaceInfo *info = new SpaceInfo(this, NULL, NULL); spaceInfoList.push_back(info); diff --git a/lib/symboldatabase.h b/lib/symboldatabase.h index 177c981be..b9f54b995 100644 --- a/lib/symboldatabase.h +++ b/lib/symboldatabase.h @@ -24,6 +24,7 @@ #include #include #include +#include class Token; class Tokenizer; @@ -223,6 +224,11 @@ public: bool argsMatch(const SpaceInfo *info, const Token *first, const Token *second, const std::string &path, unsigned int depth) const; + bool isClassOrStruct(const std::string &type) const + { + return bool(classAndStructTypes.find(type) != classAndStructTypes.end()); + } + private: // Needed by Borland C++: @@ -233,6 +239,9 @@ private: const Token *initBaseInfo(SpaceInfo *info, const Token *tok); bool isFunction(const Token *tok, const Token **funcStart, const Token **argStart) const; + /** class/struct types */ + std::set classAndStructTypes; + const Tokenizer *_tokenizer; const Settings *_settings; ErrorLogger *_errorLogger; From 38c37ad2d852fc8c69906f42adc4e0c8b64abdf8 Mon Sep 17 00:00:00 2001 From: Pete Johns Date: Sat, 1 Jan 2011 11:19:32 +1100 Subject: [PATCH 067/165] Moved array declaration detection into isVariableDeclaration() --- lib/symboldatabase.cpp | 46 +++++++++++-------------------------- lib/symboldatabase.h | 2 ++ test/testclass.cpp | 15 ++++++++++++ test/testsymboldatabase.cpp | 23 ++++++++++++++++++- 4 files changed, 52 insertions(+), 34 deletions(-) diff --git a/lib/symboldatabase.cpp b/lib/symboldatabase.cpp index f7db79018..4ed0c411b 100644 --- a/lib/symboldatabase.cpp +++ b/lib/symboldatabase.cpp @@ -1167,40 +1167,9 @@ void SymbolDatabase::SpaceInfo::getVarList() if (isVariableDeclaration(tok, vartok, typetok)) { - isClass = (!typetok->isStandardType()); + isClass = (!typetok->isStandardType() && typetok->next()->str() != "*"); tok = vartok->next(); } - - // Array? - else if (Token::Match(tok, "%type% %var% [") && tok->next()->str() != "operator") - { - if (!tok->isStandardType()) - { - isClass = true; - typetok = tok; - } - - vartok = tok->next(); - tok = vartok->next()->link()->next(); - } - - // Pointer array? - else if (Token::Match(tok, "%type% * %var% [")) - { - vartok = tok->tokAt(2); - tok = vartok->next(); - } - else if (Token::Match(tok, "%type% :: %type% * %var% [")) - { - vartok = tok->tokAt(4); - tok = vartok->next(); - } - else if (Token::Match(tok, "%type% :: %type% :: %type% * %var% [")) - { - vartok = tok->tokAt(6); - tok = vartok->next(); - } - // Container.. else if (Token::Match(tok, ":: %type% :: %type% :: %type% <") || Token::Match(tok, "%type% :: %type% :: %type% <") || @@ -1264,6 +1233,7 @@ void SymbolDatabase::SpaceInfo::getVarList() } } + // If the vartok was set in the if-blocks above, create a entry for this variable.. if (vartok && vartok->str() != "operator") { @@ -1332,7 +1302,7 @@ bool SymbolDatabase::SpaceInfo::isVariableDeclaration(const Token* tok, const To tok = skipPointers(tok->next()); - if (Token::Match(tok, "%var% ;")) + if (isSimpleVariable(tok) || isArrayVariable(tok)) { vartok = tok; typetok = potentialTypetok; @@ -1342,6 +1312,16 @@ bool SymbolDatabase::SpaceInfo::isVariableDeclaration(const Token* tok, const To return NULL != vartok; } +bool SymbolDatabase::SpaceInfo::isSimpleVariable(const Token* tok) const +{ + return Token::Match(tok, "%var% ;"); +} + +bool SymbolDatabase::SpaceInfo::isArrayVariable(const Token* tok) const +{ + return Token::Match(tok, "%var% [") && tok->next()->str() != "operator"; +} + //--------------------------------------------------------------------------- const SymbolDatabase::SpaceInfo *SymbolDatabase::findVarType(const SpaceInfo *start, const Token *type) const diff --git a/lib/symboldatabase.h b/lib/symboldatabase.h index b9f54b995..d592f70e6 100644 --- a/lib/symboldatabase.h +++ b/lib/symboldatabase.h @@ -209,6 +209,8 @@ public: * @return true if tok points to a variable declaration, false otherwise */ bool isVariableDeclaration(const Token* tok, const Token*& vartok, const Token*& typetok) const; + bool isSimpleVariable(const Token* tok) const; + bool isArrayVariable(const Token* tok) const; }; /** @brief Information about all namespaces/classes/structrues */ diff --git a/test/testclass.cpp b/test/testclass.cpp index a36dcd13a..563f07549 100644 --- a/test/testclass.cpp +++ b/test/testclass.cpp @@ -163,6 +163,7 @@ private: TEST_CASE(const42); // ticket #2282 TEST_CASE(const43); // ticket #2377 TEST_CASE(assigningPointerToPointerIsNotAConstOperation); + TEST_CASE(assigningArrayElementIsNotAConstOperation); TEST_CASE(constoperator1); // operator< can often be const TEST_CASE(constoperator2); // operator<< TEST_CASE(constoperator3); @@ -4937,6 +4938,20 @@ private: ASSERT_EQUALS("", errout.str()); } + void assigningArrayElementIsNotAConstOperation() + { + checkConst("struct s\n" + "{\n" + " ::std::string v[3];\n" + " void f()\n" + " {\n" + " v[0] = \"Happy new year!\";\n" + " }\n" + "};\n" + ); + ASSERT_EQUALS("", errout.str()); + } + // increment/decrement => not const void constincdec() { diff --git a/test/testsymboldatabase.cpp b/test/testsymboldatabase.cpp index 4cb424096..57e0afa79 100644 --- a/test/testsymboldatabase.cpp +++ b/test/testsymboldatabase.cpp @@ -56,7 +56,8 @@ private: TEST_CASE(test_isVariableDeclarationIdentifiesScopedPointerDeclaration); TEST_CASE(test_isVariableDeclarationIdentifiesDeclarationWithIndirection); TEST_CASE(test_isVariableDeclarationIdentifiesDeclarationWithMultipleIndirection); - + TEST_CASE(test_isVariableDeclarationIdentifiesArray); + TEST_CASE(test_isVariableDeclarationIdentifiesOfArrayPointers); } void test_isVariableDeclarationCanHandleNull() @@ -177,6 +178,26 @@ private: ASSERT_EQUALS("p", vartok->str()); ASSERT_EQUALS("int", typetok->str()); } + + void test_isVariableDeclarationIdentifiesArray() + { + reset(); + givenACodeSampleToTokenize array("::std::string v[3];"); + bool result = si.isVariableDeclaration(array.tokens(), vartok, typetok); + ASSERT_EQUALS(true, result); + ASSERT_EQUALS("v", vartok->str()); + ASSERT_EQUALS("string", typetok->str()); + } + + void test_isVariableDeclarationIdentifiesOfArrayPointers() + { + reset(); + givenACodeSampleToTokenize array("A *a[5];"); + bool result = si.isVariableDeclaration(array.tokens(), vartok, typetok); + ASSERT_EQUALS(true, result); + ASSERT_EQUALS("a", vartok->str()); + ASSERT_EQUALS("A", typetok->str()); + } }; REGISTER_TEST(TestSymbolDatabase) From 7918c4b804830262cd829d19d94cb46bd614e247 Mon Sep 17 00:00:00 2001 From: Pete Johns Date: Sun, 2 Jan 2011 10:36:22 +1100 Subject: [PATCH 068/165] isVariableDeclaration() now detects template variables. --- lib/symboldatabase.cpp | 132 ++++++++++++++++-------------------- lib/symboldatabase.h | 1 + test/testsymboldatabase.cpp | 115 +++++++++++++++++++++++++++++++ 3 files changed, 175 insertions(+), 73 deletions(-) diff --git a/lib/symboldatabase.cpp b/lib/symboldatabase.cpp index 4ed0c411b..31bf15a2a 100644 --- a/lib/symboldatabase.cpp +++ b/lib/symboldatabase.cpp @@ -1167,72 +1167,9 @@ void SymbolDatabase::SpaceInfo::getVarList() if (isVariableDeclaration(tok, vartok, typetok)) { - isClass = (!typetok->isStandardType() && typetok->next()->str() != "*"); + isClass = (!typetok->isStandardType() && vartok->previous()->str() != "*"); tok = vartok->next(); } - // Container.. - else if (Token::Match(tok, ":: %type% :: %type% :: %type% <") || - Token::Match(tok, "%type% :: %type% :: %type% <") || - Token::Match(tok, ":: %type% :: %type% <") || - Token::Match(tok, "%type% :: %type% <") || - Token::Match(tok, ":: %type% <") || - Token::Match(tok, "%type% <")) - { - // got an unhandled template? - if (tok->str() == "template") - continue; - - // find matching ">" - int level = 0; - const Token *tok1 = NULL; - for (; tok; tok = tok->next()) - { - if (tok->str() == "<") - { - if (level == 0) - tok1 = tok->previous(); - level++; - } - else if (tok->str() == ">") - { - level--; - if (level == 0) - break; - } - else if (tok->str() == ">>") - { - level-=2; - if (level <= 0) - break; - } - else if (tok->str() == "(") - tok = tok->link(); - - // don't crash on unhandled templates - if (tok->next() == NULL) - break; - } - if (tok && (Token::Match(tok, "> %var% ;") || Token::Match(tok, ">> %var% ;"))) - { - isClass = true; - vartok = tok->next(); - typetok = tok1; - tok = vartok->next(); - } - else if (tok && (Token::Match(tok, "> :: %type% %var% ;") || Token::Match(tok, ">> :: %type% %var% ;"))) - { - isClass = true; - vartok = tok->tokAt(3); - typetok = vartok->previous(); - tok = vartok->next(); - } - else if (tok && (Token::Match(tok, "> * %var% ;") || Token::Match(tok, ">> * %var% ;"))) - { - vartok = tok->tokAt(2); - tok = vartok->next(); - } - } - // If the vartok was set in the if-blocks above, create a entry for this variable.. if (vartok && vartok->str() != "operator") @@ -1295,17 +1232,39 @@ const Token* skipPointers(const Token* tok) bool SymbolDatabase::SpaceInfo::isVariableDeclaration(const Token* tok, const Token*& vartok, const Token*& typetok) const { - tok = skipScopeIdentifiers(tok); - if (Token::Match(tok, "%type%")) + const Token* localTypeTok = skipScopeIdentifiers(tok); + + if (Token::Match(localTypeTok, "%type% < ")) { - const Token* potentialTypetok = tok; - - tok = skipPointers(tok->next()); - - if (isSimpleVariable(tok) || isArrayVariable(tok)) + const Token* closetok = NULL; + bool found = findClosingBracket(localTypeTok->next(), closetok); + if (found) { - vartok = tok; - typetok = potentialTypetok; + if (Token::Match(closetok, "> %var% ;")) + { + vartok = closetok->next(); + typetok = localTypeTok; + } + else if (Token::Match(closetok, "> * %var% ;")) + { + vartok = closetok->tokAt(2); + typetok = localTypeTok; + } + else if (Token::Match(closetok, "> :: %type% %var% ;")) + { + vartok = closetok->tokAt(3); + typetok = closetok->tokAt(2); + } + } + } + else if (Token::Match(localTypeTok, "%type%")) + { + const Token* localVarTok = skipPointers(localTypeTok->next()); + + if (isSimpleVariable(localVarTok) || isArrayVariable(localVarTok)) + { + vartok = localVarTok; + typetok = localTypeTok; } } @@ -1322,6 +1281,33 @@ bool SymbolDatabase::SpaceInfo::isArrayVariable(const Token* tok) const return Token::Match(tok, "%var% [") && tok->next()->str() != "operator"; } +bool SymbolDatabase::SpaceInfo::findClosingBracket(const Token* tok, const Token*& close) const +{ + bool found = false; + if (NULL != tok && tok->str() == "<") + { + unsigned int depth = 0; + for (close = tok; (close != NULL) && (close->str() != ";"); close = close->next()) + { + if (close->str() == "<") + { + ++depth; + } + else if (close->str() == ">") + { + if (--depth == 0) + { + found = true; + break; + } + } + } + } + + return found; +} + + //--------------------------------------------------------------------------- const SymbolDatabase::SpaceInfo *SymbolDatabase::findVarType(const SpaceInfo *start, const Token *type) const diff --git a/lib/symboldatabase.h b/lib/symboldatabase.h index d592f70e6..cbfca5b86 100644 --- a/lib/symboldatabase.h +++ b/lib/symboldatabase.h @@ -211,6 +211,7 @@ public: bool isVariableDeclaration(const Token* tok, const Token*& vartok, const Token*& typetok) const; bool isSimpleVariable(const Token* tok) const; bool isArrayVariable(const Token* tok) const; + bool findClosingBracket(const Token* tok, const Token*& close) const; }; /** @brief Information about all namespaces/classes/structrues */ diff --git a/test/testsymboldatabase.cpp b/test/testsymboldatabase.cpp index 57e0afa79..98e80671e 100644 --- a/test/testsymboldatabase.cpp +++ b/test/testsymboldatabase.cpp @@ -35,11 +35,15 @@ private: const SymbolDatabase::SpaceInfo si; const Token* vartok; const Token* typetok; + const Token* t; + bool found; void reset() { vartok = NULL; typetok = NULL; + t = NULL; + found = false; } void run() @@ -58,6 +62,16 @@ private: TEST_CASE(test_isVariableDeclarationIdentifiesDeclarationWithMultipleIndirection); TEST_CASE(test_isVariableDeclarationIdentifiesArray); TEST_CASE(test_isVariableDeclarationIdentifiesOfArrayPointers); + TEST_CASE(isVariableDeclarationIdentifiesTemplatedPointerVariable); + TEST_CASE(isVariableDeclarationIdentifiesTemplatedVariable); + TEST_CASE(isVariableDeclarationIdentifiesTemplatedVariableIterator); + TEST_CASE(isVariableDeclarationIdentifiesNestedTemplateVariable); + TEST_CASE(isVariableDeclarationDoesNotIdentifyTemplateClass); + TEST_CASE(canFindMatchingBracketsNeedsOpen); + TEST_CASE(canFindMatchingBracketsInnerPair); + TEST_CASE(canFindMatchingBracketsOuterPair); + TEST_CASE(canFindMatchingBracketsWithTooManyClosing); + TEST_CASE(canFindMatchingBracketsWithTooManyOpening); } void test_isVariableDeclarationCanHandleNull() @@ -198,6 +212,107 @@ private: ASSERT_EQUALS("a", vartok->str()); ASSERT_EQUALS("A", typetok->str()); } + + void isVariableDeclarationIdentifiesTemplatedPointerVariable() + { + reset(); + givenACodeSampleToTokenize var("std::set* chars;"); + bool result = si.isVariableDeclaration(var.tokens(), vartok, typetok); + ASSERT_EQUALS(true, result); + ASSERT_EQUALS("chars", vartok->str()); + ASSERT_EQUALS("set", typetok->str()); + } + + void isVariableDeclarationIdentifiesTemplatedVariable() + { + reset(); + givenACodeSampleToTokenize var("std::vector ints;"); + bool result = si.isVariableDeclaration(var.tokens(), vartok, typetok); + ASSERT_EQUALS(true, result); + ASSERT_EQUALS("ints", vartok->str()); + ASSERT_EQUALS("vector", typetok->str()); + } + + void isVariableDeclarationIdentifiesTemplatedVariableIterator() + { + reset(); + givenACodeSampleToTokenize var("std::list::const_iterator floats;"); + bool result = si.isVariableDeclaration(var.tokens(), vartok, typetok); + ASSERT_EQUALS(true, result); + ASSERT_EQUALS("floats", vartok->str()); + ASSERT_EQUALS("const_iterator", typetok->str()); + } + + void isVariableDeclarationIdentifiesNestedTemplateVariable() + { + reset(); + givenACodeSampleToTokenize var("std::deque > intsets;"); + bool result = si.isVariableDeclaration(var.tokens(), vartok, typetok); + ASSERT_EQUALS(true, result); + ASSERT_EQUALS("intsets", vartok->str()); + ASSERT_EQUALS("deque", typetok->str()); + } + + void isVariableDeclarationDoesNotIdentifyTemplateClass() + { + reset(); + givenACodeSampleToTokenize var("template class SomeClass{};"); + bool result = si.isVariableDeclaration(var.tokens(), vartok, typetok); + ASSERT_EQUALS(false, result); + } + + void canFindMatchingBracketsNeedsOpen() + { + reset(); + givenACodeSampleToTokenize var("std::deque > intsets;"); + + found = si.findClosingBracket(var.tokens(), t); + ASSERT(! found); + ASSERT(! t); + } + + void canFindMatchingBracketsInnerPair() + { + reset(); + givenACodeSampleToTokenize var("std::deque > intsets;"); + + found = si.findClosingBracket(var.tokens()->tokAt(7), t); + ASSERT(found); + ASSERT_EQUALS(">", t->str()); + ASSERT_EQUALS(var.tokens()->strAt(9), t->str()); + } + + void canFindMatchingBracketsOuterPair() + { + reset(); + givenACodeSampleToTokenize var("std::deque > intsets;"); + + found = si.findClosingBracket(var.tokens()->tokAt(3), t); + ASSERT(found); + ASSERT_EQUALS(">", t->str()); + ASSERT_EQUALS(var.tokens()->strAt(10), t->str()); + + } + + void canFindMatchingBracketsWithTooManyClosing() + { + reset(); + givenACodeSampleToTokenize var("X< 1>2 > x1;\n"); + + found = si.findClosingBracket(var.tokens()->tokAt(1), t); + ASSERT(found); + ASSERT_EQUALS(">", t->str()); + ASSERT_EQUALS(var.tokens()->strAt(3), t->str()); + } + + void canFindMatchingBracketsWithTooManyOpening() + { + reset(); + givenACodeSampleToTokenize var("X < (2 < 1) > x1;\n"); + + found = si.findClosingBracket(var.tokens()->tokAt(1), t); + ASSERT(!found); + } }; REGISTER_TEST(TestSymbolDatabase) From 9c300813a4371eab7246ff12938301487938fc95 Mon Sep 17 00:00:00 2001 From: Pete Johns Date: Mon, 17 Jan 2011 08:52:26 +1100 Subject: [PATCH 069/165] Fixed gcc warning. --- lib/preprocessor.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/preprocessor.cpp b/lib/preprocessor.cpp index 467ad7f58..7a7ac1c74 100644 --- a/lib/preprocessor.cpp +++ b/lib/preprocessor.cpp @@ -1537,11 +1537,11 @@ void Preprocessor::handleIncludes(std::string &code, const std::string &filePath includePaths2.push_front(""); for (std::list::const_iterator iter = includePaths2.begin(); iter != includePaths2.end(); ++iter) { - const std::string path(Path::toNativeSeparators(*iter)); - fin.open((path + filename).c_str()); + const std::string nativePath(Path::toNativeSeparators(*iter)); + fin.open((nativePath + filename).c_str()); if (fin.is_open()) { - filename = path + filename; + filename = nativePath + filename; fileOpened = true; break; } From 481907ef147f52cb895a3e39e23d27eab964b218 Mon Sep 17 00:00:00 2001 From: Zachary Blair Date: Sun, 16 Jan 2011 13:57:29 -0800 Subject: [PATCH 070/165] Fixed #2457 (CheckOther::checkIncorrectLogicOperator: hang if variable id is 0) --- lib/checkother.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/lib/checkother.cpp b/lib/checkother.cpp index a7e955484..ff3f83d23 100644 --- a/lib/checkother.cpp +++ b/lib/checkother.cpp @@ -254,7 +254,11 @@ void CheckOther::checkIncorrectLogicOperator() { const unsigned int varId = term1Tok->varId(); if (!varId) + { + tok = Token::findmatch(endTok->next(), conditionPattern); + endTok = tok ? tok->next()->link() : NULL; continue; + } firstConstant = term1Tok->tokAt(2)->str(); if (Token::Match(term2Tok, "%varid% != %num%", varId)) From bf9528558e8097b839789db6ee7669244e855977 Mon Sep 17 00:00:00 2001 From: Robert Reif Date: Mon, 17 Jan 2011 07:21:59 +0100 Subject: [PATCH 071/165] Symbol database: pulled out classes into global scope. ticket: #2468 --- lib/checkclass.cpp | 140 ++++++++--------- lib/checkclass.h | 18 +-- lib/checkmemoryleak.cpp | 52 +++---- lib/checkmemoryleak.h | 4 +- lib/checkother.cpp | 22 +-- lib/symboldatabase.cpp | 38 ++--- lib/symboldatabase.h | 289 ++++++++++++++++++------------------ lib/tokenize.cpp | 12 +- test/testsymboldatabase.cpp | 2 +- 9 files changed, 289 insertions(+), 288 deletions(-) diff --git a/lib/checkclass.cpp b/lib/checkclass.cpp index 4c71a0bf7..5958d09c4 100644 --- a/lib/checkclass.cpp +++ b/lib/checkclass.cpp @@ -68,11 +68,11 @@ void CheckClass::constructors() createSymbolDatabase(); - std::list::const_iterator i; + std::list::const_iterator i; for (i = symbolDatabase->spaceInfoList.begin(); i != symbolDatabase->spaceInfoList.end(); ++i) { - const SymbolDatabase::SpaceInfo *info = *i; + const SpaceInfo *info = *i; // only check classes and structures if (!info->isClassOrStruct()) @@ -82,10 +82,10 @@ void CheckClass::constructors() if (info->numConstructors == 0) { // If there is a private variable, there should be a constructor.. - std::list::const_iterator var; + std::list::const_iterator var; for (var = info->varlist.begin(); var != info->varlist.end(); ++var) { - if (var->access == SymbolDatabase::Private && !var->isClass && !var->isStatic) + if (var->access == Private && !var->isClass && !var->isStatic) { noConstructorError(info->classDef, info->className, info->classDef->str() == "struct"); break; @@ -93,14 +93,14 @@ void CheckClass::constructors() } } - std::list::const_iterator func; + std::list::const_iterator func; std::vector usage(info->varlist.size()); for (func = info->functionList.begin(); func != info->functionList.end(); ++func) { - if (!func->hasBody || !(func->type == SymbolDatabase::Func::Constructor || - func->type == SymbolDatabase::Func::CopyConstructor || - func->type == SymbolDatabase::Func::OperatorEqual)) + if (!func->hasBody || !(func->type == Func::Constructor || + func->type == Func::CopyConstructor || + func->type == Func::OperatorEqual)) continue; // Mark all variables not used @@ -110,7 +110,7 @@ void CheckClass::constructors() initializeVarList(*func, callstack, info, usage); // Check if any variables are uninitialized - std::list::const_iterator var; + std::list::const_iterator var; unsigned int count = 0; for (var = info->varlist.begin(); var != info->varlist.end(); ++var, ++count) { @@ -121,7 +121,7 @@ void CheckClass::constructors() continue; // Check if this is a class constructor - if (var->isClass && func->type == SymbolDatabase::Func::Constructor) + if (var->isClass && func->type == Func::Constructor) { // Unknown type so assume it is initialized if (!var->type) @@ -129,12 +129,12 @@ void CheckClass::constructors() // Known type that doesn't need initialization or // known type that has member variables of an unknown type - else if (var->type->needInitialization != SymbolDatabase::SpaceInfo::True) + else if (var->type->needInitialization != SpaceInfo::True) continue; } // It's non-static and it's not initialized => error - if (func->type == SymbolDatabase::Func::OperatorEqual) + if (func->type == Func::OperatorEqual) { const Token *operStart = 0; if (func->token->str() == "=") @@ -155,16 +155,16 @@ void CheckClass::constructors() if (classNameUsed) operatorEqVarError(func->token, info->className, var->token->str()); } - else if (func->access != SymbolDatabase::Private) + else if (func->access != Private) uninitVarError(func->token, info->className, var->token->str()); } } } } -void CheckClass::assignVar(const std::string &varname, const SymbolDatabase::SpaceInfo *info, std::vector &usage) +void CheckClass::assignVar(const std::string &varname, const SpaceInfo *info, std::vector &usage) { - std::list::const_iterator var; + std::list::const_iterator var; unsigned int count = 0; for (var = info->varlist.begin(); var != info->varlist.end(); ++var, ++count) @@ -177,9 +177,9 @@ void CheckClass::assignVar(const std::string &varname, const SymbolDatabase::Spa } } -void CheckClass::initVar(const std::string &varname, const SymbolDatabase::SpaceInfo *info, std::vector &usage) +void CheckClass::initVar(const std::string &varname, const SpaceInfo *info, std::vector &usage) { - std::list::const_iterator var; + std::list::const_iterator var; unsigned int count = 0; for (var = info->varlist.begin(); var != info->varlist.end(); ++var, ++count) @@ -207,17 +207,17 @@ void CheckClass::clearAllVar(std::vector &usage) } } -bool CheckClass::isBaseClassFunc(const Token *tok, const SymbolDatabase::SpaceInfo *info) +bool CheckClass::isBaseClassFunc(const Token *tok, const SpaceInfo *info) { // Iterate through each base class... for (size_t i = 0; i < info->derivedFrom.size(); ++i) { - const SymbolDatabase::SpaceInfo *derivedFrom = info->derivedFrom[i].spaceInfo; + const SpaceInfo *derivedFrom = info->derivedFrom[i].spaceInfo; // Check if base class exists in database if (derivedFrom) { - std::list::const_iterator func; + std::list::const_iterator func; for (func = derivedFrom->functionList.begin(); func != derivedFrom->functionList.end(); ++func) { @@ -234,7 +234,7 @@ bool CheckClass::isBaseClassFunc(const Token *tok, const SymbolDatabase::SpaceIn return false; } -void CheckClass::initializeVarList(const SymbolDatabase::Func &func, std::list &callstack, const SymbolDatabase::SpaceInfo *info, std::vector &usage) +void CheckClass::initializeVarList(const Func &func, std::list &callstack, const SpaceInfo *info, std::vector &usage) { bool Assign = false; unsigned int indentlevel = 0; @@ -302,7 +302,7 @@ void CheckClass::initializeVarList(const SymbolDatabase::Func &func, std::listnext(), "%var% . %var% (")) { - std::list::const_iterator var; + std::list::const_iterator var; for (var = info->varlist.begin(); var != info->varlist.end(); ++var) { if (var->token->varId() == ftok->next()->varId()) @@ -359,10 +359,10 @@ void CheckClass::initializeVarList(const SymbolDatabase::Func &func, std::listprevious()->str() != "::") { // check if member function exists - std::list::const_iterator it; + std::list::const_iterator it; for (it = info->functionList.begin(); it != info->functionList.end(); ++it) { - if (ftok->next()->str() == it->tokenDef->str() && it->type != SymbolDatabase::Func::Constructor) + if (ftok->next()->str() == it->tokenDef->str() && it->type != Func::Constructor) break; } @@ -412,10 +412,10 @@ void CheckClass::initializeVarList(const SymbolDatabase::Func &func, std::list::const_iterator it; + std::list::const_iterator it; for (it = info->functionList.begin(); it != info->functionList.end(); ++it) { - if (ftok->str() == it->tokenDef->str() && it->type != SymbolDatabase::Func::Constructor) + if (ftok->str() == it->tokenDef->str() && it->type != Func::Constructor) break; } @@ -442,7 +442,7 @@ void CheckClass::initializeVarList(const SymbolDatabase::Func &func, std::list::const_iterator i; + std::list::const_iterator i; for (i = symbolDatabase->spaceInfoList.begin(); i != symbolDatabase->spaceInfoList.end(); ++i) { - const SymbolDatabase::SpaceInfo *info = *i; + const SpaceInfo *info = *i; // only check classes and structures if (!info->isClassOrStruct()) @@ -588,13 +588,13 @@ void CheckClass::privateFunctions() // check that the whole class implementation is seen bool whole = true; - std::list::const_iterator func; + std::list::const_iterator func; for (func = info->functionList.begin(); func != info->functionList.end(); ++func) { if (!func->hasBody) { // empty private copy constructors and assignment operators are OK - if ((func->type == SymbolDatabase::Func::CopyConstructor || func->type == SymbolDatabase::Func::OperatorEqual) && func->access == SymbolDatabase::Private) + if ((func->type == Func::CopyConstructor || func->type == Func::OperatorEqual) && func->access == Private) continue; whole = false; @@ -614,8 +614,8 @@ void CheckClass::privateFunctions() for (func = info->functionList.begin(); func != info->functionList.end(); ++func) { // Get private functions.. - if (func->type == SymbolDatabase::Func::Function && - func->access == SymbolDatabase::Private && func->hasBody) + if (func->type == Func::Function && + func->access == Private && func->hasBody) FuncList.push_back(func->tokenDef); } } @@ -834,15 +834,15 @@ void CheckClass::operatorEq() createSymbolDatabase(); - std::list::const_iterator i; + std::list::const_iterator i; for (i = symbolDatabase->spaceInfoList.begin(); i != symbolDatabase->spaceInfoList.end(); ++i) { - std::list::const_iterator it; + std::list::const_iterator it; for (it = (*i)->functionList.begin(); it != (*i)->functionList.end(); ++it) { - if (it->type == SymbolDatabase::Func::OperatorEqual && it->access != SymbolDatabase::Private) + if (it->type == Func::OperatorEqual && it->access != Private) { if (it->token->strAt(-2) == "void") operatorEqReturnError(it->token->tokAt(-2)); @@ -861,7 +861,7 @@ void CheckClass::operatorEqReturnError(const Token *tok) // operator= should return a reference to *this //--------------------------------------------------------------------------- -void CheckClass::checkReturnPtrThis(const SymbolDatabase::SpaceInfo *info, const SymbolDatabase::Func *func, const Token *tok, const Token *last) +void CheckClass::checkReturnPtrThis(const SpaceInfo *info, const Func *func, const Token *tok, const Token *last) { bool foundReturn = false; @@ -879,13 +879,13 @@ void CheckClass::checkReturnPtrThis(const SymbolDatabase::SpaceInfo *info, const if (Token::Match(tok->tokAt(1), "%any% (") && tok->tokAt(2)->link()->next()->str() == ";") { - std::list::const_iterator it; + std::list::const_iterator it; // check if it is a member function for (it = info->functionList.begin(); it != info->functionList.end(); ++it) { // check for a regular function with the same name and a bofy - if (it->type == SymbolDatabase::Func::Function && it->hasBody && + if (it->type == Func::Function && it->hasBody && it->token->str() == tok->next()->str()) { // check for the proper return type @@ -918,20 +918,20 @@ void CheckClass::operatorEqRetRefThis() createSymbolDatabase(); - std::list::const_iterator i; + std::list::const_iterator i; for (i = symbolDatabase->spaceInfoList.begin(); i != symbolDatabase->spaceInfoList.end(); ++i) { - const SymbolDatabase::SpaceInfo *info = *i; + const SpaceInfo *info = *i; // only check classes and structures if (info->isClassOrStruct()) { - std::list::const_iterator func; + std::list::const_iterator func; for (func = info->functionList.begin(); func != info->functionList.end(); ++func) { - if (func->type == SymbolDatabase::Func::OperatorEqual && func->hasBody) + if (func->type == Func::OperatorEqual && func->hasBody) { // make sure return signature is correct if (Token::Match(func->tokenDef->tokAt(-4), ";|}|{|public:|protected:|private: %type% &") && @@ -974,12 +974,12 @@ void CheckClass::operatorEqToSelf() createSymbolDatabase(); - std::list::const_iterator i; + std::list::const_iterator i; for (i = symbolDatabase->spaceInfoList.begin(); i != symbolDatabase->spaceInfoList.end(); ++i) { - const SymbolDatabase::SpaceInfo *info = *i; - std::list::const_iterator it; + const SpaceInfo *info = *i; + std::list::const_iterator it; // skip classes with multiple inheritance if (info->derivedFrom.size() > 1) @@ -987,7 +987,7 @@ void CheckClass::operatorEqToSelf() for (it = info->functionList.begin(); it != info->functionList.end(); ++it) { - if (it->type == SymbolDatabase::Func::OperatorEqual && it->hasBody) + if (it->type == Func::OperatorEqual && it->hasBody) { // make sure return signature is correct if (Token::Match(it->tokenDef->tokAt(-4), ";|}|{|public:|protected:|private: %type% &") && @@ -1151,18 +1151,18 @@ void CheckClass::virtualDestructor() createSymbolDatabase(); - std::list::const_iterator i; + std::list::const_iterator i; for (i = symbolDatabase->spaceInfoList.begin(); i != symbolDatabase->spaceInfoList.end(); ++i) { - const SymbolDatabase::SpaceInfo *info = *i; + const SpaceInfo *info = *i; // Skip base classes and namespaces if (info->derivedFrom.empty()) continue; // Find the destructor - const SymbolDatabase::Func *destructor = info->getDestructor(); + const Func *destructor = info->getDestructor(); // Check for destructor with implementation if (!destructor || !destructor->hasBody) @@ -1179,15 +1179,15 @@ void CheckClass::virtualDestructor() for (unsigned int j = 0; j < info->derivedFrom.size(); ++j) { // Check if base class is public and exists in database - if (info->derivedFrom[j].access != SymbolDatabase::Private && info->derivedFrom[j].spaceInfo) + if (info->derivedFrom[j].access != Private && info->derivedFrom[j].spaceInfo) { - const SymbolDatabase::SpaceInfo *spaceInfo = info->derivedFrom[j].spaceInfo; + const SpaceInfo *spaceInfo = info->derivedFrom[j].spaceInfo; // Name of base class.. const std::string baseName = spaceInfo->className; // Find the destructor declaration for the base class. - const SymbolDatabase::Func *base_destructor = spaceInfo->getDestructor(); + const Func *base_destructor = spaceInfo->getDestructor(); const Token *base = 0; if (base_destructor) base = base_destructor->token; @@ -1211,7 +1211,7 @@ void CheckClass::virtualDestructor() // Make sure that the destructor is public (protected or private // would not compile if inheritance is used in a way that would // cause the bug we are trying to find here.) - if (base_destructor->access == SymbolDatabase::Public) + if (base_destructor->access == Public) virtualDestructorError(base, baseName, derivedClass->str()); } } @@ -1270,22 +1270,22 @@ void CheckClass::checkConst() createSymbolDatabase(); - std::list::const_iterator it; + std::list::const_iterator it; for (it = symbolDatabase->spaceInfoList.begin(); it != symbolDatabase->spaceInfoList.end(); ++it) { - const SymbolDatabase::SpaceInfo *info = *it; + const SpaceInfo *info = *it; // only check classes and structures if (!info->isClassOrStruct()) continue; - std::list::const_iterator func; + std::list::const_iterator func; for (func = info->functionList.begin(); func != info->functionList.end(); ++func) { // does the function have a body? - if (func->type == SymbolDatabase::Func::Function && func->hasBody && !func->isFriend && !func->isStatic && !func->isConst && !func->isVirtual) + if (func->type == Func::Function && func->hasBody && !func->isFriend && !func->isStatic && !func->isConst && !func->isVirtual) { // get last token of return type const Token *previous = func->tokenDef->isName() ? func->token->previous() : func->token->tokAt(-2); @@ -1353,8 +1353,8 @@ void CheckClass::checkConst() if (checkConstFunc(info, paramEnd)) { std::string classname = info->className; - const SymbolDatabase::SpaceInfo *nest = info->nestedIn; - while (nest && nest->type != SymbolDatabase::SpaceInfo::Global) + const SpaceInfo *nest = info->nestedIn; + while (nest && nest->type != SpaceInfo::Global) { classname = std::string(nest->className + "::" + classname); nest = nest->nestedIn; @@ -1378,7 +1378,7 @@ void CheckClass::checkConst() } } -bool CheckClass::isMemberVar(const SymbolDatabase::SpaceInfo *info, const Token *tok) +bool CheckClass::isMemberVar(const SpaceInfo *info, const Token *tok) { const Token *tok1 = tok; @@ -1400,7 +1400,7 @@ bool CheckClass::isMemberVar(const SymbolDatabase::SpaceInfo *info, const Token if (tok->str() == info->className && tok->next()->str() == "::") tok = tok->tokAt(2); - std::list::const_iterator var; + std::list::const_iterator var; for (var = info->varlist.begin(); var != info->varlist.end(); ++var) { if (var->token->str() == tok->str()) @@ -1416,7 +1416,7 @@ bool CheckClass::isMemberVar(const SymbolDatabase::SpaceInfo *info, const Token for (unsigned int i = 0; i < info->derivedFrom.size(); ++i) { // find the base class - const SymbolDatabase::SpaceInfo *spaceInfo = info->derivedFrom[i].spaceInfo; + const SpaceInfo *spaceInfo = info->derivedFrom[i].spaceInfo; // find the function in the base class if (spaceInfo) @@ -1430,9 +1430,9 @@ bool CheckClass::isMemberVar(const SymbolDatabase::SpaceInfo *info, const Token return false; } -bool CheckClass::isConstMemberFunc(const SymbolDatabase::SpaceInfo *info, const Token *tok) +bool CheckClass::isConstMemberFunc(const SpaceInfo *info, const Token *tok) { - std::list::const_iterator func; + std::list::const_iterator func; for (func = info->functionList.begin(); func != info->functionList.end(); ++func) { @@ -1447,7 +1447,7 @@ bool CheckClass::isConstMemberFunc(const SymbolDatabase::SpaceInfo *info, const for (unsigned int i = 0; i < info->derivedFrom.size(); ++i) { // find the base class - const SymbolDatabase::SpaceInfo *spaceInfo = info->derivedFrom[i].spaceInfo; + const SpaceInfo *spaceInfo = info->derivedFrom[i].spaceInfo; // find the function in the base class if (spaceInfo) @@ -1461,7 +1461,7 @@ bool CheckClass::isConstMemberFunc(const SymbolDatabase::SpaceInfo *info, const return false; } -bool CheckClass::checkConstFunc(const SymbolDatabase::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, // it can be a const function.. @@ -1558,7 +1558,7 @@ bool CheckClass::checkConstFunc(const SymbolDatabase::SpaceInfo *info, const Tok //--------------------------------------------------------------------------- // check if this function is defined virtual in the base classes -bool CheckClass::isVirtualFunc(const SymbolDatabase::SpaceInfo *info, const Token *functionToken) const +bool CheckClass::isVirtualFunc(const SpaceInfo *info, const Token *functionToken) const { // check each base class for (unsigned int i = 0; i < info->derivedFrom.size(); ++i) @@ -1566,9 +1566,9 @@ bool CheckClass::isVirtualFunc(const SymbolDatabase::SpaceInfo *info, const Toke // check if base class exists in database if (info->derivedFrom[i].spaceInfo) { - const SymbolDatabase::SpaceInfo *derivedFrom = info->derivedFrom[i].spaceInfo; + const SpaceInfo *derivedFrom = info->derivedFrom[i].spaceInfo; - std::list::const_iterator func; + std::list::const_iterator func; // check if function defined in base class for (func = derivedFrom->functionList.begin(); func != derivedFrom->functionList.end(); ++func) diff --git a/lib/checkclass.h b/lib/checkclass.h index 9a8717720..1d393acf0 100644 --- a/lib/checkclass.h +++ b/lib/checkclass.h @@ -163,18 +163,18 @@ private: } // operatorEqRetRefThis helper function - void checkReturnPtrThis(const SymbolDatabase::SpaceInfo *info, const SymbolDatabase::Func *func, const Token *tok, const Token *last); + void checkReturnPtrThis(const SpaceInfo *info, const Func *func, const Token *tok, const Token *last); // operatorEqToSelf helper functions bool hasDeallocation(const Token *first, const Token *last); bool hasAssignSelf(const Token *first, const Token *last, const Token *rhs); // checkConst helper functions - bool isMemberVar(const SymbolDatabase::SpaceInfo *info, const Token *tok); - bool isConstMemberFunc(const SymbolDatabase::SpaceInfo *info, const Token *tok); - bool checkConstFunc(const SymbolDatabase::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); /** @brief check if this function is virtual in the base classes */ - bool isVirtualFunc(const SymbolDatabase::SpaceInfo *info, const Token *functionToken) const; + bool isVirtualFunc(const SpaceInfo *info, const Token *functionToken) const; // constructors helper function /** @brief Information about a member variable. Used when checking for uninitialized variables */ @@ -189,7 +189,7 @@ private: bool init; }; - bool isBaseClassFunc(const Token *tok, const SymbolDatabase::SpaceInfo *info); + bool isBaseClassFunc(const Token *tok, const SpaceInfo *info); /** * @brief assign a variable in the varlist @@ -197,7 +197,7 @@ private: * @param info pointer to variable SpaceInfo * @param usage reference to usage vector */ - void assignVar(const std::string &varname, const SymbolDatabase::SpaceInfo *info, std::vector &usage); + void assignVar(const std::string &varname, const SpaceInfo *info, std::vector &usage); /** * @brief initialize a variable in the varlist @@ -205,7 +205,7 @@ private: * @param info pointer to variable SpaceInfo * @param usage reference to usage vector */ - void initVar(const std::string &varname, const SymbolDatabase::SpaceInfo *info, std::vector &usage); + void initVar(const std::string &varname, const SpaceInfo *info, std::vector &usage); /** * @brief set all variables in list assigned @@ -226,7 +226,7 @@ private: * @param info pointer to variable SpaceInfo * @param usage reference to usage vector */ - void initializeVarList(const SymbolDatabase::Func &func, std::list &callstack, const SymbolDatabase::SpaceInfo *info, std::vector &usage); + void initializeVarList(const Func &func, std::list &callstack, const SpaceInfo *info, std::vector &usage); }; /// @} //--------------------------------------------------------------------------- diff --git a/lib/checkmemoryleak.cpp b/lib/checkmemoryleak.cpp index 62d883e11..c60a74e6d 100644 --- a/lib/checkmemoryleak.cpp +++ b/lib/checkmemoryleak.cpp @@ -565,14 +565,14 @@ void CheckMemoryLeakInFunction::parse_noreturn() noreturn.insert("errx"); noreturn.insert("verrx"); - std::list::const_iterator i; + std::list::const_iterator i; for (i = symbolDatabase->spaceInfoList.begin(); i != symbolDatabase->spaceInfoList.end(); ++i) { - const SymbolDatabase::SpaceInfo *info = *i; + const SpaceInfo *info = *i; // only check functions - if (info->type != SymbolDatabase::SpaceInfo::Function) + if (info->type != SpaceInfo::Function) continue; // parse this function to check if it contains an "exit" call.. @@ -2491,14 +2491,14 @@ void CheckMemoryLeakInFunction::checkScope(const Token *Tok1, const std::string //--------------------------------------------------------------------------- void CheckMemoryLeakInFunction::checkReallocUsage() { - std::list::const_iterator i; + std::list::const_iterator i; for (i = symbolDatabase->spaceInfoList.begin(); i != symbolDatabase->spaceInfoList.end(); ++i) { - const SymbolDatabase::SpaceInfo *info = *i; + const SpaceInfo *info = *i; // only check functions - if (info->type != SymbolDatabase::SpaceInfo::Function) + if (info->type != SpaceInfo::Function) continue; // Record the varid's of the function parameters @@ -2644,14 +2644,14 @@ void CheckMemoryLeakInFunction::check() // fill the "noreturn" parse_noreturn(); - std::list::const_iterator i; + std::list::const_iterator i; for (i = symbolDatabase->spaceInfoList.begin(); i != symbolDatabase->spaceInfoList.end(); ++i) { - const SymbolDatabase::SpaceInfo *info = *i; + const SpaceInfo *info = *i; // only check functions - if (info->type != SymbolDatabase::SpaceInfo::Function) + if (info->type != SpaceInfo::Function) continue; const Token *tok = info->classStart; @@ -2701,16 +2701,16 @@ void CheckMemoryLeakInClass::check() { const SymbolDatabase *symbolDatabase = _tokenizer->getSymbolDatabase(); - std::list::const_iterator i; + std::list::const_iterator i; for (i = symbolDatabase->spaceInfoList.begin(); i != symbolDatabase->spaceInfoList.end(); ++i) { - const SymbolDatabase::SpaceInfo *info = *i; + const SpaceInfo *info = *i; // only check classes and structures - if (info->type == SymbolDatabase::SpaceInfo::Class) + if (info->type == SpaceInfo::Class) { - std::list::const_iterator var; + std::list::const_iterator var; for (var = info->varlist.begin(); var != info->varlist.end(); ++var) { if (!var->isStatic && var->token->previous()->str() == "*") @@ -2718,7 +2718,7 @@ void CheckMemoryLeakInClass::check() // allocation but no deallocation of private variables in public function.. if (var->token->tokAt(-2)->isStandardType()) { - if (var->access == SymbolDatabase::Private) + if (var->access == Private) checkPublicFunctions(info, var->token); variable(info, var->token); @@ -2730,7 +2730,7 @@ void CheckMemoryLeakInClass::check() // not derived and no constructor? if (var->type->derivedFrom.empty() && var->type->numConstructors == 0) { - if (var->access == SymbolDatabase::Private) + if (var->access == Private) checkPublicFunctions(info, var->token); variable(info, var->token); @@ -2743,7 +2743,7 @@ void CheckMemoryLeakInClass::check() } -void CheckMemoryLeakInClass::variable(const SymbolDatabase::SpaceInfo *classinfo, const Token *tokVarname) +void CheckMemoryLeakInClass::variable(const SpaceInfo *classinfo, const Token *tokVarname) { const std::string varname = tokVarname->strAt(0); const std::string classname = classinfo->className; @@ -2756,12 +2756,12 @@ void CheckMemoryLeakInClass::variable(const SymbolDatabase::SpaceInfo *classinfo bool deallocInDestructor = false; // Inspect member functions - std::list::const_iterator func; + std::list::const_iterator func; for (func = classinfo->functionList.begin(); func != classinfo->functionList.end(); ++func) { const Token *functionToken = func->token; - const bool constructor = func->type == SymbolDatabase::Func::Constructor; - const bool destructor = func->type == SymbolDatabase::Func::Destructor; + const bool constructor = func->type == Func::Constructor; + const bool destructor = func->type == Func::Destructor; unsigned int indent = 0; bool initlist = false; for (const Token *tok = functionToken; tok; tok = tok->next()) @@ -2879,7 +2879,7 @@ void CheckMemoryLeakInClass::variable(const SymbolDatabase::SpaceInfo *classinfo } -void CheckMemoryLeakInClass::checkPublicFunctions(const SymbolDatabase::SpaceInfo *spaceinfo, const Token *classtok) +void CheckMemoryLeakInClass::checkPublicFunctions(const SpaceInfo *spaceinfo, const Token *classtok) { // Check that public functions deallocate the pointers that they allocate. // There is no checking how these functions are used and therefore it @@ -2891,12 +2891,12 @@ void CheckMemoryLeakInClass::checkPublicFunctions(const SymbolDatabase::SpaceInf // Parse public functions.. // If they allocate member variables, they should also deallocate - std::list::const_iterator func; + std::list::const_iterator func; for (func = spaceinfo->functionList.begin(); func != spaceinfo->functionList.end(); ++func) { - if (func->type != SymbolDatabase::Func::Constructor && - func->access == SymbolDatabase::Public && func->hasBody) + if (func->type != Func::Constructor && + func->access == Public && func->hasBody) { const Token *tok2 = func->token; while (tok2->str() != "{") @@ -3166,14 +3166,14 @@ void CheckMemoryLeakNoVar::check() const SymbolDatabase *symbolDatabase = _tokenizer->getSymbolDatabase(); - std::list::const_iterator i; + std::list::const_iterator i; for (i = symbolDatabase->spaceInfoList.begin(); i != symbolDatabase->spaceInfoList.end(); ++i) { - SymbolDatabase::SpaceInfo *info = *i; + SpaceInfo *info = *i; // only check functions - if (info->type != SymbolDatabase::SpaceInfo::Function) + if (info->type != SpaceInfo::Function) continue; // goto the "}" that ends the executable scope.. diff --git a/lib/checkmemoryleak.h b/lib/checkmemoryleak.h index 961b0d258..3875d2f9d 100644 --- a/lib/checkmemoryleak.h +++ b/lib/checkmemoryleak.h @@ -387,10 +387,10 @@ public: void check(); private: - void variable(const SymbolDatabase::SpaceInfo *spaceinfo, const Token *tokVarname); + void variable(const SpaceInfo *spaceinfo, const Token *tokVarname); /** Public functions: possible double-allocation */ - void checkPublicFunctions(const SymbolDatabase::SpaceInfo *spaceinfo, const Token *classtok); + void checkPublicFunctions(const SpaceInfo *spaceinfo, const Token *classtok); void publicAllocationError(const Token *tok, const std::string &varname); void getErrorMessages(ErrorLogger * /*errorLogger*/, const Settings * /*settings*/) diff --git a/lib/checkother.cpp b/lib/checkother.cpp index ff3f83d23..14c4bc863 100644 --- a/lib/checkother.cpp +++ b/lib/checkother.cpp @@ -1240,14 +1240,14 @@ void CheckOther::functionVariableUsage() // Parse all executing scopes.. const SymbolDatabase *symbolDatabase = _tokenizer->getSymbolDatabase(); - std::list::const_iterator i; + std::list::const_iterator i; for (i = symbolDatabase->spaceInfoList.begin(); i != symbolDatabase->spaceInfoList.end(); ++i) { - const SymbolDatabase::SpaceInfo *info = *i; + const SpaceInfo *info = *i; // only check functions - if (info->type != SymbolDatabase::SpaceInfo::Function) + if (info->type != SpaceInfo::Function) continue; // First token for the current scope.. @@ -1694,7 +1694,7 @@ void CheckOther::functionVariableUsage() if (!start->tokAt(3)->isStandardType()) { // lookup the type - const SymbolDatabase::SpaceInfo *type = symbolDatabase->findVarType(info, start->tokAt(3)); + const SpaceInfo *type = symbolDatabase->findVarType(info, start->tokAt(3)); // unknown type? if (!type) @@ -1702,7 +1702,7 @@ void CheckOther::functionVariableUsage() // has default constructor or // has members with unknown type or default constructor - else if (type->needInitialization == SymbolDatabase::SpaceInfo::False) + else if (type->needInitialization == SpaceInfo::False) allocate = false; } } @@ -1908,14 +1908,14 @@ void CheckOther::checkVariableScope() const SymbolDatabase *symbolDatabase = _tokenizer->getSymbolDatabase(); - std::list::const_iterator i; + std::list::const_iterator i; for (i = symbolDatabase->spaceInfoList.begin(); i != symbolDatabase->spaceInfoList.end(); ++i) { - const SymbolDatabase::SpaceInfo *info = *i; + const SpaceInfo *info = *i; // only check functions - if (info->type != SymbolDatabase::SpaceInfo::Function) + if (info->type != SpaceInfo::Function) continue; // Walk through all tokens.. @@ -2536,14 +2536,14 @@ void CheckOther::checkMisusedScopedObject() const SymbolDatabase * const symbolDatabase = _tokenizer->getSymbolDatabase(); - std::list::const_iterator i; + std::list::const_iterator i; for (i = symbolDatabase->spaceInfoList.begin(); i != symbolDatabase->spaceInfoList.end(); ++i) { - const SymbolDatabase::SpaceInfo *info = *i; + const SpaceInfo *info = *i; // only check functions - if (info->type != SymbolDatabase::SpaceInfo::Function) + if (info->type != SpaceInfo::Function) continue; unsigned int depth = 0; diff --git a/lib/symboldatabase.cpp b/lib/symboldatabase.cpp index 31bf15a2a..ec0539322 100644 --- a/lib/symboldatabase.cpp +++ b/lib/symboldatabase.cpp @@ -249,7 +249,7 @@ SymbolDatabase::SymbolDatabase(const Tokenizer *tokenizer, const Settings *setti // friend class declaration? else if (Token::Match(tok, "friend class| %any% ;")) { - FriendInfo friendInfo; + SpaceInfo::FriendInfo friendInfo; friendInfo.name = tok->strAt(1) == "class" ? tok->strAt(2) : tok->strAt(1); /** @todo fill this in later after parsing is complete */ @@ -411,11 +411,11 @@ SymbolDatabase::SymbolDatabase(const Tokenizer *tokenizer, const Settings *setti // check for default constructor bool hasDefaultConstructor = false; - std::list::const_iterator func; + std::list::const_iterator func; for (func = info->functionList.begin(); func != info->functionList.end(); ++func) { - if (func->type == SymbolDatabase::Func::Constructor) + if (func->type == Func::Constructor) { // check for no arguments: func ( ) if (func->argDef->next() == func->argDef->link()) @@ -745,7 +745,7 @@ void SymbolDatabase::addFunction(SpaceInfo **info, const Token **tok, const Toke func->arg = argStart; } } - else if (func->type == SymbolDatabase::Func::Destructor && + else if (func->type == Func::Destructor && (*tok)->previous()->str() == "~" && func->tokenDef->str() == (*tok)->str()) { @@ -803,7 +803,7 @@ void SymbolDatabase::addFunction(SpaceInfo **info, const Token **tok, const Toke addNewFunction(info, tok); } -void SymbolDatabase::addNewFunction(SymbolDatabase::SpaceInfo **info, const Token **tok) +void SymbolDatabase::addNewFunction(SpaceInfo **info, const Token **tok) { const Token *tok1 = *tok; SpaceInfo *new_info = new SpaceInfo(this, tok1, *info); @@ -853,7 +853,7 @@ const Token *SymbolDatabase::initBaseInfo(SpaceInfo *info, const Token *tok) // check for base classes else if (level == 0 && Token::Match(tok2, ":|,")) { - BaseInfo base; + SpaceInfo::BaseInfo base; tok2 = tok2->next(); @@ -924,7 +924,7 @@ const Token *SymbolDatabase::initBaseInfo(SpaceInfo *info, const Token *tok) //--------------------------------------------------------------------------- -unsigned int SymbolDatabase::Func::argCount() const +unsigned int Func::argCount() const { unsigned int count = 0; @@ -942,7 +942,7 @@ unsigned int SymbolDatabase::Func::argCount() const return count; } -unsigned int SymbolDatabase::Func::initializedArgCount() const +unsigned int Func::initializedArgCount() const { unsigned int count = 0; @@ -960,7 +960,7 @@ unsigned int SymbolDatabase::Func::initializedArgCount() const //--------------------------------------------------------------------------- -SymbolDatabase::SpaceInfo::SpaceInfo(SymbolDatabase *check_, const Token *classDef_, SymbolDatabase::SpaceInfo *nestedIn_) : +SpaceInfo::SpaceInfo(SymbolDatabase *check_, const Token *classDef_, SpaceInfo *nestedIn_) : check(check_), classDef(classDef_), classStart(NULL), @@ -1011,7 +1011,7 @@ SymbolDatabase::SpaceInfo::SpaceInfo(SymbolDatabase *check_, const Token *classD } bool -SymbolDatabase::SpaceInfo::hasDefaultConstructor() const +SpaceInfo::hasDefaultConstructor() const { if (numConstructors) { @@ -1028,7 +1028,7 @@ SymbolDatabase::SpaceInfo::hasDefaultConstructor() const } // Get variable list.. -void SymbolDatabase::SpaceInfo::getVarList() +void SpaceInfo::getVarList() { AccessControl varaccess = type == Class ? Private : Public; const Token *start; @@ -1230,7 +1230,7 @@ const Token* skipPointers(const Token* tok) return ret; } -bool SymbolDatabase::SpaceInfo::isVariableDeclaration(const Token* tok, const Token*& vartok, const Token*& typetok) const +bool SpaceInfo::isVariableDeclaration(const Token* tok, const Token*& vartok, const Token*& typetok) const { const Token* localTypeTok = skipScopeIdentifiers(tok); @@ -1271,17 +1271,17 @@ bool SymbolDatabase::SpaceInfo::isVariableDeclaration(const Token* tok, const To return NULL != vartok; } -bool SymbolDatabase::SpaceInfo::isSimpleVariable(const Token* tok) const +bool SpaceInfo::isSimpleVariable(const Token* tok) const { return Token::Match(tok, "%var% ;"); } -bool SymbolDatabase::SpaceInfo::isArrayVariable(const Token* tok) const +bool SpaceInfo::isArrayVariable(const Token* tok) const { return Token::Match(tok, "%var% [") && tok->next()->str() != "operator"; } -bool SymbolDatabase::SpaceInfo::findClosingBracket(const Token* tok, const Token*& close) const +bool SpaceInfo::findClosingBracket(const Token* tok, const Token*& close) const { bool found = false; if (NULL != tok && tok->str() == "<") @@ -1310,7 +1310,7 @@ bool SymbolDatabase::SpaceInfo::findClosingBracket(const Token* tok, const Token //--------------------------------------------------------------------------- -const SymbolDatabase::SpaceInfo *SymbolDatabase::findVarType(const SpaceInfo *start, const Token *type) const +const SpaceInfo *SymbolDatabase::findVarType(const SpaceInfo *start, const Token *type) const { std::list::const_iterator it; @@ -1352,7 +1352,7 @@ const SymbolDatabase::SpaceInfo *SymbolDatabase::findVarType(const SpaceInfo *st //--------------------------------------------------------------------------- -SymbolDatabase::SpaceInfo * SymbolDatabase::SpaceInfo::findInNestedList(const std::string & name) +SpaceInfo * SpaceInfo::findInNestedList(const std::string & name) { std::list::iterator it; @@ -1366,7 +1366,7 @@ SymbolDatabase::SpaceInfo * SymbolDatabase::SpaceInfo::findInNestedList(const st //--------------------------------------------------------------------------- -const SymbolDatabase::Func *SymbolDatabase::SpaceInfo::getDestructor() const +const Func *SpaceInfo::getDestructor() const { std::list::const_iterator it; for (it = functionList.begin(); it != functionList.end(); ++it) @@ -1379,7 +1379,7 @@ const SymbolDatabase::Func *SymbolDatabase::SpaceInfo::getDestructor() const //--------------------------------------------------------------------------- -unsigned int SymbolDatabase::SpaceInfo::getNestedNonFunctions() const +unsigned int SpaceInfo::getNestedNonFunctions() const { unsigned int nested = 0; std::list::const_iterator ni; diff --git a/lib/symboldatabase.h b/lib/symboldatabase.h index cbfca5b86..f143dc159 100644 --- a/lib/symboldatabase.h +++ b/lib/symboldatabase.h @@ -31,106 +31,104 @@ class Tokenizer; class Settings; class ErrorLogger; -class SymbolDatabase +class SpaceInfo; +class SymbolDatabase; + +/** + * @brief Access control. + */ +enum AccessControl { Public, Protected, Private }; + +/** @brief Information about a member variable. */ +class Var { public: - /** - * @brief Access control. - */ - enum AccessControl { Public, Protected, Private }; - - SymbolDatabase(const Tokenizer *tokenizer, const Settings *settings, ErrorLogger *errorLogger); - ~SymbolDatabase(); - - class SpaceInfo; - - /** @brief Information about a member variable. */ - class Var + Var(const Token *token_, std::size_t index_, AccessControl access_, bool mutable_, bool static_, bool const_, bool class_, const SpaceInfo *type_) + : token(token_), + index(index_), + access(access_), + isMutable(mutable_), + isStatic(static_), + isConst(const_), + isClass(class_), + type(type_) { - public: - Var(const Token *token_, std::size_t index_, AccessControl access_, bool mutable_, bool static_, bool const_, bool class_, const SpaceInfo *type_) - : token(token_), - index(index_), - access(access_), - isMutable(mutable_), - isStatic(static_), - isConst(const_), - isClass(class_), - type(type_) - { - } + } - /** @brief variable token */ - const Token *token; + /** @brief variable token */ + const Token *token; - /** @brief order declared */ - std::size_t index; + /** @brief order declared */ + std::size_t index; - /** @brief what section is this variable declared in? */ - AccessControl access; // public/protected/private + /** @brief what section is this variable declared in? */ + AccessControl access; // public/protected/private - /** @brief is this variable mutable? */ - bool isMutable; + /** @brief is this variable mutable? */ + bool isMutable; - /** @brief is this variable static? */ - bool isStatic; + /** @brief is this variable static? */ + bool isStatic; - /** @brief is this variable const? */ - bool isConst; + /** @brief is this variable const? */ + bool isConst; - /** @brief is this variable a class (or unknown type)? */ - bool isClass; + /** @brief is this variable a class (or unknown type)? */ + bool isClass; - /** @brief pointer to user defined type info (for known types) */ - const SpaceInfo *type; - }; + /** @brief pointer to user defined type info (for known types) */ + const SpaceInfo *type; +}; - class Func +class Func +{ +public: + enum Type { Constructor, CopyConstructor, OperatorEqual, Destructor, Function }; + + Func() + : tokenDef(NULL), + argDef(NULL), + token(NULL), + arg(NULL), + access(Public), + hasBody(false), + isInline(false), + isConst(false), + isVirtual(false), + isPure(false), + isStatic(false), + isFriend(false), + isExplicit(false), + isOperator(false), + retFuncPtr(false), + type(Function) { - public: - enum Type { Constructor, CopyConstructor, OperatorEqual, Destructor, Function }; + } - Func() - : tokenDef(NULL), - argDef(NULL), - token(NULL), - arg(NULL), - access(Public), - hasBody(false), - isInline(false), - isConst(false), - isVirtual(false), - isPure(false), - isStatic(false), - isFriend(false), - isExplicit(false), - isOperator(false), - retFuncPtr(false), - type(Function) - { - } + unsigned int argCount() const; + unsigned int initializedArgCount() const; - unsigned int argCount() const; - unsigned int initializedArgCount() const; - - const Token *tokenDef; // function name token in class definition - const Token *argDef; // function argument start '(' in class definition - const Token *token; // function name token in implementation - const Token *arg; // function argument start '(' - AccessControl access; // public/protected/private - bool hasBody; // has implementation - bool isInline; // implementation in class definition - bool isConst; // is const - bool isVirtual; // is virtual - bool isPure; // is pure virtual - bool isStatic; // is static - bool isFriend; // is friend - bool isExplicit; // is explicit - bool isOperator; // is operator - bool retFuncPtr; // returns function pointer - Type type; // constructor, destructor, ... - }; + const Token *tokenDef; // function name token in class definition + const Token *argDef; // function argument start '(' in class definition + const Token *token; // function name token in implementation + const Token *arg; // function argument start '(' + AccessControl access; // public/protected/private + bool hasBody; // has implementation + bool isInline; // implementation in class definition + bool isConst; // is const + bool isVirtual; // is virtual + bool isPure; // is pure virtual + bool isStatic; // is static + bool isFriend; // is friend + bool isExplicit; // is explicit + bool isOperator; // is operator + bool retFuncPtr; // returns function pointer + Type type; // constructor, destructor, ... +}; +class SpaceInfo +{ +public: struct BaseInfo { AccessControl access; // public/protected/private @@ -144,75 +142,78 @@ public: SpaceInfo *spaceInfo; }; - class SpaceInfo + enum SpaceType { Global, Class, Struct, Union, Namespace, Function }; + enum NeedInitialization { Unknown, True, False }; + + SpaceInfo(SymbolDatabase *check_, const Token *classDef_, SpaceInfo *nestedIn_); + + SymbolDatabase *check; + SpaceType type; + std::string className; + const Token *classDef; // class/struct/union/namespace token + const Token *classStart; // '{' token + const Token *classEnd; // '}' token + std::list functionList; + std::list varlist; + std::vector derivedFrom; + std::list friendList; + SpaceInfo *nestedIn; + std::list nestedList; + AccessControl access; + unsigned int numConstructors; + NeedInitialization needInitialization; + SpaceInfo * functionOf; // class/struct this function belongs to + + bool isClassOrStruct() const { - public: - enum SpaceType { Global, Class, Struct, Union, Namespace, Function }; - enum NeedInitialization { Unknown, True, False }; + return (type == Class || type == Struct); + } - SpaceInfo(SymbolDatabase *check_, const Token *classDef_, SpaceInfo *nestedIn_); + /** + * @brief find if name is in nested list + * @param name name of nested space + */ + SpaceInfo * findInNestedList(const std::string & name); - SymbolDatabase *check; - SpaceType type; - std::string className; - const Token *classDef; // class/struct/union/namespace token - const Token *classStart; // '{' token - const Token *classEnd; // '}' token - std::list functionList; - std::list varlist; - std::vector derivedFrom; - std::list friendList; - SpaceInfo *nestedIn; - std::list nestedList; - AccessControl access; - unsigned int numConstructors; - NeedInitialization needInitialization; - SpaceInfo * functionOf; // class/struct this function belongs to + void addVar(const Token *token_, AccessControl access_, bool mutable_, bool static_, bool const_, bool class_, const SpaceInfo *type_) + { + varlist.push_back(Var(token_, varlist.size(), access_, mutable_, static_, const_, class_, type_)); + } - bool isClassOrStruct() const - { - return (type == Class || type == Struct); - } + /** @brief initialize varlist */ + void getVarList(); - /** - * @brief find if name is in nested list - * @param name name of nested space - */ - SpaceInfo * findInNestedList(const std::string & name); + const Func *getDestructor() const; - void addVar(const Token *token_, AccessControl access_, bool mutable_, bool static_, bool const_, bool class_, const SpaceInfo *type_) - { - varlist.push_back(Var(token_, varlist.size(), access_, mutable_, static_, const_, class_, type_)); - } + /** + * @brief get the number of nested spaces that are not functions + * + * This returns the number of user defined types (class, struct, union) + * that are defined in this user defined type or namespace. + */ + unsigned int getNestedNonFunctions() const; - /** @brief initialize varlist */ - void getVarList(); + bool hasDefaultConstructor() const; - const Func *getDestructor() const; +private: + /** + * @brief helper function for getVarList() + * @param tok pointer to token to check + * @param vartok populated with pointer to the variable token, if found + * @param typetok populated with pointer to the type token, if found + * @return true if tok points to a variable declaration, false otherwise + */ + bool isVariableDeclaration(const Token* tok, const Token*& vartok, const Token*& typetok) const; + bool isSimpleVariable(const Token* tok) const; + bool isArrayVariable(const Token* tok) const; + bool findClosingBracket(const Token* tok, const Token*& close) const; +}; - /** - * @brief get the number of nested spaces that are not functions - * - * This returns the number of user defined types (class, struct, union) - * that are defined in this user defined type or namespace. - */ - unsigned int getNestedNonFunctions() const; - - bool hasDefaultConstructor() const; - - private: - /** - * @brief helper function for getVarList() - * @param tok pointer to token to check - * @param vartok populated with pointer to the variable token, if found - * @param typetok populated with pointer to the type token, if found - * @return true if tok points to a variable declaration, false otherwise - */ - bool isVariableDeclaration(const Token* tok, const Token*& vartok, const Token*& typetok) const; - bool isSimpleVariable(const Token* tok) const; - bool isArrayVariable(const Token* tok) const; - bool findClosingBracket(const Token* tok, const Token*& close) const; - }; +class SymbolDatabase +{ +public: + SymbolDatabase(const Tokenizer *tokenizer, const Settings *settings, ErrorLogger *errorLogger); + ~SymbolDatabase(); /** @brief Information about all namespaces/classes/structrues */ std::list spaceInfoList; diff --git a/lib/tokenize.cpp b/lib/tokenize.cpp index 6e7441daa..1eee6c69f 100644 --- a/lib/tokenize.cpp +++ b/lib/tokenize.cpp @@ -735,7 +735,7 @@ Token * Tokenizer::deleteInvalidTypedef(Token *typeDef) return tok; } -struct SpaceInfo +struct Space { bool isNamespace; std::string className; @@ -816,7 +816,7 @@ static Token *splitDefinitionFromTypedef(Token *tok) void Tokenizer::simplifyTypedef() { - std::vector spaceInfo; + std::vector spaceInfo; bool isNamespace = false; std::string className; bool hasClass = false; @@ -839,7 +839,7 @@ void Tokenizer::simplifyTypedef() } else if (hasClass && tok->str() == "{") { - SpaceInfo info; + Space info; info.isNamespace = isNamespace; info.className = className; info.classEnd = tok->link(); @@ -7954,13 +7954,13 @@ const Token *Tokenizer::getFunctionTokenByName(const char funcname[]) const if (_symbolDatabase == NULL) getSymbolDatabase(); - std::list::const_iterator i; + std::list::const_iterator i; for (i = _symbolDatabase->spaceInfoList.begin(); i != _symbolDatabase->spaceInfoList.end(); ++i) { - const SymbolDatabase::SpaceInfo *info = *i; + const SpaceInfo *info = *i; - if (info->type == SymbolDatabase::SpaceInfo::Function) + if (info->type == SpaceInfo::Function) { if (info->classDef->str() == funcname) return info->classDef; diff --git a/test/testsymboldatabase.cpp b/test/testsymboldatabase.cpp index 98e80671e..68b565276 100644 --- a/test/testsymboldatabase.cpp +++ b/test/testsymboldatabase.cpp @@ -32,7 +32,7 @@ public: {} private: - const SymbolDatabase::SpaceInfo si; + const SpaceInfo si; const Token* vartok; const Token* typetok; const Token* t; From 959e10cee5921cfa9f49faf0c2693ae9fe782f60 Mon Sep 17 00:00:00 2001 From: Robert Reif Date: Mon, 17 Jan 2011 18:29:19 +0100 Subject: [PATCH 072/165] Symbol database: renamed classes. ticket: #2468 --- lib/checkclass.cpp | 284 ++++++++++++++++++------------------ lib/checkclass.h | 24 +-- lib/checkmemoryleak.cpp | 86 +++++------ lib/checkmemoryleak.h | 4 +- lib/checkother.cpp | 76 +++++----- lib/symboldatabase.cpp | 168 ++++++++++----------- lib/symboldatabase.h | 67 +++++---- lib/tokenize.cpp | 10 +- test/testsymboldatabase.cpp | 3 +- 9 files changed, 362 insertions(+), 360 deletions(-) diff --git a/lib/checkclass.cpp b/lib/checkclass.cpp index 5958d09c4..56b0eaa5a 100644 --- a/lib/checkclass.cpp +++ b/lib/checkclass.cpp @@ -68,51 +68,51 @@ void CheckClass::constructors() createSymbolDatabase(); - std::list::const_iterator i; + std::list::const_iterator i; for (i = symbolDatabase->spaceInfoList.begin(); i != symbolDatabase->spaceInfoList.end(); ++i) { - const SpaceInfo *info = *i; + const Scope *scope = *i; // only check classes and structures - if (!info->isClassOrStruct()) + if (!scope->isClassOrStruct()) continue; // There are no constructors. - if (info->numConstructors == 0) + if (scope->numConstructors == 0) { // If there is a private variable, there should be a constructor.. - std::list::const_iterator var; - for (var = info->varlist.begin(); var != info->varlist.end(); ++var) + std::list::const_iterator var; + for (var = scope->varlist.begin(); var != scope->varlist.end(); ++var) { if (var->access == Private && !var->isClass && !var->isStatic) { - noConstructorError(info->classDef, info->className, info->classDef->str() == "struct"); + noConstructorError(scope->classDef, scope->className, scope->classDef->str() == "struct"); break; } } } - std::list::const_iterator func; - std::vector usage(info->varlist.size()); + std::list::const_iterator func; + std::vector usage(scope->varlist.size()); - for (func = info->functionList.begin(); func != info->functionList.end(); ++func) + for (func = scope->functionList.begin(); func != scope->functionList.end(); ++func) { - if (!func->hasBody || !(func->type == Func::Constructor || - func->type == Func::CopyConstructor || - func->type == Func::OperatorEqual)) + if (!func->hasBody || !(func->type == Function::eConstructor || + func->type == Function::eCopyConstructor || + func->type == Function::eOperatorEqual)) continue; // Mark all variables not used clearAllVar(usage); std::list callstack; - initializeVarList(*func, callstack, info, usage); + initializeVarList(*func, callstack, scope, usage); // Check if any variables are uninitialized - std::list::const_iterator var; + std::list::const_iterator var; unsigned int count = 0; - for (var = info->varlist.begin(); var != info->varlist.end(); ++var, ++count) + for (var = scope->varlist.begin(); var != scope->varlist.end(); ++var, ++count) { if (usage[count].assign || usage[count].init || var->isStatic) continue; @@ -121,7 +121,7 @@ void CheckClass::constructors() continue; // Check if this is a class constructor - if (var->isClass && func->type == Func::Constructor) + if (var->isClass && func->type == Function::eConstructor) { // Unknown type so assume it is initialized if (!var->type) @@ -129,12 +129,12 @@ void CheckClass::constructors() // Known type that doesn't need initialization or // known type that has member variables of an unknown type - else if (var->type->needInitialization != SpaceInfo::True) + else if (var->type->needInitialization != Scope::True) continue; } // It's non-static and it's not initialized => error - if (func->type == Func::OperatorEqual) + if (func->type == Function::eOperatorEqual) { const Token *operStart = 0; if (func->token->str() == "=") @@ -145,7 +145,7 @@ void CheckClass::constructors() bool classNameUsed = false; for (const Token *operTok = operStart; operTok != operStart->link(); operTok = operTok->next()) { - if (operTok->str() == info->className) + if (operTok->str() == scope->className) { classNameUsed = true; break; @@ -153,21 +153,21 @@ void CheckClass::constructors() } if (classNameUsed) - operatorEqVarError(func->token, info->className, var->token->str()); + operatorEqVarError(func->token, scope->className, var->token->str()); } else if (func->access != Private) - uninitVarError(func->token, info->className, var->token->str()); + uninitVarError(func->token, scope->className, var->token->str()); } } } } -void CheckClass::assignVar(const std::string &varname, const SpaceInfo *info, std::vector &usage) +void CheckClass::assignVar(const std::string &varname, const Scope *scope, std::vector &usage) { - std::list::const_iterator var; + std::list::const_iterator var; unsigned int count = 0; - for (var = info->varlist.begin(); var != info->varlist.end(); ++var, ++count) + for (var = scope->varlist.begin(); var != scope->varlist.end(); ++var, ++count) { if (var->token->str() == varname) { @@ -177,12 +177,12 @@ void CheckClass::assignVar(const std::string &varname, const SpaceInfo *info, st } } -void CheckClass::initVar(const std::string &varname, const SpaceInfo *info, std::vector &usage) +void CheckClass::initVar(const std::string &varname, const Scope *scope, std::vector &usage) { - std::list::const_iterator var; + std::list::const_iterator var; unsigned int count = 0; - for (var = info->varlist.begin(); var != info->varlist.end(); ++var, ++count) + for (var = scope->varlist.begin(); var != scope->varlist.end(); ++var, ++count) { if (var->token->str() == varname) { @@ -207,17 +207,17 @@ void CheckClass::clearAllVar(std::vector &usage) } } -bool CheckClass::isBaseClassFunc(const Token *tok, const SpaceInfo *info) +bool CheckClass::isBaseClassFunc(const Token *tok, const Scope *scope) { // Iterate through each base class... - for (size_t i = 0; i < info->derivedFrom.size(); ++i) + for (size_t i = 0; i < scope->derivedFrom.size(); ++i) { - const SpaceInfo *derivedFrom = info->derivedFrom[i].spaceInfo; + const Scope *derivedFrom = scope->derivedFrom[i].spaceInfo; // Check if base class exists in database if (derivedFrom) { - std::list::const_iterator func; + std::list::const_iterator func; for (func = derivedFrom->functionList.begin(); func != derivedFrom->functionList.end(); ++func) { @@ -234,7 +234,7 @@ bool CheckClass::isBaseClassFunc(const Token *tok, const SpaceInfo *info) return false; } -void CheckClass::initializeVarList(const Func &func, std::list &callstack, const SpaceInfo *info, std::vector &usage) +void CheckClass::initializeVarList(const Function &func, std::list &callstack, const Scope *scope, std::vector &usage) { bool Assign = false; unsigned int indentlevel = 0; @@ -251,12 +251,12 @@ void CheckClass::initializeVarList(const Func &func, std::list &cal { if (Assign && Token::Match(ftok, "%var% (")) { - initVar(ftok->str(), info, usage); + initVar(ftok->str(), scope, usage); // assignment in the initializer.. // : var(value = x) if (Token::Match(ftok->tokAt(2), "%var% =")) - assignVar(ftok->strAt(2), info, usage); + assignVar(ftok->strAt(2), scope, usage); } Assign |= (ftok->str() == ":"); @@ -282,7 +282,7 @@ void CheckClass::initializeVarList(const Func &func, std::list &cal // Variable getting value from stream? if (Token::Match(ftok, ">> %var%")) { - assignVar(ftok->strAt(1), info, usage); + assignVar(ftok->strAt(1), scope, usage); } // Before a new statement there is "[{};)=]" @@ -302,13 +302,13 @@ void CheckClass::initializeVarList(const Func &func, std::list &cal // Calling member variable function? if (Token::Match(ftok->next(), "%var% . %var% (")) { - std::list::const_iterator var; - for (var = info->varlist.begin(); var != info->varlist.end(); ++var) + std::list::const_iterator var; + for (var = scope->varlist.begin(); var != scope->varlist.end(); ++var) { if (var->token->varId() == ftok->next()->varId()) { /** @todo false negative: we assume function changes variable state */ - assignVar(ftok->next()->str(), info, usage); + assignVar(ftok->next()->str(), scope, usage); continue; } } @@ -349,7 +349,7 @@ void CheckClass::initializeVarList(const Func &func, std::list &cal // Clearing array.. else if (Token::Match(ftok, "memset ( %var% ,")) { - assignVar(ftok->strAt(2), info, usage); + assignVar(ftok->strAt(2), scope, usage); ftok = ftok->next()->link(); continue; } @@ -359,22 +359,22 @@ void CheckClass::initializeVarList(const Func &func, std::list &cal ftok->previous()->str() != "::") { // check if member function exists - std::list::const_iterator it; - for (it = info->functionList.begin(); it != info->functionList.end(); ++it) + std::list::const_iterator it; + for (it = scope->functionList.begin(); it != scope->functionList.end(); ++it) { - if (ftok->next()->str() == it->tokenDef->str() && it->type != Func::Constructor) + if (ftok->next()->str() == it->tokenDef->str() && it->type != Function::eConstructor) break; } // member function found - if (it != info->functionList.end()) + if (it != scope->functionList.end()) { // member function has implementation if (it->hasBody) { // initialize variable use list using member function callstack.push_back(ftok->str()); - initializeVarList(*it, callstack, info, usage); + initializeVarList(*it, callstack, scope, usage); callstack.pop_back(); } @@ -412,22 +412,22 @@ void CheckClass::initializeVarList(const Func &func, std::list &cal } // check if member function - std::list::const_iterator it; - for (it = info->functionList.begin(); it != info->functionList.end(); ++it) + std::list::const_iterator it; + for (it = scope->functionList.begin(); it != scope->functionList.end(); ++it) { - if (ftok->str() == it->tokenDef->str() && it->type != Func::Constructor) + if (ftok->str() == it->tokenDef->str() && it->type != Function::eConstructor) break; } // member function found - if (it != info->functionList.end()) + if (it != scope->functionList.end()) { // member function has implementation if (it->hasBody) { // initialize variable use list using member function callstack.push_back(ftok->str()); - initializeVarList(*it, callstack, info, usage); + initializeVarList(*it, callstack, scope, usage); callstack.pop_back(); } @@ -442,7 +442,7 @@ void CheckClass::initializeVarList(const Func &func, std::list &cal else { // could be a base class virtual function, so we assume it initializes everything - if (func.type != Func::Constructor && isBaseClassFunc(ftok, info)) + if (func.type != Function::eConstructor && isBaseClassFunc(ftok, scope)) { /** @todo False Negative: we should look at the base class functions to see if they * call any derived class virtual functions that change the derived class state @@ -451,7 +451,7 @@ void CheckClass::initializeVarList(const Func &func, std::list &cal } // has friends, so we assume it initializes everything - if (!info->friendList.empty()) + if (!scope->friendList.empty()) assignAllVar(usage); // the function is external and it's neither friend nor inherited virtual function. @@ -471,7 +471,7 @@ void CheckClass::initializeVarList(const Func &func, std::list &cal } if (tok->isName()) { - assignVar(tok->str(), info, usage); + assignVar(tok->str(), scope, usage); } } } @@ -481,44 +481,44 @@ void CheckClass::initializeVarList(const Func &func, std::list &cal // Assignment of member variable? else if (Token::Match(ftok, "%var% =")) { - assignVar(ftok->str(), info, usage); + assignVar(ftok->str(), scope, usage); } // Assignment of array item of member variable? else if (Token::Match(ftok, "%var% [ %any% ] =")) { - assignVar(ftok->str(), info, usage); + assignVar(ftok->str(), scope, usage); } // Assignment of member of array item of member variable? else if (Token::Match(ftok, "%var% [ %any% ] . %var% =") || Token::Match(ftok, "%var% [ %any% ] . %var% . %var% =")) { - assignVar(ftok->str(), info, usage); + assignVar(ftok->str(), scope, usage); } // Assignment of array item of member variable? else if (Token::Match(ftok, "%var% [ %any% ] [ %any% ] =")) { - assignVar(ftok->str(), info, usage); + assignVar(ftok->str(), scope, usage); } // Assignment of array item of member variable? else if (Token::Match(ftok, "* %var% =")) { - assignVar(ftok->next()->str(), info, usage); + assignVar(ftok->next()->str(), scope, usage); } // Assignment of struct member of member variable? else if (Token::Match(ftok, "%var% . %any% =")) { - assignVar(ftok->str(), info, usage); + assignVar(ftok->str(), scope, usage); } // The functions 'clear' and 'Clear' are supposed to initialize variable. if (Token::Match(ftok, "%var% . clear|Clear (")) { - assignVar(ftok->str(), info, usage); + assignVar(ftok->str(), scope, usage); } } } @@ -569,32 +569,32 @@ void CheckClass::privateFunctions() createSymbolDatabase(); - std::list::const_iterator i; + std::list::const_iterator i; for (i = symbolDatabase->spaceInfoList.begin(); i != symbolDatabase->spaceInfoList.end(); ++i) { - const SpaceInfo *info = *i; + const Scope *scope = *i; // only check classes and structures - if (!info->isClassOrStruct()) + if (!scope->isClassOrStruct()) continue; // don’t check derived classes - if (!info->derivedFrom.empty()) + if (!scope->derivedFrom.empty()) continue; // Locate some class - const Token *tok1 = info->classDef; + const Token *tok1 = scope->classDef; // check that the whole class implementation is seen bool whole = true; - std::list::const_iterator func; - for (func = info->functionList.begin(); func != info->functionList.end(); ++func) + std::list::const_iterator func; + for (func = scope->functionList.begin(); func != scope->functionList.end(); ++func) { if (!func->hasBody) { // empty private copy constructors and assignment operators are OK - if ((func->type == Func::CopyConstructor || func->type == Func::OperatorEqual) && func->access == Private) + if ((func->type == Function::eCopyConstructor || func->type == Function::eOperatorEqual) && func->access == Private) continue; whole = false; @@ -609,12 +609,12 @@ void CheckClass::privateFunctions() std::list FuncList; /** @todo embedded class have access to private functions */ - if (!info->getNestedNonFunctions()) + if (!scope->getNestedNonFunctions()) { - for (func = info->functionList.begin(); func != info->functionList.end(); ++func) + for (func = scope->functionList.begin(); func != scope->functionList.end(); ++func) { // Get private functions.. - if (func->type == Func::Function && + if (func->type == Function::eFunction && func->access == Private && func->hasBody) FuncList.push_back(func->tokenDef); } @@ -834,15 +834,15 @@ void CheckClass::operatorEq() createSymbolDatabase(); - std::list::const_iterator i; + std::list::const_iterator i; for (i = symbolDatabase->spaceInfoList.begin(); i != symbolDatabase->spaceInfoList.end(); ++i) { - std::list::const_iterator it; + std::list::const_iterator it; for (it = (*i)->functionList.begin(); it != (*i)->functionList.end(); ++it) { - if (it->type == Func::OperatorEqual && it->access != Private) + if (it->type == Function::eOperatorEqual && it->access != Private) { if (it->token->strAt(-2) == "void") operatorEqReturnError(it->token->tokAt(-2)); @@ -861,7 +861,7 @@ void CheckClass::operatorEqReturnError(const Token *tok) // operator= should return a reference to *this //--------------------------------------------------------------------------- -void CheckClass::checkReturnPtrThis(const SpaceInfo *info, const Func *func, const Token *tok, const Token *last) +void CheckClass::checkReturnPtrThis(const Scope *scope, const Function *func, const Token *tok, const Token *last) { bool foundReturn = false; @@ -871,7 +871,7 @@ void CheckClass::checkReturnPtrThis(const SpaceInfo *info, const Func *func, con if (tok->str() == "return") { foundReturn = true; - std::string cast("( " + info->className + " & )"); + std::string cast("( " + scope->className + " & )"); if (Token::Match(tok->next(), cast.c_str())) tok = tok->tokAt(4); @@ -879,22 +879,22 @@ void CheckClass::checkReturnPtrThis(const SpaceInfo *info, const Func *func, con if (Token::Match(tok->tokAt(1), "%any% (") && tok->tokAt(2)->link()->next()->str() == ";") { - std::list::const_iterator it; + std::list::const_iterator it; // check if it is a member function - for (it = info->functionList.begin(); it != info->functionList.end(); ++it) + for (it = scope->functionList.begin(); it != scope->functionList.end(); ++it) { // check for a regular function with the same name and a bofy - if (it->type == Func::Function && it->hasBody && + if (it->type == Function::eFunction && it->hasBody && it->token->str() == tok->next()->str()) { // check for the proper return type if (it->tokenDef->previous()->str() == "&" && - it->tokenDef->strAt(-2) == info->className) + it->tokenDef->strAt(-2) == scope->className) { // make sure it's not a const function if (it->arg->link()->next()->str() != "const") - checkReturnPtrThis(info, &*it, it->arg->link()->next(), it->arg->link()->next()->link()); + checkReturnPtrThis(scope, &*it, it->arg->link()->next(), it->arg->link()->next()->link()); } } } @@ -918,29 +918,29 @@ void CheckClass::operatorEqRetRefThis() createSymbolDatabase(); - std::list::const_iterator i; + std::list::const_iterator i; for (i = symbolDatabase->spaceInfoList.begin(); i != symbolDatabase->spaceInfoList.end(); ++i) { - const SpaceInfo *info = *i; + const Scope *scope = *i; // only check classes and structures - if (info->isClassOrStruct()) + if (scope->isClassOrStruct()) { - std::list::const_iterator func; + std::list::const_iterator func; - for (func = info->functionList.begin(); func != info->functionList.end(); ++func) + for (func = scope->functionList.begin(); func != scope->functionList.end(); ++func) { - if (func->type == Func::OperatorEqual && func->hasBody) + if (func->type == Function::eOperatorEqual && func->hasBody) { // make sure return signature is correct if (Token::Match(func->tokenDef->tokAt(-4), ";|}|{|public:|protected:|private: %type% &") && - func->tokenDef->strAt(-3) == info->className) + func->tokenDef->strAt(-3) == scope->className) { // find the ')' const Token *tok = func->token->next()->link(); - checkReturnPtrThis(info, &(*func), tok->tokAt(2), tok->next()->link()); + checkReturnPtrThis(scope, &(*func), tok->tokAt(2), tok->next()->link()); } } } @@ -974,29 +974,29 @@ void CheckClass::operatorEqToSelf() createSymbolDatabase(); - std::list::const_iterator i; + std::list::const_iterator i; for (i = symbolDatabase->spaceInfoList.begin(); i != symbolDatabase->spaceInfoList.end(); ++i) { - const SpaceInfo *info = *i; - std::list::const_iterator it; + const Scope *scope = *i; + std::list::const_iterator it; // skip classes with multiple inheritance - if (info->derivedFrom.size() > 1) + if (scope->derivedFrom.size() > 1) continue; - for (it = info->functionList.begin(); it != info->functionList.end(); ++it) + for (it = scope->functionList.begin(); it != scope->functionList.end(); ++it) { - if (it->type == Func::OperatorEqual && it->hasBody) + if (it->type == Function::eOperatorEqual && it->hasBody) { // make sure return signature is correct if (Token::Match(it->tokenDef->tokAt(-4), ";|}|{|public:|protected:|private: %type% &") && - it->tokenDef->strAt(-3) == info->className) + it->tokenDef->strAt(-3) == scope->className) { // check for proper function parameter signature if ((Token::Match(it->tokenDef->next(), "( const %var% & )") || Token::Match(it->tokenDef->next(), "( const %var% & %var% )")) && - it->tokenDef->strAt(3) == info->className) + it->tokenDef->strAt(3) == scope->className) { // find the parameter name const Token *rhs = it->token; @@ -1151,18 +1151,18 @@ void CheckClass::virtualDestructor() createSymbolDatabase(); - std::list::const_iterator i; + std::list::const_iterator i; for (i = symbolDatabase->spaceInfoList.begin(); i != symbolDatabase->spaceInfoList.end(); ++i) { - const SpaceInfo *info = *i; + const Scope *scope = *i; // Skip base classes and namespaces - if (info->derivedFrom.empty()) + if (scope->derivedFrom.empty()) continue; // Find the destructor - const Func *destructor = info->getDestructor(); + const Function *destructor = scope->getDestructor(); // Check for destructor with implementation if (!destructor || !destructor->hasBody) @@ -1172,22 +1172,22 @@ void CheckClass::virtualDestructor() if (destructor->token->tokAt(3)->link() == destructor->token->tokAt(4)) continue; - const Token *derived = info->classDef; + const Token *derived = scope->classDef; const Token *derivedClass = derived->tokAt(1); // Iterate through each base class... - for (unsigned int j = 0; j < info->derivedFrom.size(); ++j) + for (unsigned int j = 0; j < scope->derivedFrom.size(); ++j) { // Check if base class is public and exists in database - if (info->derivedFrom[j].access != Private && info->derivedFrom[j].spaceInfo) + if (scope->derivedFrom[j].access != Private && scope->derivedFrom[j].spaceInfo) { - const SpaceInfo *spaceInfo = info->derivedFrom[j].spaceInfo; + const Scope *spaceInfo = scope->derivedFrom[j].spaceInfo; // Name of base class.. const std::string baseName = spaceInfo->className; // Find the destructor declaration for the base class. - const Func *base_destructor = spaceInfo->getDestructor(); + const Function *base_destructor = spaceInfo->getDestructor(); const Token *base = 0; if (base_destructor) base = base_destructor->token; @@ -1270,22 +1270,22 @@ void CheckClass::checkConst() createSymbolDatabase(); - std::list::const_iterator it; + std::list::const_iterator it; for (it = symbolDatabase->spaceInfoList.begin(); it != symbolDatabase->spaceInfoList.end(); ++it) { - const SpaceInfo *info = *it; + const Scope *scope = *it; // only check classes and structures - if (!info->isClassOrStruct()) + if (!scope->isClassOrStruct()) continue; - std::list::const_iterator func; + std::list::const_iterator func; - for (func = info->functionList.begin(); func != info->functionList.end(); ++func) + for (func = scope->functionList.begin(); func != scope->functionList.end(); ++func) { // does the function have a body? - if (func->type == Func::Function && func->hasBody && !func->isFriend && !func->isStatic && !func->isConst && !func->isVirtual) + if (func->type == Function::eFunction && func->hasBody && !func->isFriend && !func->isStatic && !func->isConst && !func->isVirtual) { // get last token of return type const Token *previous = func->tokenDef->isName() ? func->token->previous() : func->token->tokAt(-2); @@ -1343,18 +1343,18 @@ void CheckClass::checkConst() const Token *paramEnd = func->arg->link(); // check if base class function is virtual - if (!info->derivedFrom.empty()) + if (!scope->derivedFrom.empty()) { - if (isVirtualFunc(info, func->tokenDef)) + if (isVirtualFunc(scope, func->tokenDef)) continue; } // if nothing non-const was found. write error.. - if (checkConstFunc(info, paramEnd)) + if (checkConstFunc(scope, paramEnd)) { - std::string classname = info->className; - const SpaceInfo *nest = info->nestedIn; - while (nest && nest->type != SpaceInfo::Global) + std::string classname = scope->className; + const Scope *nest = scope->nestedIn; + while (nest && nest->type != Scope::eGlobal) { classname = std::string(nest->className + "::" + classname); nest = nest->nestedIn; @@ -1378,7 +1378,7 @@ void CheckClass::checkConst() } } -bool CheckClass::isMemberVar(const SpaceInfo *info, const Token *tok) +bool CheckClass::isMemberVar(const Scope *scope, const Token *tok) { const Token *tok1 = tok; @@ -1397,11 +1397,11 @@ bool CheckClass::isMemberVar(const SpaceInfo *info, const Token *tok) tok = tok->tokAt(2); // ignore class namespace - if (tok->str() == info->className && tok->next()->str() == "::") + if (tok->str() == scope->className && tok->next()->str() == "::") tok = tok->tokAt(2); - std::list::const_iterator var; - for (var = info->varlist.begin(); var != info->varlist.end(); ++var) + std::list::const_iterator var; + for (var = scope->varlist.begin(); var != scope->varlist.end(); ++var) { if (var->token->str() == tok->str()) { @@ -1410,13 +1410,13 @@ bool CheckClass::isMemberVar(const SpaceInfo *info, const Token *tok) } // not found in this class - if (!info->derivedFrom.empty()) + if (!scope->derivedFrom.empty()) { // check each base class - for (unsigned int i = 0; i < info->derivedFrom.size(); ++i) + for (unsigned int i = 0; i < scope->derivedFrom.size(); ++i) { // find the base class - const SpaceInfo *spaceInfo = info->derivedFrom[i].spaceInfo; + const Scope *spaceInfo = scope->derivedFrom[i].spaceInfo; // find the function in the base class if (spaceInfo) @@ -1430,24 +1430,24 @@ bool CheckClass::isMemberVar(const SpaceInfo *info, const Token *tok) return false; } -bool CheckClass::isConstMemberFunc(const SpaceInfo *info, const Token *tok) +bool CheckClass::isConstMemberFunc(const Scope *scope, const Token *tok) { - std::list::const_iterator func; + std::list::const_iterator func; - for (func = info->functionList.begin(); func != info->functionList.end(); ++func) + for (func = scope->functionList.begin(); func != scope->functionList.end(); ++func) { if (func->tokenDef->str() == tok->str() && func->isConst) return true; } // not found in this class - if (!info->derivedFrom.empty()) + if (!scope->derivedFrom.empty()) { // check each base class - for (unsigned int i = 0; i < info->derivedFrom.size(); ++i) + for (unsigned int i = 0; i < scope->derivedFrom.size(); ++i) { // find the base class - const SpaceInfo *spaceInfo = info->derivedFrom[i].spaceInfo; + const Scope *spaceInfo = scope->derivedFrom[i].spaceInfo; // find the function in the base class if (spaceInfo) @@ -1461,7 +1461,7 @@ bool CheckClass::isConstMemberFunc(const SpaceInfo *info, const Token *tok) return false; } -bool CheckClass::checkConstFunc(const SpaceInfo *info, const Token *tok) +bool CheckClass::checkConstFunc(const Scope *scope, const Token *tok) { // if the function doesn't have any assignment nor function call, // it can be a const function.. @@ -1483,12 +1483,12 @@ bool CheckClass::checkConstFunc(const SpaceInfo *info, const Token *tok) (tok1->str().find("=") == 1 && tok1->str().find_first_of("") == std::string::npos)) { - if (tok1->previous()->varId() == 0 && !info->derivedFrom.empty()) + if (tok1->previous()->varId() == 0 && !scope->derivedFrom.empty()) { isconst = false; break; } - else if (isMemberVar(info, tok1->previous())) + else if (isMemberVar(scope, tok1->previous())) { isconst = false; break; @@ -1515,7 +1515,7 @@ bool CheckClass::checkConstFunc(const SpaceInfo *info, const Token *tok) } // streaming: << - else if (tok1->str() == "<<" && isMemberVar(info, tok1->previous())) + else if (tok1->str() == "<<" && isMemberVar(scope, tok1->previous())) { isconst = false; break; @@ -1532,7 +1532,7 @@ bool CheckClass::checkConstFunc(const SpaceInfo *info, const Token *tok) else if (Token::Match(tok1, "%var% (") && !(Token::Match(tok1, "return|c_str|if|string") || tok1->isStandardType())) { - if (!isConstMemberFunc(info, tok1)) + if (!isConstMemberFunc(scope, tok1)) { isconst = false; break; @@ -1558,17 +1558,17 @@ bool CheckClass::checkConstFunc(const SpaceInfo *info, const Token *tok) //--------------------------------------------------------------------------- // check if this function is defined virtual in the base classes -bool CheckClass::isVirtualFunc(const SpaceInfo *info, const Token *functionToken) const +bool CheckClass::isVirtualFunc(const Scope *scope, const Token *functionToken) const { // check each base class - for (unsigned int i = 0; i < info->derivedFrom.size(); ++i) + for (unsigned int i = 0; i < scope->derivedFrom.size(); ++i) { // check if base class exists in database - if (info->derivedFrom[i].spaceInfo) + if (scope->derivedFrom[i].spaceInfo) { - const SpaceInfo *derivedFrom = info->derivedFrom[i].spaceInfo; + const Scope *derivedFrom = scope->derivedFrom[i].spaceInfo; - std::list::const_iterator func; + std::list::const_iterator func; // check if function defined in base class for (func = derivedFrom->functionList.begin(); func != derivedFrom->functionList.end(); ++func) @@ -1597,7 +1597,7 @@ bool CheckClass::isVirtualFunc(const SpaceInfo *info, const Token *functionToken } // check for matching function parameters - if (returnMatch && symbolDatabase->argsMatch(info, tok->tokAt(2), functionToken->tokAt(2), std::string(""), 0)) + if (returnMatch && symbolDatabase->argsMatch(scope, tok->tokAt(2), functionToken->tokAt(2), std::string(""), 0)) { return true; } diff --git a/lib/checkclass.h b/lib/checkclass.h index 1d393acf0..1fa99d1b9 100644 --- a/lib/checkclass.h +++ b/lib/checkclass.h @@ -163,18 +163,18 @@ private: } // operatorEqRetRefThis helper function - void checkReturnPtrThis(const SpaceInfo *info, const Func *func, const Token *tok, const Token *last); + void checkReturnPtrThis(const Scope *scope, const Function *func, const Token *tok, const Token *last); // operatorEqToSelf helper functions bool hasDeallocation(const Token *first, const Token *last); bool hasAssignSelf(const Token *first, const Token *last, const Token *rhs); // checkConst helper functions - 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 isMemberVar(const Scope *scope, const Token *tok); + bool isConstMemberFunc(const Scope *scope, const Token *tok); + bool checkConstFunc(const Scope *scope, const Token *tok); /** @brief check if this function is virtual in the base classes */ - bool isVirtualFunc(const SpaceInfo *info, const Token *functionToken) const; + bool isVirtualFunc(const Scope *scope, const Token *functionToken) const; // constructors helper function /** @brief Information about a member variable. Used when checking for uninitialized variables */ @@ -189,23 +189,23 @@ private: bool init; }; - bool isBaseClassFunc(const Token *tok, const SpaceInfo *info); + bool isBaseClassFunc(const Token *tok, const Scope *scope); /** * @brief assign a variable in the varlist * @param varname name of variable to mark assigned - * @param info pointer to variable SpaceInfo + * @param scope pointer to variable Scope * @param usage reference to usage vector */ - void assignVar(const std::string &varname, const SpaceInfo *info, std::vector &usage); + void assignVar(const std::string &varname, const Scope *scope, std::vector &usage); /** * @brief initialize a variable in the varlist * @param varname name of variable to mark initialized - * @param info pointer to variable SpaceInfo + * @param scope pointer to variable Scope * @param usage reference to usage vector */ - void initVar(const std::string &varname, const SpaceInfo *info, std::vector &usage); + void initVar(const std::string &varname, const Scope *scope, std::vector &usage); /** * @brief set all variables in list assigned @@ -223,10 +223,10 @@ private: * @brief parse a scope for a constructor or member function and set the "init" flags in the provided varlist * @param func reference to the function that should be checked * @param callstack the function doesn't look into recursive function calls. - * @param info pointer to variable SpaceInfo + * @param scope pointer to variable Scope * @param usage reference to usage vector */ - void initializeVarList(const Func &func, std::list &callstack, const SpaceInfo *info, std::vector &usage); + void initializeVarList(const Function &func, std::list &callstack, const Scope *scope, std::vector &usage); }; /// @} //--------------------------------------------------------------------------- diff --git a/lib/checkmemoryleak.cpp b/lib/checkmemoryleak.cpp index c60a74e6d..a8b8e2c42 100644 --- a/lib/checkmemoryleak.cpp +++ b/lib/checkmemoryleak.cpp @@ -565,19 +565,19 @@ void CheckMemoryLeakInFunction::parse_noreturn() noreturn.insert("errx"); noreturn.insert("verrx"); - std::list::const_iterator i; + std::list::const_iterator i; for (i = symbolDatabase->spaceInfoList.begin(); i != symbolDatabase->spaceInfoList.end(); ++i) { - const SpaceInfo *info = *i; + const Scope *scope = *i; // only check functions - if (info->type != SpaceInfo::Function) + if (scope->type != Scope::eFunction) continue; // parse this function to check if it contains an "exit" call.. unsigned int indentlevel = 1; - for (const Token *tok2 = info->classStart->next(); tok2; tok2 = tok2->next()) + for (const Token *tok2 = scope->classStart->next(); tok2; tok2 = tok2->next()) { if (tok2->str() == "{") ++indentlevel; @@ -589,7 +589,7 @@ void CheckMemoryLeakInFunction::parse_noreturn() } if (Token::Match(tok2->previous(), "[;{}] exit (")) { - noreturn.insert(info->className); + noreturn.insert(scope->className); break; } } @@ -597,7 +597,7 @@ void CheckMemoryLeakInFunction::parse_noreturn() // This function is not a noreturn function if (indentlevel == 0) { - notnoreturn.insert(info->className); + notnoreturn.insert(scope->className); } } } @@ -2491,25 +2491,25 @@ void CheckMemoryLeakInFunction::checkScope(const Token *Tok1, const std::string //--------------------------------------------------------------------------- void CheckMemoryLeakInFunction::checkReallocUsage() { - std::list::const_iterator i; + std::list::const_iterator i; for (i = symbolDatabase->spaceInfoList.begin(); i != symbolDatabase->spaceInfoList.end(); ++i) { - const SpaceInfo *info = *i; + const Scope *scope = *i; // only check functions - if (info->type != SpaceInfo::Function) + if (scope->type != Scope::eFunction) continue; // Record the varid's of the function parameters std::set parameterVarIds; - for (const Token *tok2 = info->classDef->next(); tok2 && tok2->str() != ")"; tok2 = tok2->next()) + for (const Token *tok2 = scope->classDef->next(); tok2 && tok2->str() != ")"; tok2 = tok2->next()) { if (tok2->varId() != 0) parameterVarIds.insert(tok2->varId()); } - const Token *tok = info->classStart; + const Token *tok = scope->classStart; const Token *startOfFunction = tok; // Search for the "var = realloc(var, 100);" pattern within this function @@ -2644,19 +2644,19 @@ void CheckMemoryLeakInFunction::check() // fill the "noreturn" parse_noreturn(); - std::list::const_iterator i; + std::list::const_iterator i; for (i = symbolDatabase->spaceInfoList.begin(); i != symbolDatabase->spaceInfoList.end(); ++i) { - const SpaceInfo *info = *i; + const Scope *scope = *i; // only check functions - if (info->type != SpaceInfo::Function) + if (scope->type != Scope::eFunction) continue; - const Token *tok = info->classStart; - const Token *tok1 = info->classDef->next(); - bool classmember = info->functionOf != NULL; + const Token *tok = scope->classStart; + const Token *tok1 = scope->classDef->next(); + bool classmember = scope->functionOf != NULL; parseFunctionScope(tok, tok1, classmember); } @@ -2701,17 +2701,17 @@ void CheckMemoryLeakInClass::check() { const SymbolDatabase *symbolDatabase = _tokenizer->getSymbolDatabase(); - std::list::const_iterator i; + std::list::const_iterator i; for (i = symbolDatabase->spaceInfoList.begin(); i != symbolDatabase->spaceInfoList.end(); ++i) { - const SpaceInfo *info = *i; + const Scope *scope = *i; // only check classes and structures - if (info->type == SpaceInfo::Class) + if (scope->type == Scope::eClass) { - std::list::const_iterator var; - for (var = info->varlist.begin(); var != info->varlist.end(); ++var) + std::list::const_iterator var; + for (var = scope->varlist.begin(); var != scope->varlist.end(); ++var) { if (!var->isStatic && var->token->previous()->str() == "*") { @@ -2719,9 +2719,9 @@ void CheckMemoryLeakInClass::check() if (var->token->tokAt(-2)->isStandardType()) { if (var->access == Private) - checkPublicFunctions(info, var->token); + checkPublicFunctions(scope, var->token); - variable(info, var->token); + variable(scope, var->token); } // known class? @@ -2731,9 +2731,9 @@ void CheckMemoryLeakInClass::check() if (var->type->derivedFrom.empty() && var->type->numConstructors == 0) { if (var->access == Private) - checkPublicFunctions(info, var->token); + checkPublicFunctions(scope, var->token); - variable(info, var->token); + variable(scope, var->token); } } } @@ -2743,10 +2743,10 @@ void CheckMemoryLeakInClass::check() } -void CheckMemoryLeakInClass::variable(const SpaceInfo *classinfo, const Token *tokVarname) +void CheckMemoryLeakInClass::variable(const Scope *scope, const Token *tokVarname) { const std::string varname = tokVarname->strAt(0); - const std::string classname = classinfo->className; + const std::string classname = scope->className; // Check if member variable has been allocated and deallocated.. CheckMemoryLeak::AllocType Alloc = CheckMemoryLeak::No; @@ -2756,12 +2756,12 @@ void CheckMemoryLeakInClass::variable(const SpaceInfo *classinfo, const Token *t bool deallocInDestructor = false; // Inspect member functions - std::list::const_iterator func; - for (func = classinfo->functionList.begin(); func != classinfo->functionList.end(); ++func) + std::list::const_iterator func; + for (func = scope->functionList.begin(); func != scope->functionList.end(); ++func) { const Token *functionToken = func->token; - const bool constructor = func->type == Func::Constructor; - const bool destructor = func->type == Func::Destructor; + const bool constructor = func->type == Function::eConstructor; + const bool destructor = func->type == Function::eDestructor; unsigned int indent = 0; bool initlist = false; for (const Token *tok = functionToken; tok; tok = tok->next()) @@ -2795,7 +2795,7 @@ void CheckMemoryLeakInClass::variable(const SpaceInfo *classinfo, const Token *t // Foo::var1 = .. // bail out when not same class if (Token::simpleMatch(tok->previous(), "::") && - tok->strAt(-2) != classinfo->className) + tok->strAt(-2) != scope->className) return; AllocType alloc = getAllocationType(tok->tokAt((indent > 0) ? 2 : 3), 0); @@ -2826,7 +2826,7 @@ void CheckMemoryLeakInClass::variable(const SpaceInfo *classinfo, const Token *t AllocType dealloc = getDeallocationType(tok, varname); if (dealloc == No) { - std::string temp = classinfo->className + " :: " + varname; + std::string temp = scope->className + " :: " + varname; dealloc = getDeallocationType(tok, temp); } if (dealloc == No) @@ -2879,7 +2879,7 @@ void CheckMemoryLeakInClass::variable(const SpaceInfo *classinfo, const Token *t } -void CheckMemoryLeakInClass::checkPublicFunctions(const SpaceInfo *spaceinfo, const Token *classtok) +void CheckMemoryLeakInClass::checkPublicFunctions(const Scope *scope, const Token *classtok) { // Check that public functions deallocate the pointers that they allocate. // There is no checking how these functions are used and therefore it @@ -2891,11 +2891,11 @@ void CheckMemoryLeakInClass::checkPublicFunctions(const SpaceInfo *spaceinfo, co // Parse public functions.. // If they allocate member variables, they should also deallocate - std::list::const_iterator func; + std::list::const_iterator func; - for (func = spaceinfo->functionList.begin(); func != spaceinfo->functionList.end(); ++func) + for (func = scope->functionList.begin(); func != scope->functionList.end(); ++func) { - if (func->type != Func::Constructor && + if (func->type != Function::eConstructor && func->access == Public && func->hasBody) { const Token *tok2 = func->token; @@ -2908,7 +2908,7 @@ void CheckMemoryLeakInClass::checkPublicFunctions(const SpaceInfo *spaceinfo, co publicAllocationError(tok2, tok2->strAt(1)); } else if (Token::Match(tok2, "{|}|; %type% :: %varid% =", varid) && - tok2->next()->str() == spaceinfo->className) + tok2->next()->str() == scope->className) { const CheckMemoryLeak::AllocType alloc = getAllocationType(tok2->tokAt(5), varid); if (alloc != CheckMemoryLeak::No) @@ -3166,18 +3166,18 @@ void CheckMemoryLeakNoVar::check() const SymbolDatabase *symbolDatabase = _tokenizer->getSymbolDatabase(); - std::list::const_iterator i; + std::list::const_iterator i; for (i = symbolDatabase->spaceInfoList.begin(); i != symbolDatabase->spaceInfoList.end(); ++i) { - SpaceInfo *info = *i; + Scope *scope = *i; // only check functions - if (info->type != SpaceInfo::Function) + if (scope->type != Scope::eFunction) continue; // goto the "}" that ends the executable scope.. - const Token *tok = info->classEnd; + const Token *tok = scope->classEnd; // parse the executable scope until tok is reached... for (const Token *tok2 = tok->link(); tok2 && tok2 != tok; tok2 = tok2->next()) diff --git a/lib/checkmemoryleak.h b/lib/checkmemoryleak.h index 3875d2f9d..d535ea4cb 100644 --- a/lib/checkmemoryleak.h +++ b/lib/checkmemoryleak.h @@ -387,10 +387,10 @@ public: void check(); private: - void variable(const SpaceInfo *spaceinfo, const Token *tokVarname); + void variable(const Scope *scope, const Token *tokVarname); /** Public functions: possible double-allocation */ - void checkPublicFunctions(const SpaceInfo *spaceinfo, const Token *classtok); + void checkPublicFunctions(const Scope *scope, const Token *classtok); void publicAllocationError(const Token *tok, const std::string &varname); void getErrorMessages(ErrorLogger * /*errorLogger*/, const Settings * /*settings*/) diff --git a/lib/checkother.cpp b/lib/checkother.cpp index 14c4bc863..768f8b63c 100644 --- a/lib/checkother.cpp +++ b/lib/checkother.cpp @@ -562,27 +562,27 @@ static bool isOp(const Token *tok) /** * @brief This class is used to capture the control flow within a function. */ -class Scope +class ScopeInfo { public: - Scope() : _token(NULL), _parent(NULL) { } - Scope(const Token *token, Scope *parent_) : _token(token), _parent(parent_) { } - ~Scope(); + ScopeInfo() : _token(NULL), _parent(NULL) { } + ScopeInfo(const Token *token, ScopeInfo *parent_) : _token(token), _parent(parent_) { } + ~ScopeInfo(); - Scope *parent() + ScopeInfo *parent() { return _parent; } - Scope *addChild(const Token *token); - void remove(Scope *scope); + ScopeInfo *addChild(const Token *token); + void remove(ScopeInfo *scope); private: const Token *_token; - Scope *_parent; - std::list _children; + ScopeInfo *_parent; + std::list _children; }; -Scope::~Scope() +ScopeInfo::~ScopeInfo() { while (!_children.empty()) { @@ -591,18 +591,18 @@ Scope::~Scope() } } -Scope *Scope::addChild(const Token *token) +ScopeInfo *ScopeInfo::addChild(const Token *token) { - Scope *temp = new Scope(token, this); + ScopeInfo *temp = new ScopeInfo(token, this); _children.push_back(temp); return temp; } -void Scope::remove(Scope *scope) +void ScopeInfo::remove(ScopeInfo *scope) { - std::list::iterator it; + std::list::iterator it; for (it = _children.begin(); it != _children.end(); ++it) { @@ -629,7 +629,7 @@ public: public: VariableUsage(const Token *name = 0, VariableType type = standard, - Scope *scope = NULL, + ScopeInfo *scope = NULL, bool read = false, bool write = false, bool modified = false, @@ -659,13 +659,13 @@ public: const Token *_name; VariableType _type; - Scope *_scope; + ScopeInfo *_scope; bool _read; bool _write; bool _modified; // read/modify/write bool _allocateMemory; std::set _aliases; - std::set _assignments; + std::set _assignments; }; typedef std::map VariableMap; @@ -678,7 +678,7 @@ public: { return _varUsage; } - void addVar(const Token *name, VariableType type, Scope *scope, bool write_); + void addVar(const Token *name, VariableType type, ScopeInfo *scope, bool write_); void allocateMemory(unsigned int varid); void read(unsigned int varid); void readAliases(unsigned int varid); @@ -797,7 +797,7 @@ void Variables::eraseAll(unsigned int varid) void Variables::addVar(const Token *name, VariableType type, - Scope *scope, + ScopeInfo *scope, bool write_) { if (name->varId() > 0) @@ -955,7 +955,7 @@ Variables::VariableUsage *Variables::find(unsigned int varid) return 0; } -static int doAssignment(Variables &variables, const Token *tok, bool dereference, Scope *scope) +static int doAssignment(Variables &variables, const Token *tok, bool dereference, ScopeInfo *scope) { int next = 0; @@ -1090,7 +1090,7 @@ static int doAssignment(Variables &variables, const Token *tok, bool dereference // not in same scope as declaration else { - std::set::iterator assignment; + std::set::iterator assignment; // check for an assignment in this scope assignment = var1->_assignments.find(scope); @@ -1158,7 +1158,7 @@ static int doAssignment(Variables &variables, const Token *tok, bool dereference variables.clearAliases(varid1); else { - std::set::iterator assignment; + std::set::iterator assignment; // check for an assignment in this scope assignment = var1->_assignments.find(scope); @@ -1240,14 +1240,14 @@ void CheckOther::functionVariableUsage() // Parse all executing scopes.. const SymbolDatabase *symbolDatabase = _tokenizer->getSymbolDatabase(); - std::list::const_iterator i; + std::list::const_iterator i; for (i = symbolDatabase->spaceInfoList.begin(); i != symbolDatabase->spaceInfoList.end(); ++i) { - const SpaceInfo *info = *i; + const Scope *info = *i; // only check functions - if (info->type != SpaceInfo::Function) + if (info->type != Scope::eFunction) continue; // First token for the current scope.. @@ -1257,8 +1257,8 @@ void CheckOther::functionVariableUsage() Variables variables; // scopes - Scope scopes; - Scope *scope = &scopes; + ScopeInfo scopes; + ScopeInfo *scope = &scopes; unsigned int indentlevel = 0; for (const Token *tok = tok1; tok; tok = tok->next()) @@ -1267,7 +1267,7 @@ void CheckOther::functionVariableUsage() { // replace the head node when found if (indentlevel == 0) - scopes = Scope(tok, NULL); + scopes = ScopeInfo(tok, NULL); // add the new scope else scope = scope->addChild(tok); @@ -1694,7 +1694,7 @@ void CheckOther::functionVariableUsage() if (!start->tokAt(3)->isStandardType()) { // lookup the type - const SpaceInfo *type = symbolDatabase->findVarType(info, start->tokAt(3)); + const Scope *type = symbolDatabase->findVariableType(info, start->tokAt(3)); // unknown type? if (!type) @@ -1702,7 +1702,7 @@ void CheckOther::functionVariableUsage() // has default constructor or // has members with unknown type or default constructor - else if (type->needInitialization == SpaceInfo::False) + else if (type->needInitialization == Scope::False) allocate = false; } } @@ -1908,19 +1908,19 @@ void CheckOther::checkVariableScope() const SymbolDatabase *symbolDatabase = _tokenizer->getSymbolDatabase(); - std::list::const_iterator i; + std::list::const_iterator i; for (i = symbolDatabase->spaceInfoList.begin(); i != symbolDatabase->spaceInfoList.end(); ++i) { - const SpaceInfo *info = *i; + const Scope *scope = *i; // only check functions - if (info->type != SpaceInfo::Function) + if (scope->type != Scope::eFunction) continue; // Walk through all tokens.. int indentlevel = 0; - for (const Token *tok = info->classStart; tok; tok = tok->next()) + for (const Token *tok = scope->classStart; tok; tok = tok->next()) { // Skip function local class and struct declarations.. if ((tok->str() == "class") || (tok->str() == "struct") || (tok->str() == "union")) @@ -2536,19 +2536,19 @@ void CheckOther::checkMisusedScopedObject() const SymbolDatabase * const symbolDatabase = _tokenizer->getSymbolDatabase(); - std::list::const_iterator i; + std::list::const_iterator i; for (i = symbolDatabase->spaceInfoList.begin(); i != symbolDatabase->spaceInfoList.end(); ++i) { - const SpaceInfo *info = *i; + const Scope *scope = *i; // only check functions - if (info->type != SpaceInfo::Function) + if (scope->type != Scope::eFunction) continue; unsigned int depth = 0; - for (const Token *tok = info->classStart; tok; tok = tok->next()) + for (const Token *tok = scope->classStart; tok; tok = tok->next()) { if (tok->str() == "{") { diff --git a/lib/symboldatabase.cpp b/lib/symboldatabase.cpp index ec0539322..d10e64a48 100644 --- a/lib/symboldatabase.cpp +++ b/lib/symboldatabase.cpp @@ -46,14 +46,14 @@ SymbolDatabase::SymbolDatabase(const Tokenizer *tokenizer, const Settings *setti } // find all namespaces (class,struct and namespace) - SpaceInfo *info = new SpaceInfo(this, NULL, NULL); + Scope *info = new Scope(this, NULL, NULL); spaceInfoList.push_back(info); for (const Token *tok = _tokenizer->tokens(); tok; tok = tok->next()) { // Locate next class if (Token::Match(tok, "class|struct|namespace %var% [{:]")) { - SpaceInfo *new_info = new SpaceInfo(this, tok, info); + Scope *new_info = new Scope(this, tok, info); const Token *tok2 = tok->tokAt(2); // only create base list for classes and structures @@ -91,7 +91,7 @@ SymbolDatabase::SymbolDatabase(const Tokenizer *tokenizer, const Settings *setti } // check if in class or structure - else if (info->type == SpaceInfo::Class || info->type == SpaceInfo::Struct) + else if (info->type == Scope::eClass || info->type == Scope::eStruct) { const Token *funcStart = 0; const Token *argStart = 0; @@ -118,7 +118,7 @@ SymbolDatabase::SymbolDatabase(const Tokenizer *tokenizer, const Settings *setti // class function? else if (tok->previous()->str() != "::" && isFunction(tok, &funcStart, &argStart)) { - Func function; + Function function; // save the function definition argument start '(' function.argDef = argStart; @@ -136,20 +136,20 @@ SymbolDatabase::SymbolDatabase(const Tokenizer *tokenizer, const Settings *setti // 'operator =' is special if (function.tokenDef->str() == "=") - function.type = Func::OperatorEqual; + function.type = Function::eOperatorEqual; } // class constructor/destructor else if (function.tokenDef->str() == info->className) { if (function.tokenDef->previous()->str() == "~") - function.type = Func::Destructor; + function.type = Function::eDestructor; else if ((Token::Match(function.tokenDef, "%var% ( const %var% & )") || Token::Match(function.tokenDef, "%var% ( const %var% & %var% )")) && function.tokenDef->strAt(3) == info->className) - function.type = Func::CopyConstructor; + function.type = Function::eCopyConstructor; else - function.type = Func::Constructor; + function.type = Function::eConstructor; if (function.tokenDef->previous()->str() == "explicit") function.isExplicit = true; @@ -206,7 +206,7 @@ SymbolDatabase::SymbolDatabase(const Tokenizer *tokenizer, const Settings *setti function.isPure = true; // count the number of constructors - if (function.type == Func::Constructor || function.type == Func::CopyConstructor) + if (function.type == Function::eConstructor || function.type == Function::eCopyConstructor) info->numConstructors++; // assume implementation is inline (definition and implementation same) @@ -232,7 +232,7 @@ SymbolDatabase::SymbolDatabase(const Tokenizer *tokenizer, const Settings *setti info->functionList.push_back(function); const Token *tok2 = funcStart; - SpaceInfo *functionOf = info; + Scope *functionOf = info; addNewFunction(&info, &tok2); if (info) @@ -249,7 +249,7 @@ SymbolDatabase::SymbolDatabase(const Tokenizer *tokenizer, const Settings *setti // friend class declaration? else if (Token::Match(tok, "friend class| %any% ;")) { - SpaceInfo::FriendInfo friendInfo; + Scope::FriendInfo friendInfo; friendInfo.name = tok->strAt(1) == "class" ? tok->strAt(2) : tok->strAt(1); /** @todo fill this in later after parsing is complete */ @@ -258,7 +258,7 @@ SymbolDatabase::SymbolDatabase(const Tokenizer *tokenizer, const Settings *setti info->friendList.push_back(friendInfo); } } - else if (info->type == SpaceInfo::Namespace || info->type == SpaceInfo::Global) + else if (info->type == Scope::eNamespace || info->type == Scope::eGlobal) { const Token *funcStart = 0; const Token *argStart = 0; @@ -281,7 +281,7 @@ SymbolDatabase::SymbolDatabase(const Tokenizer *tokenizer, const Settings *setti // regular function else { - Func function; + Function function; // save the function definition argument start '(' function.argDef = argStart; @@ -296,9 +296,9 @@ SymbolDatabase::SymbolDatabase(const Tokenizer *tokenizer, const Settings *setti function.isInline = false; function.hasBody = true; function.arg = function.argDef; - function.type = Func::Function; + function.type = Function::eFunction; - SpaceInfo *old_info = info; + Scope *old_info = info; addNewFunction(&info, &tok); @@ -319,7 +319,7 @@ SymbolDatabase::SymbolDatabase(const Tokenizer *tokenizer, const Settings *setti Token::Match(argStart->link()->tokAt(2)->link(), ") const| {")) { const Token *tok1 = funcStart; - SpaceInfo *old_info = info; + Scope *old_info = info; // class function if (tok1->previous()->str() == "::") @@ -340,7 +340,7 @@ SymbolDatabase::SymbolDatabase(const Tokenizer *tokenizer, const Settings *setti } } - std::list::iterator it; + std::list::iterator it; // fill in base class info for (it = spaceInfoList.begin(); it != spaceInfoList.end(); ++it) @@ -354,22 +354,22 @@ SymbolDatabase::SymbolDatabase(const Tokenizer *tokenizer, const Settings *setti // finish filling in base class info for (unsigned int i = 0; i < info->derivedFrom.size(); ++i) { - std::list::iterator it1; + std::list::iterator it1; for (it1 = spaceInfoList.begin(); it1 != spaceInfoList.end(); ++it1) { - SpaceInfo *spaceInfo = *it1; + Scope *spaceInfo = *it1; /** @todo handle derived base classes and namespaces */ - if (spaceInfo->type == SpaceInfo::Class || spaceInfo->type == SpaceInfo::Struct) + if (spaceInfo->type == Scope::eClass || spaceInfo->type == Scope::eStruct) { // do class names match? if (spaceInfo->className == info->derivedFrom[i].name) { // are they in the same namespace or different namespaces with same name? if ((spaceInfo->nestedIn == info->nestedIn) || - ((spaceInfo->nestedIn && spaceInfo->nestedIn->type == SpaceInfo::Namespace) && - (info->nestedIn && info->nestedIn->type == SpaceInfo::Namespace) && + ((spaceInfo->nestedIn && spaceInfo->nestedIn->type == Scope::eNamespace) && + (info->nestedIn && info->nestedIn->type == Scope::eNamespace) && (spaceInfo->nestedIn->className == info->nestedIn->className))) { info->derivedFrom[i].spaceInfo = spaceInfo; @@ -387,10 +387,10 @@ SymbolDatabase::SymbolDatabase(const Tokenizer *tokenizer, const Settings *setti info = *it; // skip functions - if (info->type != SpaceInfo::Function) + if (info->type != Scope::eFunction) { // find variables - info->getVarList(); + info->getVariableList(); } } @@ -406,16 +406,16 @@ SymbolDatabase::SymbolDatabase(const Tokenizer *tokenizer, const Settings *setti { info = *it; - if (info->isClassOrStruct() && info->needInitialization == SpaceInfo::Unknown) + if (info->isClassOrStruct() && info->needInitialization == Scope::Unknown) { // check for default constructor bool hasDefaultConstructor = false; - std::list::const_iterator func; + std::list::const_iterator func; for (func = info->functionList.begin(); func != info->functionList.end(); ++func) { - if (func->type == Func::Constructor) + if (func->type == Function::eConstructor) { // check for no arguments: func ( ) if (func->argDef->next() == func->argDef->link()) @@ -437,7 +437,7 @@ SymbolDatabase::SymbolDatabase(const Tokenizer *tokenizer, const Settings *setti // We assume the default constructor initializes everything. // Another check will figure out if the constructor actually initializes everything. if (hasDefaultConstructor) - info->needInitialization = SpaceInfo::False; + info->needInitialization = Scope::False; // check each member variable to see if it needs initialization else @@ -445,7 +445,7 @@ SymbolDatabase::SymbolDatabase(const Tokenizer *tokenizer, const Settings *setti bool needInitialization = false; bool unknown = false; - std::list::const_iterator var; + std::list::const_iterator var; for (var = info->varlist.begin(); var != info->varlist.end(); ++var) { if (var->isClass) @@ -453,9 +453,9 @@ SymbolDatabase::SymbolDatabase(const Tokenizer *tokenizer, const Settings *setti if (var->type) { // does this type need initialization? - if (var->type->needInitialization == SpaceInfo::True) + if (var->type->needInitialization == Scope::True) needInitialization = true; - else if (var->type->needInitialization == SpaceInfo::Unknown) + else if (var->type->needInitialization == Scope::Unknown) unknown = true; } } @@ -466,12 +466,12 @@ SymbolDatabase::SymbolDatabase(const Tokenizer *tokenizer, const Settings *setti if (!unknown) { if (needInitialization) - info->needInitialization = SpaceInfo::True; + info->needInitialization = Scope::True; else - info->needInitialization = SpaceInfo::False; + info->needInitialization = Scope::False; } - if (info->needInitialization == SpaceInfo::Unknown) + if (info->needInitialization == Scope::Unknown) unknowns++; } } @@ -488,7 +488,7 @@ SymbolDatabase::SymbolDatabase(const Tokenizer *tokenizer, const Settings *setti { info = *it; - if (info->isClassOrStruct() && info->needInitialization == SpaceInfo::Unknown) + if (info->isClassOrStruct() && info->needInitialization == Scope::Unknown) { std::list locationList; ErrorLogger::ErrorMessage::FileLocation loc; @@ -511,7 +511,7 @@ SymbolDatabase::SymbolDatabase(const Tokenizer *tokenizer, const Settings *setti SymbolDatabase::~SymbolDatabase() { - std::list::iterator it; + std::list::iterator it; for (it = spaceInfoList.begin(); it != spaceInfoList.end(); ++it) delete *it; @@ -575,7 +575,7 @@ bool SymbolDatabase::isFunction(const Token *tok, const Token **funcStart, const return false; } -bool SymbolDatabase::argsMatch(const SpaceInfo *info, const Token *first, const Token *second, const std::string &path, unsigned int depth) const +bool SymbolDatabase::argsMatch(const Scope *info, const Token *first, const Token *second, const std::string &path, unsigned int depth) const { bool match = false; while (first->str() == second->str()) @@ -664,7 +664,7 @@ bool SymbolDatabase::argsMatch(const SpaceInfo *info, const Token *first, const return match; } -void SymbolDatabase::addFunction(SpaceInfo **info, const Token **tok, const Token *argStart) +void SymbolDatabase::addFunction(Scope **info, const Token **tok, const Token *argStart) { int count = 0; bool added = false; @@ -693,15 +693,15 @@ void SymbolDatabase::addFunction(SpaceInfo **info, const Token **tok, const Toke path_length++; } - std::list::iterator it1; + std::list::iterator it1; // search for match for (it1 = spaceInfoList.begin(); it1 != spaceInfoList.end(); ++it1) { - SpaceInfo *info1 = *it1; + Scope *info1 = *it1; bool match = false; - if (info1->className == tok1->str() && (info1->type != SpaceInfo::Function)) + if (info1->className == tok1->str() && (info1->type != Scope::eFunction)) { // do the spaces match (same space) or do their names match (multiple namespaces) if ((*info == info1->nestedIn) || (*info && info1 && @@ -709,7 +709,7 @@ void SymbolDatabase::addFunction(SpaceInfo **info, const Token **tok, const Toke !(*info)->className.empty() && (*info)->type == info1->nestedIn->type)) { - SpaceInfo *info2 = info1; + Scope *info2 = info1; while (info2 && count > 0) { @@ -728,7 +728,7 @@ void SymbolDatabase::addFunction(SpaceInfo **info, const Token **tok, const Toke if (match) { - std::list::iterator func; + std::list::iterator func; for (func = info1->functionList.begin(); func != info1->functionList.end(); ++func) { @@ -745,7 +745,7 @@ void SymbolDatabase::addFunction(SpaceInfo **info, const Token **tok, const Toke func->arg = argStart; } } - else if (func->type == Func::Destructor && + else if (func->type == Function::eDestructor && (*tok)->previous()->str() == "~" && func->tokenDef->str() == (*tok)->str()) { @@ -803,10 +803,10 @@ void SymbolDatabase::addFunction(SpaceInfo **info, const Token **tok, const Toke addNewFunction(info, tok); } -void SymbolDatabase::addNewFunction(SpaceInfo **info, const Token **tok) +void SymbolDatabase::addNewFunction(Scope **info, const Token **tok) { const Token *tok1 = *tok; - SpaceInfo *new_info = new SpaceInfo(this, tok1, *info); + Scope *new_info = new Scope(this, tok1, *info); // skip to start of function while (tok1 && tok1->str() != "{") @@ -837,7 +837,7 @@ void SymbolDatabase::addNewFunction(SpaceInfo **info, const Token **tok) } } -const Token *SymbolDatabase::initBaseInfo(SpaceInfo *info, const Token *tok) +const Token *SymbolDatabase::initBaseInfo(Scope *info, const Token *tok) { // goto initial '{' const Token *tok2 = tok->tokAt(2); @@ -853,7 +853,7 @@ const Token *SymbolDatabase::initBaseInfo(SpaceInfo *info, const Token *tok) // check for base classes else if (level == 0 && Token::Match(tok2, ":|,")) { - SpaceInfo::BaseInfo base; + Scope::BaseInfo base; tok2 = tok2->next(); @@ -924,7 +924,7 @@ const Token *SymbolDatabase::initBaseInfo(SpaceInfo *info, const Token *tok) //--------------------------------------------------------------------------- -unsigned int Func::argCount() const +unsigned int Function::argCount() const { unsigned int count = 0; @@ -942,7 +942,7 @@ unsigned int Func::argCount() const return count; } -unsigned int Func::initializedArgCount() const +unsigned int Function::initializedArgCount() const { unsigned int count = 0; @@ -960,48 +960,48 @@ unsigned int Func::initializedArgCount() const //--------------------------------------------------------------------------- -SpaceInfo::SpaceInfo(SymbolDatabase *check_, const Token *classDef_, SpaceInfo *nestedIn_) : +Scope::Scope(SymbolDatabase *check_, const Token *classDef_, Scope *nestedIn_) : check(check_), classDef(classDef_), classStart(NULL), classEnd(NULL), nestedIn(nestedIn_), numConstructors(0), - needInitialization(SpaceInfo::Unknown), + needInitialization(Scope::Unknown), functionOf(NULL) { if (!classDef) { - type = SpaceInfo::Global; + type = Scope::eGlobal; access = Public; } else if (classDef->str() == "class") { - type = SpaceInfo::Class; + type = Scope::eClass; className = classDef->next()->str(); access = Private; } else if (classDef->str() == "struct") { - type = SpaceInfo::Struct; + type = Scope::eStruct; className = classDef->next()->str(); access = Public; } else if (classDef->str() == "union") { - type = SpaceInfo::Union; + type = Scope::eUnion; className = classDef->next()->str(); access = Public; } else if (classDef->str() == "namespace") { - type = SpaceInfo::Namespace; + type = Scope::eNamespace; className = classDef->next()->str(); access = Public; } else { - type = SpaceInfo::Function; + type = Scope::eFunction; className = classDef->str(); access = Public; } @@ -1011,15 +1011,15 @@ SpaceInfo::SpaceInfo(SymbolDatabase *check_, const Token *classDef_, SpaceInfo * } bool -SpaceInfo::hasDefaultConstructor() const +Scope::hasDefaultConstructor() const { if (numConstructors) { - std::list::const_iterator func; + std::list::const_iterator func; for (func = functionList.begin(); func != functionList.end(); ++func) { - if (func->type == Func::Constructor && + if (func->type == Function::eConstructor && func->argDef->link() == func->argDef->next()) return true; } @@ -1028,9 +1028,9 @@ SpaceInfo::hasDefaultConstructor() const } // Get variable list.. -void SpaceInfo::getVarList() +void Scope::getVariableList() { - AccessControl varaccess = type == Class ? Private : Public; + AccessControl varaccess = type == eClass ? Private : Public; const Token *start; if (classStart) @@ -1184,7 +1184,7 @@ void SpaceInfo::getVarList() const ErrorLogger::ErrorMessage errmsg(locationList, Severity::debug, - "SymbolDatabase::SpaceInfo::getVarList found variable \'" + vartok->str() + "\' with varid 0.", + "Scope::getVariableList found variable \'" + vartok->str() + "\' with varid 0.", "debug"); if (check->_errorLogger) check->_errorLogger->reportErr(errmsg); @@ -1192,12 +1192,12 @@ void SpaceInfo::getVarList() Check::reportError(errmsg); } - const SpaceInfo *spaceInfo = NULL; + const Scope *spaceInfo = NULL; if (typetok) - spaceInfo = check->findVarType(this, typetok); + spaceInfo = check->findVariableType(this, typetok); - addVar(vartok, varaccess, isMutable, isStatic, isConst, isClass, spaceInfo); + addVariable(vartok, varaccess, isMutable, isStatic, isConst, isClass, spaceInfo); } } } @@ -1230,7 +1230,7 @@ const Token* skipPointers(const Token* tok) return ret; } -bool SpaceInfo::isVariableDeclaration(const Token* tok, const Token*& vartok, const Token*& typetok) const +bool Scope::isVariableDeclaration(const Token* tok, const Token*& vartok, const Token*& typetok) const { const Token* localTypeTok = skipScopeIdentifiers(tok); @@ -1271,17 +1271,17 @@ bool SpaceInfo::isVariableDeclaration(const Token* tok, const Token*& vartok, co return NULL != vartok; } -bool SpaceInfo::isSimpleVariable(const Token* tok) const +bool Scope::isSimpleVariable(const Token* tok) const { return Token::Match(tok, "%var% ;"); } -bool SpaceInfo::isArrayVariable(const Token* tok) const +bool Scope::isArrayVariable(const Token* tok) const { return Token::Match(tok, "%var% [") && tok->next()->str() != "operator"; } -bool SpaceInfo::findClosingBracket(const Token* tok, const Token*& close) const +bool Scope::findClosingBracket(const Token* tok, const Token*& close) const { bool found = false; if (NULL != tok && tok->str() == "<") @@ -1310,16 +1310,16 @@ bool SpaceInfo::findClosingBracket(const Token* tok, const Token*& close) const //--------------------------------------------------------------------------- -const SpaceInfo *SymbolDatabase::findVarType(const SpaceInfo *start, const Token *type) const +const Scope *SymbolDatabase::findVariableType(const Scope *start, const Token *type) const { - std::list::const_iterator it; + std::list::const_iterator it; for (it = spaceInfoList.begin(); it != spaceInfoList.end(); ++it) { - const SpaceInfo *info = *it; + const Scope *info = *it; // skip namespaces and functions - if (info->type == SpaceInfo::Namespace || info->type == SpaceInfo::Function || info->type == SpaceInfo::Global) + if (info->type == Scope::eNamespace || info->type == Scope::eFunction || info->type == Scope::eGlobal) continue; // do the names match? @@ -1328,7 +1328,7 @@ const SpaceInfo *SymbolDatabase::findVarType(const SpaceInfo *start, const Token // check if type does not have a namespace if (type->previous()->str() != "::") { - const SpaceInfo *parent = start; + const Scope *parent = start; // check if in same namespace while (parent && parent != info->nestedIn) @@ -1352,9 +1352,9 @@ const SpaceInfo *SymbolDatabase::findVarType(const SpaceInfo *start, const Token //--------------------------------------------------------------------------- -SpaceInfo * SpaceInfo::findInNestedList(const std::string & name) +Scope * Scope::findInNestedList(const std::string & name) { - std::list::iterator it; + std::list::iterator it; for (it = nestedList.begin(); it != nestedList.end(); ++it) { @@ -1366,12 +1366,12 @@ SpaceInfo * SpaceInfo::findInNestedList(const std::string & name) //--------------------------------------------------------------------------- -const Func *SpaceInfo::getDestructor() const +const Function *Scope::getDestructor() const { - std::list::const_iterator it; + std::list::const_iterator it; for (it = functionList.begin(); it != functionList.end(); ++it) { - if (it->type == Func::Destructor) + if (it->type == Function::eDestructor) return &*it; } return 0; @@ -1379,13 +1379,13 @@ const Func *SpaceInfo::getDestructor() const //--------------------------------------------------------------------------- -unsigned int SpaceInfo::getNestedNonFunctions() const +unsigned int Scope::getNestedNonFunctions() const { unsigned int nested = 0; - std::list::const_iterator ni; + std::list::const_iterator ni; for (ni = nestedList.begin(); ni != nestedList.end(); ++ni) { - if ((*ni)->type != SpaceInfo::Function) + if ((*ni)->type != Scope::eFunction) nested++; } return nested; diff --git a/lib/symboldatabase.h b/lib/symboldatabase.h index f143dc159..3897b6952 100644 --- a/lib/symboldatabase.h +++ b/lib/symboldatabase.h @@ -31,7 +31,7 @@ class Tokenizer; class Settings; class ErrorLogger; -class SpaceInfo; +class Scope; class SymbolDatabase; /** @@ -40,10 +40,10 @@ class SymbolDatabase; enum AccessControl { Public, Protected, Private }; /** @brief Information about a member variable. */ -class Var +class Variable { public: - Var(const Token *token_, std::size_t index_, AccessControl access_, bool mutable_, bool static_, bool const_, bool class_, const SpaceInfo *type_) + Variable(const Token *token_, std::size_t index_, AccessControl access_, bool mutable_, bool static_, bool const_, bool class_, const Scope *type_) : token(token_), index(index_), access(access_), @@ -77,15 +77,15 @@ public: bool isClass; /** @brief pointer to user defined type info (for known types) */ - const SpaceInfo *type; + const Scope *type; }; -class Func +class Function { public: - enum Type { Constructor, CopyConstructor, OperatorEqual, Destructor, Function }; + enum Type { eConstructor, eCopyConstructor, eOperatorEqual, eDestructor, eFunction }; - Func() + Function() : tokenDef(NULL), argDef(NULL), token(NULL), @@ -101,7 +101,7 @@ public: isExplicit(false), isOperator(false), retFuncPtr(false), - type(Function) + type(eFunction) { } @@ -126,26 +126,29 @@ public: Type type; // constructor, destructor, ... }; -class SpaceInfo +class Scope { + // let tests access private function for testing + friend class TestSymbolDatabase; + public: struct BaseInfo { AccessControl access; // public/protected/private std::string name; - SpaceInfo *spaceInfo; + Scope *spaceInfo; }; struct FriendInfo { std::string name; - SpaceInfo *spaceInfo; + Scope *spaceInfo; }; - enum SpaceType { Global, Class, Struct, Union, Namespace, Function }; + enum SpaceType { eGlobal, eClass, eStruct, eUnion, eNamespace, eFunction }; enum NeedInitialization { Unknown, True, False }; - SpaceInfo(SymbolDatabase *check_, const Token *classDef_, SpaceInfo *nestedIn_); + Scope(SymbolDatabase *check_, const Token *classDef_, Scope *nestedIn_); SymbolDatabase *check; SpaceType type; @@ -153,37 +156,37 @@ public: const Token *classDef; // class/struct/union/namespace token const Token *classStart; // '{' token const Token *classEnd; // '}' token - std::list functionList; - std::list varlist; + std::list functionList; + std::list varlist; std::vector derivedFrom; std::list friendList; - SpaceInfo *nestedIn; - std::list nestedList; + Scope *nestedIn; + std::list nestedList; AccessControl access; unsigned int numConstructors; NeedInitialization needInitialization; - SpaceInfo * functionOf; // class/struct this function belongs to + Scope * functionOf; // class/struct this function belongs to bool isClassOrStruct() const { - return (type == Class || type == Struct); + return (type == eClass || type == eStruct); } /** * @brief find if name is in nested list * @param name name of nested space */ - SpaceInfo * findInNestedList(const std::string & name); + Scope * findInNestedList(const std::string & name); - void addVar(const Token *token_, AccessControl access_, bool mutable_, bool static_, bool const_, bool class_, const SpaceInfo *type_) + void addVariable(const Token *token_, AccessControl access_, bool mutable_, bool static_, bool const_, bool class_, const Scope *type_) { - varlist.push_back(Var(token_, varlist.size(), access_, mutable_, static_, const_, class_, type_)); + varlist.push_back(Variable(token_, varlist.size(), access_, mutable_, static_, const_, class_, type_)); } /** @brief initialize varlist */ - void getVarList(); + void getVariableList(); - const Func *getDestructor() const; + const Function *getDestructor() const; /** * @brief get the number of nested spaces that are not functions @@ -197,7 +200,7 @@ public: private: /** - * @brief helper function for getVarList() + * @brief helper function for getVariableList() * @param tok pointer to token to check * @param vartok populated with pointer to the variable token, if found * @param typetok populated with pointer to the type token, if found @@ -216,7 +219,7 @@ public: ~SymbolDatabase(); /** @brief Information about all namespaces/classes/structrues */ - std::list spaceInfoList; + std::list spaceInfoList; /** * @brief find a variable type if it's a user defined type @@ -224,9 +227,9 @@ public: * @param type token containing variable type * @return pointer to type if found or NULL if not found */ - const SpaceInfo *findVarType(const SpaceInfo *start, const Token *type) const; + const Scope *findVariableType(const Scope *start, const Token *type) const; - bool argsMatch(const SpaceInfo *info, const Token *first, const Token *second, const std::string &path, unsigned int depth) const; + bool argsMatch(const Scope *info, const Token *first, const Token *second, const std::string &path, unsigned int depth) const; bool isClassOrStruct(const std::string &type) const { @@ -236,11 +239,11 @@ public: private: // Needed by Borland C++: - friend class SpaceInfo; + friend class Scope; - void addFunction(SpaceInfo **info, const Token **tok, const Token *argStart); - void addNewFunction(SpaceInfo **info, const Token **tok); - const Token *initBaseInfo(SpaceInfo *info, const Token *tok); + void addFunction(Scope **info, const Token **tok, const Token *argStart); + void addNewFunction(Scope **info, const Token **tok); + const Token *initBaseInfo(Scope *info, const Token *tok); bool isFunction(const Token *tok, const Token **funcStart, const Token **argStart) const; /** class/struct types */ diff --git a/lib/tokenize.cpp b/lib/tokenize.cpp index 1eee6c69f..bbc54c538 100644 --- a/lib/tokenize.cpp +++ b/lib/tokenize.cpp @@ -7954,16 +7954,16 @@ const Token *Tokenizer::getFunctionTokenByName(const char funcname[]) const if (_symbolDatabase == NULL) getSymbolDatabase(); - std::list::const_iterator i; + std::list::const_iterator i; for (i = _symbolDatabase->spaceInfoList.begin(); i != _symbolDatabase->spaceInfoList.end(); ++i) { - const SpaceInfo *info = *i; + const Scope *scope = *i; - if (info->type == SpaceInfo::Function) + if (scope->type == Scope::eFunction) { - if (info->classDef->str() == funcname) - return info->classDef; + if (scope->classDef->str() == funcname) + return scope->classDef; } } return NULL; diff --git a/test/testsymboldatabase.cpp b/test/testsymboldatabase.cpp index 68b565276..d9e0956d3 100644 --- a/test/testsymboldatabase.cpp +++ b/test/testsymboldatabase.cpp @@ -18,7 +18,6 @@ #include "testsuite.h" #include "testutils.h" -#define private public #include "symboldatabase.h" class TestSymbolDatabase: public TestFixture @@ -32,7 +31,7 @@ public: {} private: - const SpaceInfo si; + const Scope si; const Token* vartok; const Token* typetok; const Token* t; From 065e2e277e60051f8d5449b8a46edc657a702aa3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Mon, 17 Jan 2011 19:00:21 +0100 Subject: [PATCH 073/165] Fixed #2473 (False positive: Memory leak when there is local struct) --- lib/checkmemoryleak.cpp | 2 +- test/testmemleak.cpp | 6 ++++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/lib/checkmemoryleak.cpp b/lib/checkmemoryleak.cpp index a8b8e2c42..52b7607d2 100644 --- a/lib/checkmemoryleak.cpp +++ b/lib/checkmemoryleak.cpp @@ -921,7 +921,7 @@ Token *CheckMemoryLeakInFunction::getcode(const Token *tok, std::listvarId() == varid || - tok2->str() == ":") + tok2->str() == ":" || tok2->str() == "{") { break; } diff --git a/test/testmemleak.cpp b/test/testmemleak.cpp index cba61fb40..36978ff79 100644 --- a/test/testmemleak.cpp +++ b/test/testmemleak.cpp @@ -520,6 +520,12 @@ private: // ticket #2336: calling member function with same name as a white_list function ASSERT_EQUALS(";;use;", getcode("char *s; foo.write(s);", "s")); + + // #2473 - inner struct + ASSERT_EQUALS(";;alloc;{;;};dealloc;", + getcode("char *s = new char[10];\n" + "struct ab { int a, b; };\n" + "delete [] s;\n", "s")); } From b5020468f692a54b4db8be6079588eaeab3d3a36 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Mon, 17 Jan 2011 19:23:00 +0100 Subject: [PATCH 074/165] Fixed #2467 (false positive: possible nullptr dereference) --- lib/checknullpointer.cpp | 21 +++++++++++++++++++++ lib/checknullpointer.h | 3 +++ lib/checkuninitvar.cpp | 16 ++-------------- test/testnullpointer.cpp | 9 +++++++++ 4 files changed, 35 insertions(+), 14 deletions(-) diff --git a/lib/checknullpointer.cpp b/lib/checknullpointer.cpp index e5f03cdf2..eb9c38f71 100644 --- a/lib/checknullpointer.cpp +++ b/lib/checknullpointer.cpp @@ -32,6 +32,16 @@ CheckNullPointer instance; //--------------------------------------------------------------------------- +/** Is string uppercase? */ +bool CheckNullPointer::isUpper(const std::string &str) +{ + for (unsigned int i = 0; i < str.length(); ++i) + { + if (str[i] >= 'a' && str[i] <= 'z') + return false; + } + return true; +} /** * @brief parse a function call and extract information about variable usage @@ -526,6 +536,17 @@ void CheckNullPointer::nullPointerByCheckAndDeRef() // - if there are logical operators // - if (x) { } else { ... } + // If the if-body ends with a unknown macro then bailout + { + // goto the end paranthesis + const Token *endpar = tok->next()->link(); + const Token *endbody = endpar ? endpar->next()->link() : 0; + if (endbody && + Token::Match(endbody->tokAt(-3), "[;{}] %var% ;") && + isUpper(endbody->tokAt(-2)->str())) + continue; + } + // vartok : token for the variable const Token *vartok = 0; if (Token::Match(tok, "if ( ! %var% ) {")) diff --git a/lib/checknullpointer.h b/lib/checknullpointer.h index 70927e70f..c1b134e91 100644 --- a/lib/checknullpointer.h +++ b/lib/checknullpointer.h @@ -60,6 +60,9 @@ public: checkNullPointer.executionPaths(); } + /** Is string uppercase? */ + static bool isUpper(const std::string &str); + /** * @brief parse a function call and extract information about variable usage * @param tok first token diff --git a/lib/checkuninitvar.cpp b/lib/checkuninitvar.cpp index 62b1ac33e..c1f5f28e6 100644 --- a/lib/checkuninitvar.cpp +++ b/lib/checkuninitvar.cpp @@ -33,18 +33,6 @@ CheckUninitVar instance; //--------------------------------------------------------------------------- -/** Is string uppercase? */ -static bool isUpper(const std::string &str) -{ - for (unsigned int i = 0; i < str.length(); ++i) - { - if (str[i] >= 'a' && str[i] <= 'z') - return false; - } - return true; -} - - /// @addtogroup Checks /// @{ @@ -679,7 +667,7 @@ private: } // ticket #2367 : unexpanded macro that uses sizeof|typeof? - else if (Token::Match(tok2, "%type% (") && isUpper(tok2->str())) + else if (Token::Match(tok2, "%type% (") && CheckNullPointer::isUpper(tok2->str())) { tok2 = tok2->next()->link(); if (!tok2) @@ -703,7 +691,7 @@ private: functionCall = functionCall ? functionCall->previous() : 0; if (functionCall) { - if (functionCall->isName() && !isUpper(functionCall->str()) && use_dead_pointer(checks, tok2)) + if (functionCall->isName() && !CheckNullPointer::isUpper(functionCall->str()) && use_dead_pointer(checks, tok2)) ExecutionPath::bailOutVar(checks, tok2->varId()); } } diff --git a/test/testnullpointer.cpp b/test/testnullpointer.cpp index cd485e920..81263f9ce 100644 --- a/test/testnullpointer.cpp +++ b/test/testnullpointer.cpp @@ -859,6 +859,15 @@ private: " *p = 0;\n" "}\n"); ASSERT_EQUALS("[test.cpp:5]: (error) Possible null pointer dereference: p\n", errout.str()); + + // #2467 - unknown macro may terminate the application + check("void f(Fred *fred) {\n" + " if (fred == NULL) {\n" + " MACRO;\n" + " }\n" + " fred->a();\n" + "}"); + ASSERT_EQUALS("", errout.str()); } // Test CheckNullPointer::nullConstantDereference From 6dd16d391974c74ea5b3664b19abe08fdc00b385 Mon Sep 17 00:00:00 2001 From: Kimmo Varis Date: Mon, 17 Jan 2011 21:03:22 +0200 Subject: [PATCH 075/165] Fix crash when giving -D without argument. Fixes ticket #2476 (Crash when -D used without parameters.) --- cli/cmdlineparser.cpp | 24 ++++++++++++++++++++---- test/testcmdlineparser.cpp | 10 ++++++++++ 2 files changed, 30 insertions(+), 4 deletions(-) diff --git a/cli/cmdlineparser.cpp b/cli/cmdlineparser.cpp index 50a65992d..ebf6b6059 100644 --- a/cli/cmdlineparser.cpp +++ b/cli/cmdlineparser.cpp @@ -225,12 +225,28 @@ bool CmdLineParser::ParseFromArgs(int argc, const char* const argv[]) // User define else if (strncmp(argv[i], "-D", 2) == 0) { + std::string define; + + // "-D define" + if (strcmp(argv[i], "-D") == 0) + { + ++i; + if (i >= argc) + { + PrintMessage("cppcheck: argument to '-D' is missing"); + return false; + } + define = argv[i]; + } + // "-Ddefine" + else + { + define = 2 + argv[i]; + } + if (!_settings->userDefines.empty()) _settings->userDefines += ";"; - if (strcmp(argv[i], "-D") == 0) - _settings->userDefines += argv[++i]; - else - _settings->userDefines += 2 + argv[i]; + _settings->userDefines += define; } // Include paths diff --git a/test/testcmdlineparser.cpp b/test/testcmdlineparser.cpp index 3caba1749..2a979ab9a 100644 --- a/test/testcmdlineparser.cpp +++ b/test/testcmdlineparser.cpp @@ -46,6 +46,7 @@ private: TEST_CASE(forcelong); TEST_CASE(quietshort); TEST_CASE(quietlong); + TEST_CASE(defines_noarg); TEST_CASE(defines); TEST_CASE(defines2); TEST_CASE(defines3); @@ -230,6 +231,15 @@ private: ASSERT_EQUALS(true, settings._errorsOnly); } + void defines_noarg() + { + REDIRECT; + const char *argv[] = {"cppcheck", "-D"}; + Settings settings; + CmdLineParser parser(&settings); + ASSERT_EQUALS(false, parser.ParseFromArgs(2, argv)); + } + void defines() { REDIRECT; From bd5e9e530984fa2993cd4de5284a16ae3ec00401 Mon Sep 17 00:00:00 2001 From: Kimmo Varis Date: Mon, 17 Jan 2011 21:19:27 +0200 Subject: [PATCH 076/165] Improve checking -D arguments for command line. --- cli/cmdlineparser.cpp | 4 +++- test/testcmdlineparser.cpp | 20 ++++++++++++++++++++ 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/cli/cmdlineparser.cpp b/cli/cmdlineparser.cpp index ebf6b6059..baeb26cbf 100644 --- a/cli/cmdlineparser.cpp +++ b/cli/cmdlineparser.cpp @@ -231,11 +231,13 @@ bool CmdLineParser::ParseFromArgs(int argc, const char* const argv[]) if (strcmp(argv[i], "-D") == 0) { ++i; - if (i >= argc) + if (i >= argc || strncmp(argv[i], "-", 1) == 0 || + strncmp(argv[i], "--", 2) == 0) { PrintMessage("cppcheck: argument to '-D' is missing"); return false; } + define = argv[i]; } // "-Ddefine" diff --git a/test/testcmdlineparser.cpp b/test/testcmdlineparser.cpp index 2a979ab9a..a0a29cbd6 100644 --- a/test/testcmdlineparser.cpp +++ b/test/testcmdlineparser.cpp @@ -47,6 +47,8 @@ private: TEST_CASE(quietshort); TEST_CASE(quietlong); TEST_CASE(defines_noarg); + TEST_CASE(defines_noarg2); + TEST_CASE(defines_noarg3); TEST_CASE(defines); TEST_CASE(defines2); TEST_CASE(defines3); @@ -240,6 +242,24 @@ private: ASSERT_EQUALS(false, parser.ParseFromArgs(2, argv)); } + void defines_noarg2() + { + REDIRECT; + const char *argv[] = {"cppcheck", "-D", "-v", "file.cpp"}; + Settings settings; + CmdLineParser parser(&settings); + ASSERT_EQUALS(false, parser.ParseFromArgs(4, argv)); + } + + void defines_noarg3() + { + REDIRECT; + const char *argv[] = {"cppcheck", "-D", "--quiet", "file.cpp"}; + Settings settings; + CmdLineParser parser(&settings); + ASSERT_EQUALS(false, parser.ParseFromArgs(4, argv)); + } + void defines() { REDIRECT; From 965c1a94fd039b4916d14000003719fc45d84802 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Mon, 17 Jan 2011 20:51:15 +0100 Subject: [PATCH 077/165] Fixed #2475 (False positive in structure initialisation: The scope of the variable bits can be reduced) --- lib/checkother.cpp | 12 +++++++++++- test/testother.cpp | 24 ++++++++++++++++++++++++ 2 files changed, 35 insertions(+), 1 deletion(-) diff --git a/lib/checkother.cpp b/lib/checkother.cpp index 768f8b63c..33465af8b 100644 --- a/lib/checkother.cpp +++ b/lib/checkother.cpp @@ -2008,7 +2008,17 @@ void CheckOther::lookupVar(const Token *tok1, const std::string &varname) { if (tok->str() == "{") { - ++indentlevel; + if (tok->strAt(-1) == "=") + { + if (Token::findmatch(tok, varname.c_str(), tok->link())) + { + return; + } + + tok = tok->link(); + } + else + ++indentlevel; } else if (tok->str() == "}") diff --git a/test/testother.cpp b/test/testother.cpp index 35e4e5e2a..935c7df32 100644 --- a/test/testother.cpp +++ b/test/testother.cpp @@ -58,6 +58,7 @@ private: TEST_CASE(varScope8); TEST_CASE(varScope9); // classes may have extra side-effects TEST_CASE(varScope10); // Undefined macro FOR + TEST_CASE(varScope11); // #2475 - struct initialization is not inner scope TEST_CASE(oldStylePointerCast); @@ -576,6 +577,29 @@ private: ASSERT_EQUALS("", errout.str()); } + void varScope11() + { + varScope("int f() {\n" + " int x = 0;\n" + " AB ab = { x, 0 };\n" + "}\n"); + ASSERT_EQUALS("", errout.str()); + + varScope("int f() {\n" + " int x = 0;\n" + " if (a == 0) { ++x; }\n" + " AB ab = { x, 0 };\n" + "}\n"); + ASSERT_EQUALS("", errout.str()); + + varScope("int f() {\n" + " int x = 0;\n" + " if (a == 0) { ++x; }\n" + " if (a == 1) { AB ab = { x, 0 }; }\n" + "}\n"); + ASSERT_EQUALS("", errout.str()); + } + void checkOldStylePointerCast(const char code[]) { From c994508c3eec7d2206d20f7163361db024e65d2d Mon Sep 17 00:00:00 2001 From: Robert Reif Date: Tue, 18 Jan 2011 07:32:06 +0100 Subject: [PATCH 078/165] Symbol database: Refactor the variables API. ticket: #2468 --- lib/checkclass.cpp | 26 +++--- lib/checkmemoryleak.cpp | 20 ++--- lib/symboldatabase.cpp | 8 +- lib/symboldatabase.h | 189 ++++++++++++++++++++++++++++++++++------ 4 files changed, 188 insertions(+), 55 deletions(-) diff --git a/lib/checkclass.cpp b/lib/checkclass.cpp index 56b0eaa5a..c95ddc43a 100644 --- a/lib/checkclass.cpp +++ b/lib/checkclass.cpp @@ -85,7 +85,7 @@ void CheckClass::constructors() std::list::const_iterator var; for (var = scope->varlist.begin(); var != scope->varlist.end(); ++var) { - if (var->access == Private && !var->isClass && !var->isStatic) + if (var->isPrivate() && !var->isClass() && !var->isStatic()) { noConstructorError(scope->classDef, scope->className, scope->classDef->str() == "struct"); break; @@ -114,22 +114,22 @@ void CheckClass::constructors() unsigned int count = 0; for (var = scope->varlist.begin(); var != scope->varlist.end(); ++var, ++count) { - if (usage[count].assign || usage[count].init || var->isStatic) + if (usage[count].assign || usage[count].init || var->isStatic()) continue; - if (var->isConst && var->token->previous()->str() != "*") + if (var->isConst() && var->nameToken()->previous()->str() != "*") continue; // Check if this is a class constructor - if (var->isClass && func->type == Function::eConstructor) + if (var->isClass() && func->type == Function::eConstructor) { // Unknown type so assume it is initialized - if (!var->type) + if (!var->type()) continue; // Known type that doesn't need initialization or // known type that has member variables of an unknown type - else if (var->type->needInitialization != Scope::True) + else if (var->type()->needInitialization != Scope::True) continue; } @@ -153,10 +153,10 @@ void CheckClass::constructors() } if (classNameUsed) - operatorEqVarError(func->token, scope->className, var->token->str()); + operatorEqVarError(func->token, scope->className, var->name()); } else if (func->access != Private) - uninitVarError(func->token, scope->className, var->token->str()); + uninitVarError(func->token, scope->className, var->name()); } } } @@ -169,7 +169,7 @@ void CheckClass::assignVar(const std::string &varname, const Scope *scope, std:: for (var = scope->varlist.begin(); var != scope->varlist.end(); ++var, ++count) { - if (var->token->str() == varname) + if (var->name() == varname) { usage[count].assign = true; return; @@ -184,7 +184,7 @@ void CheckClass::initVar(const std::string &varname, const Scope *scope, std::ve for (var = scope->varlist.begin(); var != scope->varlist.end(); ++var, ++count) { - if (var->token->str() == varname) + if (var->name() == varname) { usage[count].init = true; return; @@ -305,7 +305,7 @@ void CheckClass::initializeVarList(const Function &func, std::list std::list::const_iterator var; for (var = scope->varlist.begin(); var != scope->varlist.end(); ++var) { - if (var->token->varId() == ftok->next()->varId()) + if (var->varId() == ftok->next()->varId()) { /** @todo false negative: we assume function changes variable state */ assignVar(ftok->next()->str(), scope, usage); @@ -1403,9 +1403,9 @@ bool CheckClass::isMemberVar(const Scope *scope, const Token *tok) std::list::const_iterator var; for (var = scope->varlist.begin(); var != scope->varlist.end(); ++var) { - if (var->token->str() == tok->str()) + if (var->name() == tok->str()) { - return !var->isMutable; + return !var->isMutable(); } } diff --git a/lib/checkmemoryleak.cpp b/lib/checkmemoryleak.cpp index 52b7607d2..97b63c4ef 100644 --- a/lib/checkmemoryleak.cpp +++ b/lib/checkmemoryleak.cpp @@ -2713,27 +2713,27 @@ void CheckMemoryLeakInClass::check() std::list::const_iterator var; for (var = scope->varlist.begin(); var != scope->varlist.end(); ++var) { - if (!var->isStatic && var->token->previous()->str() == "*") + if (!var->isStatic() && var->nameToken()->previous()->str() == "*") { // allocation but no deallocation of private variables in public function.. - if (var->token->tokAt(-2)->isStandardType()) + if (var->nameToken()->tokAt(-2)->isStandardType()) { - if (var->access == Private) - checkPublicFunctions(scope, var->token); + if (var->isPrivate()) + checkPublicFunctions(scope, var->nameToken()); - variable(scope, var->token); + variable(scope, var->nameToken()); } // known class? - else if (var->type) + else if (var->type()) { // not derived and no constructor? - if (var->type->derivedFrom.empty() && var->type->numConstructors == 0) + if (var->type()->derivedFrom.empty() && var->type()->numConstructors == 0) { - if (var->access == Private) - checkPublicFunctions(scope, var->token); + if (var->isPrivate()) + checkPublicFunctions(scope, var->nameToken()); - variable(scope, var->token); + variable(scope, var->nameToken()); } } } diff --git a/lib/symboldatabase.cpp b/lib/symboldatabase.cpp index d10e64a48..366aa20ff 100644 --- a/lib/symboldatabase.cpp +++ b/lib/symboldatabase.cpp @@ -448,14 +448,14 @@ SymbolDatabase::SymbolDatabase(const Tokenizer *tokenizer, const Settings *setti std::list::const_iterator var; for (var = info->varlist.begin(); var != info->varlist.end(); ++var) { - if (var->isClass) + if (var->isClass()) { - if (var->type) + if (var->type()) { // does this type need initialization? - if (var->type->needInitialization == Scope::True) + if (var->type()->needInitialization == Scope::True) needInitialization = true; - else if (var->type->needInitialization == Scope::Unknown) + else if (var->type()->needInitialization == Scope::Unknown) unknown = true; } } diff --git a/lib/symboldatabase.h b/lib/symboldatabase.h index 3897b6952..9f692abec 100644 --- a/lib/symboldatabase.h +++ b/lib/symboldatabase.h @@ -26,7 +26,8 @@ #include #include -class Token; +#include "token.h" + class Tokenizer; class Settings; class ErrorLogger; @@ -35,49 +36,181 @@ class Scope; class SymbolDatabase; /** - * @brief Access control. + * @brief Access control enumerations. */ enum AccessControl { Public, Protected, Private }; /** @brief Information about a member variable. */ class Variable { -public: - Variable(const Token *token_, std::size_t index_, AccessControl access_, bool mutable_, bool static_, bool const_, bool class_, const Scope *type_) - : token(token_), - index(index_), - access(access_), - isMutable(mutable_), - isStatic(static_), - isConst(const_), - isClass(class_), - type(type_) + /** @brief flags mask used to access specific bit. */ + enum { + fIsMutable = (1 << 0), /** @brief mutable variable */ + fIsStatic = (1 << 1), /** @brief static variable */ + fIsConst = (1 << 2), /** @brief const variable */ + fIsClass = (1 << 3) /** @brief user defined type */ + }; + + /** + * Get specified flag state. + * @param flag_ flag to get state of + * @return true if flag set or false in flag not set + */ + bool getFlag(int flag_) const + { + return bool(_flags & flag_); } - /** @brief variable token */ - const Token *token; + /** + * Set specified flag state. + * @param flag_ flag to set state + * @param state_ new state of flag + */ + void setFlag(int flag_, bool state_) + { + _flags = state_ ? _flags | flag_ : _flags & ~flag_; + } + +public: + Variable(const Token *name_, std::size_t index_, AccessControl access_, + bool mutable_, bool static_, bool const_, bool class_, + const Scope *type_) + : _name(name_), + _index(index_), + _access(access_), + _flags(0), + _type(type_) + { + setFlag(fIsMutable, mutable_); + setFlag(fIsStatic, static_); + setFlag(fIsConst, const_); + setFlag(fIsClass, class_); + } + + /** + * Get name token. + * @return name token + */ + const Token *nameToken() const + { + return _name; + } + + /** + * Get name string. + * @return name string + */ + const std::string &name() const + { + return _name->str(); + } + + /** + * Get variable ID. + * @return variable ID + */ + unsigned int varId() const + { + return _name->varId(); + } + + /** + * Get index of variable in declared order. + * @return varaible index + */ + std::size_t index() const + { + return _index; + } + + /** + * Is variable public. + * @return true if public, false if not + */ + bool isPublic() const + { + return _access == Public; + } + + /** + * Is variable protected. + * @return true if protected, false if not + */ + bool isProtected() const + { + return _access == Protected; + } + + /** + * Is variable private. + * @return true if private, false if not + */ + bool isPrivate() const + { + return _access == Private; + } + + /** + * Is variable mutable. + * @return true if mutable, false if not + */ + bool isMutable() const + { + return getFlag(fIsMutable); + } + + /** + * Is variable static. + * @return true if static, false if not + */ + bool isStatic() const + { + return getFlag(fIsStatic); + } + + /** + * Is variable const. + * @return true if const, false if not + */ + bool isConst() const + { + return getFlag(fIsConst); + } + + /** + * Is variable a user defined (or unknown) type. + * @return true if user defined type, false if not + */ + bool isClass() const + { + return getFlag(fIsClass); + } + + /** + * Get Scope pointer of known type. + * @return pointer to type if known, NULL if not known + */ + const Scope *type() const + { + return _type; + } + +private: + /** @brief variable name token */ + const Token *_name; /** @brief order declared */ - std::size_t index; + std::size_t _index; /** @brief what section is this variable declared in? */ - AccessControl access; // public/protected/private + AccessControl _access; // public/protected/private - /** @brief is this variable mutable? */ - bool isMutable; - - /** @brief is this variable static? */ - bool isStatic; - - /** @brief is this variable const? */ - bool isConst; - - /** @brief is this variable a class (or unknown type)? */ - bool isClass; + /** @brief flags */ + int _flags; /** @brief pointer to user defined type info (for known types) */ - const Scope *type; + const Scope *_type; }; class Function From 8631ee65a3586fd59a13156e96e0daa348807a90 Mon Sep 17 00:00:00 2001 From: Robert Reif Date: Tue, 18 Jan 2011 07:34:11 +0100 Subject: [PATCH 079/165] Fixed #2474 (false positive: Member variable 'A::m_SemVar' is not initialised in the constructor.) --- lib/checkclass.cpp | 21 +++++++++++++++++ lib/checkclass.h | 2 ++ test/testconstructors.cpp | 47 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 70 insertions(+) diff --git a/lib/checkclass.cpp b/lib/checkclass.cpp index c95ddc43a..c85acc311 100644 --- a/lib/checkclass.cpp +++ b/lib/checkclass.cpp @@ -133,6 +133,10 @@ void CheckClass::constructors() continue; } + // Check if type can't be copied + if (var->type && canNotCopy(var->type)) + continue; + // It's non-static and it's not initialized => error if (func->type == Function::eOperatorEqual) { @@ -162,6 +166,23 @@ void CheckClass::constructors() } } +bool CheckClass::canNotCopy(const Scope *scope) const +{ + std::list::const_iterator func; + bool privateAssign = false; + bool privateCopy = false; + + for (func = scope->functionList.begin(); func != scope->functionList.end(); ++func) + { + if (func->type == Function::eCopyConstructor && func->access == Private) + privateCopy = true; + else if (func->type == Function::eOperatorEqual && func->access == Private) + privateAssign = true; + } + + return privateAssign && privateCopy; +} + void CheckClass::assignVar(const std::string &varname, const Scope *scope, std::vector &usage) { std::list::const_iterator var; diff --git a/lib/checkclass.h b/lib/checkclass.h index 1fa99d1b9..dd5f15883 100644 --- a/lib/checkclass.h +++ b/lib/checkclass.h @@ -227,6 +227,8 @@ private: * @param usage reference to usage vector */ void initializeVarList(const Function &func, std::list &callstack, const Scope *scope, std::vector &usage); + + bool canNotCopy(const Scope *scope) const; }; /// @} //--------------------------------------------------------------------------- diff --git a/test/testconstructors.cpp b/test/testconstructors.cpp index 826baff02..ba5e90b31 100644 --- a/test/testconstructors.cpp +++ b/test/testconstructors.cpp @@ -76,6 +76,7 @@ private: TEST_CASE(initvar_private_constructor); // BUG 2354171 - private constructor TEST_CASE(initvar_copy_constructor); // ticket #1611 TEST_CASE(initvar_nested_constructor); // ticket #1375 + TEST_CASE(initvar_nocopy); // ticket #2474 TEST_CASE(initvar_destructor); // No variables need to be initialized in a destructor @@ -905,6 +906,52 @@ private: "[test.cpp:24]: (warning) Member variable 'D::d' is not initialised in the constructor.\n", errout.str()); } + void initvar_nocopy() // ticket #2474 + { + check("class B\n" + "{\n" + " B (const B & Var);\n" + " B & operator= (const B & Var);\n" + "};\n" + "class A\n" + "{\n" + " B m_SemVar;\n" + "public:\n" + " A(){}\n" + " A(const A&){}\n" + " const A& operator=(const A&){return *this;}\n" + "};\n"); + ASSERT_EQUALS("", errout.str()); + + check("class B\n" + "{\n" + "public:\n" + " B (const B & Var);\n" + " B & operator= (const B & Var);\n" + "};\n" + "class A\n" + "{\n" + " B m_SemVar;\n" + "public:\n" + " A(){}\n" + " A(const A&){}\n" + " const A& operator=(const A&){return *this;}\n" + "};\n"); + ASSERT_EQUALS("[test.cpp:12]: (warning) Member variable 'A::m_SemVar' is not initialised in the constructor.\n" + "[test.cpp:13]: (warning) Member variable 'A::m_SemVar' is not assigned a value in 'A::operator='\n", errout.str()); + + check("class A\n" + "{\n" + " B m_SemVar;\n" + "public:\n" + " A(){}\n" + " A(const A&){}\n" + " const A& operator=(const A&){return *this;}\n" + "};\n"); + ASSERT_EQUALS("[test.cpp:6]: (warning) Member variable 'A::m_SemVar' is not initialised in the constructor.\n" + "[test.cpp:7]: (warning) Member variable 'A::m_SemVar' is not assigned a value in 'A::operator='\n", errout.str()); + } + void initvar_destructor() { check("class Fred\n" From 69d4db714ee43d89d7110101f945e59ea0915656 Mon Sep 17 00:00:00 2001 From: Pete Johns Date: Tue, 18 Jan 2011 18:29:42 +1100 Subject: [PATCH 080/165] Added TODO test cases for template variables with multiple levels of pointer indirection Following email from Robert Reif --- test/testsymboldatabase.cpp | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/test/testsymboldatabase.cpp b/test/testsymboldatabase.cpp index 98e80671e..b63cc4088 100644 --- a/test/testsymboldatabase.cpp +++ b/test/testsymboldatabase.cpp @@ -63,6 +63,7 @@ private: TEST_CASE(test_isVariableDeclarationIdentifiesArray); TEST_CASE(test_isVariableDeclarationIdentifiesOfArrayPointers); TEST_CASE(isVariableDeclarationIdentifiesTemplatedPointerVariable); + TEST_CASE(isVariableDeclarationIdentifiesTemplatedPointerToPointerVariable); TEST_CASE(isVariableDeclarationIdentifiesTemplatedVariable); TEST_CASE(isVariableDeclarationIdentifiesTemplatedVariableIterator); TEST_CASE(isVariableDeclarationIdentifiesNestedTemplateVariable); @@ -223,6 +224,22 @@ private: ASSERT_EQUALS("set", typetok->str()); } + void isVariableDeclarationIdentifiesTemplatedPointerToPointerVariable() + { + reset(); + givenACodeSampleToTokenize var("std::deque*** ints;"); + bool result = si.isVariableDeclaration(var.tokens(), vartok, typetok); + TODO_ASSERT_EQUALS(true, result); + if (NULL != vartok) + { + TODO_ASSERT_EQUALS("ints", vartok->str()); + } + if (NULL != typetok) + { + TODO_ASSERT_EQUALS("deque", typetok->str()); + } + } + void isVariableDeclarationIdentifiesTemplatedVariable() { reset(); From abfd90776389e8c8ea94cf1defb5416fedb7aec5 Mon Sep 17 00:00:00 2001 From: Pete Johns Date: Tue, 18 Jan 2011 20:14:12 +1100 Subject: [PATCH 081/165] Made isVariableDeclarationIdentifiesTemplatedPointerToPointerVariable() pass. And added isVariableDeclarationIdentifiesTemplatedArrayVariable() (passing) into the bargain. --- lib/symboldatabase.cpp | 21 +++++++++------------ test/testsymboldatabase.cpp | 23 ++++++++++++++--------- 2 files changed, 23 insertions(+), 21 deletions(-) diff --git a/lib/symboldatabase.cpp b/lib/symboldatabase.cpp index 31bf15a2a..ac7a63a8e 100644 --- a/lib/symboldatabase.cpp +++ b/lib/symboldatabase.cpp @@ -1236,24 +1236,21 @@ bool SymbolDatabase::SpaceInfo::isVariableDeclaration(const Token* tok, const To if (Token::Match(localTypeTok, "%type% < ")) { - const Token* closetok = NULL; - bool found = findClosingBracket(localTypeTok->next(), closetok); + const Token* closeTok = NULL; + bool found = findClosingBracket(localTypeTok->next(), closeTok); if (found) { - if (Token::Match(closetok, "> %var% ;")) + const Token* localVarTok = skipPointers(closeTok->next()); + + if (isSimpleVariable(localVarTok) || isArrayVariable(localVarTok)) { - vartok = closetok->next(); + vartok = localVarTok; typetok = localTypeTok; } - else if (Token::Match(closetok, "> * %var% ;")) + else if (Token::Match(closeTok, "> :: %type% %var% ;")) { - vartok = closetok->tokAt(2); - typetok = localTypeTok; - } - else if (Token::Match(closetok, "> :: %type% %var% ;")) - { - vartok = closetok->tokAt(3); - typetok = closetok->tokAt(2); + vartok = closeTok->tokAt(3); + typetok = closeTok->tokAt(2); } } } diff --git a/test/testsymboldatabase.cpp b/test/testsymboldatabase.cpp index b63cc4088..7f52f80d6 100644 --- a/test/testsymboldatabase.cpp +++ b/test/testsymboldatabase.cpp @@ -64,6 +64,7 @@ private: TEST_CASE(test_isVariableDeclarationIdentifiesOfArrayPointers); TEST_CASE(isVariableDeclarationIdentifiesTemplatedPointerVariable); TEST_CASE(isVariableDeclarationIdentifiesTemplatedPointerToPointerVariable); + TEST_CASE(isVariableDeclarationIdentifiesTemplatedArrayVariable); TEST_CASE(isVariableDeclarationIdentifiesTemplatedVariable); TEST_CASE(isVariableDeclarationIdentifiesTemplatedVariableIterator); TEST_CASE(isVariableDeclarationIdentifiesNestedTemplateVariable); @@ -229,15 +230,19 @@ private: reset(); givenACodeSampleToTokenize var("std::deque*** ints;"); bool result = si.isVariableDeclaration(var.tokens(), vartok, typetok); - TODO_ASSERT_EQUALS(true, result); - if (NULL != vartok) - { - TODO_ASSERT_EQUALS("ints", vartok->str()); - } - if (NULL != typetok) - { - TODO_ASSERT_EQUALS("deque", typetok->str()); - } + ASSERT_EQUALS(true, result); + ASSERT_EQUALS("ints", vartok->str()); + ASSERT_EQUALS("deque", typetok->str()); + } + + void isVariableDeclarationIdentifiesTemplatedArrayVariable() + { + reset(); + givenACodeSampleToTokenize var("std::deque ints[3];"); + bool result = si.isVariableDeclaration(var.tokens(), vartok, typetok); + ASSERT_EQUALS(true, result); + ASSERT_EQUALS("ints", vartok->str()); + ASSERT_EQUALS("deque", typetok->str()); } void isVariableDeclarationIdentifiesTemplatedVariable() From 62063aa250019030cf7b02395b70a1ffc1d4e2a5 Mon Sep 17 00:00:00 2001 From: Pete Johns Date: Tue, 18 Jan 2011 20:51:57 +1100 Subject: [PATCH 082/165] Refactored to remove code duplication. --- lib/symboldatabase.cpp | 26 +++++++++++--------------- 1 file changed, 11 insertions(+), 15 deletions(-) diff --git a/lib/symboldatabase.cpp b/lib/symboldatabase.cpp index ac7a63a8e..53e80315c 100644 --- a/lib/symboldatabase.cpp +++ b/lib/symboldatabase.cpp @@ -1233,6 +1233,7 @@ const Token* skipPointers(const Token* tok) bool SymbolDatabase::SpaceInfo::isVariableDeclaration(const Token* tok, const Token*& vartok, const Token*& typetok) const { const Token* localTypeTok = skipScopeIdentifiers(tok); + const Token* localVarTok = NULL; if (Token::Match(localTypeTok, "%type% < ")) { @@ -1240,29 +1241,24 @@ bool SymbolDatabase::SpaceInfo::isVariableDeclaration(const Token* tok, const To bool found = findClosingBracket(localTypeTok->next(), closeTok); if (found) { - const Token* localVarTok = skipPointers(closeTok->next()); + localVarTok = skipPointers(closeTok->next()); - if (isSimpleVariable(localVarTok) || isArrayVariable(localVarTok)) + if (Token::Match(localVarTok, ":: %type% %var% ;")) { - vartok = localVarTok; - typetok = localTypeTok; - } - else if (Token::Match(closeTok, "> :: %type% %var% ;")) - { - vartok = closeTok->tokAt(3); - typetok = closeTok->tokAt(2); + localTypeTok = localVarTok->next(); + localVarTok = localVarTok->tokAt(2); } } } else if (Token::Match(localTypeTok, "%type%")) { - const Token* localVarTok = skipPointers(localTypeTok->next()); + localVarTok = skipPointers(localTypeTok->next()); + } - if (isSimpleVariable(localVarTok) || isArrayVariable(localVarTok)) - { - vartok = localVarTok; - typetok = localTypeTok; - } + if (isSimpleVariable(localVarTok) || isArrayVariable(localVarTok)) + { + vartok = localVarTok; + typetok = localTypeTok; } return NULL != vartok; From ea01c04108052921e29b81b84b6497c8670f2107 Mon Sep 17 00:00:00 2001 From: Pete Johns Date: Tue, 18 Jan 2011 21:07:33 +1100 Subject: [PATCH 083/165] Added parenths to fix build breakage. --- lib/checkclass.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/checkclass.cpp b/lib/checkclass.cpp index c85acc311..180b8e9c3 100644 --- a/lib/checkclass.cpp +++ b/lib/checkclass.cpp @@ -134,7 +134,7 @@ void CheckClass::constructors() } // Check if type can't be copied - if (var->type && canNotCopy(var->type)) + if (var->type() && canNotCopy(var->type())) continue; // It's non-static and it's not initialized => error From 75767705c719a8b1a52b09985dff36a708e8ad9d Mon Sep 17 00:00:00 2001 From: Pete Johns Date: Tue, 18 Jan 2011 21:50:22 +1100 Subject: [PATCH 084/165] Added testDoesNotIdentifyCallback for #2480 TODO --- test/testunusedprivfunc.cpp | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/test/testunusedprivfunc.cpp b/test/testunusedprivfunc.cpp index d3474daa0..2257644e7 100644 --- a/test/testunusedprivfunc.cpp +++ b/test/testunusedprivfunc.cpp @@ -60,6 +60,7 @@ private: // #2407 - FP when called from operator() TEST_CASE(fp_operator); + TEST_CASE(testDoesNotIdentifyCallback); // #2480 } @@ -447,6 +448,35 @@ private: TODO_ASSERT_EQUALS("[test.cpp:8]: (style) Unused private function 'Fred::startListening'\n", errout.str()); ASSERT_EQUALS("", errout.str()); } + + void testDoesNotIdentifyCallback() + { + check("#include " + "void callback(void (*func)(int), int arg)" + "{" + " (*func)(arg);" + "}" + "class MountOperation" + "{" + " static void Completed(int i);" + "public:" + " MountOperation(int i);" + "};" + "void MountOperation::Completed(int i)" + "{" + " std::cerr << i << std::endl;" + "}" + "MountOperation::MountOperation(int i)" + "{" + " callback(MountOperation::Completed, i);" + "}" + "int main(void)" + "{" + " MountOperation aExample(10);" + "}" + ); + TODO_ASSERT_EQUALS("", errout.str()); + } }; REGISTER_TEST(TestUnusedPrivateFunction) From 86ac25456ec535d2434a938f54a6dea61b64f700 Mon Sep 17 00:00:00 2001 From: Kimmo Varis Date: Tue, 18 Jan 2011 18:34:28 +0200 Subject: [PATCH 085/165] Move sameFileName() method to Path class. Ticket #2445 (Move FileLister classes from LIB to CLI). Moving sameFileName() to Path allows moving FileLister* classes to CLI. --- lib/filelister.h | 9 --------- lib/filelister_unix.cpp | 13 ++----------- lib/filelister_unix.h | 2 -- lib/filelister_win32.cpp | 15 +-------------- lib/filelister_win32.h | 1 - lib/path.cpp | 17 +++++++++++++++++ lib/path.h | 9 +++++++++ lib/tokenize.cpp | 2 +- 8 files changed, 30 insertions(+), 38 deletions(-) diff --git a/lib/filelister.h b/lib/filelister.h index 40eef61ea..be4c60016 100644 --- a/lib/filelister.h +++ b/lib/filelister.h @@ -49,15 +49,6 @@ public: virtual void recursiveAddFiles(std::vector &filenames, const std::string &path) = 0; - /** - * @brief Compare filenames to see if they are the same. - * On Linux the comparison is case-sensitive. On Windows it is case-insensitive. - * @param fname1 one filename - * @param fname2 other filename - * @return true if the filenames match on the current platform - */ - virtual bool sameFileName(const std::string &fname1, const std::string &fname2) = 0; - /** * @brief Check if the file extension indicates that it's a source file. * Check if the file has source file extension: *.c;*.cpp;*.cxx;*.c++;*.cc;*.txx diff --git a/lib/filelister_unix.cpp b/lib/filelister_unix.cpp index 12d179910..ed6d12f4b 100644 --- a/lib/filelister_unix.cpp +++ b/lib/filelister_unix.cpp @@ -31,6 +31,7 @@ #ifndef _WIN32 +#include "path.h" #include "filelister.h" #include "filelister_unix.h" @@ -71,7 +72,7 @@ void FileListerUnix::recursiveAddFiles2(std::vector &relative, continue; } - if (sameFileName(path,filename) || FileListerUnix::acceptFile(filename)) + if (Path::sameFileName(path,filename) || FileListerUnix::acceptFile(filename)) { relative.push_back(filename); absolute.push_back(fname); @@ -93,16 +94,6 @@ void FileListerUnix::recursiveAddFiles(std::vector &filenames, cons recursiveAddFiles2(filenames, abs, path); } -bool FileListerUnix::sameFileName(const std::string &fname1, const std::string &fname2) -{ -#if defined(__linux__) || defined(__sun) - return bool(fname1 == fname2); -#endif -#ifdef __GNUC__ - return bool(strcasecmp(fname1.c_str(), fname2.c_str()) == 0); -#endif -} - bool FileListerUnix::isDirectory(const std::string &path) { bool ret = false; diff --git a/lib/filelister_unix.h b/lib/filelister_unix.h index 7fab425b4..f0b4e4c96 100644 --- a/lib/filelister_unix.h +++ b/lib/filelister_unix.h @@ -31,8 +31,6 @@ class FileListerUnix : public FileLister { public: virtual void recursiveAddFiles(std::vector &filenames, const std::string &path); - virtual bool sameFileName(const std::string &fname1, const std::string &fname2); -// virtual static bool acceptFile(const std::string &filename); virtual bool isDirectory(const std::string &path); private: #ifndef _WIN32 diff --git a/lib/filelister_win32.cpp b/lib/filelister_win32.cpp index 9581d3fd3..041613331 100644 --- a/lib/filelister_win32.cpp +++ b/lib/filelister_win32.cpp @@ -168,7 +168,7 @@ void FileListerWin32::recursiveAddFiles(std::vector &filenames, con // File // If recursive is not used, accept all files given by user - if (sameFileName(path,ansiFfd) || FileLister::acceptFile(ansiFfd)) + if (Path::sameFileName(path,ansiFfd) || FileLister::acceptFile(ansiFfd)) { const std::string nativename = Path::fromNativeSeparators(fname.str()); filenames.push_back(nativename); @@ -192,19 +192,6 @@ void FileListerWin32::recursiveAddFiles(std::vector &filenames, con } } -bool FileListerWin32::sameFileName(const std::string &fname1, const std::string &fname2) -{ -#ifdef __GNUC__ - return bool(strcasecmp(fname1.c_str(), fname2.c_str()) == 0); -#endif -#ifdef __BORLANDC__ - return bool(stricmp(fname1.c_str(), fname2.c_str()) == 0); -#endif -#ifdef _MSC_VER - return bool(_stricmp(fname1.c_str(), fname2.c_str()) == 0); -#endif -} - bool FileListerWin32::isDirectory(const std::string &path) { return (MyIsDirectory(path) != FALSE); diff --git a/lib/filelister_win32.h b/lib/filelister_win32.h index 2d6948145..4f89438bd 100644 --- a/lib/filelister_win32.h +++ b/lib/filelister_win32.h @@ -31,7 +31,6 @@ class FileListerWin32 : public FileLister { public: virtual void recursiveAddFiles(std::vector &filenames, const std::string &path); - virtual bool sameFileName(const std::string &fname1, const std::string &fname2); virtual bool isDirectory(const std::string &path); private: diff --git a/lib/path.cpp b/lib/path.cpp index cf8383116..6660e5089 100644 --- a/lib/path.cpp +++ b/lib/path.cpp @@ -19,6 +19,7 @@ #include #include #include +#include #include "path.h" std::string Path::toNativeSeparators(const std::string &path) @@ -97,3 +98,19 @@ std::string Path::simplifyPath(const char *originalPath) return oss.str(); } + +bool Path::sameFileName(const std::string &fname1, const std::string &fname2) +{ +#if defined(__linux__) || defined(__sun) + return bool(fname1 == fname2); +#endif +#ifdef __GNUC__ + return bool(strcasecmp(fname1.c_str(), fname2.c_str()) == 0); +#endif +#ifdef __BORLANDC__ + return bool(stricmp(fname1.c_str(), fname2.c_str()) == 0); +#endif +#ifdef _MSC_VER + return bool(_stricmp(fname1.c_str(), fname2.c_str()) == 0); +#endif +} diff --git a/lib/path.h b/lib/path.h index ce8143a29..2de7a1653 100644 --- a/lib/path.h +++ b/lib/path.h @@ -54,6 +54,15 @@ public: * @return simplified path */ static std::string simplifyPath(const char *originalPath); + + /** + * @brief Compare filenames to see if they are the same. + * On Linux the comparison is case-sensitive. On Windows it is case-insensitive. + * @param fname1 one filename + * @param fname2 other filename + * @return true if the filenames match on the current platform + */ + static bool sameFileName(const std::string &fname1, const std::string &fname2); }; /// @} diff --git a/lib/tokenize.cpp b/lib/tokenize.cpp index bbc54c538..9adc3d642 100644 --- a/lib/tokenize.cpp +++ b/lib/tokenize.cpp @@ -313,7 +313,7 @@ void Tokenizer::createTokens(std::istream &code) fileIndexes.push_back(FileIndex); for (unsigned int i = 0; i < _files.size(); i++) { - if (getFileLister()->sameFileName(_files[i].c_str(), line.c_str())) + if (Path::sameFileName(_files[i].c_str(), line.c_str())) { // Use this index foundOurfile = true; From b8b2e3fae937ce61f184f9db0c5b95c5ad0cb62a Mon Sep 17 00:00:00 2001 From: Kimmo Varis Date: Tue, 18 Jan 2011 19:37:15 +0200 Subject: [PATCH 086/165] Move filelister* to cli. Ticket #2445 (Move FileLister classes from LIB to CLI). --- Makefile | 42 +++++++++++++++---------------- cli/cli.pro | 8 +++++- {lib => cli}/filelister.cpp | 0 {lib => cli}/filelister.h | 0 {lib => cli}/filelister_unix.cpp | 0 {lib => cli}/filelister_unix.h | 0 {lib => cli}/filelister_win32.cpp | 0 {lib => cli}/filelister_win32.h | 0 lib/cppcheck.cpp | 2 -- lib/lib.pri | 6 ----- lib/tokenize.cpp | 1 - test/test.pro | 6 +++++ tools/Makefile | 2 +- tools/dmake.cpp | 8 +++--- 14 files changed, 39 insertions(+), 36 deletions(-) rename {lib => cli}/filelister.cpp (100%) rename {lib => cli}/filelister.h (100%) rename {lib => cli}/filelister_unix.cpp (100%) rename {lib => cli}/filelister_unix.h (100%) rename {lib => cli}/filelister_win32.cpp (100%) rename {lib => cli}/filelister_win32.h (100%) diff --git a/Makefile b/Makefile index a8f14bc2e..0085b6f90 100644 --- a/Makefile +++ b/Makefile @@ -37,9 +37,6 @@ LIBOBJ = lib/checkautovariables.o \ lib/cppcheck.o \ lib/errorlogger.o \ lib/executionpath.o \ - lib/filelister.o \ - lib/filelister_unix.o \ - lib/filelister_win32.o \ lib/mathlib.o \ lib/path.o \ lib/preprocessor.o \ @@ -51,6 +48,9 @@ LIBOBJ = lib/checkautovariables.o \ CLIOBJ = cli/cmdlineparser.o \ cli/cppcheckexecutor.o \ + cli/filelister.o \ + cli/filelister_unix.o \ + cli/filelister_win32.o \ cli/main.o \ cli/threadexecutor.o @@ -103,8 +103,8 @@ cppcheck: $(LIBOBJ) $(CLIOBJ) $(EXTOBJ) all: cppcheck testrunner -testrunner: $(TESTOBJ) $(LIBOBJ) $(EXTOBJ) cli/threadexecutor.o cli/cmdlineparser.o cli/cppcheckexecutor.o - $(CXX) $(CPPFLAGS) $(CXXFLAGS) -o testrunner $(TESTOBJ) $(LIBOBJ) $(EXTOBJ) -lpcre cli/threadexecutor.o cli/cmdlineparser.o cli/cppcheckexecutor.o $(LDFLAGS) +testrunner: $(TESTOBJ) $(LIBOBJ) $(EXTOBJ) cli/threadexecutor.o cli/cmdlineparser.o cli/cppcheckexecutor.o cli/filelister.o cli/filelister_unix.o + $(CXX) $(CPPFLAGS) $(CXXFLAGS) -o testrunner $(TESTOBJ) $(LIBOBJ) $(EXTOBJ) -lpcre cli/threadexecutor.o cli/cmdlineparser.o cli/filelister.o cli/filelister_unix.o $(LDFLAGS) test: all ./testrunner @@ -134,7 +134,7 @@ install: cppcheck ###### Build -lib/checkautovariables.o: lib/checkautovariables.cpp lib/checkautovariables.h lib/check.h lib/token.h lib/tokenize.h lib/settings.h lib/errorlogger.h +lib/checkautovariables.o: lib/checkautovariables.cpp lib/checkautovariables.h lib/check.h lib/token.h lib/tokenize.h lib/settings.h lib/errorlogger.h lib/symboldatabase.h $(CXX) $(CPPFLAGS) $(CXXFLAGS) -Ilib -c -o lib/checkautovariables.o lib/checkautovariables.cpp lib/checkbufferoverrun.o: lib/checkbufferoverrun.cpp lib/checkbufferoverrun.h lib/check.h lib/token.h lib/tokenize.h lib/settings.h lib/errorlogger.h lib/mathlib.h lib/executionpath.h @@ -170,7 +170,7 @@ lib/checkuninitvar.o: lib/checkuninitvar.cpp lib/checkuninitvar.h lib/check.h li lib/checkunusedfunctions.o: lib/checkunusedfunctions.cpp lib/checkunusedfunctions.h lib/check.h lib/token.h lib/tokenize.h lib/settings.h lib/errorlogger.h $(CXX) $(CPPFLAGS) $(CXXFLAGS) -Ilib -c -o lib/checkunusedfunctions.o lib/checkunusedfunctions.cpp -lib/cppcheck.o: lib/cppcheck.cpp lib/cppcheck.h lib/settings.h lib/errorlogger.h lib/checkunusedfunctions.h lib/check.h lib/token.h lib/tokenize.h lib/preprocessor.h lib/filelister.h lib/path.h lib/timer.h +lib/cppcheck.o: lib/cppcheck.cpp lib/cppcheck.h lib/settings.h lib/errorlogger.h lib/checkunusedfunctions.h lib/check.h lib/token.h lib/tokenize.h lib/preprocessor.h lib/path.h lib/timer.h $(CXX) $(CPPFLAGS) $(CXXFLAGS) -Ilib -c -o lib/cppcheck.o lib/cppcheck.cpp lib/errorlogger.o: lib/errorlogger.cpp lib/errorlogger.h lib/path.h lib/cppcheck.h lib/settings.h lib/checkunusedfunctions.h lib/check.h lib/token.h lib/tokenize.h @@ -179,15 +179,6 @@ lib/errorlogger.o: lib/errorlogger.cpp lib/errorlogger.h lib/path.h lib/cppcheck lib/executionpath.o: lib/executionpath.cpp lib/executionpath.h lib/token.h $(CXX) $(CPPFLAGS) $(CXXFLAGS) -Ilib -c -o lib/executionpath.o lib/executionpath.cpp -lib/filelister.o: lib/filelister.cpp lib/filelister.h lib/filelister_win32.h lib/filelister_unix.h - $(CXX) $(CPPFLAGS) $(CXXFLAGS) -Ilib -c -o lib/filelister.o lib/filelister.cpp - -lib/filelister_unix.o: lib/filelister_unix.cpp lib/filelister.h lib/filelister_unix.h - $(CXX) $(CPPFLAGS) $(CXXFLAGS) -Ilib -c -o lib/filelister_unix.o lib/filelister_unix.cpp - -lib/filelister_win32.o: lib/filelister_win32.cpp lib/filelister.h lib/filelister_win32.h lib/path.h - $(CXX) $(CPPFLAGS) $(CXXFLAGS) -Ilib -c -o lib/filelister_win32.o lib/filelister_win32.cpp - lib/mathlib.o: lib/mathlib.cpp lib/mathlib.h lib/tokenize.h $(CXX) $(CPPFLAGS) $(CXXFLAGS) -Ilib -c -o lib/mathlib.o lib/mathlib.cpp @@ -200,7 +191,7 @@ lib/preprocessor.o: lib/preprocessor.cpp lib/preprocessor.h lib/tokenize.h lib/t lib/settings.o: lib/settings.cpp lib/settings.h $(CXX) $(CPPFLAGS) $(CXXFLAGS) -Ilib -c -o lib/settings.o lib/settings.cpp -lib/symboldatabase.o: lib/symboldatabase.cpp lib/symboldatabase.h lib/tokenize.h lib/token.h lib/settings.h lib/errorlogger.h lib/check.h +lib/symboldatabase.o: lib/symboldatabase.cpp lib/symboldatabase.h lib/token.h lib/tokenize.h lib/settings.h lib/errorlogger.h lib/check.h $(CXX) $(CPPFLAGS) $(CXXFLAGS) -Ilib -c -o lib/symboldatabase.o lib/symboldatabase.cpp lib/timer.o: lib/timer.cpp lib/timer.h @@ -209,15 +200,24 @@ lib/timer.o: lib/timer.cpp lib/timer.h lib/token.o: lib/token.cpp lib/token.h lib/errorlogger.h lib/check.h lib/tokenize.h lib/settings.h $(CXX) $(CPPFLAGS) $(CXXFLAGS) -Ilib -c -o lib/token.o lib/token.cpp -lib/tokenize.o: lib/tokenize.cpp lib/tokenize.h lib/token.h lib/filelister.h lib/mathlib.h lib/settings.h lib/errorlogger.h lib/check.h lib/path.h lib/symboldatabase.h +lib/tokenize.o: lib/tokenize.cpp lib/tokenize.h lib/token.h lib/mathlib.h lib/settings.h lib/errorlogger.h lib/check.h lib/path.h lib/symboldatabase.h $(CXX) $(CPPFLAGS) $(CXXFLAGS) -Ilib -c -o lib/tokenize.o lib/tokenize.cpp -cli/cmdlineparser.o: cli/cmdlineparser.cpp lib/cppcheck.h lib/settings.h lib/errorlogger.h lib/checkunusedfunctions.h lib/check.h lib/token.h lib/tokenize.h lib/timer.h cli/cmdlineparser.h +cli/cmdlineparser.o: cli/cmdlineparser.cpp lib/cppcheck.h lib/settings.h lib/errorlogger.h lib/checkunusedfunctions.h lib/check.h lib/token.h lib/tokenize.h lib/timer.h cli/cmdlineparser.h lib/path.h $(CXX) $(CPPFLAGS) $(CXXFLAGS) -Ilib -Iexternals -c -o cli/cmdlineparser.o cli/cmdlineparser.cpp -cli/cppcheckexecutor.o: cli/cppcheckexecutor.cpp cli/cppcheckexecutor.h lib/errorlogger.h lib/settings.h lib/cppcheck.h lib/checkunusedfunctions.h lib/check.h lib/token.h lib/tokenize.h cli/threadexecutor.h cli/cmdlineparser.h lib/filelister.h +cli/cppcheckexecutor.o: cli/cppcheckexecutor.cpp cli/cppcheckexecutor.h lib/errorlogger.h lib/settings.h lib/cppcheck.h lib/checkunusedfunctions.h lib/check.h lib/token.h lib/tokenize.h cli/threadexecutor.h cli/cmdlineparser.h cli/filelister.h lib/path.h $(CXX) $(CPPFLAGS) $(CXXFLAGS) -Ilib -Iexternals -c -o cli/cppcheckexecutor.o cli/cppcheckexecutor.cpp +cli/filelister.o: cli/filelister.cpp cli/filelister.h cli/filelister_win32.h cli/filelister_unix.h + $(CXX) $(CPPFLAGS) $(CXXFLAGS) -Ilib -Iexternals -c -o cli/filelister.o cli/filelister.cpp + +cli/filelister_unix.o: cli/filelister_unix.cpp lib/path.h cli/filelister.h cli/filelister_unix.h + $(CXX) $(CPPFLAGS) $(CXXFLAGS) -Ilib -Iexternals -c -o cli/filelister_unix.o cli/filelister_unix.cpp + +cli/filelister_win32.o: cli/filelister_win32.cpp cli/filelister.h cli/filelister_win32.h lib/path.h + $(CXX) $(CPPFLAGS) $(CXXFLAGS) -Ilib -Iexternals -c -o cli/filelister_win32.o cli/filelister_win32.cpp + cli/main.o: cli/main.cpp cli/cppcheckexecutor.h lib/errorlogger.h lib/settings.h $(CXX) $(CPPFLAGS) $(CXXFLAGS) -Ilib -Iexternals -c -o cli/main.o cli/main.cpp @@ -257,7 +257,7 @@ test/testerrorlogger.o: test/testerrorlogger.cpp test/testsuite.h lib/errorlogge test/testexceptionsafety.o: test/testexceptionsafety.cpp lib/tokenize.h lib/checkexceptionsafety.h lib/check.h lib/token.h lib/settings.h lib/errorlogger.h test/testsuite.h test/redirect.h $(CXX) $(CPPFLAGS) $(CXXFLAGS) -Ilib -Icli -Iexternals -c -o test/testexceptionsafety.o test/testexceptionsafety.cpp -test/testfilelister_unix.o: test/testfilelister_unix.cpp test/testsuite.h lib/errorlogger.h test/redirect.h lib/filelister_unix.h lib/filelister.h +test/testfilelister_unix.o: test/testfilelister_unix.cpp test/testsuite.h lib/errorlogger.h test/redirect.h $(CXX) $(CPPFLAGS) $(CXXFLAGS) -Ilib -Icli -Iexternals -c -o test/testfilelister_unix.o test/testfilelister_unix.cpp test/testincompletestatement.o: test/testincompletestatement.cpp test/testsuite.h lib/errorlogger.h test/redirect.h lib/tokenize.h lib/checkother.h lib/check.h lib/token.h lib/settings.h diff --git a/cli/cli.pro b/cli/cli.pro index 4d44d00b8..85702b9fb 100644 --- a/cli/cli.pro +++ b/cli/cli.pro @@ -14,9 +14,15 @@ include($$PWD/../lib/lib.pri) SOURCES += main.cpp \ cppcheckexecutor.cpp \ cmdlineparser.cpp \ + filelister.cpp \ + filelister_unix.cpp \ + filelister_win32.cpp \ threadexecutor.cpp HEADERS += cppcheckexecutor.h \ - cmdlineparser.h \ + cmdlineparser.h \ + filelister.h \ + filelister_unix.h \ + filelister_win32.h \ threadexecutor.h CONFIG(release, debug|release) { diff --git a/lib/filelister.cpp b/cli/filelister.cpp similarity index 100% rename from lib/filelister.cpp rename to cli/filelister.cpp diff --git a/lib/filelister.h b/cli/filelister.h similarity index 100% rename from lib/filelister.h rename to cli/filelister.h diff --git a/lib/filelister_unix.cpp b/cli/filelister_unix.cpp similarity index 100% rename from lib/filelister_unix.cpp rename to cli/filelister_unix.cpp diff --git a/lib/filelister_unix.h b/cli/filelister_unix.h similarity index 100% rename from lib/filelister_unix.h rename to cli/filelister_unix.h diff --git a/lib/filelister_win32.cpp b/cli/filelister_win32.cpp similarity index 100% rename from lib/filelister_win32.cpp rename to cli/filelister_win32.cpp diff --git a/lib/filelister_win32.h b/cli/filelister_win32.h similarity index 100% rename from lib/filelister_win32.h rename to cli/filelister_win32.h diff --git a/lib/cppcheck.cpp b/lib/cppcheck.cpp index 471887fb1..62719d6c6 100644 --- a/lib/cppcheck.cpp +++ b/lib/cppcheck.cpp @@ -20,8 +20,6 @@ #include "preprocessor.h" // preprocessor. #include "tokenize.h" // <- Tokenizer -#include "filelister.h" - #include "check.h" #include "path.h" diff --git a/lib/lib.pri b/lib/lib.pri index 80fc8eebc..efdf88452 100644 --- a/lib/lib.pri +++ b/lib/lib.pri @@ -18,9 +18,6 @@ HEADERS += $${BASEPATH}check.h \ $${BASEPATH}cppcheck.h \ $${BASEPATH}errorlogger.h \ $${BASEPATH}executionpath.h \ - $${BASEPATH}filelister.h \ - $${BASEPATH}filelister_unix.h \ - $${BASEPATH}filelister_win32.h \ $${BASEPATH}mathlib.h \ $${BASEPATH}path.h \ $${BASEPATH}preprocessor.h \ @@ -45,9 +42,6 @@ SOURCES += $${BASEPATH}checkautovariables.cpp \ $${BASEPATH}cppcheck.cpp \ $${BASEPATH}errorlogger.cpp \ $${BASEPATH}executionpath.cpp \ - $${BASEPATH}filelister.cpp \ - $${BASEPATH}filelister_unix.cpp \ - $${BASEPATH}filelister_win32.cpp \ $${BASEPATH}mathlib.cpp \ $${BASEPATH}path.cpp \ $${BASEPATH}preprocessor.cpp \ diff --git a/lib/tokenize.cpp b/lib/tokenize.cpp index 9adc3d642..d20d1ac0d 100644 --- a/lib/tokenize.cpp +++ b/lib/tokenize.cpp @@ -24,7 +24,6 @@ #include "tokenize.h" #include "token.h" -#include "filelister.h" #include "mathlib.h" #include "settings.h" #include "errorlogger.h" diff --git a/test/test.pro b/test/test.pro index 89bd3c2e7..0196222ed 100644 --- a/test/test.pro +++ b/test/test.pro @@ -18,9 +18,15 @@ include(../lib/lib.pri) # cli/* SOURCES += ../cli/cmdlineparser.cpp \ ../cli/cppcheckexecutor.cpp \ + ../cli/filelister.cpp \ + ../cli/filelister_unix.cpp \ + ../cli/filelister_win32.cpp \ ../cli/threadexecutor.cpp HEADERS += ../cli/cmdlineparser.h \ ../cli/cppcheckexecutor.h \ + ../cli/filelister.h \ + ../cli/filelister_unix.h \ + ../cli/filelister_win32.h \ ../cli/threadexecutor.h # test/* diff --git a/tools/Makefile b/tools/Makefile index f51efddb0..1143837b4 100644 --- a/tools/Makefile +++ b/tools/Makefile @@ -5,6 +5,6 @@ errmsg: errmsg.cpp g++ -Wall -pedantic -o errmsg errmsg.cpp dmake: dmake.cpp - g++ -Wall -pedantic -o dmake dmake.cpp ../lib/filelister.cpp ../lib/filelister_unix.cpp + g++ -Wall -pedantic -o dmake -I../lib dmake.cpp ../cli/filelister.cpp ../cli/filelister_unix.cpp ../lib/path.cpp diff --git a/tools/dmake.cpp b/tools/dmake.cpp index cae23376e..182a82c07 100644 --- a/tools/dmake.cpp +++ b/tools/dmake.cpp @@ -25,9 +25,9 @@ #include #if defined(_WIN32) -#include "../lib/fileLister_win32.h" +#include "../cli/fileLister_win32.h" #else // POSIX-style system -#include "../lib/filelister_unix.h" +#include "../cli/filelister_unix.h" #endif std::string objfile(std::string cppfile) @@ -230,8 +230,8 @@ int main(int argc, char **argv) fout << "cppcheck:\t$(LIBOBJ)\t$(CLIOBJ)\t$(EXTOBJ)\n"; fout << "\t$(CXX) $(CPPFLAGS) $(CXXFLAGS) -o cppcheck $(CLIOBJ) $(LIBOBJ) $(EXTOBJ) -lpcre $(LDFLAGS)\n\n"; fout << "all:\tcppcheck\ttestrunner\n\n"; - fout << "testrunner:\t$(TESTOBJ)\t$(LIBOBJ)\t$(EXTOBJ)\tcli/threadexecutor.o\tcli/cmdlineparser.o\tcli/cppcheckexecutor.o\n"; - fout << "\t$(CXX) $(CPPFLAGS) $(CXXFLAGS) -o testrunner $(TESTOBJ) $(LIBOBJ) $(EXTOBJ) -lpcre cli/threadexecutor.o cli/cmdlineparser.o cli/cppcheckexecutor.o $(LDFLAGS)\n\n"; + fout << "testrunner:\t$(TESTOBJ)\t$(LIBOBJ)\t$(EXTOBJ)\tcli/threadexecutor.o\tcli/cmdlineparser.o\tcli/cppcheckexecutor.o\tcli/filelister.o\tcli/filelister_unix.o\n"; + fout << "\t$(CXX) $(CPPFLAGS) $(CXXFLAGS) -o testrunner $(TESTOBJ) $(LIBOBJ) $(EXTOBJ) -lpcre cli/threadexecutor.o cli/cmdlineparser.o\tcli/filelister.o\tcli/filelister_unix.o $(LDFLAGS)\n\n"; fout << "test:\tall\n"; fout << "\t./testrunner\n\n"; fout << "check:\tall\n"; From 0cacc7fe4d1a3fa12080765624bb8354761ce030 Mon Sep 17 00:00:00 2001 From: Kimmo Varis Date: Tue, 18 Jan 2011 20:51:52 +0200 Subject: [PATCH 087/165] Update Visual Studio project files. Update Visual Studio 2008/2010 project files after moving filelister* files from lib/ to cli/. --- cli/cppcheck.vcproj | 14 +++++++------- cli/cppcheck.vcxproj | 14 +++++++------- cli/cppcheck.vcxproj.filters | 12 ++++++------ test/test.vcproj | 14 +++++++------- test/test.vcxproj | 14 +++++++------- test/test.vcxproj.filters | 12 ++++++------ 6 files changed, 40 insertions(+), 40 deletions(-) diff --git a/cli/cppcheck.vcproj b/cli/cppcheck.vcproj index bfb3c25f8..541363475 100755 --- a/cli/cppcheck.vcproj +++ b/cli/cppcheck.vcproj @@ -3,7 +3,7 @@ ProjectType="Visual C++" Version="9,00" Name="cppcheck" - ProjectGUID="{A610CB5D-FA83-3FC9-96AB-5689E3B50CEC}" + ProjectGUID="{7E69D6C6-32B2-32E1-BF56-A5BFBAF5E61F}" Keyword="Qt4VSv1.0"> + RelativePath="filelister.cpp" /> + RelativePath="filelister_unix.cpp" /> + RelativePath="filelister_win32.cpp" /> + RelativePath="filelister.h" /> + RelativePath="filelister_unix.h" /> + RelativePath="filelister_win32.h" /> - {E3A516D8-D69D-32D7-A444-A3674D4B1FE8} + {42BC0E8E-9175-3B2D-B8B3-9EC5C36EF49A} cppcheck Qt4VSv1.0 @@ -134,9 +134,9 @@ - - - + + + @@ -171,9 +171,9 @@ - - - + + + diff --git a/cli/cppcheck.vcxproj.filters b/cli/cppcheck.vcxproj.filters index 339cb5475..4e6b80eca 100644 --- a/cli/cppcheck.vcxproj.filters +++ b/cli/cppcheck.vcxproj.filters @@ -66,13 +66,13 @@ Source Files - + Source Files - + Source Files - + Source Files @@ -173,13 +173,13 @@ Header Files - + Header Files - + Header Files - + Header Files diff --git a/test/test.vcproj b/test/test.vcproj index 0eba6bbdd..45d3f2948 100755 --- a/test/test.vcproj +++ b/test/test.vcproj @@ -3,7 +3,7 @@ ProjectType="Visual C++" Version="9,00" Name="test" - ProjectGUID="{E690724D-4286-3049-8439-595D1CB80EAB}" + ProjectGUID="{48110A35-C2BB-3F1C-A741-C15295041A2D}" Keyword="Qt4VSv1.0"> + RelativePath="..\cli\filelister.cpp" /> + RelativePath="..\cli\filelister_unix.cpp" /> + RelativePath="..\cli\filelister_win32.cpp" /> + RelativePath="..\cli\filelister.h" /> + RelativePath="..\cli\filelister_unix.h" /> + RelativePath="..\cli\filelister_win32.h" /> - {597BA843-2D03-3F45-AB51-2E1DF1EA5136} + {081168BA-E630-3D82-8EDB-A19028999479} test Qt4VSv1.0 @@ -134,9 +134,9 @@ - - - + + + @@ -203,9 +203,9 @@ - - - + + + diff --git a/test/test.vcxproj.filters b/test/test.vcxproj.filters index 15e944c5c..84b2d7672 100644 --- a/test/test.vcxproj.filters +++ b/test/test.vcxproj.filters @@ -62,13 +62,13 @@ Source Files - + Source Files - + Source Files - + Source Files @@ -265,13 +265,13 @@ Header Files - + Header Files - + Header Files - + Header Files From 856a631f357b6bfd9b0001d57e2aa978642ae8fe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Wed, 19 Jan 2011 07:33:38 +0100 Subject: [PATCH 088/165] Fixed #2483 (SymbolDatabase compiler warning (VS2008/VS2010)) --- lib/symboldatabase.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/symboldatabase.h b/lib/symboldatabase.h index 9f692abec..c2b40a2e5 100644 --- a/lib/symboldatabase.h +++ b/lib/symboldatabase.h @@ -59,7 +59,7 @@ class Variable */ bool getFlag(int flag_) const { - return bool(_flags & flag_); + return bool((_flags & flag_) != 0); } /** From 94aafa482cbf7ae294154afe2ca2013156a59299 Mon Sep 17 00:00:00 2001 From: Pete Johns Date: Wed, 19 Jan 2011 11:58:44 +1100 Subject: [PATCH 089/165] Fixed #2480 (false positive on unused private function) --- lib/checkclass.cpp | 5 ++- test/testunusedprivfunc.cpp | 68 ++++++++++++++++++++++++++++++++++--- 2 files changed, 68 insertions(+), 5 deletions(-) diff --git a/lib/checkclass.cpp b/lib/checkclass.cpp index 180b8e9c3..26dee1a18 100644 --- a/lib/checkclass.cpp +++ b/lib/checkclass.cpp @@ -734,8 +734,11 @@ void CheckClass::privateFunctions() // or if the function address is used somewhere... // eg. sigc::mem_fun(this, &className::classFunction) const std::string _pattern2("& " + classname + " :: " + FuncList.front()->str()); + const std::string methodAsArgument("(|, " + classname + " :: " + FuncList.front()->str() + " ,|)"); if (!Token::findmatch(_tokenizer->tokens(), _pattern.c_str()) && - !Token::findmatch(_tokenizer->tokens(), _pattern2.c_str())) + !Token::findmatch(_tokenizer->tokens(), _pattern2.c_str()) && + !Token::findmatch(_tokenizer->tokens(), methodAsArgument.c_str()) + ) { unusedPrivateFunctionError(FuncList.front(), classname, FuncList.front()->str()); } diff --git a/test/testunusedprivfunc.cpp b/test/testunusedprivfunc.cpp index 2257644e7..d5e6c3c8c 100644 --- a/test/testunusedprivfunc.cpp +++ b/test/testunusedprivfunc.cpp @@ -60,7 +60,9 @@ private: // #2407 - FP when called from operator() TEST_CASE(fp_operator); - TEST_CASE(testDoesNotIdentifyCallback); // #2480 + TEST_CASE(testDoesNotIdentifyMethodAsFirstFunctionArgument); // #2480 + TEST_CASE(testDoesNotIdentifyMethodAsMiddleFunctionArgument); + TEST_CASE(testDoesNotIdentifyMethodAsLastFunctionArgument); } @@ -449,7 +451,7 @@ private: ASSERT_EQUALS("", errout.str()); } - void testDoesNotIdentifyCallback() + void testDoesNotIdentifyMethodAsFirstFunctionArgument() { check("#include " "void callback(void (*func)(int), int arg)" @@ -474,8 +476,66 @@ private: "{" " MountOperation aExample(10);" "}" - ); - TODO_ASSERT_EQUALS("", errout.str()); + ); + ASSERT_EQUALS("", errout.str()); + } + + void testDoesNotIdentifyMethodAsMiddleFunctionArgument() + { + check("#include " + "void callback(char, void (*func)(int), int arg)" + "{" + " (*func)(arg);" + "}" + "class MountOperation" + "{" + " static void Completed(int i);" + "public:" + " MountOperation(int i);" + "};" + "void MountOperation::Completed(int i)" + "{" + " std::cerr << i << std::endl;" + "}" + "MountOperation::MountOperation(int i)" + "{" + " callback('a', MountOperation::Completed, i);" + "}" + "int main(void)" + "{" + " MountOperation aExample(10);" + "}" + ); + ASSERT_EQUALS("", errout.str()); + } + + void testDoesNotIdentifyMethodAsLastFunctionArgument() + { + check("#include " + "void callback(int arg, void (*func)(int))" + "{" + " (*func)(arg);" + "}" + "class MountOperation" + "{" + " static void Completed(int i);" + "public:" + " MountOperation(int i);" + "};" + "void MountOperation::Completed(int i)" + "{" + " std::cerr << i << std::endl;" + "}" + "MountOperation::MountOperation(int i)" + "{" + " callback(i, MountOperation::Completed);" + "}" + "int main(void)" + "{" + " MountOperation aExample(10);" + "}" + ); + ASSERT_EQUALS("", errout.str()); } }; From ecac93ebedf4e88be382424f8178a3abbb6e46e6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Wed, 19 Jan 2011 18:37:33 +0100 Subject: [PATCH 090/165] Fixed #2462 (false positive: (warning) Redundant code: Found a statement that begins with numeric constant) --- lib/checkother.cpp | 3 +++ test/testincompletestatement.cpp | 9 +++++++++ 2 files changed, 12 insertions(+) diff --git a/lib/checkother.cpp b/lib/checkother.cpp index 33465af8b..de54f9029 100644 --- a/lib/checkother.cpp +++ b/lib/checkother.cpp @@ -2365,6 +2365,9 @@ void CheckOther::checkIncompleteStatement() else if (Token::simpleMatch(tok, "= {")) tok = tok->next()->link(); + else if (tok->str() == "{" && Token::Match(tok->tokAt(-2), "%type% %var%")) + tok = tok->link(); + else if (Token::Match(tok, "[;{}] %str%") || Token::Match(tok, "[;{}] %num%")) { // bailout if there is a "? :" in this statement diff --git a/test/testincompletestatement.cpp b/test/testincompletestatement.cpp index 622a0cd9f..850cb41ee 100644 --- a/test/testincompletestatement.cpp +++ b/test/testincompletestatement.cpp @@ -67,6 +67,7 @@ private: TEST_CASE(structarraynull); TEST_CASE(structarray); TEST_CASE(conditionalcall); // ; 0==x ? X() : Y(); + TEST_CASE(structinit); // #2462 : ABC abc{1,2,3}; } void test1() @@ -178,6 +179,14 @@ private: "}\n"); ASSERT_EQUALS("", errout.str()); } + + void structinit() + { + check("void f() {\n" + " ABC abc{1,2,3};\n" + "}\n"); + ASSERT_EQUALS("", errout.str()); + } }; REGISTER_TEST(TestIncompleteStatement) From b1b8ea645719d5a1ccb2c3ff15a65cf66aa12606 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Wed, 19 Jan 2011 20:41:46 +0100 Subject: [PATCH 091/165] added unit test for #2482 --- test/testincompletestatement.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/test/testincompletestatement.cpp b/test/testincompletestatement.cpp index 850cb41ee..cc098d962 100644 --- a/test/testincompletestatement.cpp +++ b/test/testincompletestatement.cpp @@ -182,10 +182,15 @@ private: void structinit() { + // #2462 - C++0x struct initialization check("void f() {\n" " ABC abc{1,2,3};\n" "}\n"); ASSERT_EQUALS("", errout.str()); + + // #2482 - false positive for empty struct + check("struct A {};"); + ASSERT_EQUALS("", errout.str()); } }; From 70eadb37bdd0ba259f1748329e0a63bfdece65cf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Wed, 19 Jan 2011 21:00:46 +0100 Subject: [PATCH 092/165] Fixed #2481 (false positive with 'break;': After insert, the iterator '*' may be invalid) --- lib/checkstl.cpp | 2 +- test/teststl.cpp | 16 ++++++++++++++++ 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/lib/checkstl.cpp b/lib/checkstl.cpp index 4743bc173..765f59b4b 100644 --- a/lib/checkstl.cpp +++ b/lib/checkstl.cpp @@ -642,7 +642,7 @@ void CheckStl::pushback() } } - else if (tok2->str() == "return") + else if (tok2->str() == "return" || tok2->str() == "break") { invalidIterator.clear(); } diff --git a/test/teststl.cpp b/test/teststl.cpp index 1c9a9e869..6a8e4ec4a 100644 --- a/test/teststl.cpp +++ b/test/teststl.cpp @@ -222,6 +222,22 @@ private: "}\n"); ASSERT_EQUALS("", errout.str()); + // Ticket #2481 + check("void foo(std::vector &r)\n" + "{\n" + " std::vector::iterator aI = r.begin();\n" + " while(aI != r.end())\n" + " {\n" + " if (*aI == 0)\n" + " {\n" + " r.insert(aI, 42);\n" + " break;\n" + " }\n" + " ++aI;\n" + " }\n" + "}\n"); + ASSERT_EQUALS("", errout.str()); + // Execution path checking.. check("void foo(std::vector &r, int c)\n" "{\n" From 9dce0dd75c4a15f4e6f9e5217d343152e2863ce4 Mon Sep 17 00:00:00 2001 From: Robert Reif Date: Thu, 20 Jan 2011 18:02:52 +0100 Subject: [PATCH 093/165] Symbol database: refactoring of classAndStructTypes parsing. ticket: #2468 --- lib/symboldatabase.cpp | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/lib/symboldatabase.cpp b/lib/symboldatabase.cpp index a174e5a15..52b3cb28e 100644 --- a/lib/symboldatabase.cpp +++ b/lib/symboldatabase.cpp @@ -38,13 +38,6 @@ SymbolDatabase::SymbolDatabase(const Tokenizer *tokenizer, const Settings *settings, ErrorLogger *errorLogger) : _tokenizer(tokenizer), _settings(settings), _errorLogger(errorLogger) { - // fill the classAndStructTypes set.. - for (const Token *tok = _tokenizer->tokens(); tok; tok = tok->next()) - { - if (Token::Match(tok, "class|struct %var% [:{;]")) - classAndStructTypes.insert(tok->next()->str()); - } - // find all namespaces (class,struct and namespace) Scope *info = new Scope(this, NULL, NULL); spaceInfoList.push_back(info); @@ -59,6 +52,9 @@ SymbolDatabase::SymbolDatabase(const Tokenizer *tokenizer, const Settings *setti // only create base list for classes and structures if (new_info->isClassOrStruct()) { + // fill the classAndStructTypes set.. + classAndStructTypes.insert(new_info->className); + // goto initial '{' tok2 = initBaseInfo(new_info, tok); } @@ -81,6 +77,17 @@ SymbolDatabase::SymbolDatabase(const Tokenizer *tokenizer, const Settings *setti tok = tok2; } + // forward declaration + else if (Token::Match(tok, "class|struct %var% ;")) + { + // fill the classAndStructTypes set.. + classAndStructTypes.insert(tok->next()->str()); + + /** @todo save forward declarations in database someday */ + tok = tok->tokAt(2); + continue; + } + else { // check for end of space From a21f8eec7c2732927eb53764f9df3ea99a929ff4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Thu, 20 Jan 2011 19:26:52 +0100 Subject: [PATCH 094/165] Fixed #2481 (false positive with break: After insert, the iterator '*' may be invalid) --- lib/checkstl.cpp | 9 ++------- test/teststl.cpp | 23 +++++++++++++++++++++++ 2 files changed, 25 insertions(+), 7 deletions(-) diff --git a/lib/checkstl.cpp b/lib/checkstl.cpp index 765f59b4b..bb5893f48 100644 --- a/lib/checkstl.cpp +++ b/lib/checkstl.cpp @@ -594,7 +594,7 @@ void CheckStl::pushback() break; --indent3; } - else if (tok3->str() == "break") + else if (tok3->str() == "break" || tok3->str() == "return") { pushbackTok = 0; break; @@ -634,12 +634,7 @@ void CheckStl::pushback() } invalidIterator = tok2->strAt(2); - if (!iteratorDeclaredInsideLoop) - { - tok2 = tok2->tokAt(3)->link(); - if (!tok2) - break; - } + tok2 = tok2->tokAt(3)->link(); } else if (tok2->str() == "return" || tok2->str() == "break") diff --git a/test/teststl.cpp b/test/teststl.cpp index 6a8e4ec4a..2d27a09e4 100644 --- a/test/teststl.cpp +++ b/test/teststl.cpp @@ -76,6 +76,7 @@ private: TEST_CASE(pushback10); TEST_CASE(insert1); + TEST_CASE(insert2); TEST_CASE(invalidcode); @@ -904,7 +905,29 @@ private: ASSERT_EQUALS("[test.cpp:6]: (error) After insert, the iterator 'iter' may be invalid\n", errout.str()); } + void insert2() + { + // Ticket: #2169 + check("void f(std::vector &vec) {\n" + " for(std::vector::iterator iter = vec.begin(); iter != vec.end(); ++iter)\n" + " {\n" + " vec.insert(iter, 0);\n" + " break;\n" + " }\n" + "}\n"); + ASSERT_EQUALS("", errout.str()); + check("void f(std::vector &vec) {\n" + " for(std::vector::iterator iter = vec.begin(); iter != vec.end(); ++iter)\n" + " {\n" + " if (*it == 0) {\n" + " vec.insert(iter, 0);\n" + " return;\n" + " }\n" + " }\n" + "}\n"); + ASSERT_EQUALS("", errout.str()); + } void invalidcode() { From 10d2909c7c91523c77df848eb86ce212f94568c1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Thu, 20 Jan 2011 20:29:06 +0100 Subject: [PATCH 095/165] CLI: updated help text for --inline-suppr. Thanks rubicon_hdr for the suggestion --- cli/cmdlineparser.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cli/cmdlineparser.cpp b/cli/cmdlineparser.cpp index baeb26cbf..e4143d052 100644 --- a/cli/cmdlineparser.cpp +++ b/cli/cmdlineparser.cpp @@ -551,7 +551,7 @@ void CmdLineParser::PrintHelp() " several paths. First given path is checked first. If\n" " paths are relative to source files, this is not needed\n" " --inline-suppr Enable inline suppressions. Use them by placing one or\n" - " more comments in the form: // cppcheck-suppress memleak\n" + " more comments, like: // cppcheck-suppress warningId\n" " on the lines before the warning to suppress.\n" " -j [jobs] Start [jobs] threads to do the checking simultaneously.\n" " -q, --quiet Only print error messages\n" From 87e3e9e703a51acba2cf0791a0295798ab0eee97 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Thu, 20 Jan 2011 20:48:35 +0100 Subject: [PATCH 096/165] Fixed #2488 (false positive with updating iterator in a for loop) --- lib/checkstl.cpp | 8 ++++++-- test/teststl.cpp | 15 +++++++++++++++ 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/lib/checkstl.cpp b/lib/checkstl.cpp index bb5893f48..fc90339bb 100644 --- a/lib/checkstl.cpp +++ b/lib/checkstl.cpp @@ -284,9 +284,13 @@ public: while (indentlevel > 0 && 0 != (tok = tok->next())) { if (tok->str() == "(") - ++indentlevel; + tok = tok->link(); else if (tok->str() == ")") - --indentlevel; + break; + + // reassigning iterator in loop head + else if (Token::Match(tok, "%var% =") && tok->str() == it->str()) + break; } if (! Token::simpleMatch(tok, ") {")) diff --git a/test/teststl.cpp b/test/teststl.cpp index 2d27a09e4..eabb2c2c3 100644 --- a/test/teststl.cpp +++ b/test/teststl.cpp @@ -53,6 +53,7 @@ private: TEST_CASE(erase3); TEST_CASE(erase4); TEST_CASE(erase5); + TEST_CASE(erase6); TEST_CASE(eraseBreak); TEST_CASE(eraseContinue); TEST_CASE(eraseReturn1); @@ -502,6 +503,20 @@ private: ASSERT_EQUALS("[test.cpp:8]: (error) Dangerous iterator usage after erase()-method.\n", errout.str()); } + void erase6() + { + check("void f() {\n" + " std::vector vec(3);\n" + " std::vector::iterator it;\n" + " std::vector::iterator itEnd = vec.end();\n" + " for (it = vec.begin(); it != itEnd; it = vec.begin(), itEnd = vec.end())\n" + " {\n" + " vec.erase(it);\n" + " }\n" + "}"); + ASSERT_EQUALS("", errout.str()); + } + void eraseBreak() { check("void f()\n" From d73709a620b50468e02598964b51803c8516b4df Mon Sep 17 00:00:00 2001 From: Robert Reif Date: Fri, 21 Jan 2011 07:42:41 +0100 Subject: [PATCH 097/165] Symbol database: rename variables. ticket: #2468 --- lib/checkclass.cpp | 46 ++++---- lib/checkmemoryleak.cpp | 10 +- lib/checkother.cpp | 6 +- lib/symboldatabase.cpp | 250 ++++++++++++++++++++-------------------- lib/symboldatabase.h | 14 +-- lib/tokenize.cpp | 2 +- 6 files changed, 164 insertions(+), 164 deletions(-) diff --git a/lib/checkclass.cpp b/lib/checkclass.cpp index 26dee1a18..76217d7f0 100644 --- a/lib/checkclass.cpp +++ b/lib/checkclass.cpp @@ -70,7 +70,7 @@ void CheckClass::constructors() std::list::const_iterator i; - for (i = symbolDatabase->spaceInfoList.begin(); i != symbolDatabase->spaceInfoList.end(); ++i) + for (i = symbolDatabase->scopeList.begin(); i != symbolDatabase->scopeList.end(); ++i) { const Scope *scope = *i; @@ -233,7 +233,7 @@ bool CheckClass::isBaseClassFunc(const Token *tok, const Scope *scope) // Iterate through each base class... for (size_t i = 0; i < scope->derivedFrom.size(); ++i) { - const Scope *derivedFrom = scope->derivedFrom[i].spaceInfo; + const Scope *derivedFrom = scope->derivedFrom[i].scope; // Check if base class exists in database if (derivedFrom) @@ -592,7 +592,7 @@ void CheckClass::privateFunctions() std::list::const_iterator i; - for (i = symbolDatabase->spaceInfoList.begin(); i != symbolDatabase->spaceInfoList.end(); ++i) + for (i = symbolDatabase->scopeList.begin(); i != symbolDatabase->scopeList.end(); ++i) { const Scope *scope = *i; @@ -860,7 +860,7 @@ void CheckClass::operatorEq() std::list::const_iterator i; - for (i = symbolDatabase->spaceInfoList.begin(); i != symbolDatabase->spaceInfoList.end(); ++i) + for (i = symbolDatabase->scopeList.begin(); i != symbolDatabase->scopeList.end(); ++i) { std::list::const_iterator it; @@ -944,7 +944,7 @@ void CheckClass::operatorEqRetRefThis() std::list::const_iterator i; - for (i = symbolDatabase->spaceInfoList.begin(); i != symbolDatabase->spaceInfoList.end(); ++i) + for (i = symbolDatabase->scopeList.begin(); i != symbolDatabase->scopeList.end(); ++i) { const Scope *scope = *i; @@ -1000,7 +1000,7 @@ void CheckClass::operatorEqToSelf() std::list::const_iterator i; - for (i = symbolDatabase->spaceInfoList.begin(); i != symbolDatabase->spaceInfoList.end(); ++i) + for (i = symbolDatabase->scopeList.begin(); i != symbolDatabase->scopeList.end(); ++i) { const Scope *scope = *i; std::list::const_iterator it; @@ -1177,7 +1177,7 @@ void CheckClass::virtualDestructor() std::list::const_iterator i; - for (i = symbolDatabase->spaceInfoList.begin(); i != symbolDatabase->spaceInfoList.end(); ++i) + for (i = symbolDatabase->scopeList.begin(); i != symbolDatabase->scopeList.end(); ++i) { const Scope *scope = *i; @@ -1203,15 +1203,15 @@ void CheckClass::virtualDestructor() for (unsigned int j = 0; j < scope->derivedFrom.size(); ++j) { // Check if base class is public and exists in database - if (scope->derivedFrom[j].access != Private && scope->derivedFrom[j].spaceInfo) + if (scope->derivedFrom[j].access != Private && scope->derivedFrom[j].scope) { - const Scope *spaceInfo = scope->derivedFrom[j].spaceInfo; + const Scope *derivedFrom = scope->derivedFrom[j].scope; // Name of base class.. - const std::string baseName = spaceInfo->className; + const std::string baseName = derivedFrom->className; // Find the destructor declaration for the base class. - const Function *base_destructor = spaceInfo->getDestructor(); + const Function *base_destructor = derivedFrom->getDestructor(); const Token *base = 0; if (base_destructor) base = base_destructor->token; @@ -1219,8 +1219,8 @@ void CheckClass::virtualDestructor() // Check that there is a destructor.. if (!base_destructor) { - if (spaceInfo->derivedFrom.empty()) - virtualDestructorError(spaceInfo->classDef, baseName, derivedClass->str()); + if (derivedFrom->derivedFrom.empty()) + virtualDestructorError(derivedFrom->classDef, baseName, derivedClass->str()); } else if (!base_destructor->isVirtual) { @@ -1230,7 +1230,7 @@ void CheckClass::virtualDestructor() // Proper solution is to check all of the base classes. If base class is not // found or if one of the base classes has virtual destructor, error should not // be printed. See TODO test case "virtualDestructorInherited" - if (spaceInfo->derivedFrom.empty()) + if (derivedFrom->derivedFrom.empty()) { // Make sure that the destructor is public (protected or private // would not compile if inheritance is used in a way that would @@ -1296,7 +1296,7 @@ void CheckClass::checkConst() std::list::const_iterator it; - for (it = symbolDatabase->spaceInfoList.begin(); it != symbolDatabase->spaceInfoList.end(); ++it) + for (it = symbolDatabase->scopeList.begin(); it != symbolDatabase->scopeList.end(); ++it) { const Scope *scope = *it; @@ -1440,12 +1440,12 @@ bool CheckClass::isMemberVar(const Scope *scope, const Token *tok) for (unsigned int i = 0; i < scope->derivedFrom.size(); ++i) { // find the base class - const Scope *spaceInfo = scope->derivedFrom[i].spaceInfo; + const Scope *derivedFrom = scope->derivedFrom[i].scope; // find the function in the base class - if (spaceInfo) + if (derivedFrom) { - if (isMemberVar(spaceInfo, tok)) + if (isMemberVar(derivedFrom, tok)) return true; } } @@ -1471,12 +1471,12 @@ bool CheckClass::isConstMemberFunc(const Scope *scope, const Token *tok) for (unsigned int i = 0; i < scope->derivedFrom.size(); ++i) { // find the base class - const Scope *spaceInfo = scope->derivedFrom[i].spaceInfo; + const Scope *derivedFrom = scope->derivedFrom[i].scope; // find the function in the base class - if (spaceInfo) + if (derivedFrom) { - if (isConstMemberFunc(spaceInfo, tok)) + if (isConstMemberFunc(derivedFrom, tok)) return true; } } @@ -1588,9 +1588,9 @@ bool CheckClass::isVirtualFunc(const Scope *scope, const Token *functionToken) c for (unsigned int i = 0; i < scope->derivedFrom.size(); ++i) { // check if base class exists in database - if (scope->derivedFrom[i].spaceInfo) + if (scope->derivedFrom[i].scope) { - const Scope *derivedFrom = scope->derivedFrom[i].spaceInfo; + const Scope *derivedFrom = scope->derivedFrom[i].scope; std::list::const_iterator func; diff --git a/lib/checkmemoryleak.cpp b/lib/checkmemoryleak.cpp index 97b63c4ef..72e58f20c 100644 --- a/lib/checkmemoryleak.cpp +++ b/lib/checkmemoryleak.cpp @@ -567,7 +567,7 @@ void CheckMemoryLeakInFunction::parse_noreturn() std::list::const_iterator i; - for (i = symbolDatabase->spaceInfoList.begin(); i != symbolDatabase->spaceInfoList.end(); ++i) + for (i = symbolDatabase->scopeList.begin(); i != symbolDatabase->scopeList.end(); ++i) { const Scope *scope = *i; @@ -2493,7 +2493,7 @@ void CheckMemoryLeakInFunction::checkReallocUsage() { std::list::const_iterator i; - for (i = symbolDatabase->spaceInfoList.begin(); i != symbolDatabase->spaceInfoList.end(); ++i) + for (i = symbolDatabase->scopeList.begin(); i != symbolDatabase->scopeList.end(); ++i) { const Scope *scope = *i; @@ -2646,7 +2646,7 @@ void CheckMemoryLeakInFunction::check() std::list::const_iterator i; - for (i = symbolDatabase->spaceInfoList.begin(); i != symbolDatabase->spaceInfoList.end(); ++i) + for (i = symbolDatabase->scopeList.begin(); i != symbolDatabase->scopeList.end(); ++i) { const Scope *scope = *i; @@ -2703,7 +2703,7 @@ void CheckMemoryLeakInClass::check() std::list::const_iterator i; - for (i = symbolDatabase->spaceInfoList.begin(); i != symbolDatabase->spaceInfoList.end(); ++i) + for (i = symbolDatabase->scopeList.begin(); i != symbolDatabase->scopeList.end(); ++i) { const Scope *scope = *i; @@ -3168,7 +3168,7 @@ void CheckMemoryLeakNoVar::check() std::list::const_iterator i; - for (i = symbolDatabase->spaceInfoList.begin(); i != symbolDatabase->spaceInfoList.end(); ++i) + for (i = symbolDatabase->scopeList.begin(); i != symbolDatabase->scopeList.end(); ++i) { Scope *scope = *i; diff --git a/lib/checkother.cpp b/lib/checkother.cpp index de54f9029..0d0808ece 100644 --- a/lib/checkother.cpp +++ b/lib/checkother.cpp @@ -1242,7 +1242,7 @@ void CheckOther::functionVariableUsage() std::list::const_iterator i; - for (i = symbolDatabase->spaceInfoList.begin(); i != symbolDatabase->spaceInfoList.end(); ++i) + for (i = symbolDatabase->scopeList.begin(); i != symbolDatabase->scopeList.end(); ++i) { const Scope *info = *i; @@ -1910,7 +1910,7 @@ void CheckOther::checkVariableScope() std::list::const_iterator i; - for (i = symbolDatabase->spaceInfoList.begin(); i != symbolDatabase->spaceInfoList.end(); ++i) + for (i = symbolDatabase->scopeList.begin(); i != symbolDatabase->scopeList.end(); ++i) { const Scope *scope = *i; @@ -2551,7 +2551,7 @@ void CheckOther::checkMisusedScopedObject() std::list::const_iterator i; - for (i = symbolDatabase->spaceInfoList.begin(); i != symbolDatabase->spaceInfoList.end(); ++i) + for (i = symbolDatabase->scopeList.begin(); i != symbolDatabase->scopeList.end(); ++i) { const Scope *scope = *i; diff --git a/lib/symboldatabase.cpp b/lib/symboldatabase.cpp index 52b3cb28e..8cd0be9ff 100644 --- a/lib/symboldatabase.cpp +++ b/lib/symboldatabase.cpp @@ -39,40 +39,40 @@ SymbolDatabase::SymbolDatabase(const Tokenizer *tokenizer, const Settings *setti : _tokenizer(tokenizer), _settings(settings), _errorLogger(errorLogger) { // find all namespaces (class,struct and namespace) - Scope *info = new Scope(this, NULL, NULL); - spaceInfoList.push_back(info); + Scope *scope = new Scope(this, NULL, NULL); + scopeList.push_back(scope); for (const Token *tok = _tokenizer->tokens(); tok; tok = tok->next()) { // Locate next class if (Token::Match(tok, "class|struct|namespace %var% [{:]")) { - Scope *new_info = new Scope(this, tok, info); + Scope *new_scope = new Scope(this, tok, scope); const Token *tok2 = tok->tokAt(2); // only create base list for classes and structures - if (new_info->isClassOrStruct()) + if (new_scope->isClassOrStruct()) { // fill the classAndStructTypes set.. - classAndStructTypes.insert(new_info->className); + classAndStructTypes.insert(new_scope->className); // goto initial '{' - tok2 = initBaseInfo(new_info, tok); + tok2 = initBaseInfo(new_scope, tok); } - new_info->classStart = tok2; - new_info->classEnd = tok2->link(); + new_scope->classStart = tok2; + new_scope->classEnd = tok2->link(); // make sure we have valid code - if (!new_info->classEnd) + if (!new_scope->classEnd) { - delete new_info; + delete new_scope; break; } - info = new_info; + scope = new_scope; // add namespace - spaceInfoList.push_back(info); + scopeList.push_back(scope); tok = tok2; } @@ -91,33 +91,33 @@ SymbolDatabase::SymbolDatabase(const Tokenizer *tokenizer, const Settings *setti else { // check for end of space - if (tok == info->classEnd) + if (tok == scope->classEnd) { - info = info->nestedIn; + scope = scope->nestedIn; continue; } // check if in class or structure - else if (info->type == Scope::eClass || info->type == Scope::eStruct) + else if (scope->type == Scope::eClass || scope->type == Scope::eStruct) { const Token *funcStart = 0; const Token *argStart = 0; // What section are we in.. if (tok->str() == "private:") - info->access = Private; + scope->access = Private; else if (tok->str() == "protected:") - info->access = Protected; + scope->access = Protected; else if (tok->str() == "public:") - info->access = Public; + scope->access = Public; else if (Token::Match(tok, "public|protected|private %var% :")) { if (tok->str() == "private") - info->access = Private; + scope->access = Private; else if (tok->str() == "protected") - info->access = Protected; + scope->access = Protected; else if (tok->str() == "public") - info->access = Public; + scope->access = Public; tok = tok->tokAt(2); } @@ -131,7 +131,7 @@ SymbolDatabase::SymbolDatabase(const Tokenizer *tokenizer, const Settings *setti function.argDef = argStart; // save the access type - function.access = info->access; + function.access = scope->access; // save the function name location function.tokenDef = funcStart; @@ -147,13 +147,13 @@ SymbolDatabase::SymbolDatabase(const Tokenizer *tokenizer, const Settings *setti } // class constructor/destructor - else if (function.tokenDef->str() == info->className) + else if (function.tokenDef->str() == scope->className) { if (function.tokenDef->previous()->str() == "~") function.type = Function::eDestructor; else if ((Token::Match(function.tokenDef, "%var% ( const %var% & )") || Token::Match(function.tokenDef, "%var% ( const %var% & %var% )")) && - function.tokenDef->strAt(3) == info->className) + function.tokenDef->strAt(3) == scope->className) function.type = Function::eCopyConstructor; else function.type = Function::eConstructor; @@ -214,7 +214,7 @@ SymbolDatabase::SymbolDatabase(const Tokenizer *tokenizer, const Settings *setti // count the number of constructors if (function.type == Function::eConstructor || function.type == Function::eCopyConstructor) - info->numConstructors++; + scope->numConstructors++; // assume implementation is inline (definition and implementation same) function.token = function.tokenDef; @@ -226,7 +226,7 @@ SymbolDatabase::SymbolDatabase(const Tokenizer *tokenizer, const Settings *setti // find the function implementation later tok = end->next(); - info->functionList.push_back(function); + scope->functionList.push_back(function); } // inline function @@ -236,14 +236,14 @@ SymbolDatabase::SymbolDatabase(const Tokenizer *tokenizer, const Settings *setti function.hasBody = true; function.arg = function.argDef; - info->functionList.push_back(function); + scope->functionList.push_back(function); const Token *tok2 = funcStart; - Scope *functionOf = info; + Scope *functionOf = scope; - addNewFunction(&info, &tok2); - if (info) - info->functionOf = functionOf; + addNewFunction(&scope, &tok2); + if (scope) + scope->functionOf = functionOf; tok = tok2; } @@ -251,7 +251,7 @@ SymbolDatabase::SymbolDatabase(const Tokenizer *tokenizer, const Settings *setti // nested class function? else if (tok->previous()->str() == "::" && isFunction(tok, &funcStart, &argStart)) - addFunction(&info, &tok, argStart); + addFunction(&scope, &tok, argStart); // friend class declaration? else if (Token::Match(tok, "friend class| %any% ;")) @@ -260,12 +260,12 @@ SymbolDatabase::SymbolDatabase(const Tokenizer *tokenizer, const Settings *setti friendInfo.name = tok->strAt(1) == "class" ? tok->strAt(2) : tok->strAt(1); /** @todo fill this in later after parsing is complete */ - friendInfo.spaceInfo = 0; + friendInfo.scope = 0; - info->friendList.push_back(friendInfo); + scope->friendList.push_back(friendInfo); } } - else if (info->type == Scope::eNamespace || info->type == Scope::eGlobal) + else if (scope->type == Scope::eNamespace || scope->type == Scope::eGlobal) { const Token *funcStart = 0; const Token *argStart = 0; @@ -278,12 +278,12 @@ SymbolDatabase::SymbolDatabase(const Tokenizer *tokenizer, const Settings *setti { // class function if (tok->previous() && tok->previous()->str() == "::") - addFunction(&info, &tok, argStart); + addFunction(&scope, &tok, argStart); // class destructor else if (tok->previous() && tok->previous()->str() == "~" && tok->previous()->previous() && tok->previous()->previous()->str() == "::") - addFunction(&info, &tok, argStart); + addFunction(&scope, &tok, argStart); // regular function else @@ -305,17 +305,17 @@ SymbolDatabase::SymbolDatabase(const Tokenizer *tokenizer, const Settings *setti function.arg = function.argDef; function.type = Function::eFunction; - Scope *old_info = info; + Scope *old_scope = scope; - addNewFunction(&info, &tok); + addNewFunction(&scope, &tok); - if (info) - old_info->functionList.push_back(function); + if (scope) + old_scope->functionList.push_back(function); // syntax error else { - info = old_info; + scope = old_scope; break; } } @@ -326,19 +326,19 @@ SymbolDatabase::SymbolDatabase(const Tokenizer *tokenizer, const Settings *setti Token::Match(argStart->link()->tokAt(2)->link(), ") const| {")) { const Token *tok1 = funcStart; - Scope *old_info = info; + Scope *old_scope = scope; // class function if (tok1->previous()->str() == "::") - addFunction(&info, &tok1, argStart); + addFunction(&scope, &tok1, argStart); // regular function else - addNewFunction(&info, &tok1); + addNewFunction(&scope, &tok1); // syntax error? - if (!info) - info = old_info; + if (!scope) + scope = old_scope; tok = tok1; } @@ -350,36 +350,36 @@ SymbolDatabase::SymbolDatabase(const Tokenizer *tokenizer, const Settings *setti std::list::iterator it; // fill in base class info - for (it = spaceInfoList.begin(); it != spaceInfoList.end(); ++it) + for (it = scopeList.begin(); it != scopeList.end(); ++it) { - info = *it; + scope = *it; // skip namespaces and functions - if (!info->isClassOrStruct()) + if (!scope->isClassOrStruct()) continue; // finish filling in base class info - for (unsigned int i = 0; i < info->derivedFrom.size(); ++i) + for (unsigned int i = 0; i < scope->derivedFrom.size(); ++i) { std::list::iterator it1; - for (it1 = spaceInfoList.begin(); it1 != spaceInfoList.end(); ++it1) + for (it1 = scopeList.begin(); it1 != scopeList.end(); ++it1) { - Scope *spaceInfo = *it1; + Scope *scope1 = *it1; /** @todo handle derived base classes and namespaces */ - if (spaceInfo->type == Scope::eClass || spaceInfo->type == Scope::eStruct) + if (scope1->type == Scope::eClass || scope1->type == Scope::eStruct) { // do class names match? - if (spaceInfo->className == info->derivedFrom[i].name) + if (scope1->className == scope->derivedFrom[i].name) { // are they in the same namespace or different namespaces with same name? - if ((spaceInfo->nestedIn == info->nestedIn) || - ((spaceInfo->nestedIn && spaceInfo->nestedIn->type == Scope::eNamespace) && - (info->nestedIn && info->nestedIn->type == Scope::eNamespace) && - (spaceInfo->nestedIn->className == info->nestedIn->className))) + if ((scope1->nestedIn == scope->nestedIn) || + ((scope1->nestedIn && scope1->nestedIn->type == Scope::eNamespace) && + (scope->nestedIn && scope->nestedIn->type == Scope::eNamespace) && + (scope1->nestedIn->className == scope->nestedIn->className))) { - info->derivedFrom[i].spaceInfo = spaceInfo; + scope->derivedFrom[i].scope = scope1; break; } } @@ -389,15 +389,15 @@ SymbolDatabase::SymbolDatabase(const Tokenizer *tokenizer, const Settings *setti } // fill in variable info - for (it = spaceInfoList.begin(); it != spaceInfoList.end(); ++it) + for (it = scopeList.begin(); it != scopeList.end(); ++it) { - info = *it; + scope = *it; // skip functions - if (info->type != Scope::eFunction) + if (scope->type != Scope::eFunction) { // find variables - info->getVariableList(); + scope->getVariableList(); } } @@ -409,18 +409,18 @@ SymbolDatabase::SymbolDatabase(const Tokenizer *tokenizer, const Settings *setti { unknowns = 0; - for (it = spaceInfoList.begin(); it != spaceInfoList.end(); ++it) + for (it = scopeList.begin(); it != scopeList.end(); ++it) { - info = *it; + scope = *it; - if (info->isClassOrStruct() && info->needInitialization == Scope::Unknown) + if (scope->isClassOrStruct() && scope->needInitialization == Scope::Unknown) { // check for default constructor bool hasDefaultConstructor = false; std::list::const_iterator func; - for (func = info->functionList.begin(); func != info->functionList.end(); ++func) + for (func = scope->functionList.begin(); func != scope->functionList.end(); ++func) { if (func->type == Function::eConstructor) { @@ -444,7 +444,7 @@ SymbolDatabase::SymbolDatabase(const Tokenizer *tokenizer, const Settings *setti // We assume the default constructor initializes everything. // Another check will figure out if the constructor actually initializes everything. if (hasDefaultConstructor) - info->needInitialization = Scope::False; + scope->needInitialization = Scope::False; // check each member variable to see if it needs initialization else @@ -453,7 +453,7 @@ SymbolDatabase::SymbolDatabase(const Tokenizer *tokenizer, const Settings *setti bool unknown = false; std::list::const_iterator var; - for (var = info->varlist.begin(); var != info->varlist.end(); ++var) + for (var = scope->varlist.begin(); var != scope->varlist.end(); ++var) { if (var->isClass()) { @@ -473,12 +473,12 @@ SymbolDatabase::SymbolDatabase(const Tokenizer *tokenizer, const Settings *setti if (!unknown) { if (needInitialization) - info->needInitialization = Scope::True; + scope->needInitialization = Scope::True; else - info->needInitialization = Scope::False; + scope->needInitialization = Scope::False; } - if (info->needInitialization == Scope::Unknown) + if (scope->needInitialization == Scope::Unknown) unknowns++; } } @@ -491,16 +491,16 @@ SymbolDatabase::SymbolDatabase(const Tokenizer *tokenizer, const Settings *setti // this shouldn't happen so output a debug warning if (retry == 100 && _settings->debugwarnings) { - for (it = spaceInfoList.begin(); it != spaceInfoList.end(); ++it) + for (it = scopeList.begin(); it != scopeList.end(); ++it) { - info = *it; + scope = *it; - if (info->isClassOrStruct() && info->needInitialization == Scope::Unknown) + if (scope->isClassOrStruct() && scope->needInitialization == Scope::Unknown) { std::list locationList; ErrorLogger::ErrorMessage::FileLocation loc; - loc.line = info->classDef->linenr(); - loc.setfile(_tokenizer->file(info->classDef)); + loc.line = scope->classDef->linenr(); + loc.setfile(_tokenizer->file(scope->classDef)); locationList.push_back(loc); const ErrorLogger::ErrorMessage errmsg(locationList, @@ -520,7 +520,7 @@ SymbolDatabase::~SymbolDatabase() { std::list::iterator it; - for (it = spaceInfoList.begin(); it != spaceInfoList.end(); ++it) + for (it = scopeList.begin(); it != scopeList.end(); ++it) delete *it; } @@ -582,7 +582,7 @@ bool SymbolDatabase::isFunction(const Token *tok, const Token **funcStart, const return false; } -bool SymbolDatabase::argsMatch(const Scope *info, const Token *first, const Token *second, const std::string &path, unsigned int depth) const +bool SymbolDatabase::argsMatch(const Scope *scope, const Token *first, const Token *second, const std::string &path, unsigned int depth) const { bool match = false; while (first->str() == second->str()) @@ -658,7 +658,7 @@ bool SymbolDatabase::argsMatch(const Scope *info, const Token *first, const Toke // nested class variable else if (depth == 0 && Token::Match(first->next(), "%var%") && - second->next()->str() == info->className && second->strAt(2) == "::" && + second->next()->str() == scope->className && second->strAt(2) == "::" && first->next()->str() == second->strAt(3)) { second = second->tokAt(2); @@ -671,7 +671,7 @@ bool SymbolDatabase::argsMatch(const Scope *info, const Token *first, const Toke return match; } -void SymbolDatabase::addFunction(Scope **info, const Token **tok, const Token *argStart) +void SymbolDatabase::addFunction(Scope **scope, const Token **tok, const Token *argStart) { int count = 0; bool added = false; @@ -703,32 +703,32 @@ void SymbolDatabase::addFunction(Scope **info, const Token **tok, const Token *a std::list::iterator it1; // search for match - for (it1 = spaceInfoList.begin(); it1 != spaceInfoList.end(); ++it1) + for (it1 = scopeList.begin(); it1 != scopeList.end(); ++it1) { - Scope *info1 = *it1; + Scope *scope1 = *it1; bool match = false; - if (info1->className == tok1->str() && (info1->type != Scope::eFunction)) + if (scope1->className == tok1->str() && (scope1->type != Scope::eFunction)) { // do the spaces match (same space) or do their names match (multiple namespaces) - if ((*info == info1->nestedIn) || (*info && info1 && - (*info)->className == info1->nestedIn->className && - !(*info)->className.empty() && - (*info)->type == info1->nestedIn->type)) + if ((*scope == scope1->nestedIn) || (*scope && scope1 && + (*scope)->className == scope1->nestedIn->className && + !(*scope)->className.empty() && + (*scope)->type == scope1->nestedIn->type)) { - Scope *info2 = info1; + Scope *scope2 = scope1; - while (info2 && count > 0) + while (scope2 && count > 0) { count--; tok1 = tok1->tokAt(2); - info2 = info2->findInNestedList(tok1->str()); + scope2 = scope2->findInNestedList(tok1->str()); } - if (count == 0 && info2) + if (count == 0 && scope2) { match = true; - info1 = info2; + scope1 = scope2; } } } @@ -737,7 +737,7 @@ void SymbolDatabase::addFunction(Scope **info, const Token **tok, const Token *a { std::list::iterator func; - for (func = info1->functionList.begin(); func != info1->functionList.end(); ++func) + for (func = scope1->functionList.begin(); func != scope1->functionList.end(); ++func) { if (!func->hasBody) { @@ -745,7 +745,7 @@ void SymbolDatabase::addFunction(Scope **info, const Token **tok, const Token *a (*tok)->str() == "operator" && func->tokenDef->str() == (*tok)->strAt(1)) { - if (argsMatch(info1, func->tokenDef->tokAt(2), (*tok)->tokAt(3), path, path_length)) + if (argsMatch(scope1, func->tokenDef->tokAt(2), (*tok)->tokAt(3), path, path_length)) { func->hasBody = true; func->token = (*tok)->next(); @@ -756,7 +756,7 @@ void SymbolDatabase::addFunction(Scope **info, const Token **tok, const Token *a (*tok)->previous()->str() == "~" && func->tokenDef->str() == (*tok)->str()) { - if (argsMatch(info1, func->tokenDef->next(), (*tok)->next(), path, path_length)) + if (argsMatch(scope1, func->tokenDef->next(), (*tok)->next(), path, path_length)) { func->hasBody = true; func->token = *tok; @@ -765,7 +765,7 @@ void SymbolDatabase::addFunction(Scope **info, const Token **tok, const Token *a } else if (func->tokenDef->str() == (*tok)->str() && (*tok)->previous()->str() != "~") { - if (argsMatch(info1, func->tokenDef->next(), (*tok)->next(), path, path_length)) + if (argsMatch(scope1, func->tokenDef->next(), (*tok)->next(), path, path_length)) { // normal function? if (!func->retFuncPtr && (*tok)->next()->link()) @@ -792,10 +792,10 @@ void SymbolDatabase::addFunction(Scope **info, const Token **tok, const Token *a if (func->hasBody) { - addNewFunction(info, tok); - if (info) + addNewFunction(scope, tok); + if (scope) { - (*info)->functionOf = info1; + (*scope)->functionOf = scope1; added = true; } break; @@ -807,13 +807,13 @@ void SymbolDatabase::addFunction(Scope **info, const Token **tok, const Token *a // check for class function for unknown class if (!added) - addNewFunction(info, tok); + addNewFunction(scope, tok); } -void SymbolDatabase::addNewFunction(Scope **info, const Token **tok) +void SymbolDatabase::addNewFunction(Scope **scope, const Token **tok) { const Token *tok1 = *tok; - Scope *new_info = new Scope(this, tok1, *info); + Scope *new_scope = new Scope(this, tok1, *scope); // skip to start of function while (tok1 && tok1->str() != "{") @@ -821,30 +821,30 @@ void SymbolDatabase::addNewFunction(Scope **info, const Token **tok) if (tok1) { - new_info->classStart = tok1; - new_info->classEnd = tok1->link(); + new_scope->classStart = tok1; + new_scope->classEnd = tok1->link(); // syntax error? - if (!new_info->classEnd) + if (!new_scope->classEnd) { - delete new_info; + delete new_scope; while (tok1->next()) tok1 = tok1->next(); - *info = NULL; + *scope = NULL; *tok = tok1; return; } - *info = new_info; + *scope = new_scope; // add space - spaceInfoList.push_back(new_info); + scopeList.push_back(new_scope); *tok = tok1; } } -const Token *SymbolDatabase::initBaseInfo(Scope *info, const Token *tok) +const Token *SymbolDatabase::initBaseInfo(Scope *scope, const Token *tok) { // goto initial '{' const Token *tok2 = tok->tokAt(2); @@ -896,7 +896,7 @@ const Token *SymbolDatabase::initBaseInfo(Scope *info, const Token *tok) } base.name += tok2->str(); - base.spaceInfo = 0; + base.scope = 0; // don't add unhandled templates if (tok2->next()->str() == "<") @@ -920,7 +920,7 @@ const Token *SymbolDatabase::initBaseInfo(Scope *info, const Token *tok) // save pattern for base class name else { - info->derivedFrom.push_back(base); + scope->derivedFrom.push_back(base); } } tok2 = tok2->next(); @@ -1199,12 +1199,12 @@ void Scope::getVariableList() Check::reportError(errmsg); } - const Scope *spaceInfo = NULL; + const Scope *scope = NULL; if (typetok) - spaceInfo = check->findVariableType(this, typetok); + scope = check->findVariableType(this, typetok); - addVariable(vartok, varaccess, isMutable, isStatic, isConst, isClass, spaceInfo); + addVariable(vartok, varaccess, isMutable, isStatic, isConst, isClass, scope); } } } @@ -1314,16 +1314,16 @@ const Scope *SymbolDatabase::findVariableType(const Scope *start, const Token *t { std::list::const_iterator it; - for (it = spaceInfoList.begin(); it != spaceInfoList.end(); ++it) + for (it = scopeList.begin(); it != scopeList.end(); ++it) { - const Scope *info = *it; + const Scope *scope = *it; // skip namespaces and functions - if (info->type == Scope::eNamespace || info->type == Scope::eFunction || info->type == Scope::eGlobal) + if (scope->type == Scope::eNamespace || scope->type == Scope::eFunction || scope->type == Scope::eGlobal) continue; // do the names match? - if (info->className == type->str()) + if (scope->className == type->str()) { // check if type does not have a namespace if (type->previous()->str() != "::") @@ -1331,18 +1331,18 @@ const Scope *SymbolDatabase::findVariableType(const Scope *start, const Token *t const Scope *parent = start; // check if in same namespace - while (parent && parent != info->nestedIn) + while (parent && parent != scope->nestedIn) parent = parent->nestedIn; - if (info->nestedIn == parent) - return info; + if (scope->nestedIn == parent) + return scope; } // type has a namespace else { // FIXME check if namespace path matches supplied path - return info; + return scope; } } } diff --git a/lib/symboldatabase.h b/lib/symboldatabase.h index c2b40a2e5..f1de6c0b0 100644 --- a/lib/symboldatabase.h +++ b/lib/symboldatabase.h @@ -269,22 +269,22 @@ public: { AccessControl access; // public/protected/private std::string name; - Scope *spaceInfo; + Scope *scope; }; struct FriendInfo { std::string name; - Scope *spaceInfo; + Scope *scope; }; - enum SpaceType { eGlobal, eClass, eStruct, eUnion, eNamespace, eFunction }; + enum ScopeType { eGlobal, eClass, eStruct, eUnion, eNamespace, eFunction }; enum NeedInitialization { Unknown, True, False }; Scope(SymbolDatabase *check_, const Token *classDef_, Scope *nestedIn_); SymbolDatabase *check; - SpaceType type; + ScopeType type; std::string className; const Token *classDef; // class/struct/union/namespace token const Token *classStart; // '{' token @@ -307,7 +307,7 @@ public: /** * @brief find if name is in nested list - * @param name name of nested space + * @param name name of nested scope */ Scope * findInNestedList(const std::string & name); @@ -322,7 +322,7 @@ public: const Function *getDestructor() const; /** - * @brief get the number of nested spaces that are not functions + * @brief get the number of nested scopes that are not functions * * This returns the number of user defined types (class, struct, union) * that are defined in this user defined type or namespace. @@ -352,7 +352,7 @@ public: ~SymbolDatabase(); /** @brief Information about all namespaces/classes/structrues */ - std::list spaceInfoList; + std::list scopeList; /** * @brief find a variable type if it's a user defined type diff --git a/lib/tokenize.cpp b/lib/tokenize.cpp index d20d1ac0d..8b069f954 100644 --- a/lib/tokenize.cpp +++ b/lib/tokenize.cpp @@ -7955,7 +7955,7 @@ const Token *Tokenizer::getFunctionTokenByName(const char funcname[]) const std::list::const_iterator i; - for (i = _symbolDatabase->spaceInfoList.begin(); i != _symbolDatabase->spaceInfoList.end(); ++i) + for (i = _symbolDatabase->scopeList.begin(); i != _symbolDatabase->scopeList.end(); ++i) { const Scope *scope = *i; From 8cec4e6de6dbadbbb61c4ca372a0f7f9937db580 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Fri, 21 Jan 2011 07:43:04 +0100 Subject: [PATCH 098/165] Makefile: updated with dmake --- Makefile | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Makefile b/Makefile index 0085b6f90..957055df5 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ # This file is generated by tools/dmake, do not edit. ifndef CXXFLAGS - CXXFLAGS=-Wall -Wextra -Wshadow -pedantic -Wno-long-long -Wfloat-equal -Wcast-qual -Wsign-conversion -g + CXXFLAGS=-Wall -Wextra -Wshadow -pedantic -Wno-long-long -Wfloat-equal -Wcast-qual -Wsign-conversion -Wconversion -g endif ifndef CXX @@ -103,8 +103,8 @@ cppcheck: $(LIBOBJ) $(CLIOBJ) $(EXTOBJ) all: cppcheck testrunner -testrunner: $(TESTOBJ) $(LIBOBJ) $(EXTOBJ) cli/threadexecutor.o cli/cmdlineparser.o cli/cppcheckexecutor.o cli/filelister.o cli/filelister_unix.o - $(CXX) $(CPPFLAGS) $(CXXFLAGS) -o testrunner $(TESTOBJ) $(LIBOBJ) $(EXTOBJ) -lpcre cli/threadexecutor.o cli/cmdlineparser.o cli/filelister.o cli/filelister_unix.o $(LDFLAGS) +testrunner: $(TESTOBJ) $(LIBOBJ) $(EXTOBJ) cli/threadexecutor.o cli/cmdlineparser.o cli/cppcheckexecutor.o + $(CXX) $(CPPFLAGS) $(CXXFLAGS) -o testrunner $(TESTOBJ) $(LIBOBJ) $(EXTOBJ) -lpcre cli/threadexecutor.o cli/cmdlineparser.o cli/cppcheckexecutor.o $(LDFLAGS) test: all ./testrunner From 767e01e24a4666111f76f9c09a5c2122557c5144 Mon Sep 17 00:00:00 2001 From: Robert Reif Date: Fri, 21 Jan 2011 19:54:41 +0100 Subject: [PATCH 099/165] Fixed #2478 (Crash when trying to analyze files (CheckClass::checkReturnPtrThis)) --- lib/checkclass.cpp | 13 +++++++++++-- test/testclass.cpp | 18 ++++++++++++++++++ 2 files changed, 29 insertions(+), 2 deletions(-) diff --git a/lib/checkclass.cpp b/lib/checkclass.cpp index 76217d7f0..c59fcb35e 100644 --- a/lib/checkclass.cpp +++ b/lib/checkclass.cpp @@ -908,7 +908,7 @@ void CheckClass::checkReturnPtrThis(const Scope *scope, const Function *func, co // check if it is a member function for (it = scope->functionList.begin(); it != scope->functionList.end(); ++it) { - // check for a regular function with the same name and a bofy + // check for a regular function with the same name and a body if (it->type == Function::eFunction && it->hasBody && it->token->str() == tok->next()->str()) { @@ -918,7 +918,16 @@ void CheckClass::checkReturnPtrThis(const Scope *scope, const Function *func, co { // make sure it's not a const function if (it->arg->link()->next()->str() != "const") - checkReturnPtrThis(scope, &*it, it->arg->link()->next(), it->arg->link()->next()->link()); + { + /** @todo make sure argument types match */ + // make sure it's not the same function + if (&*it != func) + checkReturnPtrThis(scope, &*it, it->arg->link()->next(), it->arg->link()->next()->link()); + + // just bail for now + else + return; + } } } } diff --git a/test/testclass.cpp b/test/testclass.cpp index 563f07549..431c7252e 100644 --- a/test/testclass.cpp +++ b/test/testclass.cpp @@ -104,6 +104,7 @@ private: TEST_CASE(operatorEqRetRefThis3); // ticket #1405 TEST_CASE(operatorEqRetRefThis4); // ticket #1451 TEST_CASE(operatorEqRetRefThis5); // ticket #1550 + TEST_CASE(operatorEqRetRefThis6); // ticket #2479 TEST_CASE(operatorEqToSelf1); // single class TEST_CASE(operatorEqToSelf2); // nested class TEST_CASE(operatorEqToSelf3); // multiple inheritance @@ -475,6 +476,23 @@ private: ASSERT_EQUALS("[test.cpp:5]: (style) 'operator=' should return reference to self\n", errout.str()); } + void operatorEqRetRefThis6() // ticket #2478 (segmentation fault) + { + checkOpertorEqRetRefThis( + "class UString {\n" + "public:\n" + " UString& assign( const char* c_str );\n" + " UString& operator=( const UString& s );\n" + "};\n" + "UString& UString::assign( const char* c_str ) {\n" + " std::string tmp( c_str );\n" + " return assign( tmp );\n" + "}\n" + "UString& UString::operator=( const UString& s ) {\n" + " return assign( s );\n" + "}\n"); + } + // Check that operator Equal checks for assignment to self void checkOpertorEqToSelf(const char code[]) { From 07e097561ccb574b9f72a0f8f4c3c88e31d8057c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Fri, 21 Jan 2011 20:51:01 +0100 Subject: [PATCH 100/165] dmake and Makefile updates --- Makefile | 8 ++++---- tools/dmake.cpp | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Makefile b/Makefile index 957055df5..de50b8d09 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ # This file is generated by tools/dmake, do not edit. ifndef CXXFLAGS - CXXFLAGS=-Wall -Wextra -Wshadow -pedantic -Wno-long-long -Wfloat-equal -Wcast-qual -Wsign-conversion -Wconversion -g + CXXFLAGS=-Wall -Wextra -Wshadow -pedantic -Wno-long-long -Wfloat-equal -Wcast-qual -Wsign-conversion -g endif ifndef CXX @@ -103,8 +103,8 @@ cppcheck: $(LIBOBJ) $(CLIOBJ) $(EXTOBJ) all: cppcheck testrunner -testrunner: $(TESTOBJ) $(LIBOBJ) $(EXTOBJ) cli/threadexecutor.o cli/cmdlineparser.o cli/cppcheckexecutor.o - $(CXX) $(CPPFLAGS) $(CXXFLAGS) -o testrunner $(TESTOBJ) $(LIBOBJ) $(EXTOBJ) -lpcre cli/threadexecutor.o cli/cmdlineparser.o cli/cppcheckexecutor.o $(LDFLAGS) +testrunner: $(TESTOBJ) $(LIBOBJ) $(EXTOBJ) cli/threadexecutor.o cli/cmdlineparser.o cli/cppcheckexecutor.o cli/filelister.o cli/filelister_unix.o + $(CXX) $(CPPFLAGS) $(CXXFLAGS) -o testrunner $(TESTOBJ) $(LIBOBJ) $(EXTOBJ) -lpcre cli/threadexecutor.o cli/cmdlineparser.o cli/filelister.o cli/filelister_unix.o $(LDFLAGS) test: all ./testrunner @@ -113,7 +113,7 @@ check: all ./testrunner -g -q dmake: tools/dmake.cpp - $(CXX) -o dmake tools/dmake.cpp lib/filelister*.cpp + $(CXX) -o dmake tools/dmake.cpp cli/filelister*.cpp lib/path.cpp -Ilib clean: rm -f lib/*.o cli/*.o test/*.o externals/tinyxml/*.o testrunner cppcheck cppcheck.1 diff --git a/tools/dmake.cpp b/tools/dmake.cpp index 182a82c07..0ff33c099 100644 --- a/tools/dmake.cpp +++ b/tools/dmake.cpp @@ -237,7 +237,7 @@ int main(int argc, char **argv) fout << "check:\tall\n"; fout << "\t./testrunner -g -q\n\n"; fout << "dmake:\ttools/dmake.cpp\n"; - fout << "\t$(CXX) -o dmake tools/dmake.cpp lib/filelister*.cpp\n\n"; + fout << "\t$(CXX) -o dmake tools/dmake.cpp cli/filelister*.cpp lib/path.cpp -Ilib\n\n"; fout << "clean:\n"; #ifdef _WIN32 fout << "\tdel lib\*.o\n\tdel cli\*.o\n\tdel test\*.o\n\tdel *.exe\n"; From a83aced2ec9c97b571b34f64c487343fc0fee96e Mon Sep 17 00:00:00 2001 From: Ettl Martin Date: Fri, 21 Jan 2011 23:48:42 +0100 Subject: [PATCH 101/165] fixed uninitialized members in tests --- test/testsymboldatabase.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/test/testsymboldatabase.cpp b/test/testsymboldatabase.cpp index a5632d7ff..a1154d325 100644 --- a/test/testsymboldatabase.cpp +++ b/test/testsymboldatabase.cpp @@ -28,6 +28,8 @@ public: ,si(NULL, NULL, NULL) ,vartok(NULL) ,typetok(NULL) + ,t(NULL) + ,found(false) {} private: From 69eee86ee4f2d405afdd3e132239c64ed34afcb3 Mon Sep 17 00:00:00 2001 From: Robert Reif Date: Sat, 22 Jan 2011 08:34:24 +0100 Subject: [PATCH 102/165] Tokenizer: Only create 1 symbol database. ticket: #2468 --- lib/tokenize.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/lib/tokenize.cpp b/lib/tokenize.cpp index 8b069f954..dfa75810b 100644 --- a/lib/tokenize.cpp +++ b/lib/tokenize.cpp @@ -7950,8 +7950,7 @@ void Tokenizer::simplifyStd() const Token *Tokenizer::getFunctionTokenByName(const char funcname[]) const { - if (_symbolDatabase == NULL) - getSymbolDatabase(); + getSymbolDatabase(); std::list::const_iterator i; @@ -7971,7 +7970,7 @@ const Token *Tokenizer::getFunctionTokenByName(const char funcname[]) const void Tokenizer::fillFunctionList() { - _symbolDatabase = new SymbolDatabase(this, _settings, _errorLogger); + getSymbolDatabase(); } //--------------------------------------------------------------------------- From 0746c2410a91ce2e6bb838357ede9ea66ab15ed0 Mon Sep 17 00:00:00 2001 From: Robert Reif Date: Sat, 22 Jan 2011 08:36:47 +0100 Subject: [PATCH 103/165] Symbol database: Fixed memory leak. ticket: #2468 --- lib/symboldatabase.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/lib/symboldatabase.cpp b/lib/symboldatabase.cpp index 8cd0be9ff..2545c51f0 100644 --- a/lib/symboldatabase.cpp +++ b/lib/symboldatabase.cpp @@ -842,6 +842,12 @@ void SymbolDatabase::addNewFunction(Scope **scope, const Token **tok) *tok = tok1; } + else + { + delete new_scope; + *scope = NULL; + *tok = NULL; + } } const Token *SymbolDatabase::initBaseInfo(Scope *scope, const Token *tok) From bc31f317bca078d3025b331b7b109ec160ba6b66 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Sat, 22 Jan 2011 09:27:16 +0100 Subject: [PATCH 104/165] Fixed #2491 (Tokenizer::setVarId : wrong handling of function call: 'a(b * c, 1);') --- lib/tokenize.cpp | 2 +- test/testtokenize.cpp | 5 ++--- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/lib/tokenize.cpp b/lib/tokenize.cpp index dfa75810b..c42a7151b 100644 --- a/lib/tokenize.cpp +++ b/lib/tokenize.cpp @@ -3303,7 +3303,7 @@ void Tokenizer::setVarId() // If pattern is "( %type% *|& %var% )" then check if it's a // variable declaration or a multiplication / mask - if (Token::Match(tok, "( %type% *|& %var% )") && !tok->next()->isStandardType()) + if (Token::Match(tok, "( %type% *|& %var% [),]") && !tok->next()->isStandardType()) { if (!Token::Match(tok->previous(), "%type%")) continue; diff --git a/test/testtokenize.cpp b/test/testtokenize.cpp index ee5207b96..dfa87d3bb 100644 --- a/test/testtokenize.cpp +++ b/test/testtokenize.cpp @@ -2722,6 +2722,7 @@ private: void varidFunctionCall2() { + // #2491 const std::string code("void f(int b) {\n" " x(a*b,10);\n" "}"); @@ -2730,8 +2731,7 @@ private: "2: x ( a * b"); const std::string expected2(" , 10 ) ;\n" "3: }\n"); - TODO_ASSERT_EQUALS(expected1+"@1"+expected2, tokenizeDebugListing(code)); - ASSERT_EQUALS(expected1+"@2"+expected2, tokenizeDebugListing(code)); + ASSERT_EQUALS(expected1+"@1"+expected2, tokenizeDebugListing(code)); } void varidFunctionCall3() @@ -2751,7 +2751,6 @@ private: ASSERT_EQUALS(expected, tokenizeDebugListing(code)); } - void varidStl() { const std::string actual = tokenizeDebugListing( From 5c88129f0189cf1cf1bfcea16131d3b9498c38fb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Sat, 22 Jan 2011 12:42:53 +0100 Subject: [PATCH 105/165] Fixed #2484 (false positive because template is not instantiated properly) --- lib/tokenize.cpp | 45 ++++++++++++++++----------------------------- 1 file changed, 16 insertions(+), 29 deletions(-) diff --git a/lib/tokenize.cpp b/lib/tokenize.cpp index c42a7151b..573bbffb6 100644 --- a/lib/tokenize.cpp +++ b/lib/tokenize.cpp @@ -2651,35 +2651,6 @@ static void removeTemplates(Token *tok) void Tokenizer::simplifyTemplates() { - // Don't simplify C files - { - if (_files.empty()) - return; - - std::string::size_type pos = _files[0].rfind("."); - if (pos == std::string::npos) - return; - - const std::string ext(_files[0].substr(pos)); - if (ext == ".c" || ext == ".C") - return; - } - - // Remove "typename" unless used in template arguments.. - for (Token *tok = _tokens; tok; tok = tok->next()) - { - if (tok->str() == "typename") - tok->deleteThis(); - - if (Token::simpleMatch(tok, "template <")) - { - while (tok && tok->str() != ">") - tok = tok->next(); - if (!tok) - break; - } - } - std::set expandedtemplates; // Locate specialized templates.. @@ -2775,6 +2746,22 @@ void Tokenizer::simplifyTemplates() return; } + // There are templates.. + // Remove "typename" unless used in template arguments.. + for (Token *tok = _tokens; tok; tok = tok->next()) + { + if (tok->str() == "typename") + tok->deleteThis(); + + if (Token::simpleMatch(tok, "template <")) + { + while (tok && tok->str() != ">") + tok = tok->next(); + if (!tok) + break; + } + } + // Locate possible instantiations of templates.. std::list used; for (Token *tok = _tokens; tok; tok = tok->next()) From 9551332321489d2c6fa24b99e4dadcee4e46f8f1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Sat, 22 Jan 2011 13:00:03 +0100 Subject: [PATCH 106/165] Fixed #2459 (False positive with unused private function and friend) --- lib/checkclass.cpp | 5 +++++ test/testunusedprivfunc.cpp | 13 +++++++++++++ 2 files changed, 18 insertions(+) diff --git a/lib/checkclass.cpp b/lib/checkclass.cpp index c59fcb35e..f8a7ddda4 100644 --- a/lib/checkclass.cpp +++ b/lib/checkclass.cpp @@ -583,6 +583,11 @@ void CheckClass::privateFunctions() if (Token::findmatch(_tokenizer->tokens(), "; __property ;")) return; + // skip checking if there are friends + // Todo: check if each class has friends + if (Token::findmatch(_tokenizer->tokens(), "friend")) + return; + // #2407 calls from operator() is not detected // TODO: Don't bailout. Detect the call. if (Token::findmatch(_tokenizer->tokens(), "operator ( )")) diff --git a/test/testunusedprivfunc.cpp b/test/testunusedprivfunc.cpp index d5e6c3c8c..ff6f84c60 100644 --- a/test/testunusedprivfunc.cpp +++ b/test/testunusedprivfunc.cpp @@ -53,6 +53,8 @@ private: TEST_CASE(derivedClass); // skip warning for derived classes. It might be a virtual function. + TEST_CASE(friendClass); + TEST_CASE(borland); // skip FP when using __property // No false positives when there are "unused" templates that are removed in the simplified token list @@ -387,6 +389,17 @@ private: ASSERT_EQUALS("", errout.str()); } + void friendClass() + { + // ticket #2459 - friend class + check("class Foo {\n" + "private:\n" + " friend Bar;\n" + " void f() { }\n" + "};"); + ASSERT_EQUALS("", errout.str()); + } + void borland() { // ticket #2034 - Borland C++ __property From f947955c6348f9a24d1a48357f18a5dd6f97ec38 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Sat, 22 Jan 2011 13:40:19 +0100 Subject: [PATCH 107/165] Fixed #2492 (False positive: memory leak 'return &self->foo;') --- lib/checkmemoryleak.cpp | 3 ++- test/testmemleak.cpp | 16 ++++++++++++++-- 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/lib/checkmemoryleak.cpp b/lib/checkmemoryleak.cpp index 72e58f20c..dcb203360 100644 --- a/lib/checkmemoryleak.cpp +++ b/lib/checkmemoryleak.cpp @@ -3101,7 +3101,8 @@ void CheckMemoryLeakStructMember::check() else if (tok3->str() == "return") { // Returning from function without deallocating struct member? - if (!Token::Match(tok3, "return %varid% ;", structid)) + if (!Token::Match(tok3, "return %varid% ;", structid) && + !Token::Match(tok3, "return & %varid% .", structid)) { memoryLeak(tok3, (vartok->str() + "." + tok2->strAt(2)).c_str(), Malloc); } diff --git a/test/testmemleak.cpp b/test/testmemleak.cpp index 36978ff79..4cebd567f 100644 --- a/test/testmemleak.cpp +++ b/test/testmemleak.cpp @@ -4206,7 +4206,8 @@ private: TEST_CASE(goto_); // Don't report errors if the struct is returned - TEST_CASE(ret); + TEST_CASE(ret1); + TEST_CASE(ret2); // assignments TEST_CASE(assign); @@ -4284,7 +4285,7 @@ private: ASSERT_EQUALS("", errout.str()); } - void ret() + void ret1() { check("static ABC * foo()\n" "{\n" @@ -4301,6 +4302,17 @@ private: ASSERT_EQUALS("", errout.str()); } + void ret2() + { + check("static ABC * foo()\n" + "{\n" + " struct ABC *abc = malloc(sizeof(struct ABC));\n" + " abc->a = malloc(10);\n" + " return &abc->self;\n" + "}\n"); + ASSERT_EQUALS("", errout.str()); + } + void assign() { check("static void foo()\n" From 1e25d74ba43e71fc3277d3e8ac70879e069a3334 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Sat, 22 Jan 2011 17:35:54 +0100 Subject: [PATCH 108/165] Class: better check if there are friends. ticket: #2459 --- lib/checkclass.cpp | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/lib/checkclass.cpp b/lib/checkclass.cpp index f8a7ddda4..2881d894b 100644 --- a/lib/checkclass.cpp +++ b/lib/checkclass.cpp @@ -583,11 +583,6 @@ void CheckClass::privateFunctions() if (Token::findmatch(_tokenizer->tokens(), "; __property ;")) return; - // skip checking if there are friends - // Todo: check if each class has friends - if (Token::findmatch(_tokenizer->tokens(), "friend")) - return; - // #2407 calls from operator() is not detected // TODO: Don't bailout. Detect the call. if (Token::findmatch(_tokenizer->tokens(), "operator ( )")) @@ -609,6 +604,10 @@ void CheckClass::privateFunctions() if (!scope->derivedFrom.empty()) continue; + // skip checking if there are friends + if (!scope->friendList.empty()) + continue; + // Locate some class const Token *tok1 = scope->classDef; From 8abae6f1e52283454ecebf009811bd77d1943f35 Mon Sep 17 00:00:00 2001 From: Robert Reif Date: Sat, 22 Jan 2011 17:43:36 +0100 Subject: [PATCH 109/165] Symbol database: match copy-constructor better. ticket: #2484 --- lib/symboldatabase.cpp | 4 ++++ test/testconstructors.cpp | 40 +++++++++++++++++++++++++++++++++++++-- 2 files changed, 42 insertions(+), 2 deletions(-) diff --git a/lib/symboldatabase.cpp b/lib/symboldatabase.cpp index 2545c51f0..dd288b5c6 100644 --- a/lib/symboldatabase.cpp +++ b/lib/symboldatabase.cpp @@ -155,6 +155,10 @@ SymbolDatabase::SymbolDatabase(const Tokenizer *tokenizer, const Settings *setti Token::Match(function.tokenDef, "%var% ( const %var% & %var% )")) && function.tokenDef->strAt(3) == scope->className) function.type = Function::eCopyConstructor; + else if ((Token::Match(function.tokenDef, "%var% ( %var% & )") || + Token::Match(function.tokenDef, "%var% ( %var% & %var% )")) && + function.tokenDef->strAt(2) == scope->className) + function.type = Function::eCopyConstructor; else function.type = Function::eConstructor; diff --git a/test/testconstructors.cpp b/test/testconstructors.cpp index ba5e90b31..2be7e5672 100644 --- a/test/testconstructors.cpp +++ b/test/testconstructors.cpp @@ -76,7 +76,8 @@ private: TEST_CASE(initvar_private_constructor); // BUG 2354171 - private constructor TEST_CASE(initvar_copy_constructor); // ticket #1611 TEST_CASE(initvar_nested_constructor); // ticket #1375 - TEST_CASE(initvar_nocopy); // ticket #2474 + TEST_CASE(initvar_nocopy1); // ticket #2474 + TEST_CASE(initvar_nocopy2); // ticket #2484 TEST_CASE(initvar_destructor); // No variables need to be initialized in a destructor @@ -906,7 +907,7 @@ private: "[test.cpp:24]: (warning) Member variable 'D::d' is not initialised in the constructor.\n", errout.str()); } - void initvar_nocopy() // ticket #2474 + void initvar_nocopy1() // ticket #2474 { check("class B\n" "{\n" @@ -952,6 +953,41 @@ private: "[test.cpp:7]: (warning) Member variable 'A::m_SemVar' is not assigned a value in 'A::operator='\n", errout.str()); } + void initvar_nocopy2() // ticket #2484 + { + check("class B\n" + "{\n" + " B (B & Var);\n" + " B & operator= (const B & Var);\n" + "};\n" + "class A\n" + "{\n" + " B m_SemVar;\n" + "public:\n" + " A(){}\n" + " A(const A&){}\n" + " const A& operator=(const A&){return *this;}\n" + "};\n"); + ASSERT_EQUALS("", errout.str()); + + check("class B\n" + "{\n" + "public:\n" + " B (B & Var);\n" + " B & operator= (const B & Var);\n" + "};\n" + "class A\n" + "{\n" + " B m_SemVar;\n" + "public:\n" + " A(){}\n" + " A(const A&){}\n" + " const A& operator=(const A&){return *this;}\n" + "};\n"); + ASSERT_EQUALS("[test.cpp:12]: (warning) Member variable 'A::m_SemVar' is not initialised in the constructor.\n" + "[test.cpp:13]: (warning) Member variable 'A::m_SemVar' is not assigned a value in 'A::operator='\n", errout.str()); + } + void initvar_destructor() { check("class Fred\n" From 27dce075e037461f18377d04112c45f3d01108de Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Debrard=20S=C3=A9bastien?= Date: Sat, 22 Jan 2011 19:21:56 +0100 Subject: [PATCH 110/165] Fixed #155 (check size of a variable whose type is a sized array) --- lib/checkother.cpp | 45 ++++++++++++++++++++++++ lib/checkother.h | 7 ++++ test/testother.cpp | 85 ++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 137 insertions(+) diff --git a/lib/checkother.cpp b/lib/checkother.cpp index 0d0808ece..2ff551e57 100644 --- a/lib/checkother.cpp +++ b/lib/checkother.cpp @@ -78,6 +78,35 @@ void CheckOther::checkFflushOnInputStream() } } + +void CheckOther::checkSizeofForArrayParameter() +{ + for (const Token *tok = _tokenizer->tokens(); tok; tok = tok->next()) + { + if (Token::Match(tok, "sizeof ( %var% )") || Token::Match(tok, "sizeof %var% ")) + { + int tokIdx = 1; + if (tok->tokAt(tokIdx)->str() == "(") + { + ++tokIdx; + } + if (tok->tokAt(tokIdx)->varId() > 0) + { + const Token *declTok = Token::findmatch(_tokenizer->tokens(), "%varid%", tok->tokAt(tokIdx)->varId()); + if (declTok) + { + if ((Token::simpleMatch(declTok->next(), "[")) && !(Token::simpleMatch(declTok->next()->link(), "] = {")) && !(Token::simpleMatch(declTok->next()->link(), "] ;"))) + { + sizeofForArrayParameterError(tok); + } + } + } + } + } +} + + + //--------------------------------------------------------------------------- // switch (x) // { @@ -454,6 +483,22 @@ void CheckOther::invalidScanf() } } +void CheckOther::sizeofForArrayParameterError(const Token *tok) +{ + reportError(tok, Severity::error, + "sizeofwithsilentarraypointer", "Using sizeof for array given as function argument " + "returns the size of pointer.\n" + "Giving array as function parameter and then using sizeof-operator for the array " + "argument. In this case the sizeof-operator returns the size of pointer (in the " + " system). It does not return the size of the whole array in bytes as might be " + "expected. For example, this code:\n" + " int f(char a[100]) {\n" + " return sizeof(a);\n" + " }\n" + " returns 4 (in 32-bit systems) or 8 (in 64-bit systems) instead of 100 (the " + "size of the array in bytes)." + ); +} void CheckOther::invalidScanfError(const Token *tok) { reportError(tok, Severity::warning, diff --git a/lib/checkother.h b/lib/checkother.h index 9e49d8dce..0d0798dd7 100644 --- a/lib/checkother.h +++ b/lib/checkother.h @@ -62,6 +62,7 @@ public: checkOther.sizeofCalculation(); checkOther.checkRedundantAssignmentInSwitch(); checkOther.checkAssignmentInAssert(); + checkOther.checkSizeofForArrayParameter(); } /** @brief Run checks against the simplified token list */ @@ -170,6 +171,9 @@ public: /** @brief %Check for filling zero bytes with memset() */ void checkMemsetZeroBytes(); + /** @brief %Check for using sizeof with array given as function argument */ + void checkSizeofForArrayParameter(); + // Error messages.. void cstyleCastError(const Token *tok); void dangerousUsageStrtolError(const Token *tok); @@ -193,6 +197,7 @@ public: void misusedScopeObjectError(const Token *tok, const std::string &varname); void catchExceptionByValueError(const Token *tok); void memsetZeroBytesError(const Token *tok, const std::string &varname); + void sizeofForArrayParameterError(const Token *tok); void getErrorMessages(ErrorLogger *errorLogger, const Settings *settings) { @@ -205,6 +210,7 @@ public: c.mathfunctionCallError(0); c.fflushOnInputStreamError(0, "stdin"); c.misusedScopeObjectError(NULL, "varname"); + c.sizeofForArrayParameterError(0); // style/warning c.cstyleCastError(0); @@ -247,6 +253,7 @@ public: "* using fflush() on an input stream\n" "* scoped object destroyed immediately after construction\n" "* assignment in an assert statement\n" + "* sizeof for array given as function argument\n" // style "* C-style pointer cast in cpp file\n" diff --git a/test/testother.cpp b/test/testother.cpp index 935c7df32..934ab01ca 100644 --- a/test/testother.cpp +++ b/test/testother.cpp @@ -97,6 +97,8 @@ private: TEST_CASE(catchExceptionByValue); TEST_CASE(memsetZeroBytes); + + TEST_CASE(sizeofWithSilentArrayPointer); } void check(const char code[], const char *filename = NULL) @@ -118,6 +120,7 @@ private: checkOther.sizeofCalculation(); checkOther.checkRedundantAssignmentInSwitch(); checkOther.checkAssignmentInAssert(); + checkOther.checkSizeofForArrayParameter(); // Simplify token list.. tokenizer.simplifyTokenList(); @@ -1659,6 +1662,88 @@ private: " bytes of \"p\". Second and third arguments might be inverted.\n", errout.str()); ASSERT_EQUALS("", errout.str()); } + + void sizeofWithSilentArrayPointer() + { + check("void f() {\n" + " int a[10];\n" + " std::cout << sizeof(a) / sizeof(int) << std::endl;\n" + "}\n" + ); + ASSERT_EQUALS("", errout.str()); + + check("void f() {\n" + " unsigned int a = 2;\n" + " unsigned int b = 2;\n" + " int c[(a+b)];\n" + " std::cout << sizeof(c) / sizeof(int) << std::endl;\n" + "}\n" + ); + ASSERT_EQUALS("", errout.str()); + + check("void f() {\n" + " unsigned int a = { 2 };\n" + " unsigned int b[] = { 0 };\n" + " int c[a[b[0]]];\n" + " std::cout << sizeof(c) / sizeof(int) << std::endl;\n" + "}\n" + ); + ASSERT_EQUALS("", errout.str()); + + + check("void f() {\n" + " unsigned int a[] = { 1 };\n" + " unsigned int b = 2;\n" + " int c[(a[0]+b)];\n" + " std::cout << sizeof(c) / sizeof(int) << std::endl;\n" + "}\n" + ); + ASSERT_EQUALS("", errout.str()); + + check("void f() {\n" + " int a[] = { 1, 2, 3 };\n" + " std::cout << sizeof(a) / sizeof(int) << std::endl;\n" + "}\n" + ); + ASSERT_EQUALS("", errout.str()); + + check("void f() {\n" + " int a[3] = { 1, 2, 3 };\n" + " std::cout << sizeof(a) / sizeof(int) << std::endl;\n" + "}\n" + ); + ASSERT_EQUALS("", errout.str()); + + check("void f( int a[]) {\n" + " std::cout << sizeof(a) / sizeof(int) << std::endl;\n" + "}\n" + ); + ASSERT_EQUALS("[test.cpp:2]: (error) Using sizeof for array given as " + "function argument returns the size of pointer.\n", errout.str()); + + check("void f( int a[]) {\n" + " std::cout << sizeof a / sizeof(int) << std::endl;\n" + "}\n" + ); + ASSERT_EQUALS("[test.cpp:2]: (error) Using sizeof for array given as " + "function argument returns the size of pointer.\n", errout.str()); + + check("void f( int a[3] ) {\n" + " std::cout << sizeof(a) / sizeof(int) << std::endl;\n" + "}\n" + ); + ASSERT_EQUALS("[test.cpp:2]: (error) Using sizeof for array given as " + "function argument returns the size of pointer.\n", errout.str()); + + check("void f(int *p) {\n" + " p[0] = 0;\n" + " sizeof(p);\n" + "}\n" + ); + ASSERT_EQUALS("", errout.str()); + + } + }; REGISTER_TEST(TestOther) From 9d3b242cd8abf6f014457cba869113a160500c1e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Sat, 22 Jan 2011 21:31:26 +0100 Subject: [PATCH 111/165] Fixed #1952 (false negative: buffer acces out of bounds with memcpy) --- lib/checkbufferoverrun.cpp | 83 +++++++++++++++++++++----------------- lib/checkbufferoverrun.h | 11 ++++- test/testbufferoverrun.cpp | 10 +++++ 3 files changed, 66 insertions(+), 38 deletions(-) diff --git a/lib/checkbufferoverrun.cpp b/lib/checkbufferoverrun.cpp index aa18d193d..5f7e42619 100644 --- a/lib/checkbufferoverrun.cpp +++ b/lib/checkbufferoverrun.cpp @@ -536,7 +536,7 @@ void CheckBufferOverrun::parse_for_body(const Token *tok2, const ArrayInfo &arra -void CheckBufferOverrun::checkFunctionCall(const Token &tok, unsigned int par, const ArrayInfo &arrayInfo) +void CheckBufferOverrun::checkFunctionParameter(const Token &tok, unsigned int par, const ArrayInfo &arrayInfo) { // total_size : which parameter in function call takes the total size? std::map total_size; @@ -721,6 +721,42 @@ void CheckBufferOverrun::checkFunctionCall(const Token &tok, unsigned int par, c } +void CheckBufferOverrun::checkFunctionCall(const Token *tok, const ArrayInfo &arrayInfo) +{ + + // 1st parameter.. + if (Token::Match(tok->tokAt(2), "%varid% ,|)", arrayInfo.varid)) + checkFunctionParameter(*tok, 1, arrayInfo); + else if (Token::Match(tok->tokAt(2), "%varid% + %num% ,|)", arrayInfo.varid)) + { + const ArrayInfo ai(arrayInfo.limit(MathLib::toLongNumber(tok->strAt(4)))); + checkFunctionParameter(*tok, 1, ai); + } + + // goto 2nd parameter and check it.. + for (const Token *tok2 = tok->tokAt(2); tok2; tok2 = tok2->next()) + { + if (tok2->str() == "(") + { + tok2 = tok2->link(); + continue; + } + if (tok2->str() == ";" || tok2->str() == ")") + break; + if (tok2->str() == ",") + { + if (Token::Match(tok2, ", %varid% ,|)", arrayInfo.varid)) + checkFunctionParameter(*tok, 2, arrayInfo); + else if (Token::Match(tok2, ", %varid% + %num% ,|)", arrayInfo.varid)) + { + const ArrayInfo ai(arrayInfo.limit(MathLib::toLongNumber(tok2->strAt(3)))); + checkFunctionParameter(*tok, 2, ai); + } + break; + } + } +} + void CheckBufferOverrun::checkScope(const Token *tok, const std::vector &varname, const MathLib::bigint size, const MathLib::bigint total_size, unsigned int varid) { @@ -827,9 +863,9 @@ void CheckBufferOverrun::checkScope(const Token *tok, const std::vectortokAt(4 + varc), "snprintf size"); } - // Function calls not handled + // Check function call.. if (Token::Match(tok, "%var% (")) { - continue; + // No varid => function calls are not handled + if (varid == 0) + continue; + + const ArrayInfo arrayInfo(varid, varnames, size, total_size / size); + checkFunctionCall(tok, arrayInfo); } // undefined behaviour: result of pointer arithmetic is out of bounds @@ -1081,37 +1122,7 @@ void CheckBufferOverrun::checkScope(const Token *tok, const ArrayInfo &arrayInfo // Check function call.. if (Token::Match(tok, "%var% (")) { - // 1st parameter.. - if (Token::Match(tok->tokAt(2), "%varid% ,|)", arrayInfo.varid)) - checkFunctionCall(*tok, 1, arrayInfo); - else if (Token::Match(tok->tokAt(2), "%varid% + %num% ,|)", arrayInfo.varid)) - { - const ArrayInfo ai(arrayInfo.limit(MathLib::toLongNumber(tok->strAt(4)))); - checkFunctionCall(*tok, 1, ai); - } - - // goto 2nd parameter and check it.. - for (const Token *tok2 = tok->tokAt(2); tok2; tok2 = tok2->next()) - { - if (tok2->str() == "(") - { - tok2 = tok2->link(); - continue; - } - if (tok2->str() == ";" || tok2->str() == ")") - break; - if (tok2->str() == ",") - { - if (Token::Match(tok2, ", %varid% ,|)", arrayInfo.varid)) - checkFunctionCall(*tok, 2, arrayInfo); - else if (Token::Match(tok2, ", %varid% + %num% ,|)", arrayInfo.varid)) - { - const ArrayInfo ai(arrayInfo.limit(MathLib::toLongNumber(tok2->strAt(3)))); - checkFunctionCall(*tok, 2, ai); - } - break; - } - } + checkFunctionCall(tok, arrayInfo); } if (_settings->_checkCodingStyle) diff --git a/lib/checkbufferoverrun.h b/lib/checkbufferoverrun.h index 5f3b964b8..c2e77a20b 100644 --- a/lib/checkbufferoverrun.h +++ b/lib/checkbufferoverrun.h @@ -169,12 +169,19 @@ public: void parse_for_body(const Token *tok2, const ArrayInfo &arrayInfo, const std::string &strindex, bool condition_out_of_bounds, unsigned int counter_varid, const std::string &min_counter_value, const std::string &max_counter_value); /** - * Helper function for checkScope - check a function call + * Helper function for checkFunctionCall - check a function parameter * \param tok token for the function name * \param par on what parameter is the array used * \param arrayInfo the array information */ - void checkFunctionCall(const Token &tok, const unsigned int par, const ArrayInfo &arrayInfo); + void checkFunctionParameter(const Token &tok, const unsigned int par, const ArrayInfo &arrayInfo); + + /** + * Helper function that checks if the array is used and if so calls the checkFunctionCall + * @param tok token that matches "%var% (" + * @param arrayInfo the array information + */ + void checkFunctionCall(const Token *tok, const ArrayInfo &arrayInfo); void arrayIndexOutOfBounds(const Token *tok, MathLib::bigint size, MathLib::bigint index); void arrayIndexOutOfBounds(const Token *tok, const ArrayInfo &arrayInfo, const std::vector &index); diff --git a/test/testbufferoverrun.cpp b/test/testbufferoverrun.cpp index 02aa9281d..70a99b07f 100644 --- a/test/testbufferoverrun.cpp +++ b/test/testbufferoverrun.cpp @@ -180,6 +180,7 @@ private: TEST_CASE(alloc1); // Buffer allocated with new TEST_CASE(alloc2); // Buffer allocated with malloc TEST_CASE(alloc3); // statically allocated buffer + TEST_CASE(malloc_memset); // using memset on buffer allocated with malloc TEST_CASE(memset1); TEST_CASE(memset2); @@ -2381,6 +2382,15 @@ private: ASSERT_EQUALS("[test.cpp:4]: (error) Array 's[1]' index 10 out of bounds\n", errout.str()); } + void malloc_memset() + { + check("void f() {\n" + " char *p = malloc(10);\n" + " memset(p,0,100);\n" + "}\n"); + ASSERT_EQUALS("[test.cpp:3]: (error) Buffer access out-of-bounds\n", errout.str()); + } + void memset1() { check("void foo()\n" From 86e682226455ce0451954adf4623bd4fb9260f60 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Sun, 23 Jan 2011 08:38:09 +0100 Subject: [PATCH 112/165] Fixed #2493 (false positive: (error) Possible null pointer dereference: pExpr) --- lib/checknullpointer.cpp | 2 +- test/testnullpointer.cpp | 13 +++++++++++++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/lib/checknullpointer.cpp b/lib/checknullpointer.cpp index eb9c38f71..cb4c9702b 100644 --- a/lib/checknullpointer.cpp +++ b/lib/checknullpointer.cpp @@ -608,7 +608,7 @@ void CheckNullPointer::nullPointerByCheckAndDeRef() } } - if (Token::Match(tok2, "goto|return|continue|break|throw|if")) + if (Token::Match(tok2, "goto|return|continue|break|throw|if|switch")) { if (Token::Match(tok2, "return * %varid%", varid)) nullPointerError(tok2, tok->strAt(3)); diff --git a/test/testnullpointer.cpp b/test/testnullpointer.cpp index 81263f9ce..1742fab5a 100644 --- a/test/testnullpointer.cpp +++ b/test/testnullpointer.cpp @@ -868,6 +868,19 @@ private: " fred->a();\n" "}"); ASSERT_EQUALS("", errout.str()); + + // #2493 - switch + check("void f(Fred *fred) {\n" + " if (fred == NULL) {\n" + " x = 0;\n" + " }\n" + " switch (x) {\n" + " case 1:\n" + " fred->a();\n" + " break;\n" + " };\n" + "}"); + ASSERT_EQUALS("", errout.str()); } // Test CheckNullPointer::nullConstantDereference From 2a3cce50019e1b24b5e3255c2f439bc44b572134 Mon Sep 17 00:00:00 2001 From: Robert Reif Date: Sun, 23 Jan 2011 08:41:31 +0100 Subject: [PATCH 113/165] Symbol database: fixed corruptions. ticket: #2468 --- lib/symboldatabase.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/lib/symboldatabase.cpp b/lib/symboldatabase.cpp index dd288b5c6..ff4434098 100644 --- a/lib/symboldatabase.cpp +++ b/lib/symboldatabase.cpp @@ -217,11 +217,13 @@ SymbolDatabase::SymbolDatabase(const Tokenizer *tokenizer, const Settings *setti function.isPure = true; // count the number of constructors - if (function.type == Function::eConstructor || function.type == Function::eCopyConstructor) + if (function.type == Function::eConstructor || + function.type == Function::eCopyConstructor) scope->numConstructors++; // assume implementation is inline (definition and implementation same) function.token = function.tokenDef; + function.arg = function.argDef; // out of line function if (Token::Match(end, ") const| ;") || @@ -238,7 +240,6 @@ SymbolDatabase::SymbolDatabase(const Tokenizer *tokenizer, const Settings *setti { function.isInline = true; function.hasBody = true; - function.arg = function.argDef; scope->functionList.push_back(function); @@ -831,6 +832,7 @@ void SymbolDatabase::addNewFunction(Scope **scope, const Token **tok) // syntax error? if (!new_scope->classEnd) { + (*scope)->nestedList.pop_back(); delete new_scope; while (tok1->next()) tok1 = tok1->next(); @@ -848,6 +850,7 @@ void SymbolDatabase::addNewFunction(Scope **scope, const Token **tok) } else { + (*scope)->nestedList.pop_back(); delete new_scope; *scope = NULL; *tok = NULL; From b10f0aabd65aa1d0fb6c0c7159d3bc3340284d40 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Sun, 23 Jan 2011 09:04:34 +0100 Subject: [PATCH 114/165] Fixed #2376 (simplifyTypedef: upx-ucl) --- lib/tokenize.cpp | 6 ++++++ test/testsimplifytokens.cpp | 10 ++++++++++ 2 files changed, 16 insertions(+) diff --git a/lib/tokenize.cpp b/lib/tokenize.cpp index 573bbffb6..74b9c3f3f 100644 --- a/lib/tokenize.cpp +++ b/lib/tokenize.cpp @@ -2408,6 +2408,12 @@ bool Tokenizer::tokenize(std::istream &code, // typedef.. simplifyTypedef(); + // Fix internal error by updating links (#2376) + // TODO: Remove this "createLinks". Make sure that the testcase + // TestSimplifyTokens::simplifyTypedefFunction8 + // doesn't fail. + createLinks(); + // enum.. simplifyEnum(); diff --git a/test/testsimplifytokens.cpp b/test/testsimplifytokens.cpp index 631c331c5..f41f58c51 100644 --- a/test/testsimplifytokens.cpp +++ b/test/testsimplifytokens.cpp @@ -242,6 +242,7 @@ private: TEST_CASE(simplifyTypedefFunction5); TEST_CASE(simplifyTypedefFunction6); TEST_CASE(simplifyTypedefFunction7); + TEST_CASE(simplifyTypedefFunction8); TEST_CASE(reverseArraySyntax) TEST_CASE(simplify_numeric_condition) @@ -5407,6 +5408,15 @@ private: ASSERT_EQUALS("", errout.str()); } + void simplifyTypedefFunction8() + { + // #2376 - internal error + const char code[] = "typedef int f_expand(const nrv_byte *);\n" + "void f(f_expand *(*get_fexp(int))){}\n"; + checkSimplifyTypedef(code); + ASSERT_EQUALS("", errout.str()); // make sure that there is no internal error + } + void reverseArraySyntax() { ASSERT_EQUALS("a [ 13 ]", tok("13[a]")); From 586cbd5839f7e9ba88f51abf81edb5d7b70019a0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Sun, 23 Jan 2011 09:38:38 +0100 Subject: [PATCH 115/165] Tokenizer: Upon createLinks error, report error and bailout --- lib/tokenize.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/lib/tokenize.cpp b/lib/tokenize.cpp index 74b9c3f3f..ee640937a 100644 --- a/lib/tokenize.cpp +++ b/lib/tokenize.cpp @@ -2412,7 +2412,12 @@ bool Tokenizer::tokenize(std::istream &code, // TODO: Remove this "createLinks". Make sure that the testcase // TestSimplifyTokens::simplifyTypedefFunction8 // doesn't fail. - createLinks(); + if (!createLinks()) + { + // Source has syntax errors, can't proceed + cppcheckError(0); + return false; + } // enum.. simplifyEnum(); From c04107131b791b37bcd6e42090931fdc59d8bfbb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Sun, 23 Jan 2011 14:34:26 +0100 Subject: [PATCH 116/165] when using TODO_ASSERT_EQUALS it's a good idea to pair it with a ASSERT_EQUALS --- test/testuninitvar.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/test/testuninitvar.cpp b/test/testuninitvar.cpp index 22e724ea2..b444f668e 100644 --- a/test/testuninitvar.cpp +++ b/test/testuninitvar.cpp @@ -799,6 +799,7 @@ private: " }\n" "}\n"); TODO_ASSERT_EQUALS("[test.cpp:4]: (error) Uninitialized variable: pItem\n", errout.str()); + ASSERT_EQUALS("", errout.str()); // current result } // switch.. From f5b26222ff0c0cbf61d9a042c5640fe3358fc0fd Mon Sep 17 00:00:00 2001 From: Robert Reif Date: Sun, 23 Jan 2011 22:31:35 +0100 Subject: [PATCH 117/165] Symbol database: better handling of functions returning function pointer. ticket: #2468 --- lib/symboldatabase.cpp | 42 ++++++++++++++++++++++++++++++++++-------- 1 file changed, 34 insertions(+), 8 deletions(-) diff --git a/lib/symboldatabase.cpp b/lib/symboldatabase.cpp index ff4434098..08c8d5486 100644 --- a/lib/symboldatabase.cpp +++ b/lib/symboldatabase.cpp @@ -281,6 +281,8 @@ SymbolDatabase::SymbolDatabase(const Tokenizer *tokenizer, const Settings *setti // has body? if (Token::Match(argStart->link(), ") const| {|:")) { + Scope *old_scope = scope; + // class function if (tok->previous() && tok->previous()->str() == "::") addFunction(&scope, &tok, argStart); @@ -310,19 +312,17 @@ SymbolDatabase::SymbolDatabase(const Tokenizer *tokenizer, const Settings *setti function.arg = function.argDef; function.type = Function::eFunction; - Scope *old_scope = scope; - addNewFunction(&scope, &tok); if (scope) old_scope->functionList.push_back(function); + } - // syntax error - else - { - scope = old_scope; - break; - } + // syntax error + if (!scope) + { + scope = old_scope; + break; } } @@ -339,11 +339,37 @@ SymbolDatabase::SymbolDatabase(const Tokenizer *tokenizer, const Settings *setti // regular function else + { + Function function; + + // save the function definition argument start '(' + function.argDef = argStart; + + // save the access type + function.access = Public; + + // save the function name location + function.tokenDef = funcStart; + function.token = funcStart; + + function.isInline = false; + function.hasBody = true; + function.arg = function.argDef; + function.type = Function::eFunction; + function.retFuncPtr = true; + addNewFunction(&scope, &tok1); + if (scope) + old_scope->functionList.push_back(function); + } + // syntax error? if (!scope) + { scope = old_scope; + break; + } tok = tok1; } From f611c9aec709d58056f2621866e111cdfea29da0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Mon, 24 Jan 2011 18:15:56 +0100 Subject: [PATCH 118/165] cleanup old ifdefs in cmdlineparser --- cli/cmdlineparser.cpp | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/cli/cmdlineparser.cpp b/cli/cmdlineparser.cpp index e4143d052..af6e677af 100644 --- a/cli/cmdlineparser.cpp +++ b/cli/cmdlineparser.cpp @@ -170,14 +170,12 @@ bool CmdLineParser::ParseFromArgs(int argc, const char* const argv[]) else if (strcmp(argv[i], "--xml") == 0) _settings->_xml = true; -#ifndef NDEBUG - // Experimental: Write results in xml2 format + // Write results in xml2 format else if (strcmp(argv[i], "--xml-version=2") == 0) { _settings->_xml = true; _settings->_xml_version = 2; } -#endif // Only print something when there are errors else if (strcmp(argv[i], "-q") == 0 || strcmp(argv[i], "--quiet") == 0) @@ -409,8 +407,6 @@ bool CmdLineParser::ParseFromArgs(int argc, const char* const argv[]) _settings->_showtime = SHOWTIME_NONE; } -// Rules are a debug feature -#ifndef NDEBUG // Rule given at command line else if (strncmp(argv[i], "--rule=", 7) == 0) { @@ -457,7 +453,6 @@ bool CmdLineParser::ParseFromArgs(int argc, const char* const argv[]) } } } -#endif // Print help else if (strcmp(argv[i], "-h") == 0 || strcmp(argv[i], "--help") == 0) From c7b8bd543f885bb90838ccd4f86c32cc315a7d03 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Debrard?= Date: Mon, 24 Jan 2011 19:04:56 +0100 Subject: [PATCH 119/165] fix ticket 155 - char array --- lib/checkother.cpp | 2 +- test/testother.cpp | 12 ++++++++++-- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/lib/checkother.cpp b/lib/checkother.cpp index 2ff551e57..d8e065610 100644 --- a/lib/checkother.cpp +++ b/lib/checkother.cpp @@ -95,7 +95,7 @@ void CheckOther::checkSizeofForArrayParameter() const Token *declTok = Token::findmatch(_tokenizer->tokens(), "%varid%", tok->tokAt(tokIdx)->varId()); if (declTok) { - if ((Token::simpleMatch(declTok->next(), "[")) && !(Token::simpleMatch(declTok->next()->link(), "] = {")) && !(Token::simpleMatch(declTok->next()->link(), "] ;"))) + if ((Token::simpleMatch(declTok->next(), "[")) && !(Token::Match(declTok->next()->link(), "] = %str%")) && !(Token::simpleMatch(declTok->next()->link(), "] = {")) && !(Token::simpleMatch(declTok->next()->link(), "] ;"))) { sizeofForArrayParameterError(tok); } diff --git a/test/testother.cpp b/test/testother.cpp index 934ab01ca..f71d7eb97 100644 --- a/test/testother.cpp +++ b/test/testother.cpp @@ -98,7 +98,7 @@ private: TEST_CASE(memsetZeroBytes); - TEST_CASE(sizeofWithSilentArrayPointer); + TEST_CASE(sizeofForArrayParameter); } void check(const char code[], const char *filename = NULL) @@ -1663,7 +1663,7 @@ private: ASSERT_EQUALS("", errout.str()); } - void sizeofWithSilentArrayPointer() + void sizeofForArrayParameter() { check("void f() {\n" " int a[10];\n" @@ -1742,6 +1742,14 @@ private: ); ASSERT_EQUALS("", errout.str()); + check("void f() {\n" + " char p[] = \"test\";\n" + " sizeof(p);\n" + "}\n" + ); + ASSERT_EQUALS("", errout.str()); + + } }; From a596a7a8fe656314ae3686d81894cfd26419ba14 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Mon, 24 Jan 2011 21:40:49 +0100 Subject: [PATCH 120/165] Fixed #2494 (New check: clarify calculation when using ?: operator) --- lib/checkother.cpp | 54 ++++++++++++++++++++++++++++++++++++++++++++++ lib/checkother.h | 8 +++++++ test/testother.cpp | 14 ++++++++++++ 3 files changed, 76 insertions(+) diff --git a/lib/checkother.cpp b/lib/checkother.cpp index d8e065610..76af4e0a5 100644 --- a/lib/checkother.cpp +++ b/lib/checkother.cpp @@ -35,6 +35,60 @@ CheckOther instance; //--------------------------------------------------------------------------- +void CheckOther::clarifyCalculation() +{ + if (!_settings->_checkCodingStyle) + return; + for (const Token *tok = _tokenizer->tokens(); tok; tok = tok->next()) + { + if (tok->str() == "?") + { + // condition + const Token *cond = tok->previous(); + if (cond->isName() || cond->isNumber()) + cond = cond->previous(); + else if (cond->str() == ")") + cond = cond->link()->previous(); + else + continue; + + // multiplication + if (cond->str() == "*") + cond = cond->previous(); + else + continue; + + // skip previous multiplications.. + while (cond && cond->strAt(-1) == "*" && (cond->isName() || cond->isNumber())) + cond = cond->tokAt(-2); + + if (!cond) + continue; + + // first multiplication operand + if (cond->str() == ")") + { + clarifyCalculationError(cond); + } + else if (cond->isName() || cond->isNumber()) + { + if (Token::Match(cond->previous(),"return|+|-|,|(")) + clarifyCalculationError(cond); + } + } + } +} + +void CheckOther::clarifyCalculationError(const Token *tok) +{ + reportError(tok, + Severity::information, + "clarifyCalculation", + "Please clarify precedence: 'a*b?..'\n" + "Found a suspicious multiplication of condition. Please use parantheses to clarify the code. " + "The code 'a*b?1:2' should be written as either '(a*b)?1:2' or 'a*(b?1:2)'."); +} + void CheckOther::warningOldStylePointerCast() { diff --git a/lib/checkother.h b/lib/checkother.h index 0d0798dd7..bace5a82e 100644 --- a/lib/checkother.h +++ b/lib/checkother.h @@ -70,6 +70,8 @@ public: { CheckOther checkOther(tokenizer, settings, errorLogger); + checkOther.clarifyCalculation(); + // Coding style checks checkOther.checkConstantFunctionParameter(); checkOther.checkIncompleteStatement(); @@ -87,6 +89,10 @@ public: checkOther.checkMemsetZeroBytes(); } + /** @brief Clarify calculation for ".. a * b ? .." */ + void clarifyCalculation(); + void clarifyCalculationError(const Token *tok); + /** @brief Are there C-style pointer casts in a c++ file? */ void warningOldStylePointerCast(); @@ -236,6 +242,7 @@ public: c.unassignedVariableError(0, "varname"); c.catchExceptionByValueError(0); c.memsetZeroBytesError(0, "varname"); + c.clarifyCalculationError(0); } std::string name() const @@ -274,6 +281,7 @@ public: "* assignment of a variable to itself\n" "* mutual exclusion over || always evaluating to true\n" "* exception caught by value instead of by reference\n" + "* Clarify calculation with parantheses\n" // optimisations "* optimisation: detect post increment/decrement\n"; diff --git a/test/testother.cpp b/test/testother.cpp index f71d7eb97..8546c5d83 100644 --- a/test/testother.cpp +++ b/test/testother.cpp @@ -99,6 +99,8 @@ private: TEST_CASE(memsetZeroBytes); TEST_CASE(sizeofForArrayParameter); + + TEST_CASE(clarifyCalculation); } void check(const char code[], const char *filename = NULL) @@ -134,6 +136,7 @@ private: checkOther.checkIncorrectLogicOperator(); checkOther.checkCatchExceptionByValue(); checkOther.checkMemsetZeroBytes(); + checkOther.clarifyCalculation(); } @@ -1748,8 +1751,19 @@ private: "}\n" ); ASSERT_EQUALS("", errout.str()); + } + void clarifyCalculation() + { + check("int f(char c) {\n" + " return 10 * (c == 0) ? 1 : 2;\n" + "}"); + ASSERT_EQUALS("[test.cpp:2]: (information) Please clarify precedence: 'a*b?..'\n", errout.str()); + check("void f(char c) {\n" + " printf(\"%i\", 10 * (c == 0) ? 1 : 2);\n" + "}"); + ASSERT_EQUALS("[test.cpp:2]: (information) Please clarify precedence: 'a*b?..'\n", errout.str()); } }; From 4cf56dac2b421a2034fe37618fbf81a6f5e903b7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Debrard?= Date: Tue, 25 Jan 2011 09:57:58 +0100 Subject: [PATCH 121/165] Fix 2495 incorrect sizeof error message --- lib/checkother.cpp | 13 +++++++++++-- test/testother.cpp | 16 ++++++++++++++++ 2 files changed, 27 insertions(+), 2 deletions(-) diff --git a/lib/checkother.cpp b/lib/checkother.cpp index d8e065610..3d1b53443 100644 --- a/lib/checkother.cpp +++ b/lib/checkother.cpp @@ -95,9 +95,18 @@ void CheckOther::checkSizeofForArrayParameter() const Token *declTok = Token::findmatch(_tokenizer->tokens(), "%varid%", tok->tokAt(tokIdx)->varId()); if (declTok) { - if ((Token::simpleMatch(declTok->next(), "[")) && !(Token::Match(declTok->next()->link(), "] = %str%")) && !(Token::simpleMatch(declTok->next()->link(), "] = {")) && !(Token::simpleMatch(declTok->next()->link(), "] ;"))) + if (Token::simpleMatch(declTok->next(), "[")) { - sizeofForArrayParameterError(tok); + declTok = declTok->next()->link(); + // multidimensional array + while (Token::simpleMatch(declTok->next(), "[")) + { + declTok = declTok->next()->link(); + } + if (!(Token::Match(declTok->next(), "= %str%")) && !(Token::simpleMatch(declTok->next(), "= {")) && !(Token::simpleMatch(declTok->next(), ";")) && !(Token::simpleMatch(declTok->next(), ","))) + { + sizeofForArrayParameterError(tok); + } } } } diff --git a/test/testother.cpp b/test/testother.cpp index f71d7eb97..be126778b 100644 --- a/test/testother.cpp +++ b/test/testother.cpp @@ -1749,6 +1749,22 @@ private: ); ASSERT_EQUALS("", errout.str()); + // ticket 2495 + check("void f() {\n" + " static float col[][3]={\n" + " {1,0,0},\n" + " {0,0,1},\n" + " {0,1,0},\n" + " {1,0,1},\n" + " {1,0,1},\n" + " {1,0,1},\n" + " };\n" + " const int COL_MAX=sizeof(col)/sizeof(col[0]);\n" + "}\n" + ); + ASSERT_EQUALS("", errout.str()); + + } From 5d661d25a80c7ae1803f8321f42042c158b8bc56 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Debrard?= Date: Wed, 26 Jan 2011 09:35:11 +0100 Subject: [PATCH 122/165] typo: message --- lib/checkother.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/checkother.cpp b/lib/checkother.cpp index d6754afe9..da92dd933 100644 --- a/lib/checkother.cpp +++ b/lib/checkother.cpp @@ -553,7 +553,7 @@ void CheckOther::sizeofForArrayParameterError(const Token *tok) "returns the size of pointer.\n" "Giving array as function parameter and then using sizeof-operator for the array " "argument. In this case the sizeof-operator returns the size of pointer (in the " - " system). It does not return the size of the whole array in bytes as might be " + "system). It does not return the size of the whole array in bytes as might be " "expected. For example, this code:\n" " int f(char a[100]) {\n" " return sizeof(a);\n" From 3e7f29d6f92b32e48c7d890483be8a160ccb94c4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Debrard?= Date: Wed, 26 Jan 2011 20:08:06 +0100 Subject: [PATCH 123/165] fix #2510 Improve check 'sizeof for array given as function argument' --- lib/checkother.cpp | 22 +++++++++++++++++++++- test/testother.cpp | 25 +++++++++++++++++++++++++ 2 files changed, 46 insertions(+), 1 deletion(-) diff --git a/lib/checkother.cpp b/lib/checkother.cpp index da92dd933..33f6f7641 100644 --- a/lib/checkother.cpp +++ b/lib/checkother.cpp @@ -157,7 +157,27 @@ void CheckOther::checkSizeofForArrayParameter() { declTok = declTok->next()->link(); } - if (!(Token::Match(declTok->next(), "= %str%")) && !(Token::simpleMatch(declTok->next(), "= {")) && !(Token::simpleMatch(declTok->next(), ";")) && !(Token::simpleMatch(declTok->next(), ","))) + if (!(Token::Match(declTok->next(), "= %str%")) && !(Token::simpleMatch(declTok->next(), "= {")) && !(Token::simpleMatch(declTok->next(), ";"))) + { + if (Token::simpleMatch(declTok->next(), ",")) + { + declTok = declTok->next(); + while(!Token::simpleMatch(declTok, ";")) + { + if (Token::simpleMatch(declTok, ")")) + { + sizeofForArrayParameterError(tok); + break; + } + if (Token::Match(declTok, "(|[|{")) + { + declTok = declTok->link(); + } + declTok = declTok->next(); + } + } + } + if (Token::simpleMatch(declTok->next(), ")")) { sizeofForArrayParameterError(tok); } diff --git a/test/testother.cpp b/test/testother.cpp index a578b8a7b..bdec704e3 100644 --- a/test/testother.cpp +++ b/test/testother.cpp @@ -1774,6 +1774,31 @@ private: ); ASSERT_EQUALS("", errout.str()); + // ticket 2510 + check("void f( int a[], int b) {\n" + " std::cout << sizeof(a) / sizeof(int) << std::endl;\n" + "}\n" + ); + ASSERT_EQUALS("[test.cpp:2]: (error) Using sizeof for array given as " + "function argument returns the size of pointer.\n", errout.str()); + + // ticket 2510 + check("void f( int a[3] , int b[2] ) {\n" + " std::cout << sizeof(a) / sizeof(int) << std::endl;\n" + "}\n" + ); + ASSERT_EQUALS("[test.cpp:2]: (error) Using sizeof for array given as " + "function argument returns the size of pointer.\n", errout.str()); + + // ticket 2510 + check("void f() {\n" + " char buff1[1024*64],buff2[sizeof(buff1)*(2+1)];\n" + "}\n" + ); + ASSERT_EQUALS("", errout.str()); + + + } void clarifyCalculation() From 078c36921da4c650f0cb4f1edc7e6a56e7126d33 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Debrard?= Date: Wed, 26 Jan 2011 20:10:56 +0100 Subject: [PATCH 124/165] runastyle --- lib/checkother.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/checkother.cpp b/lib/checkother.cpp index 33f6f7641..6e74c7cc6 100644 --- a/lib/checkother.cpp +++ b/lib/checkother.cpp @@ -157,12 +157,12 @@ void CheckOther::checkSizeofForArrayParameter() { declTok = declTok->next()->link(); } - if (!(Token::Match(declTok->next(), "= %str%")) && !(Token::simpleMatch(declTok->next(), "= {")) && !(Token::simpleMatch(declTok->next(), ";"))) + if (!(Token::Match(declTok->next(), "= %str%")) && !(Token::simpleMatch(declTok->next(), "= {")) && !(Token::simpleMatch(declTok->next(), ";"))) { if (Token::simpleMatch(declTok->next(), ",")) { declTok = declTok->next(); - while(!Token::simpleMatch(declTok, ";")) + while (!Token::simpleMatch(declTok, ";")) { if (Token::simpleMatch(declTok, ")")) { From 001d38261484b043b32cbbfa23dd36a00c5efa75 Mon Sep 17 00:00:00 2001 From: Kimmo Varis Date: Wed, 26 Jan 2011 23:44:15 +0200 Subject: [PATCH 125/165] GUI: Enable warnings about missing include files. --- gui/mainwindow.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/gui/mainwindow.cpp b/gui/mainwindow.cpp index 75a3f54b2..72cd10091 100644 --- a/gui/mainwindow.cpp +++ b/gui/mainwindow.cpp @@ -358,6 +358,7 @@ Settings MainWindow::GetCppcheckSettings() result.addEnabled("style"); result.addEnabled("information"); + result.addEnabled("missingInclude"); result.debug = false; result.debugwarnings = mSettings->value(SETTINGS_SHOW_DEBUG_WARNINGS, false).toBool(); result._errorsOnly = false; From 50dba88077814d643ca2a8654c256915b9613e94 Mon Sep 17 00:00:00 2001 From: Kimmo Varis Date: Thu, 27 Jan 2011 08:47:28 +0200 Subject: [PATCH 126/165] Fix formatting of debug messages to log view. Ticket #2513 (GUI: Garbage printed to log after missing include warning) The linenumber was not properly converted to the QString so there were garbage printed to the log. --- gui/erroritem.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/gui/erroritem.cpp b/gui/erroritem.cpp index 35506c697..a7b09c853 100644 --- a/gui/erroritem.cpp +++ b/gui/erroritem.cpp @@ -43,9 +43,11 @@ ErrorItem::ErrorItem(const ErrorLine &line) QString ErrorItem::ToString() const { QString str = file + " - " + id + " - " + severity +"\n"; - str += " " + summary; - str += "\n" + message; + str += summary + "\n"; + str += message + "\n"; for (int i = 0; i < files.size(); i++) - str += " " + files[i] + ": " + lines[i] + "\n"; + { + str += " " + files[i] + ": " + QString::number(lines[i]) + "\n"; + } return str; } From dcc241a2b46caad2c8da57fc2c5527ca1704cd69 Mon Sep 17 00:00:00 2001 From: Kimmo Varis Date: Thu, 27 Jan 2011 10:30:53 +0200 Subject: [PATCH 127/165] Don't print "files not found" after showing help. Fix ticket #2496 (Is error reporting for an unneeded parameter wrong?) There are several command line options / commands after which we don't want Cppcheck to even try to open any files. Eg. printing help or listing errors. So add new attribute for CmdLineParser to track use of these options and exit before checking files when the attribute is set. --- cli/cmdlineparser.cpp | 5 +++++ cli/cmdlineparser.h | 9 +++++++++ cli/cppcheckexecutor.cpp | 4 +++- 3 files changed, 17 insertions(+), 1 deletion(-) diff --git a/cli/cmdlineparser.cpp b/cli/cmdlineparser.cpp index af6e677af..0d9ded344 100644 --- a/cli/cmdlineparser.cpp +++ b/cli/cmdlineparser.cpp @@ -60,6 +60,7 @@ CmdLineParser::CmdLineParser(Settings *settings) , _showHelp(false) , _showVersion(false) , _showErrorMessages(false) + , _exitAfterPrint(false) { } @@ -75,6 +76,7 @@ bool CmdLineParser::ParseFromArgs(int argc, const char* const argv[]) if (strcmp(argv[i], "--version") == 0) { _showVersion = true; + _exitAfterPrint = true; return true; } // Flag used for various purposes during debugging @@ -365,6 +367,7 @@ bool CmdLineParser::ParseFromArgs(int argc, const char* const argv[]) //_cppcheck->getErrorMessages(); _showErrorMessages = true; _settings->_xml = true; + _exitAfterPrint = true; return true; } @@ -383,6 +386,7 @@ bool CmdLineParser::ParseFromArgs(int argc, const char* const argv[]) while (doc2.find("\n\n\n") != std::string::npos) doc2.erase(doc2.find("\n\n\n"), 1); std::cout << doc2; + _exitAfterPrint = true; return true; } @@ -459,6 +463,7 @@ bool CmdLineParser::ParseFromArgs(int argc, const char* const argv[]) { _pathnames.clear(); _showHelp = true; + _exitAfterPrint = true; break; } diff --git a/cli/cmdlineparser.h b/cli/cmdlineparser.h index 60fccb93b..7a60e24a6 100644 --- a/cli/cmdlineparser.h +++ b/cli/cmdlineparser.h @@ -84,6 +84,14 @@ public: return _showHelp; } + /** + * Return if we should exit after printing version, help etc. + */ + bool ExitAfterPrinting() const + { + return _exitAfterPrint; + } + protected: /** @@ -101,6 +109,7 @@ private: bool _showHelp; bool _showVersion; bool _showErrorMessages; + bool _exitAfterPrint; std::vector _pathnames; }; diff --git a/cli/cppcheckexecutor.cpp b/cli/cppcheckexecutor.cpp index 4885357e6..efc6ceadc 100644 --- a/cli/cppcheckexecutor.cpp +++ b/cli/cppcheckexecutor.cpp @@ -57,8 +57,10 @@ bool CppCheckExecutor::parseFromArgs(CppCheck *cppcheck, int argc, const char* c std::cout << ErrorLogger::ErrorMessage::getXMLHeader(_settings._xml_version); cppcheck->getErrorMessages(); std::cout << ErrorLogger::ErrorMessage::getXMLFooter() << std::endl; - std::exit(0); } + + if (parser.ExitAfterPrinting()) + std::exit(0); } // Check that all include paths exist From a794edd93461b521f8255d989061b3a96b065d19 Mon Sep 17 00:00:00 2001 From: Kimmo Varis Date: Thu, 27 Jan 2011 11:14:08 +0200 Subject: [PATCH 128/165] Don't stop processing cmd line after --errorlist. Ticket #2441 (Parsing of command line arguments breaks after --errorlist) Instead of stopping processing command line options after --errorlist process them all. This way e.g. --verbose can be given also after the --errorlist. --- cli/cmdlineparser.cpp | 8 ++++---- cli/cppcheckexecutor.cpp | 3 +-- test/testcmdlineparser.cpp | 32 ++++++++++++++++++++++++++++++++ 3 files changed, 37 insertions(+), 6 deletions(-) diff --git a/cli/cmdlineparser.cpp b/cli/cmdlineparser.cpp index 0d9ded344..f4a80138f 100644 --- a/cli/cmdlineparser.cpp +++ b/cli/cmdlineparser.cpp @@ -364,11 +364,9 @@ bool CmdLineParser::ParseFromArgs(int argc, const char* const argv[]) // print all possible error messages.. else if (strcmp(argv[i], "--errorlist") == 0) { - //_cppcheck->getErrorMessages(); _showErrorMessages = true; _settings->_xml = true; _exitAfterPrint = true; - return true; } // documentation.. @@ -491,15 +489,17 @@ bool CmdLineParser::ParseFromArgs(int argc, const char* const argv[]) PrintMessage("--test-2-pass doesn't work with -j option yet."); } - if (argc <= 1) _showHelp = true; if (_showHelp) { PrintHelp(); + return true; } - else if (_pathnames.empty()) + + // Print error only if we have "real" command and expect files + if (!_exitAfterPrint && _pathnames.empty()) { PrintMessage("cppcheck: No C or C++ source files found."); return false; diff --git a/cli/cppcheckexecutor.cpp b/cli/cppcheckexecutor.cpp index efc6ceadc..fdb886471 100644 --- a/cli/cppcheckexecutor.cpp +++ b/cli/cppcheckexecutor.cpp @@ -45,10 +45,9 @@ bool CppCheckExecutor::parseFromArgs(CppCheck *cppcheck, int argc, const char* c if (success) { - if (parser.GetShowVersion()) + if (parser.GetShowVersion() && !parser.GetShowErrorMessages()) { std::cout << "Cppcheck " << cppcheck->version() << std::endl; - return true; } if (parser.GetShowErrorMessages()) diff --git a/test/testcmdlineparser.cpp b/test/testcmdlineparser.cpp index a0a29cbd6..3c2599c9a 100644 --- a/test/testcmdlineparser.cpp +++ b/test/testcmdlineparser.cpp @@ -77,6 +77,9 @@ private: TEST_CASE(templatesGcc); TEST_CASE(templatesVs); TEST_CASE(xml); + TEST_CASE(errorlist1); + TEST_CASE(errorlistverbose1) + TEST_CASE(errorlistverbose2) TEST_CASE(unknownParam); } @@ -535,6 +538,35 @@ private: ASSERT(settings._xml); } + void errorlist1() + { + REDIRECT; + const char *argv[] = {"cppcheck", "--errorlist"}; + Settings settings; + CmdLineParser parser(&settings); + ASSERT(parser.ParseFromArgs(2, argv)); + } + + void errorlistverbose1() + { + REDIRECT; + const char *argv[] = {"cppcheck", "--verbose", "--errorlist"}; + Settings settings; + CmdLineParser parser(&settings); + ASSERT(parser.ParseFromArgs(3, argv)); + ASSERT(settings._verbose); + } + + void errorlistverbose2() + { + REDIRECT; + const char *argv[] = {"cppcheck", "--errorlist", "--verbose"}; + Settings settings; + CmdLineParser parser(&settings); + ASSERT(parser.ParseFromArgs(3, argv)); + ASSERT(settings._verbose); + } + void unknownParam() { REDIRECT; From 97f041f292305844cc744b080fde1b0bebea13d1 Mon Sep 17 00:00:00 2001 From: Kimmo Varis Date: Thu, 27 Jan 2011 13:14:53 +0200 Subject: [PATCH 129/165] GUI: Update homepage URL to About-dialog. --- gui/aboutdialog.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gui/aboutdialog.cpp b/gui/aboutdialog.cpp index f21bc5495..ec79fc6bf 100644 --- a/gui/aboutdialog.cpp +++ b/gui/aboutdialog.cpp @@ -27,7 +27,7 @@ AboutDialog::AboutDialog(const QString &version, QWidget *parent) mUI.setupUi(this); mUI.mVersion->setText(mUI.mVersion->text().arg(version)); - QString url = "http://cppcheck.wiki.sourceforge.net/"; + QString url = "http://cppcheck.sourceforge.net/"; mUI.mHomepage->setText(mUI.mHomepage->text().arg(url)); connect(mUI.mButtons, SIGNAL(accepted()), this, SLOT(accept())); } From 090436ea9581b8652a7b3d30f046d691e0b6b693 Mon Sep 17 00:00:00 2001 From: Kimmo Varis Date: Thu, 27 Jan 2011 14:25:10 +0200 Subject: [PATCH 130/165] Add cmd line parser tests for XML ver 2 options. --- test/testcmdlineparser.cpp | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/test/testcmdlineparser.cpp b/test/testcmdlineparser.cpp index 3c2599c9a..78dc5be51 100644 --- a/test/testcmdlineparser.cpp +++ b/test/testcmdlineparser.cpp @@ -77,6 +77,9 @@ private: TEST_CASE(templatesGcc); TEST_CASE(templatesVs); TEST_CASE(xml); + TEST_CASE(xmlver2); + TEST_CASE(xmlver2both); + TEST_CASE(xmlver2both2); TEST_CASE(errorlist1); TEST_CASE(errorlistverbose1) TEST_CASE(errorlistverbose2) @@ -536,6 +539,40 @@ private: CmdLineParser parser(&settings); ASSERT(parser.ParseFromArgs(3, argv)); ASSERT(settings._xml); + ASSERT_EQUALS(1, settings._xml_version); + } + + void xmlver2() + { + REDIRECT; + const char *argv[] = {"cppcheck", "--xml-version=2", "file.cpp"}; + Settings settings; + CmdLineParser parser(&settings); + ASSERT(parser.ParseFromArgs(3, argv)); + ASSERT(settings._xml); + ASSERT_EQUALS(2, settings._xml_version); + } + + void xmlver2both() + { + REDIRECT; + const char *argv[] = {"cppcheck", "--xml", "--xml-version=2", "file.cpp"}; + Settings settings; + CmdLineParser parser(&settings); + ASSERT(parser.ParseFromArgs(4, argv)); + ASSERT(settings._xml); + ASSERT_EQUALS(2, settings._xml_version); + } + + void xmlver2both2() + { + REDIRECT; + const char *argv[] = {"cppcheck", "--xml-version=2", "--xml", "file.cpp"}; + Settings settings; + CmdLineParser parser(&settings); + ASSERT(parser.ParseFromArgs(4, argv)); + ASSERT(settings._xml); + ASSERT_EQUALS(2, settings._xml_version); } void errorlist1() From 524498e439b988e1c13a917b4ff59f5a6b797324 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Thu, 27 Jan 2011 18:44:20 +0100 Subject: [PATCH 131/165] Tokenizer: collapse operator function names into a single token. ticket: #2519 --- lib/checkclass.cpp | 29 +++++++------------- lib/symboldatabase.cpp | 53 ++++--------------------------------- lib/tokenize.cpp | 33 ++++++++++++++++++++++- lib/tokenize.h | 6 +++++ test/testclass.cpp | 2 +- test/testsimplifytokens.cpp | 14 +++++----- test/testtokenize.cpp | 40 +++++++++++++++++++++++++--- test/testunusedprivfunc.cpp | 3 +-- 8 files changed, 99 insertions(+), 81 deletions(-) diff --git a/lib/checkclass.cpp b/lib/checkclass.cpp index 2881d894b..fc96af0cc 100644 --- a/lib/checkclass.cpp +++ b/lib/checkclass.cpp @@ -140,11 +140,7 @@ void CheckClass::constructors() // It's non-static and it's not initialized => error if (func->type == Function::eOperatorEqual) { - const Token *operStart = 0; - if (func->token->str() == "=") - operStart = func->token->tokAt(1); - else - operStart = func->token->tokAt(3); + const Token *operStart = func->token->tokAt(1); bool classNameUsed = false; for (const Token *operTok = operStart; operTok != operStart->link(); operTok = operTok->next()) @@ -376,14 +372,14 @@ void CheckClass::initializeVarList(const Function &func, std::list } // Calling member function? - else if (Token::simpleMatch(ftok, "operator = (") && + else if (Token::simpleMatch(ftok, "operator= (") && ftok->previous()->str() != "::") { // check if member function exists std::list::const_iterator it; for (it = scope->functionList.begin(); it != scope->functionList.end(); ++it) { - if (ftok->next()->str() == it->tokenDef->str() && it->type != Function::eConstructor) + if (ftok->str() == it->tokenDef->str() && it->type != Function::eConstructor) break; } @@ -583,11 +579,6 @@ void CheckClass::privateFunctions() if (Token::findmatch(_tokenizer->tokens(), "; __property ;")) return; - // #2407 calls from operator() is not detected - // TODO: Don't bailout. Detect the call. - if (Token::findmatch(_tokenizer->tokens(), "operator ( )")) - return; - createSymbolDatabase(); std::list::const_iterator i; @@ -872,8 +863,8 @@ void CheckClass::operatorEq() { if (it->type == Function::eOperatorEqual && it->access != Private) { - if (it->token->strAt(-2) == "void") - operatorEqReturnError(it->token->tokAt(-2)); + if (it->token->strAt(-1) == "void") + operatorEqReturnError(it->token->tokAt(-1)); } } } @@ -940,7 +931,7 @@ void CheckClass::checkReturnPtrThis(const Scope *scope, const Function *func, co // check of *this is returned else if (!(Token::Match(tok->tokAt(1), "(| * this ;|=") || Token::Match(tok->tokAt(1), "(| * this +=") || - Token::Match(tok->tokAt(1), "operator = ("))) + Token::Match(tok->tokAt(1), "operator= ("))) operatorEqRetRefThisError(func->token); } } @@ -971,8 +962,8 @@ void CheckClass::operatorEqRetRefThis() if (func->type == Function::eOperatorEqual && func->hasBody) { // make sure return signature is correct - if (Token::Match(func->tokenDef->tokAt(-4), ";|}|{|public:|protected:|private: %type% &") && - func->tokenDef->strAt(-3) == scope->className) + if (Token::Match(func->tokenDef->tokAt(-3), ";|}|{|public:|protected:|private: %type% &") && + func->tokenDef->strAt(-2) == scope->className) { // find the ')' const Token *tok = func->token->next()->link(); @@ -1027,8 +1018,8 @@ void CheckClass::operatorEqToSelf() if (it->type == Function::eOperatorEqual && it->hasBody) { // make sure return signature is correct - if (Token::Match(it->tokenDef->tokAt(-4), ";|}|{|public:|protected:|private: %type% &") && - it->tokenDef->strAt(-3) == scope->className) + if (Token::Match(it->tokenDef->tokAt(-3), ";|}|{|public:|protected:|private: %type% &") && + it->tokenDef->strAt(-2) == scope->className) { // check for proper function parameter signature if ((Token::Match(it->tokenDef->next(), "( const %var% & )") || diff --git a/lib/symboldatabase.cpp b/lib/symboldatabase.cpp index 08c8d5486..8b7947387 100644 --- a/lib/symboldatabase.cpp +++ b/lib/symboldatabase.cpp @@ -137,12 +137,12 @@ SymbolDatabase::SymbolDatabase(const Tokenizer *tokenizer, const Settings *setti function.tokenDef = funcStart; // operator function - if (function.tokenDef->previous()->str() == "operator") + if (function.tokenDef->str().find("operator") == 0) { function.isOperator = true; // 'operator =' is special - if (function.tokenDef->str() == "=") + if (function.tokenDef->str() == "operator=") function.type = Function::eOperatorEqual; } @@ -578,38 +578,6 @@ bool SymbolDatabase::isFunction(const Token *tok, const Token **funcStart, const return true; } - // simple operator? - else if (Token::Match(tok, "operator %any% (") && Token::Match(tok->tokAt(2)->link(), ") const| ;|{|=")) - { - *funcStart = tok->next(); - *argStart = tok->tokAt(2); - return true; - } - - // operator[] or operator()? - else if (Token::Match(tok, "operator %any% %any% (") && Token::Match(tok->tokAt(3)->link(), ") const| ;|{|=")) - { - *funcStart = tok->next(); - *argStart = tok->tokAt(3); - return true; - } - - // operator new/delete []? - else if (Token::Match(tok, "operator %any% %any% %any% (") && Token::Match(tok->tokAt(4)->link(), ") const| ;|{|=")) - { - *funcStart = tok->next(); - *argStart = tok->tokAt(4); - return true; - } - - // complex user defined operator? - else if (Token::Match(tok, "operator %any% %any% %any% %any% (") && Token::Match(tok->tokAt(5)->link(), ") const| ;|{|=")) - { - *funcStart = tok->next(); - *argStart = tok->tokAt(5); - return true; - } - return false; } @@ -772,20 +740,9 @@ void SymbolDatabase::addFunction(Scope **scope, const Token **tok, const Token * { if (!func->hasBody) { - if (func->isOperator && - (*tok)->str() == "operator" && - func->tokenDef->str() == (*tok)->strAt(1)) - { - if (argsMatch(scope1, func->tokenDef->tokAt(2), (*tok)->tokAt(3), path, path_length)) - { - func->hasBody = true; - func->token = (*tok)->next(); - func->arg = argStart; - } - } - else if (func->type == Function::eDestructor && - (*tok)->previous()->str() == "~" && - func->tokenDef->str() == (*tok)->str()) + if (func->type == Function::eDestructor && + (*tok)->previous()->str() == "~" && + func->tokenDef->str() == (*tok)->str()) { if (argsMatch(scope1, func->tokenDef->next(), (*tok)->next(), path, path_length)) { diff --git a/lib/tokenize.cpp b/lib/tokenize.cpp index ee640937a..d21484c52 100644 --- a/lib/tokenize.cpp +++ b/lib/tokenize.cpp @@ -513,7 +513,7 @@ bool Tokenizer::duplicateTypedef(Token **tokPtr, const Token *name) } else if (end->str() == "(") { - if (tok->previous()->str() == "operator") + if (tok->previous()->str().find("operator") == 0) { // conversion operator return false; @@ -2490,6 +2490,10 @@ bool Tokenizer::tokenize(std::istream &code, // remove exception specifications.. removeExceptionSpecifications(_tokens); + // Collapse operator name tokens into single token + // operator = => operator= + simplifyOperatorName(); + // simplify function pointers simplifyFunctionPointers(); @@ -9238,3 +9242,30 @@ const SymbolDatabase *Tokenizer::getSymbolDatabase() const return _symbolDatabase; } + +void Tokenizer::simplifyOperatorName() +{ + for (const Token *tok = _tokens; tok; tok = tok->next()) + { + if (Token::Match(tok, ") const| {|;|=")) + { + Token *tok1 = tok->link(); + Token *tok2 = tok1; + + tok1 = tok1->previous(); + while (tok1 && !Token::Match(tok1, "operator|{|}|;|public:|private|protected:")) + { + tok1 = tok1->previous(); + } + + if (tok1 && tok1->str() == "operator") + { + while (tok1->next() != tok2) + { + tok1->str(tok1->str() + tok1->next()->str()); + tok1->deleteNext(); + } + } + } + } +} diff --git a/lib/tokenize.h b/lib/tokenize.h index 318bdf4c4..8dacc345a 100644 --- a/lib/tokenize.h +++ b/lib/tokenize.h @@ -531,6 +531,12 @@ public: */ void simplifyQtSignalsSlots(); + /** + * Collapse operator name tokens into single token + * operator = => operator= + */ + void simplifyOperatorName(); + /** * This will return a short name describing function parameters * e.g. parameters: (int a, char b) should get name "int,char,". diff --git a/test/testclass.cpp b/test/testclass.cpp index 431c7252e..44ffed8a3 100644 --- a/test/testclass.cpp +++ b/test/testclass.cpp @@ -3506,7 +3506,7 @@ private: " typedef int* (Fred::*UnspecifiedBoolType);\n" " operator UnspecifiedBoolType() { };\n" "};\n"); - ASSERT_EQUALS("[test.cpp:4]: (information) Technically the member function 'Fred::int' can be const.\n", errout.str()); + ASSERT_EQUALS("[test.cpp:4]: (information) Technically the member function 'Fred::operatorint**' can be const.\n", errout.str()); checkConst("struct Fred {\n" " int array[10];\n" diff --git a/test/testsimplifytokens.cpp b/test/testsimplifytokens.cpp index f41f58c51..8f29e3efb 100644 --- a/test/testsimplifytokens.cpp +++ b/test/testsimplifytokens.cpp @@ -382,8 +382,8 @@ private: ASSERT_EQUALS("if ( * a )", tok("if ((char)*a)")); ASSERT_EQUALS("if ( & a )", tok("if ((int)&a)")); ASSERT_EQUALS("if ( * a )", tok("if ((unsigned int)(unsigned char)*a)")); - ASSERT_EQUALS("class A { A operator * ( int ) ; } ;", tok("class A { A operator *(int); };")); - ASSERT_EQUALS("class A { A operator * ( int ) const ; } ;", tok("class A { A operator *(int) const; };")); + ASSERT_EQUALS("class A { A operator* ( int ) ; } ;", tok("class A { A operator *(int); };")); + ASSERT_EQUALS("class A { A operator* ( int ) const ; } ;", tok("class A { A operator *(int) const; };")); ASSERT_EQUALS("if ( ! p )", tok("if (p == (char *)(char *)0)")); } @@ -2578,7 +2578,7 @@ private: { // Ticket #1997 const char code[] = "void * operator new[](size_t);"; - ASSERT_EQUALS("void * operator new [ ] ( size_t ) ;", tok(code)); + ASSERT_EQUALS("void * operatornew[] ( size_t ) ;", tok(code)); } ASSERT_EQUALS("; a [ 0 ] ;", tok(";a[0*(*p)];")); @@ -4429,7 +4429,7 @@ private: const std::string expected("struct C { " "; " "const void * pr ; " // this gets simplified to a regular pointer - "operator const void ( * ) ( ) & ( ) { return pr ; } " + "operatorconstvoid(*)()& ( ) { return pr ; } " "} ;"); ASSERT_EQUALS(expected, sizeof_(code)); @@ -4713,7 +4713,7 @@ private: "};\n"; const std::string expected = "class Fred { " "; " - "operator int * * ( ) const { } " + "operatorint** ( ) const { } " "} ;"; ASSERT_EQUALS(expected, sizeof_(code)); ASSERT_EQUALS("", errout.str()); @@ -4755,9 +4755,9 @@ private: "Fred::operator F() const { }\n"; const std::string expected = "class Fred { " "; " - "operator int * * ( ) const ; " + "operatorint** ( ) const ; " "} ; " - "Fred :: operator int * * ( ) const { }"; + "Fred :: operatorint** ( ) const { }"; ASSERT_EQUALS(expected, sizeof_(code)); ASSERT_EQUALS("", errout.str()); } diff --git a/test/testtokenize.cpp b/test/testtokenize.cpp index dfa87d3bb..561b91a95 100644 --- a/test/testtokenize.cpp +++ b/test/testtokenize.cpp @@ -293,6 +293,8 @@ private: // Tokenize JAVA TEST_CASE(java); + + TEST_CASE(simplifyOperatorName); } @@ -2990,7 +2992,7 @@ private: "1: class Foo\n" "2: {\n" "3: public:\n" - "4: void operator = ( const Foo & ) ;\n" + "4: void operator= ( const Foo & ) ;\n" "5: } ;\n"); ASSERT_EQUALS(expected, actual); @@ -3002,7 +3004,7 @@ private: "};\n"); const std::string expected("\n\n##file 0\n" "1: struct Foo {\n" - "2: void * operator new [ ] ( int ) ;\n" + "2: void * operatornew[] ( int ) ;\n" "3: } ;\n"); ASSERT_EQUALS(expected, actual); @@ -3660,7 +3662,7 @@ private: const std::string actual(tokenizeAndStringify(code)); const char expected[] = "struct foo {\n" - "void operator delete ( void * obj , size_t sz ) ;\n" + "void operatordelete ( void * obj , size_t sz ) ;\n" "}"; ASSERT_EQUALS(expected, actual); @@ -5182,6 +5184,38 @@ private: { ASSERT_EQUALS("void f ( ) { }", javatest("void f() throws Exception { }")); } + + void simplifyOperatorName() + { + // make sure C code doesn't get changed + const char code1[] = "void operator () {}" + "int main()" + "{" + " operator();" + "}"; + + const char result1 [] = "void operator ( ) { } " + "int main ( ) " + "{ " + "operator ( ) ; " + "}"; + + ASSERT_EQUALS(result1, tokenizeAndStringify(code1,false)); + + const char code2[] = "class Fred" + "{" + " Fred(const Fred & f) { operator = (f); }" + " operator = ();" + "}"; + + const char result2 [] = "class Fred " + "{ " + "Fred ( const Fred & f ) { operator= ( f ) ; } " + "operator= ( ) ; " + "}"; + + ASSERT_EQUALS(result2, tokenizeAndStringify(code2,false)); + } }; REGISTER_TEST(TestTokenizer) diff --git a/test/testunusedprivfunc.cpp b/test/testunusedprivfunc.cpp index ff6f84c60..adbbf2b20 100644 --- a/test/testunusedprivfunc.cpp +++ b/test/testunusedprivfunc.cpp @@ -460,8 +460,7 @@ private: " void startListening() {\n" " }\n" "};\n"); - TODO_ASSERT_EQUALS("[test.cpp:8]: (style) Unused private function 'Fred::startListening'\n", errout.str()); - ASSERT_EQUALS("", errout.str()); + ASSERT_EQUALS("[test.cpp:8]: (style) Unused private function 'Fred::startListening'\n", errout.str()); } void testDoesNotIdentifyMethodAsFirstFunctionArgument() From 88abeeebba5cad4c19a3a772f502faf4aaa19200 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Thu, 27 Jan 2011 21:16:25 +0100 Subject: [PATCH 132/165] Fixed #2518 (Crash when checking rockbox's firmwire) --- lib/tokenize.cpp | 10 ++++++++++ test/testtokenize.cpp | 10 ++++++++++ 2 files changed, 20 insertions(+) diff --git a/lib/tokenize.cpp b/lib/tokenize.cpp index d21484c52..bdbb6e44b 100644 --- a/lib/tokenize.cpp +++ b/lib/tokenize.cpp @@ -2041,6 +2041,16 @@ bool Tokenizer::tokenize(std::istream &code, } } + // if MACRO + for (const Token *tok = _tokens; tok; tok = tok->next()) + { + if (Token::Match(tok, "if|for|while %var% (")) + { + syntaxError(tok); + return false; + } + } + // Simplify JAVA/C# code if (isJavaOrCSharp() && _files[0].find(".java") != std::string::npos) { diff --git a/test/testtokenize.cpp b/test/testtokenize.cpp index 561b91a95..d252696c3 100644 --- a/test/testtokenize.cpp +++ b/test/testtokenize.cpp @@ -52,6 +52,7 @@ private: // don't freak out when the syntax is wrong TEST_CASE(wrong_syntax); + TEST_CASE(wrong_syntax_if_macro); // #2518 - if MACRO() TEST_CASE(minus); @@ -522,6 +523,15 @@ private: } } + void wrong_syntax_if_macro() + { + // #2518 + errout.str(""); + const std::string code("void f() { if MACRO(); }"); + tokenizeAndStringify(code.c_str(), false); + ASSERT_EQUALS("[test.cpp:1]: (error) syntax error\n", errout.str()); + } + void minus() { ASSERT_EQUALS("i = -12", tokenizeAndStringify("i = -12")); From 75695a723e2703c831c23abd3b425414a28c2b78 Mon Sep 17 00:00:00 2001 From: Kimmo Varis Date: Fri, 28 Jan 2011 08:52:18 +0200 Subject: [PATCH 133/165] Add --errorlist to CLI help. Fixes ticket #2253 (Make CLI error listing documented and public switch) --- cli/cmdlineparser.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/cli/cmdlineparser.cpp b/cli/cmdlineparser.cpp index f4a80138f..d91d5d167 100644 --- a/cli/cmdlineparser.cpp +++ b/cli/cmdlineparser.cpp @@ -540,6 +540,7 @@ void CmdLineParser::PrintHelp() " if arguments are not valid or if no input files are\n" " provided. Note that your operating system can\n" " modify this value, e.g. 256 can become 0.\n" + " --errorlist Print a list of all error messages in XML format.\n" " --exitcode-suppressions file\n" " Used when certain messages should be displayed but\n" " should not cause a non-zero exitcode.\n" From 79862573ba0b37428216c1d43c71b32fb90599a5 Mon Sep 17 00:00:00 2001 From: Robert Reif Date: Fri, 28 Jan 2011 08:33:02 +0100 Subject: [PATCH 134/165] Symbol database: better unit testing. ticket: #2468 --- lib/symboldatabase.cpp | 36 +++++++ lib/symboldatabase.h | 4 + test/testsymboldatabase.cpp | 186 ++++++++++++++++++++++++++++++++++++ 3 files changed, 226 insertions(+) diff --git a/lib/symboldatabase.cpp b/lib/symboldatabase.cpp index 8b7947387..51032d44d 100644 --- a/lib/symboldatabase.cpp +++ b/lib/symboldatabase.cpp @@ -1348,6 +1348,42 @@ const Scope *SymbolDatabase::findVariableType(const Scope *start, const Token *t //--------------------------------------------------------------------------- +const Scope *SymbolDatabase::findFunctionScopeByToken(const Token *tok) const +{ + std::list::const_iterator scope; + + for (scope = scopeList.begin(); scope != scopeList.end(); ++scope) + { + if ((*scope)->type == Scope::eFunction) + { + if ((*scope)->classDef == tok) + return (*scope); + } + } + return 0; +} + +//--------------------------------------------------------------------------- + +const Function *SymbolDatabase::findFunctionByToken(const Token *tok) const +{ + std::list::const_iterator scope; + + for (scope = scopeList.begin(); scope != scopeList.end(); ++scope) + { + std::list::const_iterator func; + + for (func = (*scope)->functionList.begin(); func != (*scope)->functionList.end(); ++func) + { + if (func->token == tok) + return &*func; + } + } + return 0; +} + +//--------------------------------------------------------------------------- + Scope * Scope::findInNestedList(const std::string & name) { std::list::iterator it; diff --git a/lib/symboldatabase.h b/lib/symboldatabase.h index f1de6c0b0..e8c858c3d 100644 --- a/lib/symboldatabase.h +++ b/lib/symboldatabase.h @@ -362,6 +362,10 @@ public: */ const Scope *findVariableType(const Scope *start, const Token *type) const; + const Scope *findFunctionScopeByToken(const Token *tok) const; + + const Function *findFunctionByToken(const Token *tok) const; + bool argsMatch(const Scope *info, const Token *first, const Token *second, const std::string &path, unsigned int depth) const; bool isClassOrStruct(const std::string &type) const diff --git a/test/testsymboldatabase.cpp b/test/testsymboldatabase.cpp index a1154d325..bfcb71b60 100644 --- a/test/testsymboldatabase.cpp +++ b/test/testsymboldatabase.cpp @@ -20,6 +20,14 @@ #include "testutils.h" #include "symboldatabase.h" +#define GET_SYMBOL_DB(code) \ + errout.str(""); \ + Settings settings; \ + Tokenizer tokenizer(&settings, this); \ + std::istringstream istr(code); \ + tokenizer.tokenize(istr, "test.cpp"); \ + const SymbolDatabase *db = tokenizer.getSymbolDatabase(); + class TestSymbolDatabase: public TestFixture { public: @@ -75,6 +83,16 @@ private: TEST_CASE(canFindMatchingBracketsOuterPair); TEST_CASE(canFindMatchingBracketsWithTooManyClosing); TEST_CASE(canFindMatchingBracketsWithTooManyOpening); + + TEST_CASE(hasRegularFunction); + TEST_CASE(hasInlineClassFunction); + TEST_CASE(hasMissingInlineClassFunction); + TEST_CASE(hasClassFunction); + + TEST_CASE(hasRegularFunctionReturningFunctionPointer); + TEST_CASE(hasInlineClassFunctionReturningFunctionPointer); + TEST_CASE(hasMissingInlineClassFunctionReturningFunctionPointer); + TEST_CASE(hasClassFunctionReturningFunctionPointer); } void test_isVariableDeclarationCanHandleNull() @@ -336,6 +354,174 @@ private: found = si.findClosingBracket(var.tokens()->tokAt(1), t); ASSERT(!found); } + + void hasRegularFunction() + { + GET_SYMBOL_DB("void func() { }\n") + + // 2 scopes: Global and Function + ASSERT(db && db->scopeList.size() == 2 && tokenizer.getFunctionTokenByName("func")); + + if (db) + { + const Scope *scope = db->findFunctionScopeByToken(tokenizer.tokens()->tokAt(1)); + + ASSERT(scope && scope->className == "func"); + + const Function *function = db->findFunctionByToken(tokenizer.tokens()->tokAt(1)); + + ASSERT(function && function->token->str() == "func"); + ASSERT(function && function->token == tokenizer.tokens()->tokAt(1)); + ASSERT(function && function->hasBody); + } + } + + void hasInlineClassFunction() + { + GET_SYMBOL_DB("class Fred { void func() { } };\n") + + // 3 scopes: Global, Class, and Function + ASSERT(db && db->scopeList.size() == 3 && tokenizer.getFunctionTokenByName("func")); + + if (db) + { + const Scope *scope = db->findFunctionScopeByToken(tokenizer.tokens()->tokAt(4)); + + ASSERT(scope && scope->className == "func"); + + const Function *function = db->findFunctionByToken(tokenizer.tokens()->tokAt(4)); + + ASSERT(function && function->token->str() == "func"); + ASSERT(function && function->token == tokenizer.tokens()->tokAt(4)); + ASSERT(function && function->hasBody && function->isInline); + } + } + + void hasMissingInlineClassFunction() + { + GET_SYMBOL_DB("class Fred { void func(); };\n") + + // 2 scopes: Global and Class (no Function scope because there is no function implementation) + ASSERT(db && db->scopeList.size() == 2 && !tokenizer.getFunctionTokenByName("func")); + + if (db) + { + const Scope *scope = db->findFunctionScopeByToken(tokenizer.tokens()->tokAt(4)); + + ASSERT(scope == NULL); + + const Function *function = db->findFunctionByToken(tokenizer.tokens()->tokAt(4)); + + ASSERT(function && function->token->str() == "func"); + ASSERT(function && function->token == tokenizer.tokens()->tokAt(4)); + ASSERT(function && !function->hasBody); + } + } + + void hasClassFunction() + { + GET_SYMBOL_DB("class Fred { void func(); }; Fred::func() { }\n") + + // 3 scopes: Global, Class, and Function + ASSERT(db && db->scopeList.size() == 3 && tokenizer.getFunctionTokenByName("func")); + + if (db) + { + const Scope *scope = db->findFunctionScopeByToken(tokenizer.tokens()->tokAt(12)); + + ASSERT(scope && scope->className == "func"); + + const Function *function = db->findFunctionByToken(tokenizer.tokens()->tokAt(12)); + + ASSERT(function && function->token->str() == "func"); + ASSERT(function && function->token == tokenizer.tokens()->tokAt(12)); + ASSERT(function && function->hasBody && !function->isInline); + } + } + + void hasRegularFunctionReturningFunctionPointer() + { + GET_SYMBOL_DB("void (*func(int f))(char) { }\n") + + // 2 scopes: Global and Function + ASSERT(db && db->scopeList.size() == 2 && tokenizer.getFunctionTokenByName("func")); + + if (db) + { + const Scope *scope = db->findFunctionScopeByToken(tokenizer.tokens()->tokAt(3)); + + ASSERT(scope && scope->className == "func"); + + const Function *function = db->findFunctionByToken(tokenizer.tokens()->tokAt(3)); + + ASSERT(function && function->token->str() == "func"); + ASSERT(function && function->token == tokenizer.tokens()->tokAt(3)); + ASSERT(function && function->hasBody && function->retFuncPtr); + } + } + + void hasInlineClassFunctionReturningFunctionPointer() + { + GET_SYMBOL_DB("class Fred { void (*func(int f))(char) { } };\n") + + // 3 scopes: Global, Class, and Function + ASSERT(db && db->scopeList.size() == 3 && tokenizer.getFunctionTokenByName("func")); + + if (db) + { + const Scope *scope = db->findFunctionScopeByToken(tokenizer.tokens()->tokAt(6)); + + ASSERT(scope && scope->className == "func"); + + const Function *function = db->findFunctionByToken(tokenizer.tokens()->tokAt(6)); + + ASSERT(function && function->token->str() == "func"); + ASSERT(function && function->token == tokenizer.tokens()->tokAt(6)); + ASSERT(function && function->hasBody && function->isInline && function->retFuncPtr); + } + } + + void hasMissingInlineClassFunctionReturningFunctionPointer() + { + GET_SYMBOL_DB("class Fred { void (*func(int f))(char); };\n") + + // 2 scopes: Global and Class (no Function scope because there is no function implementation) + ASSERT(db && db->scopeList.size() == 2 && !tokenizer.getFunctionTokenByName("func")); + + if (db) + { + const Scope *scope = db->findFunctionScopeByToken(tokenizer.tokens()->tokAt(6)); + + ASSERT(scope == NULL); + + const Function *function = db->findFunctionByToken(tokenizer.tokens()->tokAt(6)); + + ASSERT(function && function->token->str() == "func"); + ASSERT(function && function->token == tokenizer.tokens()->tokAt(6)); + ASSERT(function && !function->hasBody && function->retFuncPtr); + } + } + + void hasClassFunctionReturningFunctionPointer() + { + GET_SYMBOL_DB("class Fred { void (*func(int f))(char); }; void (*Fred::func(int f))(char) { }\n") + + // 3 scopes: Global, Class, and Function + ASSERT(db && db->scopeList.size() == 3 && tokenizer.getFunctionTokenByName("func")); + + if (db) + { + const Scope *scope = db->findFunctionScopeByToken(tokenizer.tokens()->tokAt(23)); + + ASSERT(scope && scope->className == "func"); + + const Function *function = db->findFunctionByToken(tokenizer.tokens()->tokAt(23)); + + ASSERT(function && function->token->str() == "func"); + ASSERT(function && function->token == tokenizer.tokens()->tokAt(23)); + ASSERT(function && function->hasBody && !function->isInline && function->retFuncPtr); + } + } }; REGISTER_TEST(TestSymbolDatabase) From 83625d8055e9bbb2d45a64f8cca177c8f54147c8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Fri, 28 Jan 2011 09:19:30 +0100 Subject: [PATCH 135/165] Fixed #2505 (Check processing of a preprocessor macro 'FREE') --- lib/tokenize.cpp | 2 +- test/testtokenize.cpp | 7 +++++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/lib/tokenize.cpp b/lib/tokenize.cpp index bdbb6e44b..9cbdcd6ea 100644 --- a/lib/tokenize.cpp +++ b/lib/tokenize.cpp @@ -6846,7 +6846,7 @@ bool Tokenizer::simplifyRedundantParanthesis() ret = true; } - while (Token::Match(tok->previous(), "[;{(] ( %var% (") && + while (Token::Match(tok->previous(), "[,;{}(] ( %var% (") && tok->link()->previous() == tok->tokAt(2)->link()) { // We have "( func ( *something* ))", remove the outer diff --git a/test/testtokenize.cpp b/test/testtokenize.cpp index d252696c3..f6d07042f 100644 --- a/test/testtokenize.cpp +++ b/test/testtokenize.cpp @@ -205,6 +205,7 @@ private: TEST_CASE(removeParantheses8); // Ticket #1865 TEST_CASE(removeParantheses9); // Ticket #1962 TEST_CASE(removeParantheses10); // Ticket #2320 + TEST_CASE(removeParantheses11); // Ticket #2505 TEST_CASE(tokenize_double); TEST_CASE(tokenize_strings); @@ -3688,6 +3689,12 @@ private: ASSERT_EQUALS("p = buf + 8 ;", tokenizeAndStringify("p = (buf + 8);", false)); } + void removeParantheses11() + { + // #2502 + ASSERT_EQUALS("{ } x ( ) ;", tokenizeAndStringify("{}(x());", false)); + } + void tokenize_double() { const char code[] = "void f()\n" From 081e3642980aa7809976fddb7ef1a45ea9bf49d4 Mon Sep 17 00:00:00 2001 From: Kimmo Varis Date: Fri, 28 Jan 2011 13:18:07 +0200 Subject: [PATCH 136/165] Rename --suppressions-list CLI option. The option --suppressions-list was inconsistent with other options so renaming it to --suppressions-list. Ticket: #1837 (--suppresions file.txt inconsistent) --- cli/cmdlineparser.cpp | 34 ++++++++++++++++++++++++++++++---- test/testcmdlineparser.cpp | 26 ++++++++++++++++++++++++-- 2 files changed, 54 insertions(+), 6 deletions(-) diff --git a/cli/cmdlineparser.cpp b/cli/cmdlineparser.cpp index d91d5d167..a333804a8 100644 --- a/cli/cmdlineparser.cpp +++ b/cli/cmdlineparser.cpp @@ -129,7 +129,31 @@ bool CmdLineParser::ParseFromArgs(int argc, const char* const argv[]) } // Filter errors - else if (strcmp(argv[i], "--suppressions") == 0) + else if (strncmp(argv[i], "--suppressions-list=", 20) == 0) + { + std::string filename = argv[i]; + filename = filename.substr(20); + std::ifstream f(filename.c_str()); + if (!f.is_open()) + { + std::string message("cppcheck: Couldn't open the file \""); + message += std::string(filename); + message += "\""; + PrintMessage(message); + return false; + } + const std::string errmsg(_settings->nomsg.parseFile(f)); + if (!errmsg.empty()) + { + PrintMessage(errmsg); + return false; + } + } + + // Filter errors + // This is deprecated, see --supressions-list above + else if (strcmp(argv[i], "--suppressions") == 0 && + strlen(argv[i]) == 14) { ++i; @@ -516,7 +540,7 @@ void CmdLineParser::PrintHelp() " cppcheck [--append=file] [-D] [--enable=] [--error-exitcode=[n]]\n" " [--exitcode-suppressions file] [--file-list=file.txt] [--force]\n" " [--help] [-Idir] [--inline-suppr] [-j [jobs]] [--quiet]\n" - " [--report-progress] [--style] [--suppressions file.txt]\n" + " [--report-progress] [--style] [--suppressions-list=file.txt]\n" " [--verbose] [--version] [--xml] [file or path1] [file or path]\n" "\n" "If path is given instead of filename, *.cpp, *.cxx, *.cc, *.c++ and *.c files\n" @@ -558,8 +582,10 @@ void CmdLineParser::PrintHelp() " -q, --quiet Only print error messages\n" " --report-progress Report progress messages while checking a file.\n" " -s, --style deprecated, use --enable=style\n" - " --suppressions file Suppress warnings listed in the file. Filename and line\n" - " are optional. The format of the single line in file is:\n" + " --suppressions-list=file\n" + " Suppress warnings listed in the file. Filename and line\n" + " are optional in the suppression file. The format of the\n" + " single line in the suppression file is:\n" " [error id]:[filename]:[line]\n" " --template '[text]' Format the error messages. E.g.\n" " '{file}:{line},{severity},{id},{message}' or\n" diff --git a/test/testcmdlineparser.cpp b/test/testcmdlineparser.cpp index 78dc5be51..c9bac0429 100644 --- a/test/testcmdlineparser.cpp +++ b/test/testcmdlineparser.cpp @@ -72,7 +72,9 @@ private: TEST_CASE(jobsMissingCount); TEST_CASE(jobsInvalid); TEST_CASE(reportProgress); - TEST_CASE(suppressions); // TODO: Create and test real suppression file + TEST_CASE(suppressionsOld); // TODO: Create and test real suppression file + TEST_CASE(suppressions) + TEST_CASE(suppressionsNoFile) TEST_CASE(templates); TEST_CASE(templatesGcc); TEST_CASE(templatesVs); @@ -492,8 +494,9 @@ private: ASSERT(settings.reportProgress); } - void suppressions() + void suppressionsOld() { + // TODO: Fails because there is no suppr.txt file! REDIRECT; const char *argv[] = {"cppcheck", "--suppressions suppr.txt", "file.cpp"}; Settings settings; @@ -501,6 +504,25 @@ private: ASSERT(!parser.ParseFromArgs(3, argv)); } + void suppressions() + { + // TODO: Fails because there is no suppr.txt file! + REDIRECT; + const char *argv[] = {"cppcheck", "--suppressions-list=suppr.txt", "file.cpp"}; + Settings settings; + CmdLineParser parser(&settings); + ASSERT(!parser.ParseFromArgs(3, argv)); + } + + void suppressionsNoFile() + { + REDIRECT; + const char *argv[] = {"cppcheck", "--suppressions-list=", "file.cpp"}; + Settings settings; + CmdLineParser parser(&settings); + ASSERT(!parser.ParseFromArgs(3, argv)); + } + void templates() { REDIRECT; From a299411a82a8aea27905ec1553b7b027d5a52d23 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Sat, 29 Jan 2011 16:14:09 +0100 Subject: [PATCH 137/165] Tokenizer: Better simplifications of static constants --- lib/tokenize.cpp | 12 ++++++------ test/testtokenize.cpp | 14 ++++++++++++++ 2 files changed, 20 insertions(+), 6 deletions(-) diff --git a/lib/tokenize.cpp b/lib/tokenize.cpp index 9cbdcd6ea..576dacb84 100644 --- a/lib/tokenize.cpp +++ b/lib/tokenize.cpp @@ -6231,22 +6231,22 @@ bool Tokenizer::simplifyKnownVariables() std::map constantValues; for (Token *tok = _tokens; tok; tok = tok->next()) { - if (Token::Match(tok, "static| const %type% %var% = %any% ;")) + if (Token::Match(tok, "static| const static| %type% %var% = %any% ;")) { Token *tok1 = tok; // start of statement if (tok != _tokens && !Token::Match(tok->previous(),"[;{}]")) continue; - // skip "static" - if (tok->str() == "static") + // skip "const" and "static" + while (tok->str() == "const" || tok->str() == "static") tok = tok->next(); // pod type - if (!tok->next()->isStandardType()) + if (!tok->isStandardType()) continue; - const Token * const vartok = tok->tokAt(2); - const Token * const valuetok = tok->tokAt(4); + const Token * const vartok = tok->next(); + const Token * const valuetok = tok->tokAt(3); if (valuetok->isNumber() || Token::Match(valuetok, "%str% ;")) { constantValues[vartok->varId()] = valuetok->str(); diff --git a/test/testtokenize.cpp b/test/testtokenize.cpp index f6d07042f..f2f827fb5 100644 --- a/test/testtokenize.cpp +++ b/test/testtokenize.cpp @@ -211,6 +211,7 @@ private: TEST_CASE(tokenize_strings); TEST_CASE(simplify_constants); TEST_CASE(simplify_constants2); + TEST_CASE(simplify_constants3); TEST_CASE(vardecl1); TEST_CASE(vardecl2); @@ -3812,6 +3813,19 @@ private: ASSERT_EQUALS(oss.str(), ostr.str()); } + void simplify_constants3() + { + const char code[] = + "static const char str[] = \"abcd\";\n" + "static const unsigned int SZ = sizeof(str);\n" + "void f() {\n" + "a = SZ;\n" + "}\n"; + const char expected[] = + "static const char str [ 5 ] = \"abcd\" ;\n\nvoid f ( ) {\na = 5 ;\n}"; + ASSERT_EQUALS(expected, tokenizeAndStringify(code,true)); + } + void vardecl1() { const char code[] = "unsigned int a, b;"; From d334a02801b52a6d5d372d05e03f619049fd5840 Mon Sep 17 00:00:00 2001 From: Kimmo Varis Date: Sat, 29 Jan 2011 19:04:52 +0200 Subject: [PATCH 138/165] Make --exitcode-suppressions option consistent. The --exitcode-suppressions option was inconsistent with other long options by taking the filename as separate argument. Now it expects format --exitcode-suppressions=filename.txt like other long options. Ticket: #1837 (--suppresions file.txt inconsistent) --- cli/cmdlineparser.cpp | 30 ++++++++++++++++++++++-------- test/testcmdlineparser.cpp | 25 +++++++++++++++++++++++-- 2 files changed, 45 insertions(+), 10 deletions(-) diff --git a/cli/cmdlineparser.cpp b/cli/cmdlineparser.cpp index a333804a8..c3eaa5764 100644 --- a/cli/cmdlineparser.cpp +++ b/cli/cmdlineparser.cpp @@ -104,20 +104,34 @@ bool CmdLineParser::ParseFromArgs(int argc, const char* const argv[]) } // Filter errors - else if (strcmp(argv[i], "--exitcode-suppressions") == 0) + else if (strncmp(argv[i], "--exitcode-suppressions", 23) == 0) { - ++i; + std::string filename; - if (i >= argc) + // exitcode-suppressions filename.txt + // Deprecated + if (strcmp(argv[i], "--exitcode-suppressions") == 0) { - PrintMessage("cppcheck: No file specified for the --exitcode-suppressions option"); - return false; + ++i; + + if (i >= argc || strncmp(argv[i], "-", 1) == 0 || + strncmp(argv[i], "--", 2) == 0) + { + PrintMessage("cppcheck: No filename specified for the --exitcode-suppressions option"); + return false; + } + filename = argv[i]; + } + // exitcode-suppressions=filename.txt + else + { + filename = 24 + argv[i]; } - std::ifstream f(argv[i]); + std::ifstream f(filename.c_str()); if (!f.is_open()) { - PrintMessage("cppcheck: Couldn't open the file \"" + std::string(argv[i]) + "\""); + PrintMessage("cppcheck: Couldn't open the file \"" + std::string(filename) + "\""); return false; } const std::string errmsg(_settings->nofail.parseFile(f)); @@ -565,7 +579,7 @@ void CmdLineParser::PrintHelp() " provided. Note that your operating system can\n" " modify this value, e.g. 256 can become 0.\n" " --errorlist Print a list of all error messages in XML format.\n" - " --exitcode-suppressions file\n" + " --exitcode-suppressions=file\n" " Used when certain messages should be displayed but\n" " should not cause a non-zero exitcode.\n" " --file-list=file Specify the files to check in a text file. One Filename per line.\n" diff --git a/test/testcmdlineparser.cpp b/test/testcmdlineparser.cpp index c9bac0429..6b9bdf75c 100644 --- a/test/testcmdlineparser.cpp +++ b/test/testcmdlineparser.cpp @@ -65,7 +65,9 @@ private: TEST_CASE(errorExitcode); TEST_CASE(errorExitcodeMissing); TEST_CASE(errorExitcodeStr); - TEST_CASE(exitcodeSuppressions); // TODO: Create and test real suppression file + TEST_CASE(exitcodeSuppressionsOld); // TODO: Create and test real suppression file + TEST_CASE(exitcodeSuppressions); + TEST_CASE(exitcodeSuppressionsNoFile); TEST_CASE(fileList); // TODO: Create and test real file listing file TEST_CASE(inlineSuppr); TEST_CASE(jobs); @@ -429,10 +431,29 @@ private: ASSERT(!parser.ParseFromArgs(3, argv)); } + void exitcodeSuppressionsOld() + { + // TODO: Fails since cannot open the file + REDIRECT; + const char *argv[] = {"cppcheck", "--exitcode-suppressions", "suppr.txt", "file.cpp"}; + Settings settings; + CmdLineParser parser(&settings); + ASSERT(!parser.ParseFromArgs(4, argv)); + } + void exitcodeSuppressions() { REDIRECT; - const char *argv[] = {"cppcheck", "--error-exitcode-suppressions suppr.txt", "file.cpp"}; + const char *argv[] = {"cppcheck", "--exitcode-suppressions=suppr.txt", "file.cpp"}; + Settings settings; + CmdLineParser parser(&settings); + ASSERT(!parser.ParseFromArgs(3, argv)); + } + + void exitcodeSuppressionsNoFile() + { + REDIRECT; + const char *argv[] = {"cppcheck", "--exitcode-suppressions", "file.cpp"}; Settings settings; CmdLineParser parser(&settings); ASSERT(!parser.ParseFromArgs(3, argv)); From b9a0e10b9a58091b3dc54b2a97b3f9216dddefde Mon Sep 17 00:00:00 2001 From: Kimmo Varis Date: Sat, 29 Jan 2011 19:16:23 +0200 Subject: [PATCH 139/165] Several fixes to cmd line tests. There were several tests handling two parameters as one string. Eg. "-I path" which doesn't work correctly. Fixed these problematic tests. --- test/testcmdlineparser.cpp | 42 +++++++++++++++++++------------------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/test/testcmdlineparser.cpp b/test/testcmdlineparser.cpp index 6b9bdf75c..009be82f0 100644 --- a/test/testcmdlineparser.cpp +++ b/test/testcmdlineparser.cpp @@ -312,31 +312,31 @@ private: void includes() { REDIRECT; - const char *argv[] = {"cppcheck", "-I include", "file.cpp"}; + const char *argv[] = {"cppcheck", "-I", "include", "file.cpp"}; Settings settings; CmdLineParser parser(&settings); - ASSERT(parser.ParseFromArgs(3, argv)); - ASSERT_EQUALS(" include/", settings._includePaths.front()); + ASSERT(parser.ParseFromArgs(4, argv)); + ASSERT_EQUALS("include/", settings._includePaths.front()); } void includesslash() { REDIRECT; - const char *argv[] = {"cppcheck", "-I include/", "file.cpp"}; + const char *argv[] = {"cppcheck", "-I", "include/", "file.cpp"}; Settings settings; CmdLineParser parser(&settings); - ASSERT(parser.ParseFromArgs(3, argv)); - ASSERT_EQUALS(" include/", settings._includePaths.front()); + ASSERT(parser.ParseFromArgs(4, argv)); + ASSERT_EQUALS("include/", settings._includePaths.front()); } void includesbackslash() { REDIRECT; - const char *argv[] = {"cppcheck", "-I include\\", "file.cpp"}; + const char *argv[] = {"cppcheck", "-I", "include\\", "file.cpp"}; Settings settings; CmdLineParser parser(&settings); - ASSERT(parser.ParseFromArgs(3, argv)); - ASSERT_EQUALS(" include/", settings._includePaths.front()); + ASSERT(parser.ParseFromArgs(4, argv)); + ASSERT_EQUALS("include/", settings._includePaths.front()); } void includesnospace() @@ -352,13 +352,13 @@ private: void includes2() { REDIRECT; - const char *argv[] = {"cppcheck", "-I include/", "-I framework/", "file.cpp"}; + const char *argv[] = {"cppcheck", "-I", "include/", "-I", "framework/", "file.cpp"}; Settings settings; CmdLineParser parser(&settings); - ASSERT(parser.ParseFromArgs(4, argv)); - ASSERT_EQUALS(" include/", settings._includePaths.front()); + ASSERT(parser.ParseFromArgs(6, argv)); + ASSERT_EQUALS("include/", settings._includePaths.front()); settings._includePaths.pop_front(); - ASSERT_EQUALS(" framework/", settings._includePaths.front()); + ASSERT_EQUALS("framework/", settings._includePaths.front()); } void enabledAll() @@ -462,10 +462,10 @@ private: void fileList() { REDIRECT; - const char *argv[] = {"cppcheck", "--file-list files.txt", "file.cpp"}; + const char *argv[] = {"cppcheck", "--file-list", "files.txt", "file.cpp"}; Settings settings; CmdLineParser parser(&settings); - ASSERT(!parser.ParseFromArgs(3, argv)); + ASSERT(!parser.ParseFromArgs(4, argv)); } void inlineSuppr() @@ -480,10 +480,10 @@ private: void jobs() { REDIRECT; - const char *argv[] = {"cppcheck", "-j 3", "file.cpp"}; + const char *argv[] = {"cppcheck", "-j", "3", "file.cpp"}; Settings settings; CmdLineParser parser(&settings); - ASSERT(parser.ParseFromArgs(3, argv)); + ASSERT(parser.ParseFromArgs(4, argv)); ASSERT_EQUALS(3, settings._jobs); } @@ -499,10 +499,10 @@ private: void jobsInvalid() { REDIRECT; - const char *argv[] = {"cppcheck", "-j e", "file.cpp"}; + const char *argv[] = {"cppcheck", "-j", "e", "file.cpp"}; Settings settings; CmdLineParser parser(&settings); - ASSERT(!parser.ParseFromArgs(3, argv)); + ASSERT(!parser.ParseFromArgs(4, argv)); } void reportProgress() @@ -519,10 +519,10 @@ private: { // TODO: Fails because there is no suppr.txt file! REDIRECT; - const char *argv[] = {"cppcheck", "--suppressions suppr.txt", "file.cpp"}; + const char *argv[] = {"cppcheck", "--suppressions", "suppr.txt", "file.cpp"}; Settings settings; CmdLineParser parser(&settings); - ASSERT(!parser.ParseFromArgs(3, argv)); + ASSERT(!parser.ParseFromArgs(4, argv)); } void suppressions() From 0624e418f108835da1c2d243b451438a1497ba06 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Sat, 29 Jan 2011 18:46:55 +0100 Subject: [PATCH 140/165] Memory leaks: bug fix. don't skip '}' by accident --- lib/checkmemoryleak.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/checkmemoryleak.cpp b/lib/checkmemoryleak.cpp index dcb203360..1b1dc891f 100644 --- a/lib/checkmemoryleak.cpp +++ b/lib/checkmemoryleak.cpp @@ -921,7 +921,7 @@ Token *CheckMemoryLeakInFunction::getcode(const Token *tok, std::listvarId() == varid || - tok2->str() == ":" || tok2->str() == "{") + tok2->str() == ":" || tok2->str() == "{" || tok2->str() == "}") { break; } From 49fc53165cd2320114b824b8574b84d900f395d9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Sun, 30 Jan 2011 08:34:58 +0100 Subject: [PATCH 141/165] Tokenizer: remove some unhandled macros in the global scope. ticket: #2523 --- lib/tokenize.cpp | 22 +++++++++++++++++++++- lib/tokenize.h | 3 +++ test/testtokenize.cpp | 9 +++++++++ 3 files changed, 33 insertions(+), 1 deletion(-) diff --git a/lib/tokenize.cpp b/lib/tokenize.cpp index 576dacb84..75ff66b60 100644 --- a/lib/tokenize.cpp +++ b/lib/tokenize.cpp @@ -2083,7 +2083,7 @@ bool Tokenizer::tokenize(std::istream &code, } - // remove inline SQL (Oracle PRO*C). Ticket: #1959 + // replace inline SQL with "asm()" (Oracle PRO*C). Ticket: #1959 for (Token *tok = _tokens; tok; tok = tok->next()) { if (Token::simpleMatch(tok, "EXEC SQL")) @@ -2123,6 +2123,9 @@ bool Tokenizer::tokenize(std::istream &code, } } + // remove some unhandled macros in global scope + removeMacrosInGlobalScope(); + // specify array size.. arraySize(); @@ -4383,6 +4386,23 @@ bool Tokenizer::simplifyTokenList() } //--------------------------------------------------------------------------- +void Tokenizer::removeMacrosInGlobalScope() +{ + for (Token *tok = _tokens; tok; tok = tok->next()) + { + if (tok->str() == "(") + { + tok = tok->link(); + if (Token::Match(tok, ") %type% {") && tok->strAt(1) != "const") + tok->deleteNext(); + } + + if (tok->str() == "{") + tok = tok->link(); + } +} +//--------------------------------------------------------------------------- + void Tokenizer::removeRedundantAssignment() { for (Token *tok = _tokens; tok; tok = tok->next()) diff --git a/lib/tokenize.h b/lib/tokenize.h index 8dacc345a..5662d7843 100644 --- a/lib/tokenize.h +++ b/lib/tokenize.h @@ -186,6 +186,9 @@ public: /** Simplify labels */ void labels(); + /** Remove macros in global scope */ + void removeMacrosInGlobalScope(); + /** Remove redundant assignment */ void removeRedundantAssignment(); diff --git a/test/testtokenize.cpp b/test/testtokenize.cpp index f2f827fb5..da56bdfa7 100644 --- a/test/testtokenize.cpp +++ b/test/testtokenize.cpp @@ -298,6 +298,9 @@ private: TEST_CASE(java); TEST_CASE(simplifyOperatorName); + + // Some simple cleanups of unhandled macros in the global scope + TEST_CASE(removeMacrosInGlobalScope); } @@ -5247,6 +5250,12 @@ private: ASSERT_EQUALS(result2, tokenizeAndStringify(code2,false)); } + + void removeMacrosInGlobalScope() + { + // remove some unhandled macros in the global scope. + ASSERT_EQUALS("void f ( ) { }", tokenizeAndStringify("void f() NOTHROW { }")); + } }; REGISTER_TEST(TestTokenizer) From 09998d9e181f88a369a78fc078549722c9064f0b Mon Sep 17 00:00:00 2001 From: Robert Reif Date: Sun, 30 Jan 2011 08:38:20 +0100 Subject: [PATCH 142/165] Memory leaks: less conservative checking of classes. ticket: #2517 --- lib/checkmemoryleak.cpp | 4 ++-- test/testmemleak.cpp | 40 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 42 insertions(+), 2 deletions(-) diff --git a/lib/checkmemoryleak.cpp b/lib/checkmemoryleak.cpp index 1b1dc891f..0ffab12c7 100644 --- a/lib/checkmemoryleak.cpp +++ b/lib/checkmemoryleak.cpp @@ -2727,8 +2727,8 @@ void CheckMemoryLeakInClass::check() // known class? else if (var->type()) { - // not derived and no constructor? - if (var->type()->derivedFrom.empty() && var->type()->numConstructors == 0) + // not derived? + if (var->type()->derivedFrom.empty()) { if (var->isPrivate()) checkPublicFunctions(scope, var->nameToken()); diff --git a/test/testmemleak.cpp b/test/testmemleak.cpp index 4cebd567f..16a96b0c4 100644 --- a/test/testmemleak.cpp +++ b/test/testmemleak.cpp @@ -3165,6 +3165,7 @@ private: TEST_CASE(class18); TEST_CASE(class19); // ticket #2219 TEST_CASE(class20); + TEST_CASE(class21); // ticket #2517 TEST_CASE(staticvar); @@ -4018,6 +4019,45 @@ private: ASSERT_EQUALS("[test.cpp:7]: (error) Memory leak: Fred::str1\n", errout.str()); } + void class21() // ticket #2517 + { + check("struct B { };\n" + "struct C\n" + "{\n" + " B * b;\n" + " C(B * x) : b(x) { }\n" + "};\n" + "class A\n" + "{\n" + " B *b;\n" + " C *c;\n" + "public:\n" + " A() : b(new B()), c(new C(b)) { }\n" + "}\n"); + ASSERT_EQUALS("[test.cpp:9]: (error) Memory leak: A::b\n" + "[test.cpp:10]: (error) Memory leak: A::c\n", errout.str()); + + check("struct B { };\n" + "struct C\n" + "{\n" + " B * b;\n" + " C(B * x) : b(x) { }\n" + "};\n" + "class A\n" + "{\n" + " B *b;\n" + " C *c;\n" + "public:\n" + " A()\n" + " {\n" + " b = new B();\n" + " c = new C(b);\n" + " }\n" + "}\n"); + ASSERT_EQUALS("[test.cpp:9]: (error) Memory leak: A::b\n" + "[test.cpp:10]: (error) Memory leak: A::c\n", errout.str()); + } + void staticvar() { check("class A\n" From 49848fd752fd242c37338f82cbed453e477729ac Mon Sep 17 00:00:00 2001 From: Raphael Geissert Date: Sun, 30 Jan 2011 02:09:12 -0600 Subject: [PATCH 143/165] Remove duplicated defines After simplifying define(A) conditionals, the final list of configurations could end up containing duplicate items. Ticket #1468 --- lib/preprocessor.cpp | 1 + test/testpreprocessor.cpp | 37 +++++++++++++++++++++++++++++++++++++ 2 files changed, 38 insertions(+) diff --git a/lib/preprocessor.cpp b/lib/preprocessor.cpp index 7a7ac1c74..ddf0b6128 100644 --- a/lib/preprocessor.cpp +++ b/lib/preprocessor.cpp @@ -1040,6 +1040,7 @@ std::list Preprocessor::getcfgs(const std::string &filedata, const // Re-constitute the configuration after sorting the defines defs.sort(); + defs.unique(); *it = join(defs, ';'); } diff --git a/test/testpreprocessor.cpp b/test/testpreprocessor.cpp index 4a49ce42a..92ca11320 100644 --- a/test/testpreprocessor.cpp +++ b/test/testpreprocessor.cpp @@ -173,6 +173,7 @@ private: TEST_CASE(endifsemicolon); TEST_CASE(missing_doublequote); TEST_CASE(handle_error); + TEST_CASE(dup_defines); TEST_CASE(unicodeInCode); TEST_CASE(unicodeInComment); @@ -2380,6 +2381,42 @@ private: ASSERT_EQUALS("char a[] = \"#endfile\";\nchar b[] = \"#endfile\";\n\n", actual[""]); ASSERT_EQUALS(1, (int)actual.size()); } + + void dup_defines() + { + const char filedata[] = "#ifdef A\n" + "#define B\n" + "#if defined(B) && defined(A)\n" + "a\n" + "#else\n" + "b\n" + "#endif\n" + "#endif\n"; + + // Preprocess => actual result.. + std::istringstream istr(filedata); + std::map actual; + Settings settings; + Preprocessor preprocessor(&settings, this); + preprocessor.preprocess(istr, actual, "file.c"); + + // B will always be defined if A is defined; the following test + // cases should be fixed whenever this other bug is fixed + TODO_ASSERT_EQUALS(2, static_cast(actual.size())); + ASSERT_EQUALS(3, static_cast(actual.size())); + + if (actual.find("A") == actual.end()) { + ASSERT_EQUALS("A is checked", "failed"); + } else { + ASSERT_EQUALS("A is checked", "A is checked"); + } + + if (actual.find("A;A;B") != actual.end()) { + ASSERT_EQUALS("A;A;B is NOT checked", "failed"); + } else { + ASSERT_EQUALS("A;A;B is NOT checked", "A;A;B is NOT checked"); + } + } }; REGISTER_TEST(TestPreprocessor) From 5137f5fb7f7b2605f5b16cd33e657df3e24e6977 Mon Sep 17 00:00:00 2001 From: Raphael Geissert Date: Sun, 30 Jan 2011 02:34:58 -0600 Subject: [PATCH 144/165] Detect null pointer dereferences for many FILE-related functions Ticket #1415: check for calling f{eof,read,close,...} with NULL --- lib/checknullpointer.cpp | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/lib/checknullpointer.cpp b/lib/checknullpointer.cpp index cb4c9702b..e9b1467bd 100644 --- a/lib/checknullpointer.cpp +++ b/lib/checknullpointer.cpp @@ -69,6 +69,15 @@ void CheckNullPointer::parseFunctionCall(const Token &tok, std::list Date: Sun, 30 Jan 2011 22:51:24 +1100 Subject: [PATCH 145/165] astyle formatting. --- cli/filelister_win32.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cli/filelister_win32.cpp b/cli/filelister_win32.cpp index 041613331..776e0245a 100644 --- a/cli/filelister_win32.cpp +++ b/cli/filelister_win32.cpp @@ -88,7 +88,7 @@ static BOOL MyIsDirectory(std::string path) return (GetFileAttributes(path.c_str()) & FILE_ATTRIBUTE_DIRECTORY); #else // See http://msdn.microsoft.com/en-us/library/bb773621(VS.85).aspx -return PathIsDirectory(path.c_str()); + return PathIsDirectory(path.c_str()); #endif } From 098f0bf3e659436eedae2655d78eb1867576f728 Mon Sep 17 00:00:00 2001 From: Pete Johns Date: Sun, 30 Jan 2011 22:54:19 +1100 Subject: [PATCH 146/165] Fixed #2526 (Make TODO_ASSERT_EQUALS take three arguments (value, to_be, as_is)?... Removed replaced EXPECTED with... WANTED (to-be): The future expected value. CURRENT (as-is): Documenting how cppcheck behaves now. This removes the need for an ASSERT_EQUALS but enforces the check for every TODO_ASSERT_EQUALS. --- test/testbufferoverrun.cpp | 46 +++--- test/testclass.cpp | 13 +- test/testdivision.cpp | 20 +-- test/testmemleak.cpp | 57 +++---- test/testnullpointer.cpp | 8 +- test/testobsoletefunctions.cpp | 4 +- test/testother.cpp | 5 +- test/testpostfixoperator.cpp | 3 +- test/testpreprocessor.cpp | 53 ++++--- test/testsimplifytokens.cpp | 105 ++++++++----- test/teststl.cpp | 8 +- test/testsuite.cpp | 20 ++- test/testsuite.h | 8 +- test/testtokenize.cpp | 263 +++++++++++++++++++-------------- test/testuninitvar.cpp | 8 +- test/testunusedvar.cpp | 30 ++-- 16 files changed, 367 insertions(+), 284 deletions(-) diff --git a/test/testbufferoverrun.cpp b/test/testbufferoverrun.cpp index 70a99b07f..c63094fde 100644 --- a/test/testbufferoverrun.cpp +++ b/test/testbufferoverrun.cpp @@ -561,8 +561,8 @@ private: " char str[5];\n" " memclr( 10, str ); // ERROR\n" "}\n"); - TODO_ASSERT_EQUALS("[test.cpp:9] -> [test.cpp:3]: (possible error) Array index out of bounds\n", errout.str()); - ASSERT_EQUALS("", errout.str()); // current result + TODO_ASSERT_EQUALS("[test.cpp:9] -> [test.cpp:3]: (possible error) Array index out of bounds\n", + "", errout.str()); // This is not an error check("static void memclr( char *data, int size )\n" @@ -610,8 +610,8 @@ private: "{\n" " memclr(abc->str);\n" "}\n"); - ASSERT_EQUALS("", errout.str()); - TODO_ASSERT_EQUALS("[test.cpp:13] -> [test.cpp:8]: (possible error) Array index out of bounds\n", errout.str()); + TODO_ASSERT_EQUALS("[test.cpp:13] -> [test.cpp:8]: (possible error) Array index out of bounds\n", + "", errout.str()); } @@ -795,8 +795,7 @@ private: " i+=1;\n" " }\n" "}\n"); - ASSERT_EQUALS("", errout.str()); // Catch changes - TODO_ASSERT_EQUALS("[test.cpp:6]: (error) Buffer overrun\n", errout.str()); + TODO_ASSERT_EQUALS("[test.cpp:6]: (error) Buffer overrun\n", "", errout.str()); } void array_index_19() @@ -1001,8 +1000,7 @@ private: " int *ip = &i[1];\n" " ip[-10] = 1;\n" "}\n"); - ASSERT_EQUALS("", errout.str()); - TODO_ASSERT_EQUALS("[test.cpp:5]: (error) Array ip[-10] out of bounds\n", errout.str()); + TODO_ASSERT_EQUALS("[test.cpp:5]: (error) Array ip[-10] out of bounds\n", "", errout.str()); } void array_index_29() @@ -1015,8 +1013,7 @@ private: " int *ii = &i[-5];" " ii[10] = 0;" "}\n"); - ASSERT_EQUALS("", errout.str()); - TODO_ASSERT_EQUALS("[test.cpp:6]: (error) Array ii[10] out of bounds\n", errout.str()); + TODO_ASSERT_EQUALS("[test.cpp:6]: (error) Array ii[10] out of bounds\n", "", errout.str()); } void array_index_30() @@ -1133,7 +1130,7 @@ private: " char a[10][10][10];\n" " a[2*3][4*3][2] = 'a';\n" "}\n"); - TODO_ASSERT_EQUALS("[test.cpp:4]: (error) Array 'a[10][10][10]' index a[6][12][2] out of bounds\n", errout.str()); + TODO_ASSERT_EQUALS("[test.cpp:4]: (error) Array 'a[10][10][10]' index a[6][12][2] out of bounds\n", "", errout.str()); check("void f()\n" "{\n" @@ -1201,8 +1198,7 @@ private: " };\n" " }\n" "}\n"); - ASSERT_EQUALS("", errout.str()); - TODO_ASSERT_EQUALS("[test.cpp:12]: (error) Array index out of bounds\n", errout.str()); + TODO_ASSERT_EQUALS("[test.cpp:12]: (error) Array index out of bounds\n", "", errout.str()); } void array_index_calculation() @@ -1295,8 +1291,7 @@ private: " val[i+1] = val[i];\n" " }\n" "}\n"); - ASSERT_EQUALS("", errout.str()); // catch changes - TODO_ASSERT_EQUALS("[test.cpp:5]: (error) Array 'val[5]' index -1 out of bounds\n", errout.str()); + TODO_ASSERT_EQUALS("[test.cpp:5]: (error) Array 'val[5]' index -1 out of bounds\n", "", errout.str()); } @@ -1562,8 +1557,7 @@ private: " char s[3];\n" " f1(s,3);\n" "}\n"); - TODO_ASSERT_EQUALS("[test.cpp:8] -> [test.cpp:3]: (error) Buffer access out-of-bounds\n", errout.str()); - ASSERT_EQUALS("", errout.str()); + TODO_ASSERT_EQUALS("[test.cpp:8] -> [test.cpp:3]: (error) Buffer access out-of-bounds\n", "", errout.str()); check("void f1(char *s,int size)\n" "{\n" @@ -1999,8 +1993,7 @@ private: " char buf[3];\n" " sprintf(buf, \"%s\", condition ? \"11\" : \"222\");\n" "}\n"); - ASSERT_EQUALS("", errout.str()); // catch changes - TODO_ASSERT_EQUALS("[test.cpp:4]: (error) Buffer access out-of-bounds\n", errout.str()); + TODO_ASSERT_EQUALS("[test.cpp:4]: (error) Buffer access out-of-bounds\n", "", errout.str()); } void sprintf7() @@ -2224,8 +2217,7 @@ private: " char a[5], b[50];\n" " memchr(a, b, 10);\n" "}\n"); - TODO_ASSERT_EQUALS("[test.cpp:4]: (error) Buffer access out-of-bounds\n", errout.str()); - ASSERT_EQUALS("", errout.str()); + TODO_ASSERT_EQUALS("[test.cpp:4]: (error) Buffer access out-of-bounds\n", "", errout.str()); } // ticket #2121 - buffer access out of bounds when using uint32_t @@ -2466,7 +2458,7 @@ private: ASSERT_EQUALS(9, CheckBufferOverrun::countSprintfLength("%08ld", intAsParameter)); ASSERT_EQUALS(6, CheckBufferOverrun::countSprintfLength("%.2d", intAsParameter)); ASSERT_EQUALS(9, CheckBufferOverrun::countSprintfLength("%08.2d", intAsParameter)); - TODO_ASSERT_EQUALS(5, CheckBufferOverrun::countSprintfLength("%x", intAsParameter)); + TODO_ASSERT_EQUALS(5, 2, CheckBufferOverrun::countSprintfLength("%x", intAsParameter)); ASSERT_EQUALS(5, CheckBufferOverrun::countSprintfLength("%4x", intAsParameter)); ASSERT_EQUALS(6, CheckBufferOverrun::countSprintfLength("%5x", intAsParameter)); ASSERT_EQUALS(5, CheckBufferOverrun::countSprintfLength("%.4x", intAsParameter)); @@ -2478,17 +2470,17 @@ private: Token floatTok(0); floatTok.str("1.12345f"); floatAsParameter.push_back(&floatTok); - TODO_ASSERT_EQUALS(5, CheckBufferOverrun::countSprintfLength("%.2f", floatAsParameter)); + TODO_ASSERT_EQUALS(5, 3, CheckBufferOverrun::countSprintfLength("%.2f", floatAsParameter)); ASSERT_EQUALS(9, CheckBufferOverrun::countSprintfLength("%8.2f", floatAsParameter)); - TODO_ASSERT_EQUALS(5, CheckBufferOverrun::countSprintfLength("%2.2f", floatAsParameter)); + TODO_ASSERT_EQUALS(5, 3, CheckBufferOverrun::countSprintfLength("%2.2f", floatAsParameter)); std::list floatAsParameter2; Token floatTok2(0); floatTok2.str("100.12345f"); floatAsParameter2.push_back(&floatTok2); - TODO_ASSERT_EQUALS(7, CheckBufferOverrun::countSprintfLength("%2.2f", floatAsParameter2)); - TODO_ASSERT_EQUALS(7, CheckBufferOverrun::countSprintfLength("%.2f", floatAsParameter)); - TODO_ASSERT_EQUALS(7, CheckBufferOverrun::countSprintfLength("%4.2f", floatAsParameter)); + TODO_ASSERT_EQUALS(7, 3, CheckBufferOverrun::countSprintfLength("%2.2f", floatAsParameter2)); + TODO_ASSERT_EQUALS(7, 3, CheckBufferOverrun::countSprintfLength("%.2f", floatAsParameter)); + TODO_ASSERT_EQUALS(7, 5, CheckBufferOverrun::countSprintfLength("%4.2f", floatAsParameter)); std::list multipleParams; multipleParams.push_back(&strTok); diff --git a/test/testclass.cpp b/test/testclass.cpp index 44ffed8a3..03080cfb8 100644 --- a/test/testclass.cpp +++ b/test/testclass.cpp @@ -1498,7 +1498,8 @@ private: "public:\n" " ~B() { int a; }\n" "};\n"); - TODO_ASSERT_EQUALS("[test.cpp:7]: (error) Class A which is inherited by class B does not have a virtual destructor\n", errout.str()); + TODO_ASSERT_EQUALS("[test.cpp:7]: (error) Class A which is inherited by class B does not have a virtual destructor\n", + "", errout.str()); } void virtualDestructorTemplate() @@ -4303,7 +4304,8 @@ private: "std::vector m_strVec;\n" "};\n" ); - TODO_ASSERT_EQUALS("[test.cpp:4]: (information) Technically the member function 'A::strGetSize' can be const.\n", errout.str()); + TODO_ASSERT_EQUALS("[test.cpp:4]: (information) Technically the member function 'A::strGetSize' can be const.\n", + "", errout.str()); } void const26() // ticket #1847 @@ -4625,8 +4627,8 @@ private: "}\n" "using namespace N;\n" "int Base::getResourceName() { return var; }\n"); - ASSERT_EQUALS("", errout.str()); - TODO_ASSERT_EQUALS("[test.cpp:11] -> [test.cpp:6]: (information) Technically the member function 'N::Base::getResourceName' can be const.\n", errout.str()); + TODO_ASSERT_EQUALS("[test.cpp:11] -> [test.cpp:6]: (information) Technically the member function 'N::Base::getResourceName' can be const.\n", + "", errout.str()); } void const36() // ticket #2003 @@ -5076,7 +5078,8 @@ private: " A(){}\n" " unsigned int GetVecSize() {return m_v.size();}\n" "}"); - TODO_ASSERT_EQUALS("[test.cpp:7]: (information) Technically the member function 'A::GetVecSize' can be const.\n", errout.str()); + TODO_ASSERT_EQUALS("[test.cpp:7]: (information) Technically the member function 'A::GetVecSize' can be const.\n", + "", errout.str()); } void constVirtualFunc() diff --git a/test/testdivision.cpp b/test/testdivision.cpp index 6757a4a2f..aee9c6cde 100644 --- a/test/testdivision.cpp +++ b/test/testdivision.cpp @@ -74,8 +74,8 @@ private: " unsigned int uvar = 2;\n" " return ivar / uvar;\n" "}\n"); - TODO_ASSERT_EQUALS("[test.cpp:5]: (style) Division with signed and unsigned operators\n", errout.str()); - ASSERT_EQUALS("", errout.str()); + TODO_ASSERT_EQUALS("[test.cpp:5]: (style) Division with signed and unsigned operators\n", + "", errout.str()); } void division2() @@ -86,8 +86,8 @@ private: " unsigned int uvar = 2;\n" " return uvar / ivar;\n" "}\n"); - TODO_ASSERT_EQUALS("[test.cpp:5]: (style) Division with signed and unsigned operators\n", errout.str()); - ASSERT_EQUALS("", errout.str()); + TODO_ASSERT_EQUALS("[test.cpp:5]: (style) Division with signed and unsigned operators\n", + "", errout.str()); } void division4() @@ -166,8 +166,8 @@ private: " unsigned int c = a / b;\n" " }\n" "}\n", true); - ASSERT_EQUALS("", errout.str()); - TODO_ASSERT_EQUALS("unsigned division", errout.str()); + TODO_ASSERT_EQUALS("unsigned division", + "", errout.str()); check("void a(int i) { }\n" "int foo( unsigned int sz )\n" @@ -186,8 +186,8 @@ private: " unsigned long uvar = 2;\n" " return ivar / uvar;\n" "}\n"); - ASSERT_EQUALS("", errout.str()); - TODO_ASSERT_EQUALS("unsigned division", errout.str()); + TODO_ASSERT_EQUALS("unsigned division", + "", errout.str()); check("void f()\n" "{\n" @@ -195,8 +195,8 @@ private: " unsigned long long uvar = 2;\n" " return ivar / uvar;\n" "}\n"); - ASSERT_EQUALS("", errout.str()); - TODO_ASSERT_EQUALS("unsigned division", errout.str()); + TODO_ASSERT_EQUALS("unsigned division", + "", errout.str()); } }; diff --git a/test/testmemleak.cpp b/test/testmemleak.cpp index 16a96b0c4..6699e56ac 100644 --- a/test/testmemleak.cpp +++ b/test/testmemleak.cpp @@ -403,8 +403,8 @@ private: ASSERT_EQUALS(";;dealloc;", getcode("char *s; free(reinterpret_cast(s));", "s")); ASSERT_EQUALS(";;dealloc;", getcode("char *s; delete s;", "s")); ASSERT_EQUALS(";;dealloc;", getcode("char *s; delete (s);", "s")); - ASSERT_EQUALS(";;;", getcode("char *s; delete (void *)(s);", "s")); // current result.. - TODO_ASSERT_EQUALS(";;dealloc;", getcode("char *s; delete (void *)(s);", "s")); // ..wanted result + TODO_ASSERT_EQUALS(";;dealloc;", + ";;;", getcode("char *s; delete (void *)(s);", "s")); ASSERT_EQUALS(";;dealloc;", getcode("char *s; delete [] s;", "s")); ASSERT_EQUALS(";;dealloc;", getcode("char *s; delete [] (s);", "s")); ASSERT_EQUALS(";;dealloc;", getcode("void *p; foo(fclose(p));", "p")); @@ -453,7 +453,8 @@ private: // Since we don't check how the return value is used we must bail out ASSERT_EQUALS("", getcode("char *s; int ret = asprintf(&s, \"xyz\");", "s")); - TODO_ASSERT_EQUALS(";;alloc;", getcode("char *s; int ret; ret=asprintf(&s, \"xyz\"); if (ret==-1) return;", "s")); + TODO_ASSERT_EQUALS(";;alloc;", + "", getcode("char *s; int ret; ret=asprintf(&s, \"xyz\"); if (ret==-1) return;", "s")); // use.. ASSERT_EQUALS(";;use;", getcode("char *s; a(s);", "s")); @@ -695,10 +696,8 @@ private: ASSERT_EQUALS("; use ;", simplifycode("; while1 { if { dealloc ; return ; } if { if { continue ; } } }")); // scope.. - // current result - ok - ASSERT_EQUALS("; assign ; dealloc ; if alloc ; }", simplifycode("; assign ; { dealloc ; if alloc ; } }")); - // wanted result - better - TODO_ASSERT_EQUALS("; assign ; if alloc ; }", simplifycode("; assign ; { dealloc ; if alloc ; } }")); + TODO_ASSERT_EQUALS("; assign ; if alloc ; }", + "; assign ; dealloc ; if alloc ; }", simplifycode("; assign ; { dealloc ; if alloc ; } }")); // callfunc.. ASSERT_EQUALS("; callfunc ; }", simplifycode(";callfunc;}")); @@ -713,8 +712,10 @@ private: ASSERT_EQUALS(";", simplifycode("; if { alloc; exit; }")); ASSERT_EQUALS("; alloc ;", simplifycode("; alloc ; if { use; exit; }")); ASSERT_EQUALS("; alloc ;", simplifycode("; alloc ; if(!var) { exit; }")); - TODO_ASSERT_EQUALS(";", simplifycode("; alloc ; if(var) { exit; }")); - TODO_ASSERT_EQUALS(";\n; alloc ;", simplifycode("; alloc ; ifv { exit; }")); + TODO_ASSERT_EQUALS(";", + "; if(var) exit ;", simplifycode("; alloc ; if(var) { exit; }")); + TODO_ASSERT_EQUALS(";\n; alloc ;", + "; alloc ; ifv exit ;", simplifycode("; alloc ; ifv { exit; }")); // try-catch ASSERT_EQUALS("; }", simplifycode("; try ; catch exit ; }")); @@ -808,8 +809,8 @@ private: ASSERT_EQUALS(2, dofindleak(";alloc;\n if assign;\n dealloc;")); // loop.. - TODO_ASSERT_EQUALS(1, dofindleak("; loop { alloc ; if break; dealloc ; }")); - TODO_ASSERT_EQUALS(1, dofindleak("; loop { alloc ; if continue; dealloc ; }")); + TODO_ASSERT_EQUALS(1, notfound, dofindleak("; loop { alloc ; if break; dealloc ; }")); + TODO_ASSERT_EQUALS(1, notfound, dofindleak("; loop { alloc ; if continue; dealloc ; }")); ASSERT_EQUALS(notfound, dofindleak("; loop { alloc ; if break; } dealloc ;")); ASSERT_EQUALS(1, dofindleak("; loop alloc ;")); ASSERT_EQUALS(1, dofindleak("; loop alloc ; dealloc ;")); @@ -1132,13 +1133,11 @@ private: " }\n" " delete [] x;\n" "}\n", true); - TODO_ASSERT_EQUALS("[test.cpp:6]: (error) Memory leak: x\n", errout.str()); - ASSERT_EQUALS("", errout.str()); + TODO_ASSERT_EQUALS("[test.cpp:6]: (error) Memory leak: x\n", + "", errout.str()); } - - void forwhile5() { check("void f(const char **a)\n" @@ -1187,8 +1186,10 @@ private: "\n" " return a;\n" "}\n"); - TODO_ASSERT_EQUALS("[test.cpp:10]: (error) Memory leak: a\n", errout.str()); - ASSERT_EQUALS("[test.cpp:8]: (error) Common realloc mistake: \'a\' nulled but not freed upon failure\n", errout.str()); + TODO_ASSERT_EQUALS("[test.cpp:10]: (error) Memory leak: a\n", + + "[test.cpp:8]: (error) Common realloc mistake: \'a\' nulled but not freed upon failure\n", + errout.str()); } @@ -1478,8 +1479,8 @@ private: " char *p = new char[100];\n" " foo(p);\n" "}\n"); - TODO_ASSERT_EQUALS("[test.cpp:11]: (error) Memory leak: p\n", errout.str()); - ASSERT_EQUALS("", errout.str()); + TODO_ASSERT_EQUALS("[test.cpp:11]: (error) Memory leak: p\n", + "", errout.str()); } @@ -1880,8 +1881,8 @@ private: " char *p;\n" " foo(&p);\n" "}\n"); - TODO_ASSERT_EQUALS(std::string("[test.cpp:11]: (error) Memory leak: p\n"), errout.str()); - ASSERT_EQUALS("", errout.str()); + TODO_ASSERT_EQUALS(std::string("[test.cpp:11]: (error) Memory leak: p\n"), + "", errout.str()); check("void foo(char **str)\n" "{\n" @@ -2083,8 +2084,10 @@ private: " free(a);\n" "}\n"); - TODO_ASSERT_EQUALS("[test.cpp:5]: (error) Memory leak: a\n", errout.str()); - ASSERT_EQUALS("[test.cpp:4]: (error) Common realloc mistake: \'a\' nulled but not freed upon failure\n", errout.str()); + TODO_ASSERT_EQUALS("[test.cpp:5]: (error) Memory leak: a\n", + + "[test.cpp:4]: (error) Common realloc mistake: \'a\' nulled but not freed upon failure\n", + errout.str()); } void realloc5() @@ -2296,8 +2299,8 @@ private: " free(str);\n" " char c = *str;\n" "}\n"); - TODO_ASSERT_EQUALS("[test.cpp:5]: (error) Dereferencing 'str' after it is deallocated / released\n", errout.str()); - ASSERT_EQUALS("", errout.str()); + TODO_ASSERT_EQUALS("[test.cpp:5]: (error) Dereferencing 'str' after it is deallocated / released\n", + "", errout.str()); check("void foo()\n" "{\n" @@ -4184,8 +4187,8 @@ private: "private:\n" " char *s;\n" "};\n"); - ASSERT_EQUALS("", errout.str()); - TODO_ASSERT_EQUALS("publicAllocation", errout.str()); + TODO_ASSERT_EQUALS("publicAllocation", + "", errout.str()); } void func2() diff --git a/test/testnullpointer.cpp b/test/testnullpointer.cpp index 1742fab5a..53198703c 100644 --- a/test/testnullpointer.cpp +++ b/test/testnullpointer.cpp @@ -464,8 +464,8 @@ private: " p = new FooCar;\n" " p->abcd();\n" "}\n"); - TODO_ASSERT_EQUALS("[test.cpp:8]: (error) Possible null pointer dereference: p\n", errout.str()); - ASSERT_EQUALS("", errout.str()); + TODO_ASSERT_EQUALS("[test.cpp:8]: (error) Possible null pointer dereference: p\n", + "", errout.str()); check("static void foo()\n" "{\n" @@ -707,8 +707,8 @@ private: " argv32[i] = 0;\n" " }\n" "}\n"); - ASSERT_EQUALS("", errout.str()); - TODO_ASSERT_EQUALS("error", errout.str()); + TODO_ASSERT_EQUALS("error", + "", errout.str()); } void nullpointer7() diff --git a/test/testobsoletefunctions.cpp b/test/testobsoletefunctions.cpp index 760e46222..a489191f0 100644 --- a/test/testobsoletefunctions.cpp +++ b/test/testobsoletefunctions.cpp @@ -166,8 +166,8 @@ private: " const char i = index(var, 0);\n" " return i;\n" "}\n"); - ASSERT_EQUALS("", errout.str()); - TODO_ASSERT_EQUALS("[test.cpp:4]: (style) Found obsolete function 'index'. It is recommended to use the function 'strchr' instead\n", errout.str()); + TODO_ASSERT_EQUALS("[test.cpp:4]: (style) Found obsolete function 'index'. It is recommended to use the function 'strchr' instead\n", + "", errout.str()); } void test_qt_index() diff --git a/test/testother.cpp b/test/testother.cpp index bdec704e3..a835ba30d 100644 --- a/test/testother.cpp +++ b/test/testother.cpp @@ -1662,8 +1662,9 @@ private: "}\n" ); TODO_ASSERT_EQUALS("[test.cpp:2]: (warning) memset() called to fill 0" - " bytes of \"p\". Second and third arguments might be inverted.\n", errout.str()); - ASSERT_EQUALS("", errout.str()); + " bytes of \"p\". Second and third arguments might be inverted.\n", + + "", errout.str()); } void sizeofForArrayParameter() diff --git a/test/testpostfixoperator.cpp b/test/testpostfixoperator.cpp index 2970537eb..b789d977e 100644 --- a/test/testpostfixoperator.cpp +++ b/test/testpostfixoperator.cpp @@ -295,7 +295,8 @@ private: " std::cout << k << std::endl;\n" " return 0;\n" "}\n"); - TODO_ASSERT_EQUALS("", errout.str()); + TODO_ASSERT_EQUALS("", + "[test.cpp:8]: (performance) Prefer prefix ++/-- operators for non-primitive types.\n", errout.str()); } void testiterator() diff --git a/test/testpreprocessor.cpp b/test/testpreprocessor.cpp index 92ca11320..0cd5fb4ab 100644 --- a/test/testpreprocessor.cpp +++ b/test/testpreprocessor.cpp @@ -429,8 +429,8 @@ private: preprocessor.preprocess(istr, actual, "file.c"); // Make sure an error message is written.. - ASSERT_EQUALS("", errout.str()); // no change? - TODO_ASSERT_EQUALS("[test.cpp:3]: this preprocessor condition is always true", errout.str()); + TODO_ASSERT_EQUALS("[test.cpp:3]: this preprocessor condition is always true", + "", errout.str()); // Compare results.. ASSERT_EQUALS("\n\n\n\n\n\n", actual[""]); @@ -755,7 +755,7 @@ private: ASSERT_EQUALS(true, Preprocessor::match_cfg_def(cfg, "A<2")); ASSERT_EQUALS(false, Preprocessor::match_cfg_def(cfg, "A==2")); ASSERT_EQUALS(false, Preprocessor::match_cfg_def(cfg, "A<1")); - TODO_ASSERT_EQUALS(true, Preprocessor::match_cfg_def(cfg, "A>=1&&B<=A")); + TODO_ASSERT_EQUALS(true, false, Preprocessor::match_cfg_def(cfg, "A>=1&&B<=A")); } } @@ -778,7 +778,8 @@ private: // Compare results.. ASSERT_EQUALS(1, static_cast(actual.size())); ASSERT_EQUALS("\n\n\nB\n\n", actual[""]); - TODO_ASSERT_EQUALS("\nA\n\n\n\n", actual["LIBVER=101"]); + TODO_ASSERT_EQUALS("\nA\n\n\n\n", + "", actual["LIBVER=101"]); } void if_cond2() @@ -1009,8 +1010,7 @@ private: preprocessor.preprocess(istr, actual, "file.c"); // Compare results.. - ASSERT_EQUALS(1, static_cast(actual.size())); - TODO_ASSERT_EQUALS(2, static_cast(actual.size())); + TODO_ASSERT_EQUALS(2, 1, static_cast(actual.size())); ASSERT_EQUALS("\nfoo();\n\n", actual[""]); } } @@ -1170,8 +1170,9 @@ private: // the "defined(DEF_10) || defined(DEF_11)" are not handled correctly.. ASSERT_EQUALS("(debug) unhandled configuration: defined(DEF_10)||defined(DEF_11)\n", errout.str()); - TODO_ASSERT_EQUALS(2, actual.size()); - TODO_ASSERT_EQUALS("\na1;\n\n", actual["DEF_10"]); + TODO_ASSERT_EQUALS(2, 1, actual.size()); + TODO_ASSERT_EQUALS("\na1;\n\n", + "", actual["DEF_10"]); } @@ -2312,8 +2313,8 @@ private: // Compare results.. ASSERT_EQUALS("\n\n\n\n", actual[""]); - TODO_ASSERT_EQUALS(1, actual.size()); - ASSERT_EQUALS(2, (int)actual.size()); + TODO_ASSERT_EQUALS(1, + 2, actual.size()); } void define_ifndef2() @@ -2401,21 +2402,27 @@ private: preprocessor.preprocess(istr, actual, "file.c"); // B will always be defined if A is defined; the following test - // cases should be fixed whenever this other bug is fixed - TODO_ASSERT_EQUALS(2, static_cast(actual.size())); - ASSERT_EQUALS(3, static_cast(actual.size())); + // cases should be fixed whenever this other bug is fixed + TODO_ASSERT_EQUALS(2, + 3, static_cast(actual.size())); - if (actual.find("A") == actual.end()) { - ASSERT_EQUALS("A is checked", "failed"); - } else { - ASSERT_EQUALS("A is checked", "A is checked"); - } + if (actual.find("A") == actual.end()) + { + ASSERT_EQUALS("A is checked", "failed"); + } + else + { + ASSERT_EQUALS("A is checked", "A is checked"); + } - if (actual.find("A;A;B") != actual.end()) { - ASSERT_EQUALS("A;A;B is NOT checked", "failed"); - } else { - ASSERT_EQUALS("A;A;B is NOT checked", "A;A;B is NOT checked"); - } + if (actual.find("A;A;B") != actual.end()) + { + ASSERT_EQUALS("A;A;B is NOT checked", "failed"); + } + else + { + ASSERT_EQUALS("A;A;B is NOT checked", "A;A;B is NOT checked"); + } } }; diff --git a/test/testsimplifytokens.cpp b/test/testsimplifytokens.cpp index 8f29e3efb..e298bcfd0 100644 --- a/test/testsimplifytokens.cpp +++ b/test/testsimplifytokens.cpp @@ -697,8 +697,8 @@ private: " if (c>0) { c++; }\n" " c++;\n" "}\n"; - TODO_ASSERT_EQUALS("void f ( int & c ) { c = 3 ; { ; } ; }", tok(code)); - ASSERT_EQUALS("void f ( int & c ) { c = 1 ; { c ++ ; } c ++ ; }", tok(code)); + TODO_ASSERT_EQUALS("void f ( int & c ) { c = 3 ; { ; } ; }", + "void f ( int & c ) { c = 1 ; { c ++ ; } c ++ ; }", tok(code)); } @@ -712,8 +712,8 @@ private: " if (c>0) { ++c; }\n" " ++c;\n" "}\n"; - TODO_ASSERT_EQUALS("void f ( int & c ) { c = 3 ; { ; } ; }", tok(code)); - ASSERT_EQUALS("void f ( int & c ) { c = 1 ; { ++ c ; } ++ c ; }", tok(code)); + TODO_ASSERT_EQUALS("void f ( int & c ) { c = 3 ; { ; } ; }", + "void f ( int & c ) { c = 1 ; { ++ c ; } ++ c ; }", tok(code)); } { @@ -1600,14 +1600,22 @@ private: " return 0;\n" "}\n"; - const std::string expected("; " - "int main ( ) { " - "std :: vector < int > v ; " - "v . push_back ( 4 ) ; " - "return 0 ; " - "}"); + const std::string wanted("; " + "int main ( ) { " + "std :: vector < int > v ; " + "v . push_back ( 4 ) ; " + "return 0 ; " + "}"); - TODO_ASSERT_EQUALS(expected, sizeof_(code)); + const std::string current("; " + "int main ( ) { " + "ABC < int > :: type v ; " + "v . push_back ( 4 ) ; " + "return 0 ; " + "}" + ); + + TODO_ASSERT_EQUALS(wanted, current, sizeof_(code)); } { @@ -1822,14 +1830,18 @@ private: " return 0;\n" "}\n"; - // The expected result.. - const std::string expected("; " - "; " - "int main ( ) { b<2> ( ) ; return 0 ; } " - "void b<2> ( ) { a<2> ( ) ; } " - "void a<2> ( ) { }"); + const std::string wanted("; " + "; " + "int main ( ) { b<2> ( ) ; return 0 ; } " + "void b<2> ( ) { a<2> ( ) ; } " + "void a<2> ( ) { }"); - TODO_ASSERT_EQUALS(expected, sizeof_(code)); + const std::string current("; " + "int main ( ) { b<2> ( ) ; return 0 ; } " + "void b<2> ( ) { a < 2 > ( ) ; }" + ); + + TODO_ASSERT_EQUALS(wanted, current, sizeof_(code)); } void template17() @@ -1845,7 +1857,7 @@ private: "\n" "shared_ptr i;\n"; - // Assert that there are not segmentation fault.. + // Assert that there is no segmentation fault.. sizeof_(code); } @@ -2030,20 +2042,29 @@ private: " A a2;\n" "}\n"; - // The expected result.. - const std::string expected("template < class T , int n >" - " class A" - " { T ar [ n ] ; } ;" - " void f ( )" - " {" - " A a1 ;" - " A a2 ;" - " }" - " class A" - " { int ar [ 2 ] ; }" - " class A" - " { int ar [ 3 ] ; }"); - TODO_ASSERT_EQUALS(expected, sizeof_(code)); + const std::string wanted("template < class T , int n >" + " class A" + " { T ar [ n ] ; } ;" + " void f ( )" + " {" + " A a1 ;" + " A a2 ;" + " }" + " class A" + " { int ar [ 2 ] ; }" + " class A" + " { int ar [ 3 ] ; }"); + + const std::string current("; " + "void f ( ) " + "{ " + "A < int , ( int ) 2 > a1 ; " + "A a2 ; " + "} " + "class A " + "{ int ar [ 3 ] ; }" + ); + TODO_ASSERT_EQUALS(wanted, current, sizeof_(code)); } } @@ -2177,7 +2198,9 @@ private: ASSERT_EQUALS("; a . x = b ( ) ; if ( ! ( a . x ) ) { ; }", simplifyIfAssign(";if(!(a->x=b()));")); ASSERT_EQUALS("A ( ) a = b ; if ( a ) { ; }", simplifyIfAssign("A() if(a=b);")); ASSERT_EQUALS("void foo ( int a ) { a = b ( ) ; if ( 0 <= a ) { ; } }", tok("void foo(int a) {if((a=b())>=0);}")); - TODO_ASSERT_EQUALS("void foo ( A a ) { a . c = b ( ) ; if ( 0 <= a . c ) { ; } }", tok("void foo(A a) {if((a.c=b())>=0);}")); + TODO_ASSERT_EQUALS("void foo ( A a ) { a . c = b ( ) ; if ( 0 <= a . c ) { ; } }", + "void foo ( A a ) { a . c = b ( ) ; if ( a . c >= 0 ) { ; } }", + tok("void foo(A a) {if((a.c=b())>=0);}")); } void ifAssignWithCast() @@ -3508,14 +3531,20 @@ private: ASSERT_EQUALS(expected, tok(code, false)); // TODO: the definition and assignment should be split up - const char todo[] = + const char wanted[] = "; " "void g ( fp f ) " "{ " "int ( * f2 ) ( ) ; f2 = ( int ( * ) ( ) ) f ; " "}"; + const char current[] = + "; " + "void g ( int ( * f ) ( ) ) " + "{ " + "int ( * f2 ) ( ) = ( int ( * ) ( ) ) f ; " + "}"; - TODO_ASSERT_EQUALS(todo, tok(code, false)); + TODO_ASSERT_EQUALS(wanted, current, tok(code, false)); } { @@ -6159,7 +6188,9 @@ private: ASSERT_EQUALS("; struct A a ; a . buf = x ;", tok("; struct A a = { .buf = x };")); ASSERT_EQUALS("; struct A a ; a . buf = & key ;", tok("; struct A a = { .buf = &key };")); ASSERT_EQUALS("; struct ABC abc ; abc . a = 3 ; abc . b = x ; abc . c = & key ;", tok("; struct ABC abc = { .a = 3, .b = x, .c = &key };")); - TODO_ASSERT_EQUALS("; struct A a ; a . buf = { 0 } ;", tok("; struct A a = { .buf = {0} };")); + TODO_ASSERT_EQUALS("; struct A a ; a . buf = { 0 } ;", + "; struct A a ; a = { . buf = { 0 } } ;", + tok("; struct A a = { .buf = {0} };")); } void simplifyStructDecl() diff --git a/test/teststl.cpp b/test/teststl.cpp index eabb2c2c3..748c46ac0 100644 --- a/test/teststl.cpp +++ b/test/teststl.cpp @@ -257,8 +257,7 @@ private: " ++aI;\n" " }\n" "}\n"); - ASSERT_EQUALS("", errout.str()); - TODO_ASSERT_EQUALS("[test.cpp:14] (error) After insert, the iterator 'aI' may be invalid", errout.str()); + TODO_ASSERT_EQUALS("[test.cpp:14] (error) After insert, the iterator 'aI' may be invalid", "", errout.str()); } void iterator8() @@ -629,8 +628,7 @@ private: " }\n" " }\n" "}\n"); - TODO_ASSERT_EQUALS("[test.cpp:9]: (error) Dangerous iterator usage after erase()-method.\n", errout.str()); - ASSERT_EQUALS("", errout.str()); + TODO_ASSERT_EQUALS("[test.cpp:9]: (error) Dangerous iterator usage after erase()-method.\n", "", errout.str()); } void eraseGoto() @@ -701,7 +699,7 @@ private: " foo.erase(*it);\n" " }\n" "}\n"); - TODO_ASSERT_EQUALS("[test.cpp:6]: (error) Iterator 'it' becomes invalid when deleted by value from 'foo'\n", errout.str()); + TODO_ASSERT_EQUALS("[test.cpp:6]: (error) Iterator 'it' becomes invalid when deleted by value from 'foo'\n", "", errout.str()); check("void f()\n" "{\n" diff --git a/test/testsuite.cpp b/test/testsuite.cpp index 9b7e62cfb..b4ea73800 100644 --- a/test/testsuite.cpp +++ b/test/testsuite.cpp @@ -176,9 +176,13 @@ void TestFixture::assertEqualsDouble(const char *filename, int linenr, double ex assertEquals(filename, linenr, ostr1.str(), ostr2.str(), msg); } -void TestFixture::todoAssertEquals(const char *filename, int linenr, const std::string &expected, const std::string &actual) +void TestFixture::todoAssertEquals(const char *filename, int linenr, + const std::string &wanted, + const std::string ¤t, + const std::string &actual) { - if (expected == actual) + assertEquals(filename, linenr, current, actual); + if (wanted == actual) { assertEquals(filename, linenr, "TODO assertion", "The assertion succeeded"); } @@ -188,13 +192,13 @@ void TestFixture::todoAssertEquals(const char *filename, int linenr, const std:: } } -void TestFixture::todoAssertEquals(const char *filename, int linenr, unsigned int expected, unsigned int actual) +void TestFixture::todoAssertEquals(const char *filename, int linenr, unsigned int wanted, unsigned int current, unsigned int actual) { - std::ostringstream ostr1; - ostr1 << expected; - std::ostringstream ostr2; - ostr2 << actual; - todoAssertEquals(filename, linenr, ostr1.str(), ostr2.str()); + std::ostringstream wantedStr, currentStr, actualStr; + wantedStr << wanted; + currentStr << current; + actualStr << actual; + todoAssertEquals(filename, linenr, wantedStr.str(), currentStr.str(), actualStr.str()); } void TestFixture::assertThrowFail(const char *filename, int linenr) diff --git a/test/testsuite.h b/test/testsuite.h index edc8fcfeb..78a52f9d0 100644 --- a/test/testsuite.h +++ b/test/testsuite.h @@ -52,8 +52,10 @@ protected: void assertEquals(const char *filename, int linenr, long long expected, long long actual, const std::string &msg=""); void assertEqualsDouble(const char *filename, int linenr, double expected, double actual, const std::string &msg=""); - void todoAssertEquals(const char *filename, int linenr, const std::string &expected, const std::string &actual); - void todoAssertEquals(const char *filename, int linenr, unsigned int expected, unsigned int actual); + void todoAssertEquals(const char *filename, int linenr, const std::string &wanted, + const std::string ¤t, const std::string &actual); + void todoAssertEquals(const char *filename, int linenr, unsigned int wanted, + unsigned int current, unsigned int actual); void assertThrowFail(const char *filename, int linenr); void processOptions(const options& args); public: @@ -75,7 +77,7 @@ public: #define ASSERT_EQUALS_DOUBLE( EXPECTED , ACTUAL ) assertEqualsDouble(__FILE__, __LINE__, EXPECTED, ACTUAL) #define ASSERT_EQUALS_MSG( EXPECTED , ACTUAL, MSG ) assertEquals(__FILE__, __LINE__, EXPECTED, ACTUAL, MSG) #define ASSERT_THROW( CMD, EXCEPTION ) try { CMD ; assertThrowFail(__FILE__, __LINE__); } catch (EXCEPTION &) { } catch (...) { assertThrowFail(__FILE__, __LINE__); } -#define TODO_ASSERT_EQUALS( EXPECTED , ACTUAL ) todoAssertEquals(__FILE__, __LINE__, EXPECTED, ACTUAL) +#define TODO_ASSERT_EQUALS( WANTED , CURRENT , ACTUAL ) todoAssertEquals(__FILE__, __LINE__, WANTED, CURRENT, ACTUAL) #define REGISTER_TEST( CLASSNAME ) namespace { CLASSNAME instance; } #endif diff --git a/test/testtokenize.cpp b/test/testtokenize.cpp index da56bdfa7..5f71f753f 100644 --- a/test/testtokenize.cpp +++ b/test/testtokenize.cpp @@ -1132,11 +1132,9 @@ private: TODO_ASSERT_EQUALS( expected1 + " if ( true ) { a ( ) ; } }", - simplifyKnownVariables(code)); - - ASSERT_EQUALS( expected1 + " if ( b ) { a ( ) ; } }", simplifyKnownVariables(code)); + } { @@ -1156,6 +1154,7 @@ private: TODO_ASSERT_EQUALS( "void f ( ) { bool b ; b = false ; { b = false ; } { b = true ; } if ( true ) { a ( ) ; } }", + "void f ( ) { bool b ; b = false ; { b = false ; } { b = true ; } if ( b ) { a ( ) ; } }", simplifyKnownVariables(code)); } @@ -1366,7 +1365,6 @@ private: " }\n" "}\n"; - // wanted result TODO_ASSERT_EQUALS( "void foo ( int x ) " "{" @@ -1374,16 +1372,14 @@ private: " if ( x ) { a [ 0 ] = 0 ; c = 1 ; }" " else { a [ 0 ] = 0 ; } " "}", - simplifyKnownVariables(code)); - // Current result - ASSERT_EQUALS( "void foo ( int x ) " "{" " int a [ 10 ] ; int c ; c = 0 ;" " if ( x ) { a [ 0 ] = 0 ; c ++ ; }" " else { a [ c ] = 0 ; } " "}", + simplifyKnownVariables(code)); } @@ -1638,14 +1634,21 @@ private: " int i = v;\n" " return h | i;\n" "}\n"; - const char expected[] = "\n\n##file 0\n" - "1: int foo ( int u@1 , int v@2 )\n" - "2: {\n" - "3: ;\n" - "4:\n" - "5: return u@1 | v@2 ;\n" - "6: }\n"; - TODO_ASSERT_EQUALS(expected, tokenizeDebugListing(code, true)); + const char wanted[] = "\n\n##file 0\n" + "1: int foo ( int u@1 , int v@2 )\n" + "2: {\n" + "3: ;\n" + "4:\n" + "5: return u@1 | v@2 ;\n" + "6: }\n"; + const char current[] = "\n\n##file 0\n" + "1: int foo ( int u@1 , int v@2 )\n" + "2: {\n" + "3: ;\n" + "4: int i@4 ; i@4 = v@2 ;\n" + "5: return u@1 | i@4 ;\n" + "6: }\n"; + TODO_ASSERT_EQUALS(wanted, current, tokenizeDebugListing(code, true)); } { @@ -1655,14 +1658,21 @@ private: " int i = v;\n" " return h ^ i;\n" "}\n"; - const char expected[] = "\n\n##file 0\n" - "1: int foo ( int u@1 , int v@2 )\n" - "2: {\n" - "3: ;\n" - "4:\n" - "5: return u@1 ^ v@2 ;\n" - "6: }\n"; - TODO_ASSERT_EQUALS(expected, tokenizeDebugListing(code, true)); + const char wanted[] = "\n\n##file 0\n" + "1: int foo ( int u@1 , int v@2 )\n" + "2: {\n" + "3: ;\n" + "4:\n" + "5: return u@1 ^ v@2 ;\n" + "6: }\n"; + const char current[] = "\n\n##file 0\n" + "1: int foo ( int u@1 , int v@2 )\n" + "2: {\n" + "3: ;\n" + "4: int i@4 ; i@4 = v@2 ;\n" + "5: return u@1 ^ i@4 ;\n" + "6: }\n"; + TODO_ASSERT_EQUALS(wanted, current, tokenizeDebugListing(code, true)); } { @@ -1672,14 +1682,21 @@ private: " int i = v;\n" " return h % i;\n" "}\n"; - const char expected[] = "\n\n##file 0\n" - "1: int foo ( int u@1 , int v@2 )\n" - "2: {\n" - "3: ;\n" - "4:\n" - "5: return u@1 % v@2 ;\n" - "6: }\n"; - TODO_ASSERT_EQUALS(expected, tokenizeDebugListing(code, true)); + const char wanted[] = "\n\n##file 0\n" + "1: int foo ( int u@1 , int v@2 )\n" + "2: {\n" + "3: ;\n" + "4:\n" + "5: return u@1 % v@2 ;\n" + "6: }\n"; + const char current[] = "\n\n##file 0\n" + "1: int foo ( int u@1 , int v@2 )\n" + "2: {\n" + "3: ;\n" + "4: int i@4 ; i@4 = v@2 ;\n" + "5: return u@1 % i@4 ;\n" + "6: }\n"; + TODO_ASSERT_EQUALS(wanted, current, tokenizeDebugListing(code, true)); } { @@ -1723,14 +1740,22 @@ private: " int i = v;\n" " return h == i;\n" "}\n"; - const char expected[] = "\n\n##file 0\n" - "1: bool foo ( int u@1 , int v@2 )\n" - "2: {\n" - "3: ;\n" - "4: ;\n" - "5: return u@1 == v@2 ;\n" - "6: }\n"; - TODO_ASSERT_EQUALS(expected, tokenizeDebugListing(code, true)); + const char wanted[] = "\n\n##file 0\n" + "1: bool foo ( int u@1 , int v@2 )\n" + "2: {\n" + "3: ;\n" + "4: ;\n" + "5: return u@1 == v@2 ;\n" + "6: }\n"; + const char current[] = "\n\n##file 0\n" + "1: bool foo ( int u@1 , int v@2 )\n" + "2: {\n" + "3: ;\n" + "4: int i@4 ; i@4 = v@2 ;\n" + "5: return u@1 == i@4 ;\n" + "6: }\n"; + + TODO_ASSERT_EQUALS(wanted, current, tokenizeDebugListing(code, true)); } { @@ -1740,14 +1765,21 @@ private: " int i = v;\n" " return h != i;\n" "}\n"; - const char expected[] = "\n\n##file 0\n" + const char wanted[] = "\n\n##file 0\n" + "1: bool foo ( int u@1 , int v@2 )\n" + "2: {\n" + "3: ;\n" + "4: ;\n" + "5: return u@1 != v@2 ;\n" + "6: }\n"; + const char current[] = "\n\n##file 0\n" "1: bool foo ( int u@1 , int v@2 )\n" "2: {\n" "3: ;\n" - "4: ;\n" - "5: return u@1 != v@2 ;\n" + "4: int i@4 ; i@4 = v@2 ;\n" + "5: return u@1 != i@4 ;\n" "6: }\n"; - TODO_ASSERT_EQUALS(expected, tokenizeDebugListing(code, true)); + TODO_ASSERT_EQUALS(wanted, current, tokenizeDebugListing(code, true)); } { @@ -1757,14 +1789,15 @@ private: " int i = v;\n" " return h > i;\n" "}\n"; - const char expected[] = "\n\n##file 0\n" - "1: bool foo ( int u@1 , int v@2 )\n" - "2: {\n" - "3: ;\n" - "4: ;\n" - "5: return u@1 > v@2 ;\n" - "6: }\n"; - TODO_ASSERT_EQUALS(expected, tokenizeDebugListing(code, true)); + const char wanted[] = "\n\n##file 0\n" + "1: bool foo ( int u@1 , int v@2 )\n" + "2: {\n" + "3: ;\n" + "4: ;\n" + "5: return u@1 > v@2 ;\n" + "6: }\n"; + const char current[] = "\n\n##file 0\n1: bool foo ( int u@1 , int v@2 )\n2: {\n3: ;\n4: int i@4 ; i@4 = v@2 ;\n5: return u@1 > i@4 ;\n6: }\n"; + TODO_ASSERT_EQUALS(wanted, current, tokenizeDebugListing(code, true)); } { @@ -1774,14 +1807,15 @@ private: " int i = v;\n" " return h >= i;\n" "}\n"; - const char expected[] = "\n\n##file 0\n" - "1: bool foo ( int u@1 , int v@2 )\n" - "2: {\n" - "3: ;\n" - "4: ;\n" - "5: return u@1 >= v@2 ;\n" - "6: }\n"; - TODO_ASSERT_EQUALS(expected, tokenizeDebugListing(code, true)); + const char wanted[] = "\n\n##file 0\n" + "1: bool foo ( int u@1 , int v@2 )\n" + "2: {\n" + "3: ;\n" + "4: ;\n" + "5: return u@1 >= v@2 ;\n" + "6: }\n"; + const char current[] = "\n\n##file 0\n1: bool foo ( int u@1 , int v@2 )\n2: {\n3: ;\n4: int i@4 ; i@4 = v@2 ;\n5: return u@1 >= i@4 ;\n6: }\n"; + TODO_ASSERT_EQUALS(wanted, current, tokenizeDebugListing(code, true)); } { @@ -1791,14 +1825,15 @@ private: " int i = v;\n" " return h < i;\n" "}\n"; - const char expected[] = "\n\n##file 0\n" - "1: bool foo ( int u@1 , int v@2 )\n" - "2: {\n" - "3: ;\n" - "4: ;\n" - "5: return u@1 < v@2 ;\n" - "6: }\n"; - TODO_ASSERT_EQUALS(expected, tokenizeDebugListing(code, true)); + const char wanted[] = "\n\n##file 0\n" + "1: bool foo ( int u@1 , int v@2 )\n" + "2: {\n" + "3: ;\n" + "4: ;\n" + "5: return u@1 < v@2 ;\n" + "6: }\n"; + const char current[] = "\n\n##file 0\n1: bool foo ( int u@1 , int v@2 )\n2: {\n3: ;\n4: int i@4 ; i@4 = v@2 ;\n5: return u@1 < i@4 ;\n6: }\n"; + TODO_ASSERT_EQUALS(wanted, current, tokenizeDebugListing(code, true)); } { @@ -1808,14 +1843,15 @@ private: " int i = v;\n" " return h <= i;\n" "}\n"; - const char expected[] = "\n\n##file 0\n" - "1: bool foo ( int u@1 , int v@2 )\n" - "2: {\n" - "3: ;\n" - "4: ;\n" - "5: return u@1 <= v@2 ;\n" - "6: }\n"; - TODO_ASSERT_EQUALS(expected, tokenizeDebugListing(code, true)); + const char wanted[] = "\n\n##file 0\n" + "1: bool foo ( int u@1 , int v@2 )\n" + "2: {\n" + "3: ;\n" + "4: ;\n" + "5: return u@1 <= v@2 ;\n" + "6: }\n"; + const char current[] = "\n\n##file 0\n1: bool foo ( int u@1 , int v@2 )\n2: {\n3: ;\n4: int i@4 ; i@4 = v@2 ;\n5: return u@1 <= i@4 ;\n6: }\n"; + TODO_ASSERT_EQUALS(wanted, current, tokenizeDebugListing(code, true)); } { @@ -1825,14 +1861,15 @@ private: " int i = v;\n" " return h && i;\n" "}\n"; - const char expected[] = "\n\n##file 0\n" - "1: bool foo ( int u@1 , int v@2 )\n" - "2: {\n" - "3: ;\n" - "4: ;\n" - "5: return u@1 && v@2 ;\n" - "6: }\n"; - TODO_ASSERT_EQUALS(expected, tokenizeDebugListing(code, true)); + const char wanted[] = "\n\n##file 0\n" + "1: bool foo ( int u@1 , int v@2 )\n" + "2: {\n" + "3: ;\n" + "4: ;\n" + "5: return u@1 && v@2 ;\n" + "6: }\n"; + const char current[] = "\n\n##file 0\n1: bool foo ( int u@1 , int v@2 )\n2: {\n3: ;\n4: int i@4 ; i@4 = v@2 ;\n5: return u@1 && i@4 ;\n6: }\n"; + TODO_ASSERT_EQUALS(wanted, current, tokenizeDebugListing(code, true)); } { @@ -1842,14 +1879,15 @@ private: " int i = v;\n" " return h || i;\n" "}\n"; - const char expected[] = "\n\n##file 0\n" - "1: bool foo ( int u@1 , int v@2 )\n" - "2: {\n" - "3: ;\n" - "4: ;\n" - "5: return u@1 || v@2 ;\n" - "6: }\n"; - TODO_ASSERT_EQUALS(expected, tokenizeDebugListing(code, true)); + const char wanted[] = "\n\n##file 0\n" + "1: bool foo ( int u@1 , int v@2 )\n" + "2: {\n" + "3: ;\n" + "4: ;\n" + "5: return u@1 || v@2 ;\n" + "6: }\n"; + const char current[] = "\n\n##file 0\n1: bool foo ( int u@1 , int v@2 )\n2: {\n3: ;\n4: int i@4 ; i@4 = v@2 ;\n5: return u@1 || i@4 ;\n6: }\n"; + TODO_ASSERT_EQUALS(wanted, current, tokenizeDebugListing(code, true)); } } @@ -3212,20 +3250,21 @@ private: " A::buf[10] = 0;\n" "}"); - const std::string expected("\n\n##file 0\n" - "1: class A\n" - "2: {\n" - "3: public:\n" - "4: static char buf@1 [ 20 ] ;\n" - "5: } ;\n" - "6: char A :: buf@1 [ 20 ] ;\n" - "7: int main ( )\n" - "8: {\n" - "9: char buf@2 [ 2 ] ;\n" - "10: A :: buf@1 [ 10 ] = 0 ;\n" - "11: }\n"); + const std::string wanted("\n\n##file 0\n" + "1: class A\n" + "2: {\n" + "3: public:\n" + "4: static char buf@1 [ 20 ] ;\n" + "5: } ;\n" + "6: char A :: buf@1 [ 20 ] ;\n" + "7: int main ( )\n" + "8: {\n" + "9: char buf@2 [ 2 ] ;\n" + "10: A :: buf@1 [ 10 ] = 0 ;\n" + "11: }\n"); - TODO_ASSERT_EQUALS(expected, actual); + const char current[] = "\n\n##file 0\n1: class A\n2: {\n3: public:\n4: static char buf@1 [ 20 ] ;\n5: } ;\n6: char A :: buf [ 20 ] ;\n7: int main ( )\n8: {\n9: char buf@2 [ 2 ] ;\n10: A :: buf [ 10 ] = 0 ;\n11: }\n"; + TODO_ASSERT_EQUALS(wanted, current, actual); } void varidclass7() @@ -3895,12 +3934,12 @@ private: void vardecl_stl_2() { const char code1[] = "{ std::string x = \"abc\"; }"; - TODO_ASSERT_EQUALS("{ std :: string x ; x = \"abc\" ; }", tokenizeAndStringify(code1)); - ASSERT_EQUALS("{ std :: string x = \"abc\" ; }", tokenizeAndStringify(code1)); + TODO_ASSERT_EQUALS("{ std :: string x ; x = \"abc\" ; }", + "{ std :: string x = \"abc\" ; }", tokenizeAndStringify(code1)); const char code2[] = "{ std::vector x = y; }"; - TODO_ASSERT_EQUALS("{ std :: vector < int > x ; x = y ; }", tokenizeAndStringify(code2)); - ASSERT_EQUALS("{ std :: vector < int > x = y ; }", tokenizeAndStringify(code2)); + TODO_ASSERT_EQUALS("{ std :: vector < int > x ; x = y ; }", + "{ std :: vector < int > x = y ; }", tokenizeAndStringify(code2)); } void vardecl_template() @@ -4569,8 +4608,8 @@ private: { // tokenize ">>" into "> >" const char *code = "list> ints;\n"; - ASSERT_EQUALS("list < list < int >> ints ;", tokenizeAndStringify(code)); - TODO_ASSERT_EQUALS("list < list < int > > ints ;", tokenizeAndStringify(code)); + TODO_ASSERT_EQUALS("list < list < int > > ints ;", + "list < list < int >> ints ;", tokenizeAndStringify(code)); } void cpp0xdefault() @@ -4602,8 +4641,8 @@ private: " foo();" "}" "foo::foo() = delete;"; - ASSERT_EQUALS("struct foo { foo ( ) ; } foo :: foo ( ) = delete ;", tokenizeAndStringify(code)); - TODO_ASSERT_EQUALS("struct foo { }", tokenizeAndStringify(code)); + TODO_ASSERT_EQUALS("struct foo { }", + "struct foo { foo ( ) ; } foo :: foo ( ) = delete ;", tokenizeAndStringify(code)); } } diff --git a/test/testuninitvar.cpp b/test/testuninitvar.cpp index b444f668e..641c3aa72 100644 --- a/test/testuninitvar.cpp +++ b/test/testuninitvar.cpp @@ -798,8 +798,8 @@ private: " x--;\n" " }\n" "}\n"); - TODO_ASSERT_EQUALS("[test.cpp:4]: (error) Uninitialized variable: pItem\n", errout.str()); - ASSERT_EQUALS("", errout.str()); // current result + TODO_ASSERT_EQUALS("[test.cpp:4]: (error) Uninitialized variable: pItem\n", + "", errout.str()); } // switch.. @@ -1364,8 +1364,8 @@ private: " int x[10];\n" " calc(x,10);\n" "}\n"); - TODO_ASSERT_EQUALS("[test.cpp:4]: (error) Uninitialized variable: x\n", errout.str()); - ASSERT_EQUALS("", errout.str()); + TODO_ASSERT_EQUALS("[test.cpp:4]: (error) Uninitialized variable: x\n", + "", errout.str()); // #2401 - unknown function/macro might init the variable checkUninitVar("int f() {\n" diff --git a/test/testunusedvar.cpp b/test/testunusedvar.cpp index 1c08bbc39..a417ccf5f 100644 --- a/test/testunusedvar.cpp +++ b/test/testunusedvar.cpp @@ -657,7 +657,8 @@ private: " int a[10];\n" " f(a[0]);\n" "}\n"); - TODO_ASSERT_EQUALS("[test.cpp:4]: (style) Variable 'a' is not assigned a value\n", errout.str()); + TODO_ASSERT_EQUALS("[test.cpp:4]: (style) Variable 'a' is not assigned a value\n", + "", errout.str()); // f() can not write a (not supported yet) functionVariableUsage("void f(const int & i) { }\n" @@ -666,7 +667,8 @@ private: " int a[10];\n" " f(a[0]);\n" "}\n"); - TODO_ASSERT_EQUALS("[test.cpp:4]: (style) Variable 'a' is not assigned a value\n", errout.str()); + TODO_ASSERT_EQUALS("[test.cpp:4]: (style) Variable 'a' is not assigned a value\n", + "", errout.str()); // f() writes a functionVariableUsage("void f(int & i) { }\n" @@ -811,37 +813,37 @@ private: "{\n" " int * i[2];\n" "}\n"); - TODO_ASSERT_EQUALS("[test.cpp:3]: (style) Unused variable: i\n", errout.str()); + TODO_ASSERT_EQUALS("[test.cpp:3]: (style) Unused variable: i\n", "", errout.str()); functionVariableUsage("void foo()\n" "{\n" " const int * i[2];\n" "}\n"); - TODO_ASSERT_EQUALS("[test.cpp:3]: (style) Unused variable: i\n", errout.str()); + TODO_ASSERT_EQUALS("[test.cpp:3]: (style) Unused variable: i\n", "", errout.str()); functionVariableUsage("void foo()\n" "{\n" " void * i[2];\n" "}\n"); - TODO_ASSERT_EQUALS("[test.cpp:3]: (style) Unused variable: i\n", errout.str()); + TODO_ASSERT_EQUALS("[test.cpp:3]: (style) Unused variable: i\n", "", errout.str()); functionVariableUsage("void foo()\n" "{\n" " const void * i[2];\n" "}\n"); - TODO_ASSERT_EQUALS("[test.cpp:3]: (style) Unused variable: i\n", errout.str()); + TODO_ASSERT_EQUALS("[test.cpp:3]: (style) Unused variable: i\n", "", errout.str()); functionVariableUsage("void foo()\n" "{\n" " struct A * i[2];\n" "}\n"); - TODO_ASSERT_EQUALS("[test.cpp:3]: (style) Unused variable: i\n", errout.str()); + TODO_ASSERT_EQUALS("[test.cpp:3]: (style) Unused variable: i\n", "", errout.str()); functionVariableUsage("void foo()\n" "{\n" " const struct A * i[2];\n" "}\n"); - TODO_ASSERT_EQUALS("[test.cpp:3]: (style) Unused variable: i\n", errout.str()); + TODO_ASSERT_EQUALS("[test.cpp:3]: (style) Unused variable: i\n", "", errout.str()); functionVariableUsage("void foo(int n)\n" "{\n" @@ -1076,15 +1078,14 @@ private: " a = b = c;\n" "\n" "}\n"); - ASSERT_EQUALS( - "[test.cpp:3]: (style) Variable 'a' is assigned a value that is never used\n" - "[test.cpp:3]: (style) Variable 'b' is assigned a value that is never used\n", - errout.str()); TODO_ASSERT_EQUALS( "[test.cpp:3]: (style) Variable 'a' is assigned a value that is never used\n" "[test.cpp:3]: (style) Variable 'b' is assigned a value that is never used\n" "[test.cpp:3]: (style) Variable 'c' is assigned a value that is never used\n", + + "[test.cpp:3]: (style) Variable 'a' is assigned a value that is never used\n" + "[test.cpp:3]: (style) Variable 'b' is assigned a value that is never used\n", errout.str()); } @@ -2311,9 +2312,10 @@ private: " func();\n" " } while(a--);\n" "}\n"); - ASSERT_EQUALS("", errout.str()); TODO_ASSERT_EQUALS("[test.cpp:4]: (style) Unused variable: x\n" - "[test.cpp:4]: (style) Unused variable: z\n", errout.str()); + "[test.cpp:4]: (style) Unused variable: z\n", + + "", errout.str()); } void localvarStruct4() From b944168bdc3e413b0482a5444b8bd645e4dad012 Mon Sep 17 00:00:00 2001 From: Raphael Geissert Date: Sun, 30 Jan 2011 12:47:17 -0600 Subject: [PATCH 147/165] Check for cpp conditionals where a define is already guaranteed --- lib/preprocessor.cpp | 15 ++++++ test/testpreprocessor.cpp | 109 +++++++++++++++++++++++++++++++++++++- 2 files changed, 122 insertions(+), 2 deletions(-) diff --git a/lib/preprocessor.cpp b/lib/preprocessor.cpp index ddf0b6128..6a29c9e13 100644 --- a/lib/preprocessor.cpp +++ b/lib/preprocessor.cpp @@ -888,6 +888,21 @@ std::list Preprocessor::getcfgs(const std::string &filedata, const def += ";"; def += *it; } + else + { + std::ostringstream lineStream; + lineStream << __LINE__; + + ErrorLogger::ErrorMessage errmsg; + ErrorLogger::ErrorMessage::FileLocation loc; + loc.setfile(filename); + loc.line = linenr; + errmsg._callStack.push_back(loc); + errmsg._severity = Severity::fromString("error"); + errmsg.setmsg(*it+" is already guaranteed to be defined"); + errmsg._id = "preprocessor" + lineStream.str(); + _errorLogger->reportErr(errmsg); + } } if (from_negation) { diff --git a/test/testpreprocessor.cpp b/test/testpreprocessor.cpp index 0cd5fb4ab..76823ad26 100644 --- a/test/testpreprocessor.cpp +++ b/test/testpreprocessor.cpp @@ -429,13 +429,118 @@ private: preprocessor.preprocess(istr, actual, "file.c"); // Make sure an error message is written.. - TODO_ASSERT_EQUALS("[test.cpp:3]: this preprocessor condition is always true", - "", errout.str()); + ASSERT_EQUALS("[file.c:3]: (error) ABC is already guaranteed to be defined\n", + errout.str()); // Compare results.. ASSERT_EQUALS("\n\n\n\n\n\n", actual[""]); ASSERT_EQUALS("\nA\n\nB\n\n\n", actual["ABC"]); ASSERT_EQUALS(2, static_cast(actual.size())); + + test7a(); + test7b(); + test7c(); + test7d(); + } + + void test7a() + { + const char filedata[] = "#ifndef ABC\n" + "A\n" + "#ifndef ABC\n" + "B\n" + "#endif\n" + "#endif\n"; + + // Preprocess => actual result.. + std::istringstream istr(filedata); + std::map actual; + Settings settings; + Preprocessor preprocessor(&settings, this); + errout.str(""); + preprocessor.preprocess(istr, actual, "file.c"); + + // Make sure an error message is written.. + TODO_ASSERT_EQUALS("[file.c:3]: (error) ABC is already guaranteed NOT to be defined\n", + "", errout.str()); + + // Compare results.. + ASSERT_EQUALS(2, static_cast(actual.size())); + } + + void test7b() + { + const char filedata[] = "#ifndef ABC\n" + "A\n" + "#ifdef ABC\n" + "B\n" + "#endif\n" + "#endif\n"; + + // Preprocess => actual result.. + std::istringstream istr(filedata); + std::map actual; + Settings settings; + Preprocessor preprocessor(&settings, this); + errout.str(""); + preprocessor.preprocess(istr, actual, "file.c"); + + // Make sure an error message is written.. + TODO_ASSERT_EQUALS("[file.c:3]: (error) ABC is already guaranteed NOT to be defined\n", + "", errout.str()); + + // Compare results.. + ASSERT_EQUALS(2, static_cast(actual.size())); + } + + void test7c() + { + const char filedata[] = "#ifdef ABC\n" + "A\n" + "#ifndef ABC\n" + "B\n" + "#endif\n" + "#endif\n"; + + // Preprocess => actual result.. + std::istringstream istr(filedata); + std::map actual; + Settings settings; + Preprocessor preprocessor(&settings, this); + errout.str(""); + preprocessor.preprocess(istr, actual, "file.c"); + + // Make sure an error message is written.. + ASSERT_EQUALS("[file.c:3]: (error) ABC is already guaranteed to be defined\n", + errout.str()); + + // Compare results.. + ASSERT_EQUALS(2, static_cast(actual.size())); + } + + void test7d() + { + const char filedata[] = "#if defined(ABC)\n" + "A\n" + "#if defined(ABC)\n" + "B\n" + "#endif\n" + "#endif\n"; + + // Preprocess => actual result.. + std::istringstream istr(filedata); + std::map actual; + Settings settings; + Preprocessor preprocessor(&settings, this); + errout.str(""); + preprocessor.preprocess(istr, actual, "file.c"); + + // Make sure an error message is written.. + ASSERT_EQUALS("[file.c:3]: (error) ABC is already guaranteed to be defined\n", + errout.str()); + + // Compare results.. + ASSERT_EQUALS(2, static_cast(actual.size())); } From 66253af1e5ffe8e2d1613eea30623896364c8568 Mon Sep 17 00:00:00 2001 From: Raphael Geissert Date: Sun, 30 Jan 2011 17:33:44 -0600 Subject: [PATCH 148/165] Handle "#endif !defined" conditionals --- lib/preprocessor.cpp | 32 ++++++++++++++++++++++++++++++-- test/testpreprocessor.cpp | 26 ++++++++++++++++++++++++++ 2 files changed, 56 insertions(+), 2 deletions(-) diff --git a/lib/preprocessor.cpp b/lib/preprocessor.cpp index 6a29c9e13..3e5ca8726 100644 --- a/lib/preprocessor.cpp +++ b/lib/preprocessor.cpp @@ -714,13 +714,14 @@ void Preprocessor::preprocess(std::istream &srcCodeStream, std::string &processe std::string Preprocessor::getdef(std::string line, bool def) { // If def is true, the line must start with "#ifdef" - if (def && line.find("#ifdef ") != 0 && line.find("#if ") != 0 && line.find("#elif ") != 0 && line.find("#if defined ") != 0) + if (def && line.find("#ifdef ") != 0 && line.find("#if ") != 0 + && (line.find("#elif ") != 0 || line.find("#elif !") == 0)) { return ""; } // If def is false, the line must start with "#ifndef" - if (!def && line.find("#ifndef ") != 0) + if (!def && line.find("#ifndef ") != 0 && line.find("#elif !") != 0) { return ""; } @@ -728,6 +729,17 @@ std::string Preprocessor::getdef(std::string line, bool def) // Remove the "#ifdef" or "#ifndef" if (line.find("#if defined ") == 0) line.erase(0, 11); + else if (line.find("#elif !defined(") == 0) + { + std::string::size_type pos = 0; + + line.erase(0, 15); + pos = line.find(")"); + // if pos == ::npos then another part of the code will complain + // about the mismatch + if (pos != std::string::npos) + line.erase(pos, 1); + } else line.erase(0, line.find(" ")); @@ -1360,6 +1372,22 @@ std::string Preprocessor::getcode(const std::string &filedata, std::string cfg, } } + else if (line.find("#elif !") == 0) + { + if (matched_ifdef.back()) + { + matching_ifdef.back() = false; + } + else + { + if (!match_cfg_def(cfgmap, ndef)) + { + matching_ifdef.back() = true; + matched_ifdef.back() = true; + } + } + } + else if (line.find("#elif ") == 0) { if (matched_ifdef.back()) diff --git a/test/testpreprocessor.cpp b/test/testpreprocessor.cpp index 76823ad26..80d32aacc 100644 --- a/test/testpreprocessor.cpp +++ b/test/testpreprocessor.cpp @@ -911,6 +911,7 @@ private: if_cond2b(); if_cond2c(); if_cond2d(); + if_cond2e(); } void if_cond2b() @@ -998,6 +999,31 @@ private: ASSERT_EQUALS("\n!a\n\nb\n\n\n\n\n\n\n\n\n\n\n\n", actual["B"]); } + void if_cond2e() + { + const char filedata[] = "#if !defined(A)\n" + "!a\n" + "#elif !defined(B)\n" + "!b\n" + "#endif\n"; + + // Preprocess => actual result.. + errout.str(""); + std::istringstream istr(filedata); + std::map actual; + Settings settings; + settings.debug = settings.debugwarnings = true; + Preprocessor preprocessor(&settings, this); + preprocessor.preprocess(istr, actual, "file.c"); + + // Compare results.. + ASSERT_EQUALS(3, static_cast(actual.size())); + ASSERT_EQUALS("\n!a\n\n\n\n", actual[""]); + ASSERT_EQUALS("\n\n\n!b\n\n", actual["A"]); + TODO_ASSERT_EQUALS("\n\n\n\n\n", "", actual["A;B"]); + ASSERT_EQUALS("", errout.str()); + } + void if_cond3() { const char filedata[] = "#ifdef A\n" From b4a249f26ee39afcc70c6555b599b0561898f56d Mon Sep 17 00:00:00 2001 From: Raphael Geissert Date: Sun, 30 Jan 2011 18:40:59 -0600 Subject: [PATCH 149/165] Reduce std::string::find() abuse --- lib/preprocessor.cpp | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/lib/preprocessor.cpp b/lib/preprocessor.cpp index 3e5ca8726..dcb292d9f 100644 --- a/lib/preprocessor.cpp +++ b/lib/preprocessor.cpp @@ -714,22 +714,22 @@ void Preprocessor::preprocess(std::istream &srcCodeStream, std::string &processe std::string Preprocessor::getdef(std::string line, bool def) { // If def is true, the line must start with "#ifdef" - if (def && line.find("#ifdef ") != 0 && line.find("#if ") != 0 - && (line.find("#elif ") != 0 || line.find("#elif !") == 0)) + if (def && line.compare(0, 7, "#ifdef ") != 0 && line.compare(0, 4, "#if ") != 0 + && (line.compare(0, 6, "#elif ") != 0 || line.compare(0, 7, "#elif !") == 0)) { return ""; } // If def is false, the line must start with "#ifndef" - if (!def && line.find("#ifndef ") != 0 && line.find("#elif !") != 0) + if (!def && line.compare(0, 8, "#ifndef ") != 0 && line.compare(0, 7, "#elif !") != 0) { return ""; } // Remove the "#ifdef" or "#ifndef" - if (line.find("#if defined ") == 0) + if (line.compare(0, 12, "#if defined ") == 0) line.erase(0, 11); - else if (line.find("#elif !defined(") == 0) + else if (line.compare(0, 15, "#elif !defined(") == 0) { std::string::size_type pos = 0; @@ -880,7 +880,7 @@ std::list Preprocessor::getcfgs(const std::string &filedata, const simplifyCondition(varmap, def, false); } - if (! deflist.empty() && line.find("#elif ") == 0) + if (! deflist.empty() && line.compare(0, 6, "#elif ") == 0) deflist.pop_back(); deflist.push_back(def); def = ""; @@ -930,7 +930,7 @@ std::list Preprocessor::getcfgs(const std::string &filedata, const } } - else if (line.find("#else") == 0 && ! deflist.empty()) + else if (line.compare(0, 5, "#else") == 0 && ! deflist.empty()) { if (deflist.back() == "!") { @@ -946,7 +946,7 @@ std::list Preprocessor::getcfgs(const std::string &filedata, const } } - else if (line.find("#endif") == 0 && ! deflist.empty()) + else if (line.compare(0, 6, "#endif") == 0 && ! deflist.empty()) { if (deflist.back() == "!") ndeflist.pop_back(); @@ -1372,7 +1372,7 @@ std::string Preprocessor::getcode(const std::string &filedata, std::string cfg, } } - else if (line.find("#elif !") == 0) + else if (line.compare(0, 7, "#elif !") == 0) { if (matched_ifdef.back()) { @@ -1388,7 +1388,7 @@ std::string Preprocessor::getcode(const std::string &filedata, std::string cfg, } } - else if (line.find("#elif ") == 0) + else if (line.compare(0, 6, "#elif ") == 0) { if (matched_ifdef.back()) { From 29ca5fbe1e74c58eea345a74dee2018ef23c5631 Mon Sep 17 00:00:00 2001 From: Raphael Geissert Date: Sun, 30 Jan 2011 18:47:49 -0600 Subject: [PATCH 150/165] Minor optimisations to the preprocessor --- lib/preprocessor.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/lib/preprocessor.cpp b/lib/preprocessor.cpp index dcb292d9f..e76c2b43c 100644 --- a/lib/preprocessor.cpp +++ b/lib/preprocessor.cpp @@ -713,6 +713,9 @@ void Preprocessor::preprocess(std::istream &srcCodeStream, std::string &processe // Get the DEF in this line: "#ifdef DEF" std::string Preprocessor::getdef(std::string line, bool def) { + if (line.empty() || line[0] != '#') + return ""; + // If def is true, the line must start with "#ifdef" if (def && line.compare(0, 7, "#ifdef ") != 0 && line.compare(0, 4, "#if ") != 0 && (line.compare(0, 6, "#elif ") != 0 || line.compare(0, 7, "#elif !") == 0)) @@ -787,6 +790,8 @@ std::list Preprocessor::getcfgs(const std::string &filedata, const if (_errorLogger) _errorLogger->reportProgress(filename, "Preprocessing (get configurations 1)", 0); + if (line.empty()) + continue; if (line.compare(0, 6, "#file ") == 0) { @@ -818,6 +823,9 @@ std::list Preprocessor::getcfgs(const std::string &filedata, const if (!line.empty() && line.compare(0, 3, "#if") != 0) includeguard = false; + if (line[0] != '#') + continue; + if (includeguard) continue; From 386de53ff730bc6d688955bf1eff9436aa33ba10 Mon Sep 17 00:00:00 2001 From: Raphael Geissert Date: Sun, 30 Jan 2011 20:37:37 -0600 Subject: [PATCH 151/165] Formatting, sorry --- lib/preprocessor.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/preprocessor.cpp b/lib/preprocessor.cpp index e76c2b43c..4cdd5f729 100644 --- a/lib/preprocessor.cpp +++ b/lib/preprocessor.cpp @@ -714,7 +714,7 @@ void Preprocessor::preprocess(std::istream &srcCodeStream, std::string &processe std::string Preprocessor::getdef(std::string line, bool def) { if (line.empty() || line[0] != '#') - return ""; + return ""; // If def is true, the line must start with "#ifdef" if (def && line.compare(0, 7, "#ifdef ") != 0 && line.compare(0, 4, "#if ") != 0 @@ -791,7 +791,7 @@ std::list Preprocessor::getcfgs(const std::string &filedata, const _errorLogger->reportProgress(filename, "Preprocessing (get configurations 1)", 0); if (line.empty()) - continue; + continue; if (line.compare(0, 6, "#file ") == 0) { @@ -823,8 +823,8 @@ std::list Preprocessor::getcfgs(const std::string &filedata, const if (!line.empty() && line.compare(0, 3, "#if") != 0) includeguard = false; - if (line[0] != '#') - continue; + if (line[0] != '#') + continue; if (includeguard) continue; From 800d8d1e056ddba9318fc2a8be85572587d2928c Mon Sep 17 00:00:00 2001 From: Kimmo Varis Date: Mon, 31 Jan 2011 09:18:35 +0200 Subject: [PATCH 152/165] Cleanup makefile a bit. Align object file lists first line. Remove excessive use of tabs. --- Makefile | 16 ++++++++-------- tools/dmake.cpp | 16 ++++++++-------- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/Makefile b/Makefile index de50b8d09..09aadde1c 100644 --- a/Makefile +++ b/Makefile @@ -22,7 +22,7 @@ MAN_SOURCE=man/cppcheck.1.xml ###### Object Files -LIBOBJ = lib/checkautovariables.o \ +LIBOBJ = lib/checkautovariables.o \ lib/checkbufferoverrun.o \ lib/checkclass.o \ lib/checkexceptionsafety.o \ @@ -46,7 +46,7 @@ LIBOBJ = lib/checkautovariables.o \ lib/token.o \ lib/tokenize.o -CLIOBJ = cli/cmdlineparser.o \ +CLIOBJ = cli/cmdlineparser.o \ cli/cppcheckexecutor.o \ cli/filelister.o \ cli/filelister_unix.o \ @@ -90,7 +90,7 @@ TESTOBJ = test/options.o \ test/testunusedprivfunc.o \ test/testunusedvar.o -EXTOBJ = externals/tinyxml/tinystr.o \ +EXTOBJ = externals/tinyxml/tinystr.o \ externals/tinyxml/tinyxml.o \ externals/tinyxml/tinyxmlerror.o \ externals/tinyxml/tinyxmlparser.o @@ -98,13 +98,13 @@ EXTOBJ = externals/tinyxml/tinystr.o \ ###### Targets -cppcheck: $(LIBOBJ) $(CLIOBJ) $(EXTOBJ) +cppcheck: $(LIBOBJ) $(CLIOBJ) $(EXTOBJ) $(CXX) $(CPPFLAGS) $(CXXFLAGS) -o cppcheck $(CLIOBJ) $(LIBOBJ) $(EXTOBJ) -lpcre $(LDFLAGS) -all: cppcheck testrunner +all: cppcheck testrunner -testrunner: $(TESTOBJ) $(LIBOBJ) $(EXTOBJ) cli/threadexecutor.o cli/cmdlineparser.o cli/cppcheckexecutor.o cli/filelister.o cli/filelister_unix.o - $(CXX) $(CPPFLAGS) $(CXXFLAGS) -o testrunner $(TESTOBJ) $(LIBOBJ) $(EXTOBJ) -lpcre cli/threadexecutor.o cli/cmdlineparser.o cli/filelister.o cli/filelister_unix.o $(LDFLAGS) +testrunner: $(TESTOBJ) $(LIBOBJ) $(EXTOBJ) cli/threadexecutor.o cli/cmdlineparser.o cli/cppcheckexecutor.o cli/filelister.o cli/filelister_unix.o + $(CXX) $(CPPFLAGS) $(CXXFLAGS) -o testrunner $(TESTOBJ) $(LIBOBJ) $(EXTOBJ) -lpcre cli/threadexecutor.o cli/cmdlineparser.o cli/filelister.o cli/filelister_unix.o $(LDFLAGS) test: all ./testrunner @@ -127,7 +127,7 @@ man/cppcheck.1: $(MAN_SOURCE) tags: ctags -R --exclude=doxyoutput . -install: cppcheck +install: cppcheck install -d ${BIN} install cppcheck ${BIN} diff --git a/tools/dmake.cpp b/tools/dmake.cpp index 0ff33c099..434a4128c 100644 --- a/tools/dmake.cpp +++ b/tools/dmake.cpp @@ -208,11 +208,11 @@ int main(int argc, char **argv) fout << "MAN_SOURCE=man/cppcheck.1.xml\n\n"; fout << "\n###### Object Files\n\n"; - fout << "LIBOBJ = " << objfile(libfiles[0]); + fout << "LIBOBJ = " << objfile(libfiles[0]); for (unsigned int i = 1; i < libfiles.size(); ++i) fout << " \\" << std::endl << std::string(14, ' ') << objfile(libfiles[i]); fout << "\n\n"; - fout << "CLIOBJ = " << objfile(clifiles[0]); + fout << "CLIOBJ = " << objfile(clifiles[0]); for (unsigned int i = 1; i < clifiles.size(); ++i) fout << " \\" << std::endl << std::string(14, ' ') << objfile(clifiles[i]); fout << "\n\n"; @@ -220,18 +220,18 @@ int main(int argc, char **argv) for (unsigned int i = 1; i < testfiles.size(); ++i) fout << " \\" << std::endl << std::string(14, ' ') << objfile(testfiles[i]); fout << "\n\n"; - fout << "EXTOBJ = " << objfile(externalfiles[0]); + fout << "EXTOBJ = " << objfile(externalfiles[0]); for (unsigned int i = 1; i < externalfiles.size(); ++i) fout << " \\" << std::endl << std::string(14, ' ') << objfile(externalfiles[i]); fout << "\n\n"; fout << "\n###### Targets\n\n"; - fout << "cppcheck:\t$(LIBOBJ)\t$(CLIOBJ)\t$(EXTOBJ)\n"; + fout << "cppcheck: $(LIBOBJ) $(CLIOBJ) $(EXTOBJ)\n"; fout << "\t$(CXX) $(CPPFLAGS) $(CXXFLAGS) -o cppcheck $(CLIOBJ) $(LIBOBJ) $(EXTOBJ) -lpcre $(LDFLAGS)\n\n"; - fout << "all:\tcppcheck\ttestrunner\n\n"; - fout << "testrunner:\t$(TESTOBJ)\t$(LIBOBJ)\t$(EXTOBJ)\tcli/threadexecutor.o\tcli/cmdlineparser.o\tcli/cppcheckexecutor.o\tcli/filelister.o\tcli/filelister_unix.o\n"; - fout << "\t$(CXX) $(CPPFLAGS) $(CXXFLAGS) -o testrunner $(TESTOBJ) $(LIBOBJ) $(EXTOBJ) -lpcre cli/threadexecutor.o cli/cmdlineparser.o\tcli/filelister.o\tcli/filelister_unix.o $(LDFLAGS)\n\n"; + fout << "all:\tcppcheck testrunner\n\n"; + fout << "testrunner: $(TESTOBJ) $(LIBOBJ) $(EXTOBJ) cli/threadexecutor.o cli/cmdlineparser.o cli/cppcheckexecutor.o cli/filelister.o cli/filelister_unix.o\n"; + fout << "\t$(CXX) $(CPPFLAGS) $(CXXFLAGS) -o testrunner $(TESTOBJ) $(LIBOBJ) $(EXTOBJ) -lpcre cli/threadexecutor.o cli/cmdlineparser.o cli/filelister.o cli/filelister_unix.o $(LDFLAGS)\n\n"; fout << "test:\tall\n"; fout << "\t./testrunner\n\n"; fout << "check:\tall\n"; @@ -248,7 +248,7 @@ int main(int argc, char **argv) fout << "\t$(XP) $(DB2MAN) $(MAN_SOURCE)\n\n"; fout << "tags:\n"; fout << "\tctags -R --exclude=doxyoutput .\n\n"; - fout << "install:\tcppcheck\n"; + fout << "install: cppcheck\n"; fout << "\tinstall -d ${BIN}\n"; fout << "\tinstall cppcheck ${BIN}\n\n"; #endif From 43b0e2a74c12df59afa23758154ce416957bbb31 Mon Sep 17 00:00:00 2001 From: Kimmo Varis Date: Mon, 31 Jan 2011 10:25:14 +0200 Subject: [PATCH 153/165] GUI: Fill summary data when reading XML file. When reading XML file there is no summary data stored so we must dublicate the message data to summary. Since message can be long try to find full stop from the message and cut summary to it. Ticket: #2402 ([GUI] Summary is not shown for loaded .xml file) --- gui/xmlreport.cpp | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/gui/xmlreport.cpp b/gui/xmlreport.cpp index c82478055..f481f3615 100644 --- a/gui/xmlreport.cpp +++ b/gui/xmlreport.cpp @@ -159,6 +159,16 @@ ErrorLine XmlReport::ReadError(QXmlStreamReader *reader) line.line = attribs.value("", LineAttribute).toString().toUInt(); line.id = attribs.value("", IdAttribute).toString(); line.severity = attribs.value("", SeverityAttribute).toString(); + + // NOTE: This dublicates the message to Summary-field. But since + // old XML format doesn't have separate summary and verbose messages + // we must add same message to both data so it shows up in GUI. + // Check if there is full stop and cut the summary to it. + QString summary = attribs.value("", MsgAttribute).toString(); + const int ind = summary.indexOf('.'); + if (ind != -1) + summary = summary.left(ind + 1); + line.summary = summary; line.message = attribs.value("", MsgAttribute).toString(); } return line; From b7cb684b1b842862da65ffb9e9ca1839c3532a3c Mon Sep 17 00:00:00 2001 From: Kimmo Varis Date: Mon, 31 Jan 2011 10:32:23 +0200 Subject: [PATCH 154/165] GUI: Write error summary to CSV and TXT reports. It makes more sense to write the one-line summary to TXT and especially to CSV reports. Long multi-line verbose messages ruin the layout these files. --- gui/csvreport.cpp | 2 +- gui/txtreport.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/gui/csvreport.cpp b/gui/csvreport.cpp index a9016e42e..0080f1434 100644 --- a/gui/csvreport.cpp +++ b/gui/csvreport.cpp @@ -65,7 +65,7 @@ void CsvReport::WriteError(const ErrorItem &error) QString line; const QString file = QDir::toNativeSeparators(error.files[error.files.size() - 1]); line += QString("%1,%2,").arg(file).arg(error.lines[error.lines.size() - 1]); - line += QString("%1,%2").arg(error.severity).arg(error.message); + line += QString("%1,%2").arg(error.severity).arg(error.summary); mTxtWriter << line << endl; } diff --git a/gui/txtreport.cpp b/gui/txtreport.cpp index a6f8dbe4b..20c34d7b7 100644 --- a/gui/txtreport.cpp +++ b/gui/txtreport.cpp @@ -76,7 +76,7 @@ void TxtReport::WriteError(const ErrorItem &error) } } - line += QString("(%1) %2").arg(error.severity).arg(error.message); + line += QString("(%1) %2").arg(error.severity).arg(error.summary); mTxtWriter << line << endl; } From f70aaac5cde249e5ebdf657c2fd0976e995339f6 Mon Sep 17 00:00:00 2001 From: Kimmo Varis Date: Mon, 31 Jan 2011 11:16:32 +0200 Subject: [PATCH 155/165] GUI: Reword the option for checking all #ifdefs. The current wording was confusing (espcially related to CLI) since it said the option will make Cppcheck to check all #ifdef configs. But this really is case only when there is excessive amount of those configs and without the option some would be ignored. So format the option text in line of CLI switch and say it is forcing not enabling checking of all configurations. --- gui/settings.ui | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gui/settings.ui b/gui/settings.ui index ac5f19f33..8d6fc2e3d 100644 --- a/gui/settings.ui +++ b/gui/settings.ui @@ -7,7 +7,7 @@ 0 0 589 - 281 + 313 @@ -135,7 +135,7 @@ - Check all #ifdef configurations + Force checking all #ifdef configurations From 0112cd505d089695dc3adb485536cea12042747f Mon Sep 17 00:00:00 2001 From: Kimmo Varis Date: Mon, 31 Jan 2011 11:20:03 +0200 Subject: [PATCH 156/165] GUI: Update translation files. --- gui/cppcheck_de.ts | 59 +++++++++++++++++++++++----------------------- gui/cppcheck_en.ts | 59 +++++++++++++++++++++++----------------------- gui/cppcheck_fi.ts | 59 +++++++++++++++++++++++----------------------- gui/cppcheck_ja.ts | 59 +++++++++++++++++++++++----------------------- gui/cppcheck_nl.ts | 59 +++++++++++++++++++++++----------------------- gui/cppcheck_pl.ts | 57 ++++++++++++++++++++++---------------------- gui/cppcheck_ru.ts | 59 +++++++++++++++++++++++----------------------- gui/cppcheck_se.ts | 59 +++++++++++++++++++++++----------------------- gui/cppcheck_sr.ts | 59 +++++++++++++++++++++++----------------------- 9 files changed, 269 insertions(+), 260 deletions(-) diff --git a/gui/cppcheck_de.ts b/gui/cppcheck_de.ts index 9b3ff31ea..3c7b047a7 100644 --- a/gui/cppcheck_de.ts +++ b/gui/cppcheck_de.ts @@ -222,10 +222,10 @@ kate -l(line) (file) - - - - + + + + Cppcheck Cppcheck @@ -552,28 +552,28 @@ kate -l(line) (file) Kein passenden Dateien zum Überprüfen gefunden! - + License Lizenz - + Authors Autoren - + XML files (*.xml);;Text files (*.txt);;CSV files (*.csv) XML-Dateien (*.xml);;Textdateien (*.txt);;CSV-Dateien (*.csv) - + Save the report file Speichert die Berichtdatei - - + + XML files (*.xml) XML-Dateien (*.xml) @@ -584,40 +584,40 @@ kate -l(line) (file) - - + + Project: - + Open the report file - + Checking is running. Do you want to stop the checking and exit Cppcheck?. - + Text files (*.txt) Textdateien (*.txt) - + CSV files (*.csv) CSV-Dateien (*.csv) - + Cppcheck - %1 Cppcheck - %1 - + Failed to change the language: %1 @@ -633,39 +633,39 @@ Do you want to stop the checking and exit Cppcheck?. - - + + Cppcheck Help - + Failed to load help file (not found) - + Failed to load help file - - + + Project files (*.cppcheck);;All files(*.*) - + Select Project File - + Select Project Filename - + No project file loaded @@ -1018,8 +1018,9 @@ Legen Sie unter dem Menü Ansicht fest, welche Art von Fehlern angezeigt werden - Check all #ifdef configurations - Alle #ifdef-Konfigurationen überprüfen + Force checking all #ifdef configurations + Check all #ifdef configurations + Alle #ifdef-Konfigurationen überprüfen diff --git a/gui/cppcheck_en.ts b/gui/cppcheck_en.ts index 3a96b3c94..9ee278852 100644 --- a/gui/cppcheck_en.ts +++ b/gui/cppcheck_en.ts @@ -224,10 +224,10 @@ kate -l(line) (file) - - - - + + + + Cppcheck Cppcheck @@ -554,28 +554,28 @@ kate -l(line) (file) No suitable files found to check! - + License License - + Authors Authors - + XML files (*.xml);;Text files (*.txt);;CSV files (*.csv) XML files (*.xml);;Text files (*.txt);;CSV files (*.csv) - + Save the report file Save the report file - - + + XML files (*.xml) XML files (*.xml) @@ -586,40 +586,40 @@ kate -l(line) (file) - - + + Project: - + Open the report file - + Checking is running. Do you want to stop the checking and exit Cppcheck?. - + Text files (*.txt) Text files (*.txt) - + CSV files (*.csv) - + Cppcheck - %1 Cppcheck - %1 - + Failed to change the language: %1 @@ -633,39 +633,39 @@ Do you want to stop the checking and exit Cppcheck?. %1 - - + + Cppcheck Help - + Failed to load help file (not found) - + Failed to load help file - - + + Project files (*.cppcheck);;All files(*.*) - + Select Project File - + Select Project Filename - + No project file loaded @@ -1018,8 +1018,9 @@ To toggle what kind of errors are shown, open view menu. - Check all #ifdef configurations - Check all #ifdef configurations + Force checking all #ifdef configurations + Check all #ifdef configurations + Check all #ifdef configurations diff --git a/gui/cppcheck_fi.ts b/gui/cppcheck_fi.ts index 57924099c..303d349e6 100644 --- a/gui/cppcheck_fi.ts +++ b/gui/cppcheck_fi.ts @@ -226,10 +226,10 @@ kate -l(line) (file) - - - - + + + + Cppcheck Cppcheck @@ -556,28 +556,28 @@ kate -l(line) (file) Tarkistettavaksi sopivia tiedostoja ei löytynyt! - + License Lisenssi - + Authors Tekijät - + XML files (*.xml);;Text files (*.txt);;CSV files (*.csv) XML-tiedostot (*.xml);;Tekstitiedostot (*.txt);;CSV-tiedostot (*.csv) - + Save the report file Tallenna raportti - - + + XML files (*.xml) XML-tiedostot (*xml) @@ -588,40 +588,40 @@ kate -l(line) (file) - - + + Project: - + Open the report file - + Checking is running. Do you want to stop the checking and exit Cppcheck?. - + Text files (*.txt) Tekstitiedostot (*.txt) - + CSV files (*.csv) - + Cppcheck - %1 Cppcheck - %1 - + Failed to change the language: %1 @@ -637,39 +637,39 @@ Do you want to stop the checking and exit Cppcheck?. - - + + Cppcheck Help - + Failed to load help file (not found) - + Failed to load help file - - + + Project files (*.cppcheck);;All files(*.*) - + Select Project File - + Select Project Filename - + No project file loaded @@ -1022,8 +1022,9 @@ Määrittääksesi minkä tyyppisiä virheitä näytetään, avaa näkymä valik - Check all #ifdef configurations - Tarkista kaikki #ifdef kombinaatiot + Force checking all #ifdef configurations + Check all #ifdef configurations + Tarkista kaikki #ifdef kombinaatiot diff --git a/gui/cppcheck_ja.ts b/gui/cppcheck_ja.ts index 911b32756..222900f08 100644 --- a/gui/cppcheck_ja.ts +++ b/gui/cppcheck_ja.ts @@ -210,10 +210,10 @@ kate -l(line) (file) - - - - + + + + Cppcheck Cppcheck @@ -546,24 +546,24 @@ kate -l(line) (file) - - + + Project: プロジェクト: - - + + XML files (*.xml) XML ファイル (*.xml) - + Open the report file レポートを開く - + Checking is running. Do you want to stop the checking and exit Cppcheck?. @@ -572,42 +572,42 @@ Do you want to stop the checking and exit Cppcheck?. 解析を停止してCppcheckを終了しますか?. - + License ライセンス - + Authors 作者 - + XML files (*.xml);;Text files (*.txt);;CSV files (*.csv) XML ファイル (*.xml);;テキストファイル (*.txt);;CSV形式ファイル (*.csv) - + Save the report file レポートを保存 - + Text files (*.txt) テキストファイル (*.txt) - + CSV files (*.csv) CSV形式ファイル (*.csv) - + Cppcheck - %1 Cppcheck - %1 - + Failed to change the language: %1 @@ -620,39 +620,39 @@ Do you want to stop the checking and exit Cppcheck?. - - + + Cppcheck Help Cppcheck ヘルプ - + Failed to load help file (not found) ヘルプファイルが見つかりませんでした - + Failed to load help file ヘルプファイルの読み込みに失敗しました - - + + Project files (*.cppcheck);;All files(*.*) プロジェクトファイル (*.cppcheck);;All files(*.*) - + Select Project File プロジェクトファイルを選択 - + Select Project Filename プロジェクトファイル名を選択 - + No project file loaded プロジェクトファイルが読み込まれていません @@ -1003,8 +1003,9 @@ To toggle what kind of errors are shown, open view menu. - Check all #ifdef configurations - すべての #ifdef をチェックする + Force checking all #ifdef configurations + Check all #ifdef configurations + すべての #ifdef をチェックする diff --git a/gui/cppcheck_nl.ts b/gui/cppcheck_nl.ts index c5e5e6747..a5ac7b33f 100644 --- a/gui/cppcheck_nl.ts +++ b/gui/cppcheck_nl.ts @@ -224,10 +224,10 @@ kate -l(line) (file) - - - - + + + + Cppcheck Cppcheck @@ -554,28 +554,28 @@ kate -l(line) (file) Geen geschikte bestanden gevonden om te controleren! - + License Licentie - + Authors Auteurs - + XML files (*.xml);;Text files (*.txt);;CSV files (*.csv) XML bestanden (*.xml);;Tekst bestanden (*.txt);;CSV bestanden (*.csv) - + Save the report file Rapport opslaan - - + + XML files (*.xml) XML bestanden (*.xml) @@ -586,40 +586,40 @@ kate -l(line) (file) - - + + Project: - + Open the report file - + Checking is running. Do you want to stop the checking and exit Cppcheck?. - + Text files (*.txt) Tekst bestanden (*.txt) - + CSV files (*.csv) - + Cppcheck - %1 Cppcheck - %1 - + Failed to change the language: %1 @@ -633,39 +633,39 @@ Do you want to stop the checking and exit Cppcheck?. %1 - - + + Cppcheck Help - + Failed to load help file (not found) - + Failed to load help file - - + + Project files (*.cppcheck);;All files(*.*) - + Select Project File - + Select Project Filename - + No project file loaded @@ -1018,8 +1018,9 @@ Gebruik het uitzicht menu om te selecteren welke fouten getoond worden. - Check all #ifdef configurations - Controleer alle #ifdef combinaties + Force checking all #ifdef configurations + Check all #ifdef configurations + Controleer alle #ifdef combinaties diff --git a/gui/cppcheck_pl.ts b/gui/cppcheck_pl.ts index c35ddefb1..79013cad9 100644 --- a/gui/cppcheck_pl.ts +++ b/gui/cppcheck_pl.ts @@ -211,10 +211,10 @@ kate -l(line) (file) - - - - + + + + Cppcheck @@ -547,92 +547,92 @@ kate -l(line) (file) - - + + Project: - + Open the report file - + License - + Authors - + XML files (*.xml);;Text files (*.txt);;CSV files (*.csv) - + Save the report file - - + + Cppcheck Help - + Failed to load help file (not found) - + Failed to load help file - + Select Project Filename - + No project file loaded - - + + XML files (*.xml) - + Checking is running. Do you want to stop the checking and exit Cppcheck?. - + Text files (*.txt) - + CSV files (*.csv) - + Cppcheck - %1 - + Failed to change the language: %1 @@ -641,13 +641,13 @@ Do you want to stop the checking and exit Cppcheck?. - - + + Project files (*.cppcheck);;All files(*.*) - + Select Project File @@ -994,7 +994,8 @@ To toggle what kind of errors are shown, open view menu. - Check all #ifdef configurations + Force checking all #ifdef configurations + Check all #ifdef configurations diff --git a/gui/cppcheck_ru.ts b/gui/cppcheck_ru.ts index 6c3d6d407..56e10c928 100644 --- a/gui/cppcheck_ru.ts +++ b/gui/cppcheck_ru.ts @@ -214,10 +214,10 @@ kate -l(line) (file) - - - - + + + + Cppcheck Cppcheck @@ -544,28 +544,28 @@ kate -l(line) (file) - + License Лицензия - + Authors Авторы - + XML files (*.xml);;Text files (*.txt);;CSV files (*.csv) - + Save the report file - - + + XML files (*.xml) @@ -576,40 +576,40 @@ kate -l(line) (file) - - + + Project: - + Open the report file - + Checking is running. Do you want to stop the checking and exit Cppcheck?. - + Text files (*.txt) Текстовые файлы (*.txt) - + CSV files (*.csv) - + Cppcheck - %1 Cppcheck - %1 - + Failed to change the language: %1 @@ -625,39 +625,39 @@ Do you want to stop the checking and exit Cppcheck?. - - + + Cppcheck Help - + Failed to load help file (not found) - + Failed to load help file - - + + Project files (*.cppcheck);;All files(*.*) - + Select Project File - + Select Project Filename - + No project file loaded @@ -1007,8 +1007,9 @@ To toggle what kind of errors are shown, open view menu. - Check all #ifdef configurations - Проверять все варианты #ifdef конфигураций + Force checking all #ifdef configurations + Check all #ifdef configurations + Проверять все варианты #ifdef конфигураций diff --git a/gui/cppcheck_se.ts b/gui/cppcheck_se.ts index 278a2de3f..0fec2db9a 100644 --- a/gui/cppcheck_se.ts +++ b/gui/cppcheck_se.ts @@ -224,10 +224,10 @@ kate -l(line) (file) - - - - + + + + Cppcheck Cppcheck @@ -555,28 +555,28 @@ kate -l(line) (file) Inga lämpliga filer hittades! - + License Licens - + Authors Utvecklare - + XML files (*.xml);;Text files (*.txt);;CSV files (*.csv) XML filer (*.xml);;Text filer (*.txt);;CSV filer (*.csv) - + Save the report file Spara rapport - - + + XML files (*.xml) XML filer (*.xml) @@ -587,40 +587,40 @@ kate -l(line) (file) - - + + Project: - + Open the report file - + Checking is running. Do you want to stop the checking and exit Cppcheck?. - + Text files (*.txt) Text filer (*.txt) - + CSV files (*.csv) CSV filer (*.csv) - + Cppcheck - %1 Cppcheck - %1 - + Failed to change the language: %1 @@ -636,39 +636,39 @@ Do you want to stop the checking and exit Cppcheck?. - - + + Cppcheck Help - + Failed to load help file (not found) - + Failed to load help file - - + + Project files (*.cppcheck);;All files(*.*) - + Select Project File - + Select Project Filename - + No project file loaded @@ -1021,8 +1021,9 @@ För att ställa in vilka fel som skall visas använd visa menyn. - Check all #ifdef configurations - Kontrollera alla #ifdef konfigurationer + Force checking all #ifdef configurations + Check all #ifdef configurations + Kontrollera alla #ifdef konfigurationer diff --git a/gui/cppcheck_sr.ts b/gui/cppcheck_sr.ts index 4beb61085..8710dd855 100644 --- a/gui/cppcheck_sr.ts +++ b/gui/cppcheck_sr.ts @@ -224,10 +224,10 @@ kate -l(line) (file) - - - - + + + + Cppcheck Cppcheck @@ -554,28 +554,28 @@ kate -l(line) (file) No suitable files found to check! - + License License - + Authors Authors - + XML files (*.xml);;Text files (*.txt);;CSV files (*.csv) XML files (*.xml);;Text files (*.txt);;CSV files (*.csv) - + Save the report file Save the report file - - + + XML files (*.xml) XML files (*.xml) @@ -586,40 +586,40 @@ kate -l(line) (file) - - + + Project: - + Open the report file - + Checking is running. Do you want to stop the checking and exit Cppcheck?. - + Text files (*.txt) Text files (*.txt) - + CSV files (*.csv) - + Cppcheck - %1 Cppcheck - %1 - + Failed to change the language: %1 @@ -633,39 +633,39 @@ Do you want to stop the checking and exit Cppcheck?. %1 - - + + Cppcheck Help - + Failed to load help file (not found) - + Failed to load help file - - + + Project files (*.cppcheck);;All files(*.*) - + Select Project File - + Select Project Filename - + No project file loaded @@ -1018,8 +1018,9 @@ To toggle what kind of errors are shown, open view menu. - Check all #ifdef configurations - Check all #ifdef configurations + Force checking all #ifdef configurations + Check all #ifdef configurations + Check all #ifdef configurations From f3111b541ee117c09bafd62f8333718e5ddf5bd8 Mon Sep 17 00:00:00 2001 From: Ettl Martin Date: Mon, 31 Jan 2011 13:46:51 +0100 Subject: [PATCH 157/165] #2528 added todo-testcase --- test/testbufferoverrun.cpp | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/test/testbufferoverrun.cpp b/test/testbufferoverrun.cpp index c63094fde..7b1f4d905 100644 --- a/test/testbufferoverrun.cpp +++ b/test/testbufferoverrun.cpp @@ -106,6 +106,7 @@ private: TEST_CASE(array_index_29); // ticket #1734 TEST_CASE(array_index_30); // ticket #2086 - out of bounds when type is unknown TEST_CASE(array_index_31); // ticket #2120 - out of bounds in subfunction when type is unknown + TEST_CASE(array_index_32); TEST_CASE(array_index_multidim); TEST_CASE(array_index_switch_in_for); TEST_CASE(array_index_calculation); @@ -1067,6 +1068,21 @@ private: ASSERT_EQUALS("", errout.str()); } + void array_index_32() + { + check("class X\n" + "{\n" + " public:\n" + " X()\n" + " {\n" + " m_x[0] = 0;\n" + " m_x[1] = 0;\n" + " }\n" + " int m_x[1];\n" + "};\n"); + TODO_ASSERT_EQUALS("[test.cpp:7]: (error) Array 'm_x[1]' index 1 out of bounds\n","", errout.str()); + } + void array_index_multidim() { check("void f()\n" From 757c840633ce8dcafbdf6cfa8c1dd8730fdbf08b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Mon, 31 Jan 2011 17:26:07 +0100 Subject: [PATCH 158/165] astyle formatting --- cli/filelister_win32.cpp | 2 +- test/testbufferoverrun.cpp | 2 +- test/testpreprocessor.cpp | 6 +++--- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/cli/filelister_win32.cpp b/cli/filelister_win32.cpp index 776e0245a..041613331 100644 --- a/cli/filelister_win32.cpp +++ b/cli/filelister_win32.cpp @@ -88,7 +88,7 @@ static BOOL MyIsDirectory(std::string path) return (GetFileAttributes(path.c_str()) & FILE_ATTRIBUTE_DIRECTORY); #else // See http://msdn.microsoft.com/en-us/library/bb773621(VS.85).aspx - return PathIsDirectory(path.c_str()); +return PathIsDirectory(path.c_str()); #endif } diff --git a/test/testbufferoverrun.cpp b/test/testbufferoverrun.cpp index 7b1f4d905..4966231ba 100644 --- a/test/testbufferoverrun.cpp +++ b/test/testbufferoverrun.cpp @@ -1073,7 +1073,7 @@ private: check("class X\n" "{\n" " public:\n" - " X()\n" + " X()\n" " {\n" " m_x[0] = 0;\n" " m_x[1] = 0;\n" diff --git a/test/testpreprocessor.cpp b/test/testpreprocessor.cpp index 80d32aacc..2d9486d49 100644 --- a/test/testpreprocessor.cpp +++ b/test/testpreprocessor.cpp @@ -430,7 +430,7 @@ private: // Make sure an error message is written.. ASSERT_EQUALS("[file.c:3]: (error) ABC is already guaranteed to be defined\n", - errout.str()); + errout.str()); // Compare results.. ASSERT_EQUALS("\n\n\n\n\n\n", actual[""]); @@ -512,7 +512,7 @@ private: // Make sure an error message is written.. ASSERT_EQUALS("[file.c:3]: (error) ABC is already guaranteed to be defined\n", - errout.str()); + errout.str()); // Compare results.. ASSERT_EQUALS(2, static_cast(actual.size())); @@ -537,7 +537,7 @@ private: // Make sure an error message is written.. ASSERT_EQUALS("[file.c:3]: (error) ABC is already guaranteed to be defined\n", - errout.str()); + errout.str()); // Compare results.. ASSERT_EQUALS(2, static_cast(actual.size())); From 202c8eb4a0463139ad47f5bff3a0445590889526 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Mon, 31 Jan 2011 17:30:27 +0100 Subject: [PATCH 159/165] Fixed #2525 (False positive 'Possible null pointer dereference') --- lib/checknullpointer.cpp | 6 ++++++ test/testnullpointer.cpp | 9 +++++++++ 2 files changed, 15 insertions(+) diff --git a/lib/checknullpointer.cpp b/lib/checknullpointer.cpp index e9b1467bd..bd36a4e37 100644 --- a/lib/checknullpointer.cpp +++ b/lib/checknullpointer.cpp @@ -485,6 +485,12 @@ void CheckNullPointer::nullPointerByDeRefAndChec() break; } + if (tok1->str() == ")" && Token::simpleMatch(tok1->link()->previous(), "sizeof (")) + { + tok1 = tok1->link()->previous(); + continue; + } + if (tok1->str() == "break") break; diff --git a/test/testnullpointer.cpp b/test/testnullpointer.cpp index 53198703c..0c9e09a1f 100644 --- a/test/testnullpointer.cpp +++ b/test/testnullpointer.cpp @@ -437,6 +437,15 @@ private: " }\n" "}\n"); ASSERT_EQUALS("", errout.str()); + + // #2525 - sizeof + check("void f() {\n" + " int *test = NULL;\n" + " int c = sizeof(test[0]);\n" + " if (!test)\n" + " ;\n" + "}\n"); + ASSERT_EQUALS("", errout.str()); } void nullpointer5() From dcc0f28f3415de9dbf7d50a191f9c19b99c92c7b Mon Sep 17 00:00:00 2001 From: Greg Hewgill Date: Tue, 1 Feb 2011 08:07:41 +1300 Subject: [PATCH 160/165] check that misused scope object does not pick nested class --- test/testother.cpp | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/test/testother.cpp b/test/testother.cpp index a835ba30d..7573b9d5e 100644 --- a/test/testother.cpp +++ b/test/testother.cpp @@ -89,6 +89,7 @@ private: TEST_CASE(testMisusedScopeObjectDoesNotPickLocalClassConstructors); TEST_CASE(testMisusedScopeObjectDoesNotPickUsedObject); TEST_CASE(testMisusedScopeObjectDoesNotPickPureC); + TEST_CASE(testMisusedScopeObjectDoesNotPickNestedClass); TEST_CASE(trac2071); TEST_CASE(trac2084); @@ -1358,6 +1359,27 @@ private: ASSERT_EQUALS("", errout.str()); } + void testMisusedScopeObjectDoesNotPickNestedClass() + { + const char code[] = "class ios_base {\n" + "public:\n" + " class Init {\n" + " public:\n" + " };\n" + "};\n" + "class foo {\n" + "public:\n" + " foo();\n" + " void Init(int);\n" + "};\n" + "foo::foo() {\n" + " Init(0);\n" + "}\n"; + + check(code, "test.cpp"); + ASSERT_EQUALS("", errout.str()); + } + void trac2084() { check("#include \n" From 52fea0f24521c58ddbb639e2c2642ba459bf488a Mon Sep 17 00:00:00 2001 From: Robert Reif Date: Mon, 31 Jan 2011 22:18:16 +0200 Subject: [PATCH 161/165] Ticket #2522 (update project files to fix missing include messages) --- cppcheck.cppcheck | 4 ++++ gui/gui.cppcheck | 13 +++++++------ 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/cppcheck.cppcheck b/cppcheck.cppcheck index a76e7db2a..188043b4f 100644 --- a/cppcheck.cppcheck +++ b/cppcheck.cppcheck @@ -3,10 +3,14 @@ + + + + diff --git a/gui/gui.cppcheck b/gui/gui.cppcheck index 632b61115..7c87003bd 100644 --- a/gui/gui.cppcheck +++ b/gui/gui.cppcheck @@ -1,6 +1,7 @@ - - - - - - + + + + + + + From 250149300dd86ab6bebfea7d5d78f29dbcf4ced5 Mon Sep 17 00:00:00 2001 From: Kimmo Varis Date: Tue, 1 Feb 2011 08:33:02 +0200 Subject: [PATCH 162/165] Move FileLister* to CLI doxygen-module. I forgot to update the doxygen module when moving FileLister* to CLI. Also add CLI doxygen group for ThreadExecutor. --- cli/filelister.h | 2 +- cli/filelister_unix.h | 2 +- cli/filelister_win32.h | 2 +- cli/threadexecutor.h | 5 +++++ 4 files changed, 8 insertions(+), 3 deletions(-) diff --git a/cli/filelister.h b/cli/filelister.h index be4c60016..aa292b701 100644 --- a/cli/filelister.h +++ b/cli/filelister.h @@ -22,7 +22,7 @@ #include #include -/// @addtogroup Core +/// @addtogroup CLI /// @{ /** diff --git a/cli/filelister_unix.h b/cli/filelister_unix.h index f0b4e4c96..594580f0d 100644 --- a/cli/filelister_unix.h +++ b/cli/filelister_unix.h @@ -23,7 +23,7 @@ #include #include "filelister.h" -/// @addtogroup Core +/// @addtogroup CLI /// @{ diff --git a/cli/filelister_win32.h b/cli/filelister_win32.h index 4f89438bd..1095c79d7 100644 --- a/cli/filelister_win32.h +++ b/cli/filelister_win32.h @@ -23,7 +23,7 @@ #include #include "filelister.h" -/// @addtogroup Core +/// @addtogroup CLI /// @{ diff --git a/cli/threadexecutor.h b/cli/threadexecutor.h index 44238f5e9..1fb0af877 100644 --- a/cli/threadexecutor.h +++ b/cli/threadexecutor.h @@ -25,6 +25,9 @@ #include "settings.h" #include "errorlogger.h" +/// @addtogroup CLI +/// @{ + /** * This class will take a list of filenames and settings and check then * all files using threads. @@ -95,4 +98,6 @@ private: void operator=(const ThreadExecutor &); }; +/// @} + #endif // THREADEXECUTOR_H From 2d1ccad44e52cbc679528c0dc58e068123d13a4a Mon Sep 17 00:00:00 2001 From: Pete Johns Date: Tue, 1 Feb 2011 19:55:02 +1100 Subject: [PATCH 163/165] Turned failing ASSERT_EQUALS into TODO_ASSERT_EQUALS. --- test/testother.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/testother.cpp b/test/testother.cpp index 7573b9d5e..af08d80c4 100644 --- a/test/testother.cpp +++ b/test/testother.cpp @@ -1377,7 +1377,7 @@ private: "}\n"; check(code, "test.cpp"); - ASSERT_EQUALS("", errout.str()); + TODO_ASSERT_EQUALS("", "[test.cpp:13]: (error) instance of \"Init\" object destroyed immediately\n", errout.str()); } void trac2084() From 8298c07d60e2be7df17dc58b33fffd435d544ce0 Mon Sep 17 00:00:00 2001 From: Pete Johns Date: Tue, 1 Feb 2011 19:56:05 +1100 Subject: [PATCH 164/165] Astyle formatting. --- cli/filelister_win32.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cli/filelister_win32.cpp b/cli/filelister_win32.cpp index 041613331..776e0245a 100644 --- a/cli/filelister_win32.cpp +++ b/cli/filelister_win32.cpp @@ -88,7 +88,7 @@ static BOOL MyIsDirectory(std::string path) return (GetFileAttributes(path.c_str()) & FILE_ATTRIBUTE_DIRECTORY); #else // See http://msdn.microsoft.com/en-us/library/bb773621(VS.85).aspx -return PathIsDirectory(path.c_str()); + return PathIsDirectory(path.c_str()); #endif } From c2de1a8a52d21a37ee49ecf21be16abc9b3c0f09 Mon Sep 17 00:00:00 2001 From: Kimmo Varis Date: Mon, 31 Jan 2011 22:49:52 +0200 Subject: [PATCH 165/165] Convert "too many configurations" message to information message. The "too many configurations"-message is currently only printed to the log. So it won't be seen by users integrating Cppcheck using XML error file. It is also easily missed in the GUI as it only shows up in the checking log. Making it a information message it shows up with the other errors and tells user that file was not completely checked. Ticket #2527 (Make "too many configurations" message an error message) --- lib/cppcheck.cpp | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/lib/cppcheck.cpp b/lib/cppcheck.cpp index 62719d6c6..db0a15105 100644 --- a/lib/cppcheck.cpp +++ b/lib/cppcheck.cpp @@ -151,13 +151,21 @@ unsigned int CppCheck::check() // was used. if (!_settings._force && checkCount > 11) { - if (_settings._errorsOnly == false) - { - const std::string fixedpath = Path::toNativeSeparators(fname); - _errorLogger.reportOut(std::string("Bailing out from checking ") + fixedpath + - ": Too many configurations. Recheck this file with --force if you want to check them all."); - } - + const std::string fixedpath = Path::toNativeSeparators(fname); + ErrorLogger::ErrorMessage::FileLocation location; + location.setfile(fixedpath); + std::list loclist; + loclist.push_back(location); + const std::string msg("Interrupted checking because of too many #ifdef configurations.\n" + "The checking of the file was interrupted because there were too many " + "#ifdef configurations. Checking of all #ifdef configurations can be forced " + "by --force command line option or from GUI preferences. However that may " + "increase the checking time."); + ErrorLogger::ErrorMessage errmsg(loclist, + Severity::information, + msg, + "toomanyconfigs"); + _errorLogger.reportErr(errmsg); break; }