diff --git a/Makefile b/Makefile index 9153bf4b3..6624500a1 100644 --- a/Makefile +++ b/Makefile @@ -518,7 +518,7 @@ $(libcppdir)/checkfunctions.o: lib/checkfunctions.cpp lib/addoninfo.h lib/astuti $(libcppdir)/checkinternal.o: lib/checkinternal.cpp lib/addoninfo.h lib/astutils.h lib/check.h lib/checkinternal.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/suppressions.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkinternal.cpp -$(libcppdir)/checkio.o: lib/checkio.cpp lib/addoninfo.h lib/check.h lib/checkio.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/sourcelocation.h lib/standards.h lib/suppressions.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h +$(libcppdir)/checkio.o: lib/checkio.cpp lib/addoninfo.h lib/astutils.h lib/check.h lib/checkio.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/suppressions.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkio.cpp $(libcppdir)/checkleakautovar.o: lib/checkleakautovar.cpp lib/addoninfo.h lib/astutils.h lib/check.h lib/checkleakautovar.h lib/checkmemoryleak.h lib/checknullpointer.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/suppressions.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h diff --git a/lib/checkio.cpp b/lib/checkio.cpp index 2d52f9ad4..a3805dc7a 100644 --- a/lib/checkio.cpp +++ b/lib/checkio.cpp @@ -19,6 +19,7 @@ //--------------------------------------------------------------------------- #include "checkio.h" +#include "astutils.h" #include "errortypes.h" #include "library.h" #include "mathlib.h" @@ -152,6 +153,10 @@ void CheckIO::checkFileUsage() for (const Scope * scope : symbolDatabase->functionScopes) { int indent = 0; for (const Token *tok = scope->bodyStart; tok != scope->bodyEnd; tok = tok->next()) { + if (Token::Match(tok, "%name% (") && isUnevaluated(tok)) { + tok = tok->linkAt(1); + continue; + } if (tok->str() == "{") indent++; else if (tok->str() == "}") { diff --git a/lib/checkleakautovar.cpp b/lib/checkleakautovar.cpp index 2f9f5909d..bbfcd4e24 100644 --- a/lib/checkleakautovar.cpp +++ b/lib/checkleakautovar.cpp @@ -350,6 +350,11 @@ bool CheckLeakAutoVar::checkScope(const Token * const startToken, if (!tok || tok == endToken) break; + if (Token::Match(tok, "%name% (") && isUnevaluated(tok)) { + tok = tok->linkAt(1); + continue; + } + if (Token::Match(tok, "const %type%")) tok = tok->tokAt(2); diff --git a/man/manual.md b/man/manual.md index bc710d6d9..298a51749 100644 --- a/man/manual.md +++ b/man/manual.md @@ -966,7 +966,7 @@ To use a .cfg file shipped with cppcheck, pass the `--library=` option. The | avr.cfg | | | bento4.cfg | [Bento4](http://www.bento4.com/) | | boost.cfg | [Boost](http://www.boost.org/)| -| bsd.cfg | [*BSD](https://www.freebsd.org/) | +| bsd.cfg | [BSD](https://www.freebsd.org/) | | cairo.cfg | [cairo](https://www.cairographics.org/) | | cppcheck-lib.cfg | [Cppcheck](http://cppcheck.net/) | Used in selfcheck of the Cppcheck code base | cppunit.cfg | [CppUnit](https://sourceforge.net/projects/cppunit/) | @@ -974,7 +974,7 @@ To use a .cfg file shipped with cppcheck, pass the `--library=` option. The | embedded_sql.cfg | | | emscripten.cfg | | | ginac.cfg | | -| gnu.cfg | [*nix](https://www.gnu.org/) | +| gnu.cfg | [GNU](https://www.gnu.org/) | | googletest.cfg | [GoogleTest](https://github.com/google/googletest) | | gtk.cfg | [GTK](https://www.gtk.org/) | | icu.cfg | | @@ -997,7 +997,7 @@ To use a .cfg file shipped with cppcheck, pass the `--library=` option. The | pcre.cfg | [PCRE](https://pcre.org/) | | posix.cfg | [POSIX](https://pubs.opengroup.org/onlinepubs/9699919799/) | | python.cfg | | -| qt.cfg | [Qt](https://www.qt.io/) | +| qt.cfg | [Qt](https://doc.qt.io/qt.html) | | ruby.cfg | | | sdl.cfg | | | sfml.cfg | | diff --git a/test/cfg/std.cpp b/test/cfg/std.cpp index b8305bb62..030f46f3f 100644 --- a/test/cfg/std.cpp +++ b/test/cfg/std.cpp @@ -602,6 +602,15 @@ void nullPointer_localtime_s(const std::time_t *restrict time, struct tm *restri (void)std::localtime_s(time, NULL); (void)std::localtime_s(time, result); } + +void memleak_localtime_s(const std::time_t *restrict time, struct tm *restrict result) +{ + const time_t t = time(0); + const struct tm* const now = new tm(); + if (localtime_s(now, &t) == 0) + std::cout << now->tm_mday << std::endl; + // cppcheck-suppress memleak +} #endif // __STDC_LIB_EXT1__ size_t nullPointer_strftime(char *s, size_t max, const char *fmt, const struct tm *p) diff --git a/test/testio.cpp b/test/testio.cpp index 8f89f0a7b..4f01d6b6f 100644 --- a/test/testio.cpp +++ b/test/testio.cpp @@ -549,6 +549,14 @@ private: " fclose(f[1]);\n" "}"); ASSERT_EQUALS("", errout.str()); + + // #12236 + check("void f() {\n" + " FILE* f = fopen(\"abc\", \"r\");\n" + " decltype(fclose(f)) y;\n" + " y = fclose(f);\n" + "}\n"); + ASSERT_EQUALS("", errout.str()); } void fileIOwithoutPositioning() { diff --git a/test/testleakautovar.cpp b/test/testleakautovar.cpp index 6ca90726d..ed6983ec3 100644 --- a/test/testleakautovar.cpp +++ b/test/testleakautovar.cpp @@ -111,6 +111,7 @@ private: TEST_CASE(deallocuse10); TEST_CASE(deallocuse11); // #8302 TEST_CASE(deallocuse12); + TEST_CASE(deallocuse13); TEST_CASE(doublefree1); TEST_CASE(doublefree2); @@ -127,6 +128,7 @@ private: TEST_CASE(doublefree13); // #11008 TEST_CASE(doublefree14); // #9708 TEST_CASE(doublefree15); + TEST_CASE(doublefree16); // exit TEST_CASE(exit1); @@ -908,6 +910,20 @@ private: ASSERT_EQUALS("", errout.str()); } + void deallocuse13() { + check("void f() {\n" // #9695 + " auto* a = new int[2];\n" + " delete[] a;\n" + " a[1] = 0;\n" + " auto* b = static_cast(malloc(8));\n" + " free(b);\n" + " b[1] = 0;\n" + "}\n", true); + ASSERT_EQUALS("[test.cpp:4]: (error) Dereferencing 'a' after it is deallocated / released\n" + "[test.cpp:7]: (error) Dereferencing 'b' after it is deallocated / released\n", + errout.str()); + } + void doublefree1() { // #3895 check("void f(char *p) {\n" " if (x)\n" @@ -1566,6 +1582,15 @@ private: ASSERT_EQUALS("", errout.str()); } + void doublefree16() { // #12236 + check("void f() {\n" + " FILE* f = fopen(\"abc\", \"r\");\n" + " decltype(fclose(f)) y;\n" + " y = fclose(f);\n" + "}\n"); + ASSERT_EQUALS("", errout.str()); + } + void exit1() { check("void f() {\n" " char *p = malloc(10);\n"