Checkmemleakautovar: fix crash and FP (#2196)

This fixes crashes found by daca where valueType() is NULL. Also,
somewhat related, it removes warnings when casting to a type that is
unknown to cppcheck, for example, there is no longer a warning for the
following code:

	void* f() {
		void *x = malloc(1);
		return (mytype)x;
	}
This commit is contained in:
Rikard Falkeborn 2019-09-21 14:59:54 +02:00 committed by Sebastian
parent 5ac0b0e752
commit 46ac0d79c1
3 changed files with 27 additions and 3 deletions

View File

@ -465,7 +465,7 @@ $(libcppdir)/ctu.o: lib/ctu.cpp externals/tinyxml/tinyxml2.h lib/astutils.h lib/
$(libcppdir)/errorlogger.o: lib/errorlogger.cpp externals/tinyxml/tinyxml2.h lib/analyzerinfo.h lib/check.h lib/config.h lib/cppcheck.h lib/errorlogger.h lib/importproject.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/suppressions.h lib/templatesimplifier.h lib/timer.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/valueflow.h $(libcppdir)/errorlogger.o: lib/errorlogger.cpp externals/tinyxml/tinyxml2.h lib/analyzerinfo.h lib/check.h lib/config.h lib/cppcheck.h lib/errorlogger.h lib/importproject.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/suppressions.h lib/templatesimplifier.h lib/timer.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/valueflow.h
$(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CPPFILESDIR) $(CXXFLAGS) $(UNDEF_STRICT_ANSI) -c -o $(libcppdir)/errorlogger.o $(libcppdir)/errorlogger.cpp $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CPPFILESDIR) $(CXXFLAGS) $(UNDEF_STRICT_ANSI) -c -o $(libcppdir)/errorlogger.o $(libcppdir)/errorlogger.cpp
$(libcppdir)/exprengine.o: lib/exprengine.cpp lib/config.h lib/errorlogger.h lib/exprengine.h lib/importproject.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/standards.h lib/suppressions.h lib/symboldatabase.h lib/templatesimplifier.h lib/timer.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/valueflow.h $(libcppdir)/exprengine.o: lib/exprengine.cpp lib/astutils.h lib/config.h lib/errorlogger.h lib/exprengine.h lib/importproject.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/standards.h lib/suppressions.h lib/symboldatabase.h lib/templatesimplifier.h lib/timer.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/valueflow.h
$(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CPPFILESDIR) $(CXXFLAGS) $(UNDEF_STRICT_ANSI) -c -o $(libcppdir)/exprengine.o $(libcppdir)/exprengine.cpp $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CPPFILESDIR) $(CXXFLAGS) $(UNDEF_STRICT_ANSI) -c -o $(libcppdir)/exprengine.o $(libcppdir)/exprengine.cpp
$(libcppdir)/importproject.o: lib/importproject.cpp externals/picojson.h externals/tinyxml/tinyxml2.h lib/config.h lib/errorlogger.h lib/importproject.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/suppressions.h lib/templatesimplifier.h lib/timer.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/valueflow.h $(libcppdir)/importproject.o: lib/importproject.cpp externals/picojson.h externals/tinyxml/tinyxml2.h lib/config.h lib/errorlogger.h lib/importproject.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/suppressions.h lib/templatesimplifier.h lib/timer.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/valueflow.h
@ -603,7 +603,7 @@ test/testinternal.o: test/testinternal.cpp lib/check.h lib/checkinternal.h lib/c
test/testio.o: test/testio.cpp lib/check.h lib/checkio.h lib/config.h lib/errorlogger.h lib/importproject.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/standards.h lib/suppressions.h lib/templatesimplifier.h lib/timer.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/valueflow.h test/testsuite.h test/testio.o: test/testio.cpp lib/check.h lib/checkio.h lib/config.h lib/errorlogger.h lib/importproject.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/standards.h lib/suppressions.h lib/templatesimplifier.h lib/timer.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/valueflow.h test/testsuite.h
$(CXX) ${INCLUDE_FOR_TEST} $(CPPFLAGS) $(CPPFILESDIR) $(CXXFLAGS) $(UNDEF_STRICT_ANSI) -c -o test/testio.o test/testio.cpp $(CXX) ${INCLUDE_FOR_TEST} $(CPPFLAGS) $(CPPFILESDIR) $(CXXFLAGS) $(UNDEF_STRICT_ANSI) -c -o test/testio.o test/testio.cpp
test/testleakautovar.o: test/testleakautovar.cpp externals/simplecpp/simplecpp.h lib/check.h lib/checkleakautovar.h lib/config.h lib/errorlogger.h lib/importproject.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/standards.h lib/suppressions.h lib/templatesimplifier.h lib/timer.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/valueflow.h test/testsuite.h test/testleakautovar.o: test/testleakautovar.cpp externals/simplecpp/simplecpp.h externals/tinyxml/tinyxml2.h lib/check.h lib/checkleakautovar.h lib/config.h lib/errorlogger.h lib/importproject.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/standards.h lib/suppressions.h lib/templatesimplifier.h lib/timer.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/valueflow.h test/testsuite.h
$(CXX) ${INCLUDE_FOR_TEST} $(CPPFLAGS) $(CPPFILESDIR) $(CXXFLAGS) $(UNDEF_STRICT_ANSI) -c -o test/testleakautovar.o test/testleakautovar.cpp $(CXX) ${INCLUDE_FOR_TEST} $(CPPFLAGS) $(CPPFILESDIR) $(CXXFLAGS) $(UNDEF_STRICT_ANSI) -c -o test/testleakautovar.o test/testleakautovar.cpp
test/testlibrary.o: test/testlibrary.cpp externals/tinyxml/tinyxml2.h lib/config.h lib/errorlogger.h lib/importproject.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/standards.h lib/suppressions.h lib/templatesimplifier.h lib/timer.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/valueflow.h test/testsuite.h test/testlibrary.o: test/testlibrary.cpp externals/tinyxml/tinyxml2.h lib/config.h lib/errorlogger.h lib/importproject.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/standards.h lib/suppressions.h lib/templatesimplifier.h lib/timer.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/valueflow.h test/testsuite.h

View File

@ -936,7 +936,10 @@ void CheckLeakAutoVar::ret(const Token *tok, const VarInfo &varInfo)
continue; continue;
tok2 = tok2->next(); tok2 = tok2->next();
while (tok2 && tok2->isCast() && (tok2->valueType() && (tok2->valueType()->pointer || (tok2->valueType()->typeSize(*mSettings) >= mSettings->sizeof_pointer)))) while (tok2 && tok2->isCast() && tok2->valueType() &&
(tok2->valueType()->pointer ||
(tok2->valueType()->typeSize(*mSettings) == 0) ||
(tok2->valueType()->typeSize(*mSettings) >= mSettings->sizeof_pointer)))
tok2 = tok2->astOperand2() ? tok2->astOperand2() : tok2->astOperand1(); tok2 = tok2->astOperand2() ? tok2->astOperand2() : tok2->astOperand1();
if (Token::Match(tok2, "%varid%", varid)) if (Token::Match(tok2, "%varid%", varid))
tok2 = tok2->next(); tok2 = tok2->next();

View File

@ -24,6 +24,7 @@
#include "tokenize.h" #include "tokenize.h"
#include <simplecpp.h> #include <simplecpp.h>
#include <tinyxml2.h>
#include <vector> #include <vector>
class TestLeakAutoVar : public TestFixture { class TestLeakAutoVar : public TestFixture {
@ -47,6 +48,14 @@ private:
settings.library.smartPointers.insert("std::shared_ptr"); settings.library.smartPointers.insert("std::shared_ptr");
settings.library.smartPointers.insert("std::unique_ptr"); settings.library.smartPointers.insert("std::unique_ptr");
const char xmldata[] = "<?xml version=\"1.0\"?>\n"
"<def>\n"
" <podtype name=\"uint8_t\" sign=\"u\" size=\"1\"/>\n"
"</def>";
tinyxml2::XMLDocument doc;
doc.Parse(xmldata, sizeof(xmldata));
settings.library.load(doc);
// Assign // Assign
TEST_CASE(assign1); TEST_CASE(assign1);
TEST_CASE(assign2); TEST_CASE(assign2);
@ -1735,6 +1744,18 @@ private:
" return (void*)(short)x;\n" " return (void*)(short)x;\n"
"}", true); "}", true);
ASSERT_EQUALS("[test.cpp:3]: (error) Memory leak: x\n", errout.str()); ASSERT_EQUALS("[test.cpp:3]: (error) Memory leak: x\n", errout.str());
check("void* f() {\n"
" void *x = malloc(1);\n"
" return (mytype)x;\n"
"}", true);
ASSERT_EQUALS("", errout.str());
check("void* f() {\n" // Do not crash
" void *x = malloc(1);\n"
" return (mytype)y;\n"
"}", true);
ASSERT_EQUALS("[test.cpp:3]: (error) Memory leak: x\n", errout.str());
} }
void test1() { // 3809 void test1() { // 3809