diff --git a/Makefile b/Makefile index e33c888013c..0446f6a67b4 100644 --- a/Makefile +++ b/Makefile @@ -448,7 +448,7 @@ validateRules: ###### Build -$(libcppdir)/valueflow.o: lib/valueflow.cpp lib/addoninfo.h lib/analyzer.h lib/astutils.h lib/calculate.h lib/check.h lib/checkuninitvar.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/findtoken.h lib/forwardanalyzer.h lib/infer.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/programmemory.h lib/reverseanalyzer.h lib/settings.h lib/smallvector.h lib/sourcelocation.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 lib/valueptr.h lib/vf_analyzers.h lib/vf_common.h lib/vf_settokenvalue.h lib/vfvalue.h +$(libcppdir)/valueflow.o: lib/valueflow.cpp lib/addoninfo.h lib/analyzer.h lib/astutils.h lib/calculate.h lib/check.h lib/checkuninitvar.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/findtoken.h lib/forwardanalyzer.h lib/infer.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/programmemory.h lib/reverseanalyzer.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/suppressions.h lib/symboldatabase.h lib/templatesimplifier.h lib/timer.h lib/token.h lib/tokenlist.h lib/utils.h lib/valueflow.h lib/valueptr.h lib/vf_analyzers.h lib/vf_common.h lib/vf_settokenvalue.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/valueflow.cpp $(libcppdir)/tokenize.o: lib/tokenize.cpp externals/simplecpp/simplecpp.h lib/addoninfo.h lib/astutils.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/preprocessor.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/summaries.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 lib/vfvalue.h @@ -463,7 +463,7 @@ $(libcppdir)/addoninfo.o: lib/addoninfo.cpp externals/picojson/picojson.h lib/ad $(libcppdir)/analyzerinfo.o: lib/analyzerinfo.cpp externals/tinyxml2/tinyxml2.h lib/analyzerinfo.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/filesettings.h lib/mathlib.h lib/path.h lib/platform.h lib/standards.h lib/utils.h lib/xml.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/analyzerinfo.cpp -$(libcppdir)/astutils.o: lib/astutils.cpp lib/addoninfo.h lib/astutils.h lib/check.h lib/checkclass.h lib/config.h lib/errortypes.h lib/findtoken.h lib/infer.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/valueflow.h lib/valueptr.h lib/vfvalue.h +$(libcppdir)/astutils.o: lib/astutils.cpp lib/addoninfo.h lib/astutils.h lib/check.h lib/checkclass.h lib/config.h lib/errortypes.h lib/findtoken.h lib/infer.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/utils.h lib/valueflow.h lib/valueptr.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/astutils.cpp $(libcppdir)/check.o: lib/check.cpp lib/addoninfo.h lib/check.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/standards.h lib/suppressions.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h @@ -718,7 +718,7 @@ test/testbool.o: test/testbool.cpp externals/simplecpp/simplecpp.h lib/addoninfo test/testboost.o: test/testboost.cpp externals/simplecpp/simplecpp.h lib/addoninfo.h lib/check.h lib/checkboost.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/preprocessor.h lib/settings.h lib/standards.h lib/suppressions.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testboost.cpp -test/testbufferoverrun.o: test/testbufferoverrun.cpp externals/simplecpp/simplecpp.h lib/addoninfo.h lib/check.h lib/checkbufferoverrun.h lib/color.h lib/config.h lib/ctu.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/preprocessor.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 test/fixture.h test/helpers.h +test/testbufferoverrun.o: test/testbufferoverrun.cpp externals/simplecpp/simplecpp.h lib/addoninfo.h lib/check.h lib/checkbufferoverrun.h lib/color.h lib/config.h lib/ctu.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/preprocessor.h lib/settings.h lib/standards.h lib/suppressions.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testbufferoverrun.cpp test/testcharvar.o: test/testcharvar.cpp externals/simplecpp/simplecpp.h lib/addoninfo.h lib/check.h lib/checkother.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/preprocessor.h lib/settings.h lib/standards.h lib/suppressions.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h @@ -844,7 +844,7 @@ test/testsizeof.o: test/testsizeof.cpp externals/simplecpp/simplecpp.h lib/addon test/teststandards.o: test/teststandards.cpp lib/addoninfo.h lib/check.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/standards.h lib/suppressions.h lib/utils.h test/fixture.h $(CXX) ${INCLUDE_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/teststandards.cpp -test/teststl.o: test/teststl.cpp externals/simplecpp/simplecpp.h lib/addoninfo.h lib/check.h lib/checkstl.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/preprocessor.h lib/settings.h lib/standards.h lib/suppressions.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h +test/teststl.o: test/teststl.cpp externals/simplecpp/simplecpp.h lib/addoninfo.h lib/check.h lib/checkstl.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/preprocessor.h lib/settings.h lib/standards.h lib/suppressions.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/teststl.cpp test/teststring.o: test/teststring.cpp externals/simplecpp/simplecpp.h lib/addoninfo.h lib/check.h lib/checkstring.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/preprocessor.h lib/settings.h lib/standards.h lib/suppressions.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h @@ -877,7 +877,7 @@ test/testtokenlist.o: test/testtokenlist.cpp externals/simplecpp/simplecpp.h lib test/testtokenrange.o: test/testtokenrange.cpp externals/simplecpp/simplecpp.h lib/addoninfo.h lib/check.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/preprocessor.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/tokenrange.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testtokenrange.cpp -test/testtype.o: test/testtype.cpp externals/simplecpp/simplecpp.h lib/addoninfo.h lib/check.h lib/checktype.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/preprocessor.h lib/settings.h lib/standards.h lib/suppressions.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h +test/testtype.o: test/testtype.cpp externals/simplecpp/simplecpp.h lib/addoninfo.h lib/check.h lib/checktype.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/preprocessor.h lib/settings.h lib/standards.h lib/suppressions.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testtype.cpp test/testuninitvar.o: test/testuninitvar.cpp externals/simplecpp/simplecpp.h lib/addoninfo.h lib/check.h lib/checkuninitvar.h lib/color.h lib/config.h lib/ctu.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/preprocessor.h lib/settings.h lib/standards.h lib/suppressions.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h diff --git a/lib/check64bit.cpp b/lib/check64bit.cpp index 02196cfc043..166151cb339 100644 --- a/lib/check64bit.cpp +++ b/lib/check64bit.cpp @@ -161,3 +161,18 @@ void Check64BitPortability::returnIntegerError(const Token *tok) "and Linux they are of different width. In worst case you end up casting 64-bit integer down to 32-bit pointer. " "The safe way is to always return a pointer.", CWE758, Certainty::normal); } + +void Check64BitPortability::runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLogger) +{ + Check64BitPortability check64BitPortability(&tokenizer, &tokenizer.getSettings(), errorLogger); + check64BitPortability.pointerassignment(); +} + +void Check64BitPortability::getErrorMessages(ErrorLogger *errorLogger, const Settings *settings) const +{ + Check64BitPortability c(nullptr, settings, errorLogger); + c.assignmentAddressToIntegerError(nullptr); + c.assignmentIntegerToAddressError(nullptr); + c.returnIntegerError(nullptr); + c.returnPointerError(nullptr); +} diff --git a/lib/check64bit.h b/lib/check64bit.h index 9b154fa1912..2f9c791c2eb 100644 --- a/lib/check64bit.h +++ b/lib/check64bit.h @@ -24,14 +24,13 @@ #include "check.h" #include "config.h" -#include "tokenize.h" #include class ErrorLogger; class Settings; class Token; - +class Tokenizer; /// @addtogroup Checks /// @{ @@ -53,10 +52,7 @@ class CPPCHECKLIB Check64BitPortability : public Check { : Check(myName(), tokenizer, settings, errorLogger) {} /** @brief Run checks against the normal token list */ - void runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLogger) override { - Check64BitPortability check64BitPortability(&tokenizer, &tokenizer.getSettings(), errorLogger); - check64BitPortability.pointerassignment(); - } + void runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLogger) override; /** Check for pointer assignment */ void pointerassignment(); @@ -66,13 +62,7 @@ class CPPCHECKLIB Check64BitPortability : public Check { void returnIntegerError(const Token *tok); void returnPointerError(const Token *tok); - void getErrorMessages(ErrorLogger *errorLogger, const Settings *settings) const override { - Check64BitPortability c(nullptr, settings, errorLogger); - c.assignmentAddressToIntegerError(nullptr); - c.assignmentIntegerToAddressError(nullptr); - c.returnIntegerError(nullptr); - c.returnPointerError(nullptr); - } + void getErrorMessages(ErrorLogger *errorLogger, const Settings *settings) const override; static std::string myName() { return "64-bit portability"; diff --git a/lib/checkassert.cpp b/lib/checkassert.cpp index 9020e9002df..8c82742ef4a 100644 --- a/lib/checkassert.cpp +++ b/lib/checkassert.cpp @@ -182,3 +182,16 @@ bool CheckAssert::inSameScope(const Token* returnTok, const Token* assignTok) // TODO: even if a return is in the same scope, the assignment might not affect it. return returnTok->scope() == assignTok->scope(); } + +void CheckAssert::runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLogger) +{ + CheckAssert checkAssert(&tokenizer, &tokenizer.getSettings(), errorLogger); + checkAssert.assertWithSideEffects(); +} + +void CheckAssert::getErrorMessages(ErrorLogger *errorLogger, const Settings *settings) const +{ + CheckAssert c(nullptr, settings, errorLogger); + c.sideEffectInAssertError(nullptr, "function"); + c.assignmentInAssertError(nullptr, "var"); +} diff --git a/lib/checkassert.h b/lib/checkassert.h index ff8ac491e96..e34237b0f5e 100644 --- a/lib/checkassert.h +++ b/lib/checkassert.h @@ -24,7 +24,6 @@ #include "check.h" #include "config.h" -#include "tokenize.h" #include @@ -32,6 +31,7 @@ class ErrorLogger; class Scope; class Settings; class Token; +class Tokenizer; /// @addtogroup Checks /// @{ @@ -49,10 +49,7 @@ class CPPCHECKLIB CheckAssert : public Check { : Check(myName(), tokenizer, settings, errorLogger) {} /** run checks, the token list is not simplified */ - void runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLogger) override { - CheckAssert checkAssert(&tokenizer, &tokenizer.getSettings(), errorLogger); - checkAssert.assertWithSideEffects(); - } + void runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLogger) override; void assertWithSideEffects(); @@ -62,11 +59,7 @@ class CPPCHECKLIB CheckAssert : public Check { void sideEffectInAssertError(const Token *tok, const std::string& functionName); void assignmentInAssertError(const Token *tok, const std::string &varname); - void getErrorMessages(ErrorLogger *errorLogger, const Settings *settings) const override { - CheckAssert c(nullptr, settings, errorLogger); - c.sideEffectInAssertError(nullptr, "function"); - c.assignmentInAssertError(nullptr, "var"); - } + void getErrorMessages(ErrorLogger *errorLogger, const Settings *settings) const override; static std::string myName() { return "Assert"; diff --git a/lib/checkautovariables.cpp b/lib/checkautovariables.cpp index 7366cd1bd5a..fea4d1c2533 100644 --- a/lib/checkautovariables.cpp +++ b/lib/checkautovariables.cpp @@ -787,3 +787,28 @@ void CheckAutoVariables::errorInvalidDeallocation(const Token *tok, const ValueF "The deallocation of " + type + " results in undefined behaviour. You should only free memory " "that has been allocated dynamically.", CWE590, Certainty::normal); } + +void CheckAutoVariables::runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLogger) +{ + CheckAutoVariables checkAutoVariables(&tokenizer, &tokenizer.getSettings(), errorLogger); + checkAutoVariables.assignFunctionArg(); + checkAutoVariables.checkVarLifetime(); + checkAutoVariables.autoVariables(); +} + +void CheckAutoVariables::getErrorMessages(ErrorLogger *errorLogger, const Settings *settings) const +{ + CheckAutoVariables c(nullptr,settings,errorLogger); + c.errorAutoVariableAssignment(nullptr, false); + c.errorReturnReference(nullptr, ErrorPath{}, false); + c.errorDanglingReference(nullptr, nullptr, ErrorPath{}); + c.errorReturnTempReference(nullptr, ErrorPath{}, false); + c.errorDanglingTempReference(nullptr, ErrorPath{}, false); + c.errorInvalidDeallocation(nullptr, nullptr); + c.errorUselessAssignmentArg(nullptr); + c.errorUselessAssignmentPtrArg(nullptr); + c.errorReturnDanglingLifetime(nullptr, nullptr); + c.errorInvalidLifetime(nullptr, nullptr); + c.errorDanglngLifetime(nullptr, nullptr); + c.errorDanglingTemporaryLifetime(nullptr, nullptr, nullptr); +} diff --git a/lib/checkautovariables.h b/lib/checkautovariables.h index fb4f116d5a0..5e6898e5b4e 100644 --- a/lib/checkautovariables.h +++ b/lib/checkautovariables.h @@ -25,7 +25,6 @@ #include "check.h" #include "config.h" #include "errortypes.h" -#include "tokenize.h" #include #include @@ -34,6 +33,7 @@ class Settings; class Token; class ErrorLogger; class Variable; +class Tokenizer; namespace ValueFlow { class Value; @@ -55,12 +55,7 @@ class CPPCHECKLIB CheckAutoVariables : public Check { : Check(myName(), tokenizer, settings, errorLogger) {} /** @brief Run checks against the normal token list */ - void runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLogger) override { - CheckAutoVariables checkAutoVariables(&tokenizer, &tokenizer.getSettings(), errorLogger); - checkAutoVariables.assignFunctionArg(); - checkAutoVariables.checkVarLifetime(); - checkAutoVariables.autoVariables(); - } + void runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLogger) override; /** assign function argument */ void assignFunctionArg(); @@ -90,21 +85,7 @@ class CPPCHECKLIB CheckAutoVariables : public Check { void errorUselessAssignmentArg(const Token *tok); void errorUselessAssignmentPtrArg(const Token *tok); - void getErrorMessages(ErrorLogger *errorLogger, const Settings *settings) const override { - CheckAutoVariables c(nullptr,settings,errorLogger); - c.errorAutoVariableAssignment(nullptr, false); - c.errorReturnReference(nullptr, ErrorPath{}, false); - c.errorDanglingReference(nullptr, nullptr, ErrorPath{}); - c.errorReturnTempReference(nullptr, ErrorPath{}, false); - c.errorDanglingTempReference(nullptr, ErrorPath{}, false); - c.errorInvalidDeallocation(nullptr, nullptr); - c.errorUselessAssignmentArg(nullptr); - c.errorUselessAssignmentPtrArg(nullptr); - c.errorReturnDanglingLifetime(nullptr, nullptr); - c.errorInvalidLifetime(nullptr, nullptr); - c.errorDanglngLifetime(nullptr, nullptr); - c.errorDanglingTemporaryLifetime(nullptr, nullptr, nullptr); - } + void getErrorMessages(ErrorLogger *errorLogger, const Settings *settings) const override; static std::string myName() { return "Auto Variables"; diff --git a/lib/checkbool.cpp b/lib/checkbool.cpp index acc9b5dc4e1..20d82c23c57 100644 --- a/lib/checkbool.cpp +++ b/lib/checkbool.cpp @@ -517,3 +517,36 @@ void CheckBool::returnValueBoolError(const Token *tok) { reportError(tok, Severity::style, "returnNonBoolInBooleanFunction", "Non-boolean value returned from function returning bool"); } + +void CheckBool::runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLogger) +{ + CheckBool checkBool(&tokenizer, &tokenizer.getSettings(), errorLogger); + + // Checks + checkBool.checkComparisonOfBoolExpressionWithInt(); + checkBool.checkComparisonOfBoolWithInt(); + checkBool.checkAssignBoolToFloat(); + checkBool.pointerArithBool(); + checkBool.returnValueOfFunctionReturningBool(); + checkBool.checkComparisonOfFuncReturningBool(); + checkBool.checkComparisonOfBoolWithBool(); + checkBool.checkIncrementBoolean(); + checkBool.checkAssignBoolToPointer(); + checkBool.checkBitwiseOnBoolean(); +} + +void CheckBool::getErrorMessages(ErrorLogger *errorLogger, const Settings *settings) const +{ + CheckBool c(nullptr, settings, errorLogger); + c.assignBoolToPointerError(nullptr); + c.assignBoolToFloatError(nullptr); + c.comparisonOfFuncReturningBoolError(nullptr, "func_name"); + c.comparisonOfTwoFuncsReturningBoolError(nullptr, "func_name1", "func_name2"); + c.comparisonOfBoolWithBoolError(nullptr, "var_name"); + c.incrementBooleanError(nullptr); + c.bitwiseOnBooleanError(nullptr, "expression", "&&"); + c.comparisonOfBoolExpressionWithIntError(nullptr, true); + c.pointerArithBoolError(nullptr); + c.comparisonOfBoolWithInvalidComparator(nullptr, "expression"); + c.returnValueBoolError(nullptr); +} diff --git a/lib/checkbool.h b/lib/checkbool.h index 8a4b151829e..996158c3050 100644 --- a/lib/checkbool.h +++ b/lib/checkbool.h @@ -24,13 +24,13 @@ #include "check.h" #include "config.h" -#include "tokenize.h" #include class ErrorLogger; class Settings; class Token; +class Tokenizer; /// @addtogroup Checks /// @{ @@ -49,21 +49,7 @@ class CPPCHECKLIB CheckBool : public Check { : Check(myName(), tokenizer, settings, errorLogger) {} /** @brief Run checks against the normal token list */ - void runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLogger) override { - CheckBool checkBool(&tokenizer, &tokenizer.getSettings(), errorLogger); - - // Checks - checkBool.checkComparisonOfBoolExpressionWithInt(); - checkBool.checkComparisonOfBoolWithInt(); - checkBool.checkAssignBoolToFloat(); - checkBool.pointerArithBool(); - checkBool.returnValueOfFunctionReturningBool(); - checkBool.checkComparisonOfFuncReturningBool(); - checkBool.checkComparisonOfBoolWithBool(); - checkBool.checkIncrementBoolean(); - checkBool.checkAssignBoolToPointer(); - checkBool.checkBitwiseOnBoolean(); - } + void runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLogger) override; /** @brief %Check for comparison of function returning bool*/ void checkComparisonOfFuncReturningBool(); @@ -109,20 +95,7 @@ class CPPCHECKLIB CheckBool : public Check { void pointerArithBoolError(const Token *tok); void returnValueBoolError(const Token *tok); - void getErrorMessages(ErrorLogger *errorLogger, const Settings *settings) const override { - CheckBool c(nullptr, settings, errorLogger); - c.assignBoolToPointerError(nullptr); - c.assignBoolToFloatError(nullptr); - c.comparisonOfFuncReturningBoolError(nullptr, "func_name"); - c.comparisonOfTwoFuncsReturningBoolError(nullptr, "func_name1", "func_name2"); - c.comparisonOfBoolWithBoolError(nullptr, "var_name"); - c.incrementBooleanError(nullptr); - c.bitwiseOnBooleanError(nullptr, "expression", "&&"); - c.comparisonOfBoolExpressionWithIntError(nullptr, true); - c.pointerArithBoolError(nullptr); - c.comparisonOfBoolWithInvalidComparator(nullptr, "expression"); - c.returnValueBoolError(nullptr); - } + void getErrorMessages(ErrorLogger *errorLogger, const Settings *settings) const override; static std::string myName() { return "Boolean"; diff --git a/lib/checkboost.cpp b/lib/checkboost.cpp index 1c38eb05c00..a246426f8b5 100644 --- a/lib/checkboost.cpp +++ b/lib/checkboost.cpp @@ -21,6 +21,7 @@ #include "errortypes.h" #include "symboldatabase.h" #include "token.h" +#include "tokenize.h" #include @@ -64,3 +65,18 @@ void CheckBoost::boostForeachError(const Token *tok) "BOOST_FOREACH caches the end() iterator. It's undefined behavior if you modify the container inside.", CWE664, Certainty::normal ); } + +void CheckBoost::runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLogger) +{ + if (!tokenizer.isCPP()) + return; + + CheckBoost checkBoost(&tokenizer, &tokenizer.getSettings(), errorLogger); + checkBoost.checkBoostForeachModification(); +} + +void CheckBoost::getErrorMessages(ErrorLogger *errorLogger, const Settings *settings) const +{ + CheckBoost c(nullptr, settings, errorLogger); + c.boostForeachError(nullptr); +} diff --git a/lib/checkboost.h b/lib/checkboost.h index f66b0eadfaa..97eb5c3e712 100644 --- a/lib/checkboost.h +++ b/lib/checkboost.h @@ -24,13 +24,13 @@ #include "check.h" #include "config.h" -#include "tokenize.h" #include class ErrorLogger; class Settings; class Token; +class Tokenizer; /// @addtogroup Checks /// @{ @@ -48,23 +48,14 @@ class CPPCHECKLIB CheckBoost : public Check { : Check(myName(), tokenizer, settings, errorLogger) {} /** @brief Run checks against the normal token list */ - void runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLogger) override { - if (!tokenizer.isCPP()) - return; - - CheckBoost checkBoost(&tokenizer, &tokenizer.getSettings(), errorLogger); - checkBoost.checkBoostForeachModification(); - } + void runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLogger) override; /** @brief %Check for container modification while using the BOOST_FOREACH macro */ void checkBoostForeachModification(); void boostForeachError(const Token *tok); - void getErrorMessages(ErrorLogger *errorLogger, const Settings *settings) const override { - CheckBoost c(nullptr, settings, errorLogger); - c.boostForeachError(nullptr); - } + void getErrorMessages(ErrorLogger *errorLogger, const Settings *settings) const override; static std::string myName() { return "Boost usage"; diff --git a/lib/checkbufferoverrun.cpp b/lib/checkbufferoverrun.cpp index 5f3abbb05ab..433eaa49b27 100644 --- a/lib/checkbufferoverrun.cpp +++ b/lib/checkbufferoverrun.cpp @@ -24,6 +24,7 @@ #include "astutils.h" #include "errorlogger.h" +#include "errortypes.h" #include "library.h" #include "mathlib.h" #include "platform.h" @@ -1205,3 +1206,30 @@ void CheckBufferOverrun::negativeMemoryAllocationSizeError(const Token* tok, con reportError(errorPath, inconclusive ? Severity::warning : Severity::error, "negativeMemoryAllocationSize", msg, CWE131, inconclusive ? Certainty::inconclusive : Certainty::normal); } + +void CheckBufferOverrun::runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLogger) +{ + CheckBufferOverrun checkBufferOverrun(&tokenizer, &tokenizer.getSettings(), errorLogger); + checkBufferOverrun.arrayIndex(); + checkBufferOverrun.pointerArithmetic(); + checkBufferOverrun.bufferOverflow(); + checkBufferOverrun.arrayIndexThenCheck(); + checkBufferOverrun.stringNotZeroTerminated(); + checkBufferOverrun.objectIndex(); + checkBufferOverrun.argumentSize(); + checkBufferOverrun.negativeArraySize(); +} + +void CheckBufferOverrun::getErrorMessages(ErrorLogger *errorLogger, const Settings *settings) const +{ + CheckBufferOverrun c(nullptr, settings, errorLogger); + c.arrayIndexError(nullptr, std::vector(), std::vector()); + c.pointerArithmeticError(nullptr, nullptr, nullptr); + c.negativeIndexError(nullptr, std::vector(), std::vector()); + c.arrayIndexThenCheckError(nullptr, "i"); + c.bufferOverflowError(nullptr, nullptr, Certainty::normal); + c.objectIndexError(nullptr, nullptr, true); + c.argumentSizeError(nullptr, "function", 1, "buffer", nullptr, nullptr); + c.negativeMemoryAllocationSizeError(nullptr, nullptr); + c.negativeArraySizeError(nullptr); +} diff --git a/lib/checkbufferoverrun.h b/lib/checkbufferoverrun.h index 8e719a58ceb..0be21fcd33d 100644 --- a/lib/checkbufferoverrun.h +++ b/lib/checkbufferoverrun.h @@ -25,12 +25,10 @@ #include "check.h" #include "config.h" #include "ctu.h" -#include "errortypes.h" #include "mathlib.h" -#include "symboldatabase.h" -#include "tokenize.h" #include "vfvalue.h" +#include #include #include #include @@ -39,6 +37,10 @@ class ErrorLogger; class Settings; class Token; +class Tokenizer; +class Variable; +struct Dimension; +enum class Certainty : std::uint8_t; /// @addtogroup Checks /// @{ @@ -62,30 +64,9 @@ class CPPCHECKLIB CheckBufferOverrun : public Check { CheckBufferOverrun(const Tokenizer *tokenizer, const Settings *settings, ErrorLogger *errorLogger) : Check(myName(), tokenizer, settings, errorLogger) {} - void runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLogger) override { - CheckBufferOverrun checkBufferOverrun(&tokenizer, &tokenizer.getSettings(), errorLogger); - checkBufferOverrun.arrayIndex(); - checkBufferOverrun.pointerArithmetic(); - checkBufferOverrun.bufferOverflow(); - checkBufferOverrun.arrayIndexThenCheck(); - checkBufferOverrun.stringNotZeroTerminated(); - checkBufferOverrun.objectIndex(); - checkBufferOverrun.argumentSize(); - checkBufferOverrun.negativeArraySize(); - } + void runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLogger) override; - void getErrorMessages(ErrorLogger *errorLogger, const Settings *settings) const override { - CheckBufferOverrun c(nullptr, settings, errorLogger); - c.arrayIndexError(nullptr, std::vector(), std::vector()); - c.pointerArithmeticError(nullptr, nullptr, nullptr); - c.negativeIndexError(nullptr, std::vector(), std::vector()); - c.arrayIndexThenCheckError(nullptr, "i"); - c.bufferOverflowError(nullptr, nullptr, Certainty::normal); - c.objectIndexError(nullptr, nullptr, true); - c.argumentSizeError(nullptr, "function", 1, "buffer", nullptr, nullptr); - c.negativeMemoryAllocationSizeError(nullptr, nullptr); - c.negativeArraySizeError(nullptr); - } + void getErrorMessages(ErrorLogger *errorLogger, const Settings *settings) const override; /** @brief Parse current TU and extract file info */ Check::FileInfo *getFileInfo(const Tokenizer &tokenizer, const Settings &settings) const override; diff --git a/lib/checkclass.cpp b/lib/checkclass.cpp index 12488f02f41..a7c775166ac 100644 --- a/lib/checkclass.cpp +++ b/lib/checkclass.cpp @@ -3743,4 +3743,77 @@ bool CheckClass::analyseWholeProgram(const CTU::FileInfo *ctu, const std::list(), "f"); + c.virtualFunctionCallInConstructorError(nullptr, std::list(), "f"); + c.thisUseAfterFree(nullptr, nullptr, nullptr); + c.unsafeClassRefMemberError(nullptr, "UnsafeClass::var"); +} diff --git a/lib/checkclass.h b/lib/checkclass.h index 71ee1e035c1..1242889d6d9 100644 --- a/lib/checkclass.h +++ b/lib/checkclass.h @@ -23,7 +23,6 @@ #include "check.h" #include "config.h" -#include "tokenize.h" #include "symboldatabase.h" #include @@ -35,6 +34,7 @@ class ErrorLogger; class Settings; +class Tokenizer; class Token; /// @addtogroup Checks @@ -59,35 +59,7 @@ class CPPCHECKLIB CheckClass : public Check { CheckClass(const Tokenizer *tokenizer, const Settings *settings, ErrorLogger *errorLogger); /** @brief Run checks on the normal token list */ - void runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLogger) override { - if (tokenizer.isC()) - return; - - CheckClass checkClass(&tokenizer, &tokenizer.getSettings(), errorLogger); - - // can't be a simplified check .. the 'sizeof' is used. - checkClass.checkMemset(); - checkClass.constructors(); - checkClass.privateFunctions(); - checkClass.operatorEqRetRefThis(); - checkClass.thisSubtraction(); - checkClass.operatorEqToSelf(); - checkClass.initializerListOrder(); - checkClass.initializationListUsage(); - checkClass.checkSelfInitialization(); - checkClass.virtualDestructor(); - checkClass.checkConst(); - checkClass.copyconstructors(); - checkClass.checkVirtualFunctionCallInConstructor(); - checkClass.checkDuplInheritedMembers(); - checkClass.checkExplicitConstructors(); - checkClass.checkCopyCtorAndEqOperator(); - checkClass.checkOverride(); - checkClass.checkUselessOverride(); - checkClass.checkReturnByReference(); - checkClass.checkThisUseAfterFree(); - checkClass.checkUnsafeClassRefMember(); - } + void runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLogger) override; /** @brief %Check that all class constructors are ok */ void constructors(); @@ -210,48 +182,7 @@ class CPPCHECKLIB CheckClass : public Check { void unsafeClassRefMemberError(const Token *tok, const std::string &varname); void checkDuplInheritedMembersRecursive(const Type* typeCurrent, const Type* typeBase); - void getErrorMessages(ErrorLogger *errorLogger, const Settings *settings) const override { - CheckClass c(nullptr, settings, errorLogger); - c.noConstructorError(nullptr, "classname", false); - c.noExplicitConstructorError(nullptr, "classname", false); - //c.copyConstructorMallocError(nullptr, 0, "var"); - c.copyConstructorShallowCopyError(nullptr, "var"); - c.noCopyConstructorError(nullptr, false, nullptr, false); - c.noOperatorEqError(nullptr, false, nullptr, false); - c.noDestructorError(nullptr, false, nullptr); - c.uninitVarError(nullptr, false, Function::eConstructor, "classname", "varname", false, false); - c.uninitVarError(nullptr, true, Function::eConstructor, "classname", "varnamepriv", false, false); - c.uninitVarError(nullptr, false, Function::eConstructor, "classname", "varname", true, false); - c.uninitVarError(nullptr, true, Function::eConstructor, "classname", "varnamepriv", true, false); - c.missingMemberCopyError(nullptr, Function::eConstructor, "classname", "varnamepriv"); - c.operatorEqVarError(nullptr, "classname", emptyString, false); - c.unusedPrivateFunctionError(nullptr, "classname", "funcname"); - c.memsetError(nullptr, "memfunc", "classname", "class"); - c.memsetErrorReference(nullptr, "memfunc", "class"); - c.memsetErrorFloat(nullptr, "class"); - c.mallocOnClassWarning(nullptr, "malloc", nullptr); - c.mallocOnClassError(nullptr, "malloc", nullptr, "std::string"); - c.virtualDestructorError(nullptr, "Base", "Derived", false); - c.thisSubtractionError(nullptr); - c.operatorEqRetRefThisError(nullptr); - c.operatorEqMissingReturnStatementError(nullptr, true); - c.operatorEqShouldBeLeftUnimplementedError(nullptr); - c.operatorEqToSelfError(nullptr); - c.checkConstError(nullptr, "class", "function", false); - c.checkConstError(nullptr, "class", "function", true); - c.initializerListError(nullptr, nullptr, "class", "variable"); - c.suggestInitializationList(nullptr, "variable"); - c.selfInitializationError(nullptr, "var"); - c.duplInheritedMembersError(nullptr, nullptr, "class", "class", "variable", false, false); - c.copyCtorAndEqOperatorError(nullptr, "class", false, false); - c.overrideError(nullptr, nullptr); - c.uselessOverrideError(nullptr, nullptr); - c.returnByReferenceError(nullptr, nullptr); - c.pureVirtualFunctionCallInConstructorError(nullptr, std::list(), "f"); - c.virtualFunctionCallInConstructorError(nullptr, std::list(), "f"); - c.thisUseAfterFree(nullptr, nullptr, nullptr); - c.unsafeClassRefMemberError(nullptr, "UnsafeClass::var"); - } + void getErrorMessages(ErrorLogger *errorLogger, const Settings *settings) const override; static std::string myName() { return "Class"; diff --git a/lib/checkcondition.cpp b/lib/checkcondition.cpp index c92a32aae9e..ddfa5a90546 100644 --- a/lib/checkcondition.cpp +++ b/lib/checkcondition.cpp @@ -2047,3 +2047,48 @@ void CheckCondition::compareValueOutOfTypeRangeError(const Token *comparison, co CWE398, Certainty::normal); } + +void CheckCondition::runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLogger) +{ + CheckCondition checkCondition(&tokenizer, &tokenizer.getSettings(), errorLogger); + checkCondition.multiCondition(); + checkCondition.clarifyCondition(); // not simplified because ifAssign + checkCondition.multiCondition2(); + checkCondition.checkIncorrectLogicOperator(); + checkCondition.checkInvalidTestForOverflow(); + checkCondition.duplicateCondition(); + checkCondition.checkPointerAdditionResultNotNull(); + checkCondition.checkDuplicateConditionalAssign(); + checkCondition.assignIf(); + checkCondition.checkBadBitmaskCheck(); + checkCondition.comparison(); + checkCondition.checkModuloAlwaysTrueFalse(); + checkCondition.checkAssignmentInCondition(); + checkCondition.checkCompareValueOutOfTypeRange(); + checkCondition.alwaysTrueFalse(); +} + +void CheckCondition::getErrorMessages(ErrorLogger *errorLogger, const Settings *settings) const +{ + CheckCondition c(nullptr, settings, errorLogger); + + c.assignIfError(nullptr, nullptr, emptyString, false); + c.badBitmaskCheckError(nullptr); + c.comparisonError(nullptr, "&", 6, "==", 1, false); + c.duplicateConditionError(nullptr, nullptr, ErrorPath{}); + c.overlappingElseIfConditionError(nullptr, 1); + c.mismatchingBitAndError(nullptr, 0xf0, nullptr, 1); + c.oppositeInnerConditionError(nullptr, nullptr, ErrorPath{}); + c.identicalInnerConditionError(nullptr, nullptr, ErrorPath{}); + c.identicalConditionAfterEarlyExitError(nullptr, nullptr, ErrorPath{}); + c.incorrectLogicOperatorError(nullptr, "foo > 3 && foo < 4", true, false, ErrorPath{}); + c.redundantConditionError(nullptr, "If x > 11 the condition x > 10 is always true.", false); + c.moduloAlwaysTrueFalseError(nullptr, "1"); + c.clarifyConditionError(nullptr, true, false); + c.alwaysTrueFalseError(nullptr, nullptr, nullptr); + c.invalidTestForOverflow(nullptr, nullptr, "false"); + c.pointerAdditionResultNotNullError(nullptr, nullptr); + c.duplicateConditionalAssignError(nullptr, nullptr); + c.assignmentInCondition(nullptr); + c.compareValueOutOfTypeRangeError(nullptr, "unsigned char", 256, true); +} diff --git a/lib/checkcondition.h b/lib/checkcondition.h index 92e4c7b88c3..1d890a41480 100644 --- a/lib/checkcondition.h +++ b/lib/checkcondition.h @@ -26,7 +26,6 @@ #include "config.h" #include "mathlib.h" #include "errortypes.h" -#include "tokenize.h" #include #include @@ -35,6 +34,7 @@ class Settings; class Token; class ErrorLogger; class ValueType; +class Tokenizer; namespace ValueFlow { class Value; @@ -57,24 +57,7 @@ class CPPCHECKLIB CheckCondition : public Check { CheckCondition(const Tokenizer *tokenizer, const Settings *settings, ErrorLogger *errorLogger) : Check(myName(), tokenizer, settings, errorLogger) {} - void runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLogger) override { - CheckCondition checkCondition(&tokenizer, &tokenizer.getSettings(), errorLogger); - checkCondition.multiCondition(); - checkCondition.clarifyCondition(); // not simplified because ifAssign - checkCondition.multiCondition2(); - checkCondition.checkIncorrectLogicOperator(); - checkCondition.checkInvalidTestForOverflow(); - checkCondition.duplicateCondition(); - checkCondition.checkPointerAdditionResultNotNull(); - checkCondition.checkDuplicateConditionalAssign(); - checkCondition.assignIf(); - checkCondition.checkBadBitmaskCheck(); - checkCondition.comparison(); - checkCondition.checkModuloAlwaysTrueFalse(); - checkCondition.checkAssignmentInCondition(); - checkCondition.checkCompareValueOutOfTypeRange(); - checkCondition.alwaysTrueFalse(); - } + void runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLogger) override; /** mismatching assignment / comparison */ void assignIf(); @@ -172,29 +155,7 @@ class CPPCHECKLIB CheckCondition : public Check { void checkCompareValueOutOfTypeRange(); void compareValueOutOfTypeRangeError(const Token *comparison, const std::string &type, MathLib::bigint value, bool result); - void getErrorMessages(ErrorLogger *errorLogger, const Settings *settings) const override { - CheckCondition c(nullptr, settings, errorLogger); - - c.assignIfError(nullptr, nullptr, emptyString, false); - c.badBitmaskCheckError(nullptr); - c.comparisonError(nullptr, "&", 6, "==", 1, false); - c.duplicateConditionError(nullptr, nullptr, ErrorPath{}); - c.overlappingElseIfConditionError(nullptr, 1); - c.mismatchingBitAndError(nullptr, 0xf0, nullptr, 1); - c.oppositeInnerConditionError(nullptr, nullptr, ErrorPath{}); - c.identicalInnerConditionError(nullptr, nullptr, ErrorPath{}); - c.identicalConditionAfterEarlyExitError(nullptr, nullptr, ErrorPath{}); - c.incorrectLogicOperatorError(nullptr, "foo > 3 && foo < 4", true, false, ErrorPath{}); - c.redundantConditionError(nullptr, "If x > 11 the condition x > 10 is always true.", false); - c.moduloAlwaysTrueFalseError(nullptr, "1"); - c.clarifyConditionError(nullptr, true, false); - c.alwaysTrueFalseError(nullptr, nullptr, nullptr); - c.invalidTestForOverflow(nullptr, nullptr, "false"); - c.pointerAdditionResultNotNullError(nullptr, nullptr); - c.duplicateConditionalAssignError(nullptr, nullptr); - c.assignmentInCondition(nullptr); - c.compareValueOutOfTypeRangeError(nullptr, "unsigned char", 256, true); - } + void getErrorMessages(ErrorLogger *errorLogger, const Settings *settings) const override; static std::string myName() { return "Condition"; diff --git a/lib/checkexceptionsafety.cpp b/lib/checkexceptionsafety.cpp index c75ecf05f5d..a0c0a58d7d0 100644 --- a/lib/checkexceptionsafety.cpp +++ b/lib/checkexceptionsafety.cpp @@ -19,12 +19,13 @@ //--------------------------------------------------------------------------- #include "checkexceptionsafety.h" +#include "astutils.h" #include "errortypes.h" #include "library.h" #include "settings.h" #include "symboldatabase.h" #include "token.h" -#include "astutils.h" +#include "tokenize.h" #include #include @@ -408,3 +409,30 @@ void CheckExceptionSafety::rethrowNoCurrentExceptionError(const Token *tok) " More: https://isocpp.org/wiki/faq/exceptions#throw-without-an-object", CWE480, Certainty::normal); } + +void CheckExceptionSafety::runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLogger) +{ + if (tokenizer.isC()) + return; + + CheckExceptionSafety checkExceptionSafety(&tokenizer, &tokenizer.getSettings(), errorLogger); + checkExceptionSafety.destructors(); + checkExceptionSafety.deallocThrow(); + checkExceptionSafety.checkRethrowCopy(); + checkExceptionSafety.checkCatchExceptionByValue(); + checkExceptionSafety.nothrowThrows(); + checkExceptionSafety.unhandledExceptionSpecification(); + checkExceptionSafety.rethrowNoCurrentException(); +} + +void CheckExceptionSafety::getErrorMessages(ErrorLogger *errorLogger, const Settings *settings) const +{ + CheckExceptionSafety c(nullptr, settings, errorLogger); + c.destructorsError(nullptr, "Class"); + c.deallocThrowError(nullptr, "p"); + c.rethrowCopyError(nullptr, "varname"); + c.catchExceptionByValueError(nullptr); + c.noexceptThrowError(nullptr); + c.unhandledExceptionSpecificationError(nullptr, nullptr, "funcname"); + c.rethrowNoCurrentExceptionError(nullptr); +} diff --git a/lib/checkexceptionsafety.h b/lib/checkexceptionsafety.h index ef40c56016f..516a4ba2be8 100644 --- a/lib/checkexceptionsafety.h +++ b/lib/checkexceptionsafety.h @@ -23,14 +23,13 @@ #include "check.h" #include "config.h" -#include "tokenize.h" #include class Settings; class ErrorLogger; class Token; - +class Tokenizer; /// @addtogroup Checks /// @{ @@ -54,19 +53,7 @@ class CPPCHECKLIB CheckExceptionSafety : public Check { CheckExceptionSafety(const Tokenizer *tokenizer, const Settings *settings, ErrorLogger *errorLogger) : Check(myName(), tokenizer, settings, errorLogger) {} - void runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLogger) override { - if (tokenizer.isC()) - return; - - CheckExceptionSafety checkExceptionSafety(&tokenizer, &tokenizer.getSettings(), errorLogger); - checkExceptionSafety.destructors(); - checkExceptionSafety.deallocThrow(); - checkExceptionSafety.checkRethrowCopy(); - checkExceptionSafety.checkCatchExceptionByValue(); - checkExceptionSafety.nothrowThrows(); - checkExceptionSafety.unhandledExceptionSpecification(); - checkExceptionSafety.rethrowNoCurrentException(); - } + void runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLogger) override; /** Don't throw exceptions in destructors */ void destructors(); @@ -101,16 +88,7 @@ class CPPCHECKLIB CheckExceptionSafety : public Check { void rethrowNoCurrentExceptionError(const Token *tok); /** Generate all possible errors (for --errorlist) */ - void getErrorMessages(ErrorLogger *errorLogger, const Settings *settings) const override { - CheckExceptionSafety c(nullptr, settings, errorLogger); - c.destructorsError(nullptr, "Class"); - c.deallocThrowError(nullptr, "p"); - c.rethrowCopyError(nullptr, "varname"); - c.catchExceptionByValueError(nullptr); - c.noexceptThrowError(nullptr); - c.unhandledExceptionSpecificationError(nullptr, nullptr, "funcname"); - c.rethrowNoCurrentExceptionError(nullptr); - } + void getErrorMessages(ErrorLogger *errorLogger, const Settings *settings) const override; /** Short description of class (for --doc) */ static std::string myName() { diff --git a/lib/checkfunctions.cpp b/lib/checkfunctions.cpp index d5f5cc8a044..607d083aaa2 100644 --- a/lib/checkfunctions.cpp +++ b/lib/checkfunctions.cpp @@ -23,8 +23,11 @@ #include "checkfunctions.h" #include "astutils.h" +#include "errortypes.h" +#include "library.h" #include "mathlib.h" #include "platform.h" +#include "settings.h" #include "standards.h" #include "symboldatabase.h" #include "token.h" @@ -34,6 +37,7 @@ #include #include +#include #include #include #include @@ -829,3 +833,44 @@ void CheckFunctions::useStandardLibraryError(const Token *tok, const std::string "useStandardLibrary", "Consider using " + expected + " instead of loop."); } + +void CheckFunctions::runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLogger) +{ + CheckFunctions checkFunctions(&tokenizer, &tokenizer.getSettings(), errorLogger); + + checkFunctions.checkIgnoredReturnValue(); + checkFunctions.checkMissingReturn(); // Missing "return" in exit path + + // --check-library : functions with nonmatching configuration + checkFunctions.checkLibraryMatchFunctions(); + + checkFunctions.checkProhibitedFunctions(); + checkFunctions.invalidFunctionUsage(); + checkFunctions.checkMathFunctions(); + checkFunctions.memsetZeroBytes(); + checkFunctions.memsetInvalid2ndParam(); + checkFunctions.returnLocalStdMove(); + checkFunctions.useStandardLibrary(); +} + +void CheckFunctions::getErrorMessages(ErrorLogger *errorLogger, const Settings *settings) const +{ + CheckFunctions c(nullptr, settings, errorLogger); + + for (auto i = settings->library.functionwarn().cbegin(); i != settings->library.functionwarn().cend(); ++i) { + c.reportError(nullptr, Severity::style, i->first+"Called", i->second.message); + } + + c.invalidFunctionArgError(nullptr, "func_name", 1, nullptr,"1:4"); + c.invalidFunctionArgBoolError(nullptr, "func_name", 1); + c.invalidFunctionArgStrError(nullptr, "func_name", 1); + c.ignoredReturnValueError(nullptr, "malloc"); + c.mathfunctionCallWarning(nullptr); + c.mathfunctionCallWarning(nullptr, "1 - erf(x)", "erfc(x)"); + c.memsetZeroBytesError(nullptr); + c.memsetFloatError(nullptr, "varname"); + c.memsetValueOutOfRangeError(nullptr, "varname"); + c.missingReturnError(nullptr); + c.copyElisionError(nullptr); + c.useStandardLibraryError(nullptr, "memcpy"); +} diff --git a/lib/checkfunctions.h b/lib/checkfunctions.h index e1e96f53fa4..806157b2919 100644 --- a/lib/checkfunctions.h +++ b/lib/checkfunctions.h @@ -24,16 +24,13 @@ #include "check.h" #include "config.h" -#include "errortypes.h" -#include "library.h" -#include "settings.h" -#include "tokenize.h" -#include #include class Token; class ErrorLogger; +class Tokenizer; +class Settings; namespace ValueFlow { class Value; @@ -58,23 +55,7 @@ class CPPCHECKLIB CheckFunctions : public Check { : Check(myName(), tokenizer, settings, errorLogger) {} /** @brief Run checks against the normal token list */ - void runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLogger) override { - CheckFunctions checkFunctions(&tokenizer, &tokenizer.getSettings(), errorLogger); - - checkFunctions.checkIgnoredReturnValue(); - checkFunctions.checkMissingReturn(); // Missing "return" in exit path - - // --check-library : functions with nonmatching configuration - checkFunctions.checkLibraryMatchFunctions(); - - checkFunctions.checkProhibitedFunctions(); - checkFunctions.invalidFunctionUsage(); - checkFunctions.checkMathFunctions(); - checkFunctions.memsetZeroBytes(); - checkFunctions.memsetInvalid2ndParam(); - checkFunctions.returnLocalStdMove(); - checkFunctions.useStandardLibrary(); - } + void runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLogger) override; /** Check for functions that should not be used */ void checkProhibitedFunctions(); @@ -126,26 +107,7 @@ class CPPCHECKLIB CheckFunctions : public Check { void copyElisionError(const Token *tok); void useStandardLibraryError(const Token *tok, const std::string& expected); - void getErrorMessages(ErrorLogger *errorLogger, const Settings *settings) const override { - CheckFunctions c(nullptr, settings, errorLogger); - - for (auto i = settings->library.functionwarn().cbegin(); i != settings->library.functionwarn().cend(); ++i) { - c.reportError(nullptr, Severity::style, i->first+"Called", i->second.message); - } - - c.invalidFunctionArgError(nullptr, "func_name", 1, nullptr,"1:4"); - c.invalidFunctionArgBoolError(nullptr, "func_name", 1); - c.invalidFunctionArgStrError(nullptr, "func_name", 1); - c.ignoredReturnValueError(nullptr, "malloc"); - c.mathfunctionCallWarning(nullptr); - c.mathfunctionCallWarning(nullptr, "1 - erf(x)", "erfc(x)"); - c.memsetZeroBytesError(nullptr); - c.memsetFloatError(nullptr, "varname"); - c.memsetValueOutOfRangeError(nullptr, "varname"); - c.missingReturnError(nullptr); - c.copyElisionError(nullptr); - c.useStandardLibraryError(nullptr, "memcpy"); - } + void getErrorMessages(ErrorLogger *errorLogger, const Settings *settings) const override; static std::string myName() { return "Check function usage"; diff --git a/lib/checkinternal.cpp b/lib/checkinternal.cpp index 7983126f538..94c0bb893ab 100644 --- a/lib/checkinternal.cpp +++ b/lib/checkinternal.cpp @@ -21,6 +21,8 @@ #include "checkinternal.h" #include "astutils.h" +#include "errortypes.h" +#include "settings.h" #include "symboldatabase.h" #include "token.h" #include "tokenize.h" @@ -388,4 +390,34 @@ void CheckInternal::extraWhitespaceError(const Token* tok, const std::string& pa ); } +void CheckInternal::runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLogger) +{ + if (!tokenizer.getSettings().checks.isEnabled(Checks::internalCheck)) + return; + + CheckInternal checkInternal(&tokenizer, &tokenizer.getSettings(), errorLogger); + + checkInternal.checkTokenMatchPatterns(); + checkInternal.checkTokenSimpleMatchPatterns(); + checkInternal.checkMissingPercentCharacter(); + checkInternal.checkUnknownPattern(); + checkInternal.checkRedundantNextPrevious(); + checkInternal.checkExtraWhitespace(); + checkInternal.checkRedundantTokCheck(); +} + +void CheckInternal::getErrorMessages(ErrorLogger *errorLogger, const Settings *settings) const +{ + CheckInternal c(nullptr, settings, errorLogger); + c.multiComparePatternError(nullptr, ";|%type%", "Match"); + c.simplePatternError(nullptr, "class {", "Match"); + c.complexPatternError(nullptr, "%type% ( )", "Match"); + c.missingPercentCharacterError(nullptr, "%num", "Match"); + c.unknownPatternError(nullptr, "%typ"); + c.redundantNextPreviousError(nullptr, "previous", "next"); + c.orInComplexPattern(nullptr, "||", "Match"); + c.extraWhitespaceError(nullptr, "%str% ", "Match"); + c.checkRedundantTokCheckError(nullptr); +} + #endif // #ifdef CHECK_INTERNAL diff --git a/lib/checkinternal.h b/lib/checkinternal.h index e308ec0dbbd..70eb13f0651 100644 --- a/lib/checkinternal.h +++ b/lib/checkinternal.h @@ -24,14 +24,13 @@ #include "check.h" #include "config.h" -#include "errortypes.h" -#include "settings.h" -#include "tokenize.h" #include class ErrorLogger; class Token; +class Tokenizer; +class Settings; /// @addtogroup Checks /// @{ @@ -48,20 +47,7 @@ class CPPCHECKLIB CheckInternal : public Check { CheckInternal(const Tokenizer *tokenizer, const Settings *settings, ErrorLogger *errorLogger) : Check(myName(), tokenizer, settings, errorLogger) {} - void runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLogger) override { - if (!tokenizer.getSettings().checks.isEnabled(Checks::internalCheck)) - return; - - CheckInternal checkInternal(&tokenizer, &tokenizer.getSettings(), errorLogger); - - checkInternal.checkTokenMatchPatterns(); - checkInternal.checkTokenSimpleMatchPatterns(); - checkInternal.checkMissingPercentCharacter(); - checkInternal.checkUnknownPattern(); - checkInternal.checkRedundantNextPrevious(); - checkInternal.checkExtraWhitespace(); - checkInternal.checkRedundantTokCheck(); - } + void runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLogger) override; /** @brief %Check if a simple pattern is used inside Token::Match or Token::findmatch */ void checkTokenMatchPatterns(); @@ -94,18 +80,7 @@ class CPPCHECKLIB CheckInternal : public Check { void extraWhitespaceError(const Token *tok, const std::string &pattern, const std::string &funcname); void checkRedundantTokCheckError(const Token *tok); - void getErrorMessages(ErrorLogger *errorLogger, const Settings *settings) const override { - CheckInternal c(nullptr, settings, errorLogger); - c.multiComparePatternError(nullptr, ";|%type%", "Match"); - c.simplePatternError(nullptr, "class {", "Match"); - c.complexPatternError(nullptr, "%type% ( )", "Match"); - c.missingPercentCharacterError(nullptr, "%num", "Match"); - c.unknownPatternError(nullptr, "%typ"); - c.redundantNextPreviousError(nullptr, "previous", "next"); - c.orInComplexPattern(nullptr, "||", "Match"); - c.extraWhitespaceError(nullptr, "%str% ", "Match"); - c.checkRedundantTokCheckError(nullptr); - } + void getErrorMessages(ErrorLogger *errorLogger, const Settings *settings) const override; static std::string myName() { return "cppcheck internal API usage"; diff --git a/lib/checkio.cpp b/lib/checkio.cpp index 7808f2ddf4b..c1bbaefe777 100644 --- a/lib/checkio.cpp +++ b/lib/checkio.cpp @@ -2023,3 +2023,41 @@ void CheckIO::invalidScanfFormatWidthError(const Token* tok, nonneg int numForma reportError(tok, Severity::error, "invalidScanfFormatWidth", errmsg.str(), CWE687, Certainty::normal); } } + +void CheckIO::runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLogger) +{ + CheckIO checkIO(&tokenizer, &tokenizer.getSettings(), errorLogger); + + checkIO.checkWrongPrintfScanfArguments(); + checkIO.checkCoutCerrMisusage(); + checkIO.checkFileUsage(); + checkIO.invalidScanf(); +} + +void CheckIO::getErrorMessages(ErrorLogger *errorLogger, const Settings *settings) const +{ + CheckIO c(nullptr, settings, errorLogger); + c.coutCerrMisusageError(nullptr, "cout"); + c.fflushOnInputStreamError(nullptr, "stdin"); + c.ioWithoutPositioningError(nullptr); + c.readWriteOnlyFileError(nullptr); + c.writeReadOnlyFileError(nullptr); + c.useClosedFileError(nullptr); + c.seekOnAppendedFileError(nullptr); + c.incompatibleFileOpenError(nullptr, "tmp"); + c.invalidScanfError(nullptr); + c.wrongPrintfScanfArgumentsError(nullptr, "printf",3,2); + c.invalidScanfArgTypeError_s(nullptr, 1, "s", nullptr); + c.invalidScanfArgTypeError_int(nullptr, 1, "d", nullptr, false); + c.invalidScanfArgTypeError_float(nullptr, 1, "f", nullptr); + c.invalidPrintfArgTypeError_s(nullptr, 1, nullptr); + c.invalidPrintfArgTypeError_n(nullptr, 1, nullptr); + c.invalidPrintfArgTypeError_p(nullptr, 1, nullptr); + c.invalidPrintfArgTypeError_uint(nullptr, 1, "u", nullptr); + c.invalidPrintfArgTypeError_sint(nullptr, 1, "i", nullptr); + c.invalidPrintfArgTypeError_float(nullptr, 1, "f", nullptr); + c.invalidLengthModifierError(nullptr, 1, "I"); + c.invalidScanfFormatWidthError(nullptr, 10, 5, nullptr, "s"); + c.invalidScanfFormatWidthError(nullptr, 99, -1, nullptr, "s"); + c.wrongPrintfScanfPosixParameterPositionError(nullptr, "printf", 2, 1); +} diff --git a/lib/checkio.h b/lib/checkio.h index 0f7d9b560e2..6485207e9e0 100644 --- a/lib/checkio.h +++ b/lib/checkio.h @@ -23,7 +23,6 @@ #include "check.h" #include "config.h" -#include "tokenize.h" #include #include @@ -34,6 +33,7 @@ class Settings; class Token; class Variable; class ErrorLogger; +class Tokenizer; enum class Severity : std::uint8_t; /// @addtogroup Checks @@ -53,14 +53,7 @@ class CPPCHECKLIB CheckIO : public Check { : Check(myName(), tokenizer, settings, errorLogger) {} /** @brief Run checks on the normal token list */ - void runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLogger) override { - CheckIO checkIO(&tokenizer, &tokenizer.getSettings(), errorLogger); - - checkIO.checkWrongPrintfScanfArguments(); - checkIO.checkCoutCerrMisusage(); - checkIO.checkFileUsage(); - checkIO.invalidScanf(); - } + void runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLogger) override; /** @brief %Check for missusage of std::cout */ void checkCoutCerrMisusage(); @@ -135,32 +128,7 @@ class CPPCHECKLIB CheckIO : public Check { static void argumentType(std::ostream & os, const ArgumentInfo * argInfo); static Severity getSeverity(const ArgumentInfo *argInfo); - void getErrorMessages(ErrorLogger *errorLogger, const Settings *settings) const override { - CheckIO c(nullptr, settings, errorLogger); - c.coutCerrMisusageError(nullptr, "cout"); - c.fflushOnInputStreamError(nullptr, "stdin"); - c.ioWithoutPositioningError(nullptr); - c.readWriteOnlyFileError(nullptr); - c.writeReadOnlyFileError(nullptr); - c.useClosedFileError(nullptr); - c.seekOnAppendedFileError(nullptr); - c.incompatibleFileOpenError(nullptr, "tmp"); - c.invalidScanfError(nullptr); - c.wrongPrintfScanfArgumentsError(nullptr, "printf",3,2); - c.invalidScanfArgTypeError_s(nullptr, 1, "s", nullptr); - c.invalidScanfArgTypeError_int(nullptr, 1, "d", nullptr, false); - c.invalidScanfArgTypeError_float(nullptr, 1, "f", nullptr); - c.invalidPrintfArgTypeError_s(nullptr, 1, nullptr); - c.invalidPrintfArgTypeError_n(nullptr, 1, nullptr); - c.invalidPrintfArgTypeError_p(nullptr, 1, nullptr); - c.invalidPrintfArgTypeError_uint(nullptr, 1, "u", nullptr); - c.invalidPrintfArgTypeError_sint(nullptr, 1, "i", nullptr); - c.invalidPrintfArgTypeError_float(nullptr, 1, "f", nullptr); - c.invalidLengthModifierError(nullptr, 1, "I"); - c.invalidScanfFormatWidthError(nullptr, 10, 5, nullptr, "s"); - c.invalidScanfFormatWidthError(nullptr, 99, -1, nullptr, "s"); - c.wrongPrintfScanfPosixParameterPositionError(nullptr, "printf", 2, 1); - } + void getErrorMessages(ErrorLogger *errorLogger, const Settings *settings) const override; static std::string myName() { return "IO using format string"; diff --git a/lib/checkleakautovar.cpp b/lib/checkleakautovar.cpp index ad91eb3e383..bdc92a8f6ed 100644 --- a/lib/checkleakautovar.cpp +++ b/lib/checkleakautovar.cpp @@ -1241,3 +1241,17 @@ void CheckLeakAutoVar::ret(const Token *tok, VarInfo &varInfo, const bool isEndO for (const int varId : toRemove) varInfo.erase(varId); } + +void CheckLeakAutoVar::runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLogger) +{ + CheckLeakAutoVar checkLeakAutoVar(&tokenizer, &tokenizer.getSettings(), errorLogger); + checkLeakAutoVar.check(); +} + +void CheckLeakAutoVar::getErrorMessages(ErrorLogger *errorLogger, const Settings *settings) const +{ + CheckLeakAutoVar c(nullptr, settings, errorLogger); + c.deallocReturnError(nullptr, nullptr, "p"); + c.configurationInfo(nullptr, { nullptr, VarInfo::USED }); // user configuration is needed to complete analysis + c.doubleFreeError(nullptr, nullptr, "varname", 0); +} diff --git a/lib/checkleakautovar.h b/lib/checkleakautovar.h index c5060065ed9..dbd7f5168bf 100644 --- a/lib/checkleakautovar.h +++ b/lib/checkleakautovar.h @@ -25,7 +25,6 @@ #include "check.h" #include "config.h" #include "library.h" -#include "tokenize.h" #include #include @@ -36,7 +35,7 @@ class ErrorLogger; class Settings; class Token; - +class Tokenizer; class CPPCHECKLIB VarInfo { public: @@ -115,10 +114,7 @@ class CPPCHECKLIB CheckLeakAutoVar : public Check { CheckLeakAutoVar(const Tokenizer *tokenizer, const Settings *settings, ErrorLogger *errorLogger) : Check(myName(), tokenizer, settings, errorLogger) {} - void runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLogger) override { - CheckLeakAutoVar checkLeakAutoVar(&tokenizer, &tokenizer.getSettings(), errorLogger); - checkLeakAutoVar.check(); - } + void runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLogger) override; /** check for leaks in all scopes */ void check(); @@ -160,12 +156,7 @@ class CPPCHECKLIB CheckLeakAutoVar : public Check { /** message: user configuration is needed to complete analysis */ void configurationInfo(const Token* tok, const std::pair& functionUsage); - void getErrorMessages(ErrorLogger *errorLogger, const Settings *settings) const override { - CheckLeakAutoVar c(nullptr, settings, errorLogger); - c.deallocReturnError(nullptr, nullptr, "p"); - c.configurationInfo(nullptr, { nullptr, VarInfo::USED }); // user configuration is needed to complete analysis - c.doubleFreeError(nullptr, nullptr, "varname", 0); - } + void getErrorMessages(ErrorLogger *errorLogger, const Settings *settings) const override; static std::string myName() { return "Leaks (auto variables)"; diff --git a/lib/checkmemoryleak.cpp b/lib/checkmemoryleak.cpp index df9d6564436..bf4f6f6964d 100644 --- a/lib/checkmemoryleak.cpp +++ b/lib/checkmemoryleak.cpp @@ -497,6 +497,22 @@ void CheckMemoryLeakInFunction::checkReallocUsage() } //--------------------------------------------------------------------------- +void CheckMemoryLeakInFunction::runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLogger) +{ + CheckMemoryLeakInFunction checkMemoryLeak(&tokenizer, &tokenizer.getSettings(), errorLogger); + checkMemoryLeak.checkReallocUsage(); +} + +void CheckMemoryLeakInFunction::getErrorMessages(ErrorLogger *e, const Settings *settings) const +{ + CheckMemoryLeakInFunction c(nullptr, settings, e); + c.memleakError(nullptr, "varname"); + c.resourceLeakError(nullptr, "varname"); + c.deallocuseError(nullptr, "varname"); + const std::list callstack; + c.mismatchAllocDealloc(callstack, "varname"); + c.memleakUponReallocFailureError(nullptr, "realloc", "varname"); +} //--------------------------------------------------------------------------- // Checks for memory leaks in classes.. @@ -683,6 +699,22 @@ void CheckMemoryLeakInClass::publicAllocationError(const Token *tok, const std:: reportError(tok, Severity::warning, "publicAllocationError", "$symbol:" + varname + "\nPossible leak in public function. The pointer '$symbol' is not deallocated before it is allocated.", CWE398, Certainty::normal); } +void CheckMemoryLeakInClass::runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLogger) +{ + if (!tokenizer.isCPP()) + return; + + CheckMemoryLeakInClass checkMemoryLeak(&tokenizer, &tokenizer.getSettings(), errorLogger); + checkMemoryLeak.check(); +} + +void CheckMemoryLeakInClass::getErrorMessages(ErrorLogger *e, const Settings *settings) const +{ + CheckMemoryLeakInClass c(nullptr, settings, e); + c.publicAllocationError(nullptr, "varname"); + c.unsafeClassError(nullptr, "class", "class::varname"); +} + void CheckMemoryLeakStructMember::check() { @@ -930,6 +962,14 @@ void CheckMemoryLeakStructMember::checkStructVariable(const Variable* const vari } } +void CheckMemoryLeakStructMember::runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLogger) +{ + CheckMemoryLeakStructMember checkMemoryLeak(&tokenizer, &tokenizer.getSettings(), errorLogger); + checkMemoryLeak.check(); +} + +void CheckMemoryLeakStructMember::getErrorMessages(ErrorLogger * /*errorLogger*/, const Settings * /*settings*/) const +{} void CheckMemoryLeakNoVar::check() @@ -1162,3 +1202,17 @@ void CheckMemoryLeakNoVar::unsafeArgAllocError(const Token *tok, const std::stri CWE401, Certainty::inconclusive); // Inconclusive because funcName may never throw } + +void CheckMemoryLeakNoVar::runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLogger) +{ + CheckMemoryLeakNoVar checkMemoryLeak(&tokenizer, &tokenizer.getSettings(), errorLogger); + checkMemoryLeak.check(); +} + +void CheckMemoryLeakNoVar::getErrorMessages(ErrorLogger *e, const Settings *settings) const +{ + CheckMemoryLeakNoVar c(nullptr, settings, e); + c.functionCallLeak(nullptr, "funcName", "funcName"); + c.returnValueNotUsedError(nullptr, "funcName"); + c.unsafeArgAllocError(nullptr, "funcName", "shared_ptr", "int"); +} diff --git a/lib/checkmemoryleak.h b/lib/checkmemoryleak.h index 93e716929b3..86a4bc60a30 100644 --- a/lib/checkmemoryleak.h +++ b/lib/checkmemoryleak.h @@ -34,7 +34,6 @@ #include "check.h" #include "config.h" -#include "tokenize.h" #include #include @@ -47,6 +46,7 @@ class Token; class Variable; class ErrorLogger; struct CWE; +class Tokenizer; enum class Severity : std::uint8_t; /// @addtogroup Core @@ -177,10 +177,7 @@ class CPPCHECKLIB CheckMemoryLeakInFunction : public Check, public CheckMemoryLe CheckMemoryLeakInFunction(const Tokenizer *tokenizer, const Settings *settings, ErrorLogger *errorLogger) : Check(myName(), tokenizer, settings, errorLogger), CheckMemoryLeak(tokenizer, errorLogger, settings) {} - void runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLogger) override { - CheckMemoryLeakInFunction checkMemoryLeak(&tokenizer, &tokenizer.getSettings(), errorLogger); - checkMemoryLeak.checkReallocUsage(); - } + void runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLogger) override; /** * Checking for a memory leak caused by improper realloc usage. @@ -188,15 +185,7 @@ class CPPCHECKLIB CheckMemoryLeakInFunction : public Check, public CheckMemoryLe void checkReallocUsage(); /** Report all possible errors (for the --errorlist) */ - void getErrorMessages(ErrorLogger *e, const Settings *settings) const override { - CheckMemoryLeakInFunction c(nullptr, settings, e); - c.memleakError(nullptr, "varname"); - c.resourceLeakError(nullptr, "varname"); - c.deallocuseError(nullptr, "varname"); - const std::list callstack; - c.mismatchAllocDealloc(callstack, "varname"); - c.memleakUponReallocFailureError(nullptr, "realloc", "varname"); - } + void getErrorMessages(ErrorLogger *e, const Settings *settings) const override; /** * Get name of class (--doc) @@ -231,13 +220,7 @@ class CPPCHECKLIB CheckMemoryLeakInClass : public Check, private CheckMemoryLeak CheckMemoryLeakInClass(const Tokenizer *tokenizer, const Settings *settings, ErrorLogger *errorLogger) : Check(myName(), tokenizer, settings, errorLogger), CheckMemoryLeak(tokenizer, errorLogger, settings) {} - void runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLogger) override { - if (!tokenizer.isCPP()) - return; - - CheckMemoryLeakInClass checkMemoryLeak(&tokenizer, &tokenizer.getSettings(), errorLogger); - checkMemoryLeak.check(); - } + void runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLogger) override; void check(); @@ -249,11 +232,7 @@ class CPPCHECKLIB CheckMemoryLeakInClass : public Check, private CheckMemoryLeak void unsafeClassError(const Token *tok, const std::string &classname, const std::string &varname); - void getErrorMessages(ErrorLogger *e, const Settings *settings) const override { - CheckMemoryLeakInClass c(nullptr, settings, e); - c.publicAllocationError(nullptr, "varname"); - c.unsafeClassError(nullptr, "class", "class::varname"); - } + void getErrorMessages(ErrorLogger *e, const Settings *settings) const override; static std::string myName() { return "Memory leaks (class variables)"; @@ -278,10 +257,7 @@ class CPPCHECKLIB CheckMemoryLeakStructMember : public Check, private CheckMemor CheckMemoryLeakStructMember(const Tokenizer *tokenizer, const Settings *settings, ErrorLogger *errorLogger) : Check(myName(), tokenizer, settings, errorLogger), CheckMemoryLeak(tokenizer, errorLogger, settings) {} - void runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLogger) override { - CheckMemoryLeakStructMember checkMemoryLeak(&tokenizer, &tokenizer.getSettings(), errorLogger); - checkMemoryLeak.check(); - } + void runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLogger) override; void check(); @@ -290,7 +266,7 @@ class CPPCHECKLIB CheckMemoryLeakStructMember : public Check, private CheckMemor void checkStructVariable(const Variable* variable) const; - void getErrorMessages(ErrorLogger * /*errorLogger*/, const Settings * /*settings*/) const override {} + void getErrorMessages(ErrorLogger * errorLogger, const Settings * settings) const override; static std::string myName() { return "Memory leaks (struct members)"; @@ -315,10 +291,7 @@ class CPPCHECKLIB CheckMemoryLeakNoVar : public Check, private CheckMemoryLeak { CheckMemoryLeakNoVar(const Tokenizer *tokenizer, const Settings *settings, ErrorLogger *errorLogger) : Check(myName(), tokenizer, settings, errorLogger), CheckMemoryLeak(tokenizer, errorLogger, settings) {} - void runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLogger) override { - CheckMemoryLeakNoVar checkMemoryLeak(&tokenizer, &tokenizer.getSettings(), errorLogger); - checkMemoryLeak.check(); - } + void runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLogger) override; void check(); @@ -345,12 +318,7 @@ class CPPCHECKLIB CheckMemoryLeakNoVar : public Check, private CheckMemoryLeak { void returnValueNotUsedError(const Token* tok, const std::string &alloc); void unsafeArgAllocError(const Token *tok, const std::string &funcName, const std::string &ptrType, const std::string &objType); - void getErrorMessages(ErrorLogger *e, const Settings *settings) const override { - CheckMemoryLeakNoVar c(nullptr, settings, e); - c.functionCallLeak(nullptr, "funcName", "funcName"); - c.returnValueNotUsedError(nullptr, "funcName"); - c.unsafeArgAllocError(nullptr, "funcName", "shared_ptr", "int"); - } + void getErrorMessages(ErrorLogger *e, const Settings *settings) const override; static std::string myName() { return "Memory leaks (address not taken)"; diff --git a/lib/checknullpointer.cpp b/lib/checknullpointer.cpp index d6f5a3ea9a7..1a19acd4878 100644 --- a/lib/checknullpointer.cpp +++ b/lib/checknullpointer.cpp @@ -682,3 +682,19 @@ bool CheckNullPointer::analyseWholeProgram(const CTU::FileInfo *ctu, const std:: return foundErrors; } + +void CheckNullPointer::runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLogger) +{ + CheckNullPointer checkNullPointer(&tokenizer, &tokenizer.getSettings(), errorLogger); + checkNullPointer.nullPointer(); + checkNullPointer.arithmetic(); + checkNullPointer.nullConstantDereference(); +} + +void CheckNullPointer::getErrorMessages(ErrorLogger *errorLogger, const Settings *settings) const +{ + CheckNullPointer c(nullptr, settings, errorLogger); + c.nullPointerError(nullptr, "pointer", nullptr, false); + c.pointerArithmeticError(nullptr, nullptr, false); + c.redundantConditionWarning(nullptr, nullptr, nullptr, false); +} diff --git a/lib/checknullpointer.h b/lib/checknullpointer.h index 4cabe1749de..644a76ee676 100644 --- a/lib/checknullpointer.h +++ b/lib/checknullpointer.h @@ -24,7 +24,6 @@ #include "check.h" #include "config.h" -#include "tokenize.h" #include "vfvalue.h" #include @@ -34,6 +33,7 @@ class ErrorLogger; class Library; class Settings; class Token; +class Tokenizer; /// @addtogroup Checks /// @{ @@ -77,12 +77,7 @@ class CPPCHECKLIB CheckNullPointer : public Check { : Check(myName(), tokenizer, settings, errorLogger) {} /** @brief Run checks against the normal token list */ - void runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLogger) override { - CheckNullPointer checkNullPointer(&tokenizer, &tokenizer.getSettings(), errorLogger); - checkNullPointer.nullPointer(); - checkNullPointer.arithmetic(); - checkNullPointer.nullConstantDereference(); - } + void runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLogger) override; /** @brief possible null pointer dereference */ void nullPointer(); @@ -106,12 +101,7 @@ class CPPCHECKLIB CheckNullPointer : public Check { bool analyseWholeProgram(const CTU::FileInfo *ctu, const std::list &fileInfo, const Settings& settings, ErrorLogger &errorLogger) override; /** Get error messages. Used by --errorlist */ - void getErrorMessages(ErrorLogger *errorLogger, const Settings *settings) const override { - CheckNullPointer c(nullptr, settings, errorLogger); - c.nullPointerError(nullptr, "pointer", nullptr, false); - c.pointerArithmeticError(nullptr, nullptr, false); - c.redundantConditionWarning(nullptr, nullptr, nullptr, false); - } + void getErrorMessages(ErrorLogger *errorLogger, const Settings *settings) const override; /** Name of check */ static std::string myName() { diff --git a/lib/checkother.cpp b/lib/checkother.cpp index 6c987511025..297589902d7 100644 --- a/lib/checkother.cpp +++ b/lib/checkother.cpp @@ -4320,3 +4320,128 @@ void CheckOther::overlappingWriteFunction(const Token *tok) const std::string &funcname = tok ? tok->str() : emptyString; reportError(tok, Severity::error, "overlappingWriteFunction", "Overlapping read/write in " + funcname + "() is undefined behavior"); } + +void CheckOther::runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLogger) +{ + CheckOther checkOther(&tokenizer, &tokenizer.getSettings(), errorLogger); + + // Checks + checkOther.warningOldStylePointerCast(); + checkOther.suspiciousFloatingPointCast(); + checkOther.invalidPointerCast(); + checkOther.checkCharVariable(); + checkOther.redundantBitwiseOperationInSwitchError(); + checkOther.checkSuspiciousCaseInSwitch(); + checkOther.checkDuplicateBranch(); + checkOther.checkDuplicateExpression(); + checkOther.checkRedundantAssignment(); + checkOther.checkUnreachableCode(); + checkOther.checkSuspiciousSemicolon(); + checkOther.checkVariableScope(); + checkOther.checkSignOfUnsignedVariable(); // don't ignore casts (#3574) + checkOther.checkIncompleteArrayFill(); + checkOther.checkVarFuncNullUB(); + checkOther.checkNanInArithmeticExpression(); + checkOther.checkCommaSeparatedReturn(); + checkOther.checkRedundantPointerOp(); + checkOther.checkZeroDivision(); + checkOther.checkNegativeBitwiseShift(); + checkOther.checkInterlockedDecrement(); + checkOther.checkUnusedLabel(); + checkOther.checkEvaluationOrder(); + checkOther.checkFuncArgNamesDifferent(); + checkOther.checkShadowVariables(); + checkOther.checkKnownArgument(); + checkOther.checkKnownPointerToBool(); + checkOther.checkComparePointers(); + checkOther.checkIncompleteStatement(); + checkOther.checkRedundantCopy(); + checkOther.clarifyCalculation(); + checkOther.checkPassByReference(); + checkOther.checkConstVariable(); + checkOther.checkConstPointer(); + checkOther.checkComparisonFunctionIsAlwaysTrueOrFalse(); + checkOther.checkInvalidFree(); + checkOther.clarifyStatement(); + checkOther.checkCastIntToCharAndBack(); + checkOther.checkMisusedScopedObject(); + checkOther.checkAccessOfMovedVariable(); + checkOther.checkModuloOfOne(); + checkOther.checkOverlappingWrite(); +} + +void CheckOther::getErrorMessages(ErrorLogger *errorLogger, const Settings *settings) const +{ + CheckOther c(nullptr, settings, errorLogger); + + // error + c.zerodivError(nullptr, nullptr); + c.misusedScopeObjectError(nullptr, "varname"); + c.invalidPointerCastError(nullptr, "float *", "double *", false, false); + c.negativeBitwiseShiftError(nullptr, 1); + c.negativeBitwiseShiftError(nullptr, 2); + c.raceAfterInterlockedDecrementError(nullptr); + c.invalidFreeError(nullptr, "malloc", false); + c.overlappingWriteUnion(nullptr); + c.overlappingWriteFunction(nullptr); + + //performance + c.redundantCopyError(nullptr, "varname"); + c.redundantCopyError(nullptr, nullptr, "var"); + + // style/warning + c.checkComparisonFunctionIsAlwaysTrueOrFalseError(nullptr, "isless","varName",false); + c.checkCastIntToCharAndBackError(nullptr, "func_name"); + c.cstyleCastError(nullptr); + c.suspiciousFloatingPointCastError(nullptr); + c.passedByValueError(nullptr, false); + c.constVariableError(nullptr, nullptr); + c.constStatementError(nullptr, "type", false); + c.signedCharArrayIndexError(nullptr); + c.unknownSignCharArrayIndexError(nullptr); + c.charBitOpError(nullptr); + c.variableScopeError(nullptr, "varname"); + c.redundantAssignmentInSwitchError(nullptr, nullptr, "var"); + c.suspiciousCaseInSwitchError(nullptr, "||"); + c.selfAssignmentError(nullptr, "varname"); + c.clarifyCalculationError(nullptr, "+"); + c.clarifyStatementError(nullptr); + c.duplicateBranchError(nullptr, nullptr, ErrorPath{}); + c.duplicateAssignExpressionError(nullptr, nullptr, true); + c.oppositeExpressionError(nullptr, ErrorPath{}); + c.duplicateExpressionError(nullptr, nullptr, nullptr, ErrorPath{}); + c.duplicateValueTernaryError(nullptr); + c.duplicateExpressionTernaryError(nullptr, ErrorPath{}); + c.duplicateBreakError(nullptr, false); + c.unreachableCodeError(nullptr, nullptr, false); + c.unsignedLessThanZeroError(nullptr, nullptr, "varname"); + c.unsignedPositiveError(nullptr, nullptr, "varname"); + c.pointerLessThanZeroError(nullptr, nullptr); + c.pointerPositiveError(nullptr, nullptr); + c.suspiciousSemicolonError(nullptr); + c.incompleteArrayFillError(nullptr, "buffer", "memset", false); + c.varFuncNullUBError(nullptr); + c.nanInArithmeticExpressionError(nullptr); + c.commaSeparatedReturnError(nullptr); + c.redundantPointerOpError(nullptr, "varname", false, /*addressOfDeref*/ true); + c.unusedLabelError(nullptr, false, false); + c.unusedLabelError(nullptr, false, true); + c.unusedLabelError(nullptr, true, false); + c.unusedLabelError(nullptr, true, true); + c.unknownEvaluationOrder(nullptr); + c.accessMovedError(nullptr, "v", nullptr, false); + c.funcArgNamesDifferent("function", 1, nullptr, nullptr); + c.redundantBitwiseOperationInSwitchError(nullptr, "varname"); + c.shadowError(nullptr, nullptr, "variable"); + c.shadowError(nullptr, nullptr, "function"); + c.shadowError(nullptr, nullptr, "argument"); + c.knownArgumentError(nullptr, nullptr, nullptr, "x", false); + c.knownPointerToBoolError(nullptr, nullptr); + c.comparePointersError(nullptr, nullptr, nullptr); + c.redundantAssignmentError(nullptr, nullptr, "var", false); + c.redundantInitializationError(nullptr, nullptr, "var", false); + + const std::vector nullvec; + c.funcArgOrderDifferent("function", nullptr, nullptr, nullvec, nullvec); + c.checkModuloOfOneError(nullptr); +} diff --git a/lib/checkother.h b/lib/checkother.h index 71eba43362b..38c68503e4d 100644 --- a/lib/checkother.h +++ b/lib/checkother.h @@ -25,7 +25,6 @@ #include "check.h" #include "config.h" #include "errortypes.h" -#include "tokenize.h" #include #include @@ -40,6 +39,7 @@ class Token; class Function; class Variable; class ErrorLogger; +class Tokenizer; /// @addtogroup Checks /// @{ @@ -69,53 +69,7 @@ class CPPCHECKLIB CheckOther : public Check { /** @brief Run checks against the normal token list */ - void runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLogger) override { - CheckOther checkOther(&tokenizer, &tokenizer.getSettings(), errorLogger); - - // Checks - checkOther.warningOldStylePointerCast(); - checkOther.suspiciousFloatingPointCast(); - checkOther.invalidPointerCast(); - checkOther.checkCharVariable(); - checkOther.redundantBitwiseOperationInSwitchError(); - checkOther.checkSuspiciousCaseInSwitch(); - checkOther.checkDuplicateBranch(); - checkOther.checkDuplicateExpression(); - checkOther.checkRedundantAssignment(); - checkOther.checkUnreachableCode(); - checkOther.checkSuspiciousSemicolon(); - checkOther.checkVariableScope(); - checkOther.checkSignOfUnsignedVariable(); // don't ignore casts (#3574) - checkOther.checkIncompleteArrayFill(); - checkOther.checkVarFuncNullUB(); - checkOther.checkNanInArithmeticExpression(); - checkOther.checkCommaSeparatedReturn(); - checkOther.checkRedundantPointerOp(); - checkOther.checkZeroDivision(); - checkOther.checkNegativeBitwiseShift(); - checkOther.checkInterlockedDecrement(); - checkOther.checkUnusedLabel(); - checkOther.checkEvaluationOrder(); - checkOther.checkFuncArgNamesDifferent(); - checkOther.checkShadowVariables(); - checkOther.checkKnownArgument(); - checkOther.checkKnownPointerToBool(); - checkOther.checkComparePointers(); - checkOther.checkIncompleteStatement(); - checkOther.checkRedundantCopy(); - checkOther.clarifyCalculation(); - checkOther.checkPassByReference(); - checkOther.checkConstVariable(); - checkOther.checkConstPointer(); - checkOther.checkComparisonFunctionIsAlwaysTrueOrFalse(); - checkOther.checkInvalidFree(); - checkOther.clarifyStatement(); - checkOther.checkCastIntToCharAndBack(); - checkOther.checkMisusedScopedObject(); - checkOther.checkAccessOfMovedVariable(); - checkOther.checkModuloOfOne(); - checkOther.checkOverlappingWrite(); - } + void runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLogger) override; /** @brief Clarify calculation for ".. a * b ? .." */ void clarifyCalculation(); @@ -296,80 +250,7 @@ class CPPCHECKLIB CheckOther : public Check { void comparePointersError(const Token *tok, const ValueFlow::Value *v1, const ValueFlow::Value *v2); void checkModuloOfOneError(const Token *tok); - void getErrorMessages(ErrorLogger *errorLogger, const Settings *settings) const override { - CheckOther c(nullptr, settings, errorLogger); - - // error - c.zerodivError(nullptr, nullptr); - c.misusedScopeObjectError(nullptr, "varname"); - c.invalidPointerCastError(nullptr, "float *", "double *", false, false); - c.negativeBitwiseShiftError(nullptr, 1); - c.negativeBitwiseShiftError(nullptr, 2); - c.raceAfterInterlockedDecrementError(nullptr); - c.invalidFreeError(nullptr, "malloc", false); - c.overlappingWriteUnion(nullptr); - c.overlappingWriteFunction(nullptr); - - //performance - c.redundantCopyError(nullptr, "varname"); - c.redundantCopyError(nullptr, nullptr, "var"); - - // style/warning - c.checkComparisonFunctionIsAlwaysTrueOrFalseError(nullptr, "isless","varName",false); - c.checkCastIntToCharAndBackError(nullptr, "func_name"); - c.cstyleCastError(nullptr); - c.suspiciousFloatingPointCastError(nullptr); - c.passedByValueError(nullptr, false); - c.constVariableError(nullptr, nullptr); - c.constStatementError(nullptr, "type", false); - c.signedCharArrayIndexError(nullptr); - c.unknownSignCharArrayIndexError(nullptr); - c.charBitOpError(nullptr); - c.variableScopeError(nullptr, "varname"); - c.redundantAssignmentInSwitchError(nullptr, nullptr, "var"); - c.suspiciousCaseInSwitchError(nullptr, "||"); - c.selfAssignmentError(nullptr, "varname"); - c.clarifyCalculationError(nullptr, "+"); - c.clarifyStatementError(nullptr); - c.duplicateBranchError(nullptr, nullptr, ErrorPath{}); - c.duplicateAssignExpressionError(nullptr, nullptr, true); - c.oppositeExpressionError(nullptr, ErrorPath{}); - c.duplicateExpressionError(nullptr, nullptr, nullptr, ErrorPath{}); - c.duplicateValueTernaryError(nullptr); - c.duplicateExpressionTernaryError(nullptr, ErrorPath{}); - c.duplicateBreakError(nullptr, false); - c.unreachableCodeError(nullptr, nullptr, false); - c.unsignedLessThanZeroError(nullptr, nullptr, "varname"); - c.unsignedPositiveError(nullptr, nullptr, "varname"); - c.pointerLessThanZeroError(nullptr, nullptr); - c.pointerPositiveError(nullptr, nullptr); - c.suspiciousSemicolonError(nullptr); - c.incompleteArrayFillError(nullptr, "buffer", "memset", false); - c.varFuncNullUBError(nullptr); - c.nanInArithmeticExpressionError(nullptr); - c.commaSeparatedReturnError(nullptr); - c.redundantPointerOpError(nullptr, "varname", false, /*addressOfDeref*/ true); - c.unusedLabelError(nullptr, false, false); - c.unusedLabelError(nullptr, false, true); - c.unusedLabelError(nullptr, true, false); - c.unusedLabelError(nullptr, true, true); - c.unknownEvaluationOrder(nullptr); - c.accessMovedError(nullptr, "v", nullptr, false); - c.funcArgNamesDifferent("function", 1, nullptr, nullptr); - c.redundantBitwiseOperationInSwitchError(nullptr, "varname"); - c.shadowError(nullptr, nullptr, "variable"); - c.shadowError(nullptr, nullptr, "function"); - c.shadowError(nullptr, nullptr, "argument"); - c.knownArgumentError(nullptr, nullptr, nullptr, "x", false); - c.knownPointerToBoolError(nullptr, nullptr); - c.comparePointersError(nullptr, nullptr, nullptr); - c.redundantAssignmentError(nullptr, nullptr, "var", false); - c.redundantInitializationError(nullptr, nullptr, "var", false); - - const std::vector nullvec; - c.funcArgOrderDifferent("function", nullptr, nullptr, nullvec, nullvec); - c.checkModuloOfOneError(nullptr); - } + void getErrorMessages(ErrorLogger *errorLogger, const Settings *settings) const override; static std::string myName() { return "Other"; diff --git a/lib/checkpostfixoperator.cpp b/lib/checkpostfixoperator.cpp index eb8d57a39e2..5ebcd65cd6b 100644 --- a/lib/checkpostfixoperator.cpp +++ b/lib/checkpostfixoperator.cpp @@ -27,6 +27,7 @@ #include "settings.h" #include "symboldatabase.h" #include "token.h" +#include "tokenize.h" #include @@ -87,3 +88,18 @@ void CheckPostfixOperator::postfixOperatorError(const Token *tok) "involves keeping a copy of the previous value around and " "adds a little extra code.", CWE398, Certainty::normal); } + +void CheckPostfixOperator::runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLogger) +{ + if (tokenizer.isC()) + return; + + CheckPostfixOperator checkPostfixOperator(&tokenizer, &tokenizer.getSettings(), errorLogger); + checkPostfixOperator.postfixOperator(); +} + +void CheckPostfixOperator::getErrorMessages(ErrorLogger *errorLogger, const Settings *settings) const +{ + CheckPostfixOperator c(nullptr, settings, errorLogger); + c.postfixOperatorError(nullptr); +} diff --git a/lib/checkpostfixoperator.h b/lib/checkpostfixoperator.h index e30bfb7cf98..cadd562ddd2 100644 --- a/lib/checkpostfixoperator.h +++ b/lib/checkpostfixoperator.h @@ -24,13 +24,13 @@ #include "check.h" #include "config.h" -#include "tokenize.h" #include class ErrorLogger; class Settings; class Token; +class Tokenizer; /// @addtogroup Checks /// @{ @@ -51,13 +51,7 @@ class CPPCHECKLIB CheckPostfixOperator : public Check { CheckPostfixOperator(const Tokenizer *tokenizer, const Settings *settings, ErrorLogger *errorLogger) : Check(myName(), tokenizer, settings, errorLogger) {} - void runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLogger) override { - if (tokenizer.isC()) - return; - - CheckPostfixOperator checkPostfixOperator(&tokenizer, &tokenizer.getSettings(), errorLogger); - checkPostfixOperator.postfixOperator(); - } + void runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLogger) override; /** Check postfix operators */ void postfixOperator(); @@ -65,10 +59,7 @@ class CPPCHECKLIB CheckPostfixOperator : public Check { /** Report Error */ void postfixOperatorError(const Token *tok); - void getErrorMessages(ErrorLogger *errorLogger, const Settings *settings) const override { - CheckPostfixOperator c(nullptr, settings, errorLogger); - c.postfixOperatorError(nullptr); - } + void getErrorMessages(ErrorLogger *errorLogger, const Settings *settings) const override; static std::string myName() { return "Using postfix operators"; diff --git a/lib/checksizeof.cpp b/lib/checksizeof.cpp index c14de0a78db..4136a55fb99 100644 --- a/lib/checksizeof.cpp +++ b/lib/checksizeof.cpp @@ -501,3 +501,35 @@ void CheckSizeof::arithOperationsOnVoidPointerError(const Token* tok, const std: const std::string verbose = message + " Arithmetic operations on 'void *' is a GNU C extension, which defines the 'sizeof(void)' to be 1."; reportError(tok, Severity::portability, "arithOperationsOnVoidPointer", "$symbol:" + varname + '\n' + message + '\n' + verbose, CWE467, Certainty::normal); } + +void CheckSizeof::runChecks(const Tokenizer& tokenizer, ErrorLogger* errorLogger) +{ + CheckSizeof checkSizeof(&tokenizer, &tokenizer.getSettings(), errorLogger); + + // Checks + checkSizeof.sizeofsizeof(); + checkSizeof.sizeofCalculation(); + checkSizeof.sizeofFunction(); + checkSizeof.suspiciousSizeofCalculation(); + checkSizeof.checkSizeofForArrayParameter(); + checkSizeof.checkSizeofForPointerSize(); + checkSizeof.checkSizeofForNumericParameter(); + checkSizeof.sizeofVoid(); +} + +void CheckSizeof::getErrorMessages(ErrorLogger* errorLogger, const Settings* settings) const +{ + CheckSizeof c(nullptr, settings, errorLogger); + c.sizeofForArrayParameterError(nullptr); + c.sizeofForPointerError(nullptr, "varname"); + c.divideBySizeofError(nullptr, "memset"); + c.sizeofForNumericParameterError(nullptr); + c.sizeofsizeofError(nullptr); + c.sizeofCalculationError(nullptr, false); + c.sizeofFunctionError(nullptr); + c.multiplySizeofError(nullptr); + c.divideSizeofError(nullptr); + c.sizeofVoidError(nullptr); + c.sizeofDereferencedVoidPointerError(nullptr, "varname"); + c.arithOperationsOnVoidPointerError(nullptr, "varname", "vartype"); +} diff --git a/lib/checksizeof.h b/lib/checksizeof.h index 81d6db49c64..2ba64419f38 100644 --- a/lib/checksizeof.h +++ b/lib/checksizeof.h @@ -24,13 +24,13 @@ #include "check.h" #include "config.h" -#include "tokenize.h" #include class ErrorLogger; class Settings; class Token; +class Tokenizer; /// @addtogroup Checks /// @{ @@ -49,19 +49,7 @@ class CPPCHECKLIB CheckSizeof : public Check { : Check(myName(), tokenizer, settings, errorLogger) {} /** @brief Run checks against the normal token list */ - void runChecks(const Tokenizer& tokenizer, ErrorLogger* errorLogger) override { - CheckSizeof checkSizeof(&tokenizer, &tokenizer.getSettings(), errorLogger); - - // Checks - checkSizeof.sizeofsizeof(); - checkSizeof.sizeofCalculation(); - checkSizeof.sizeofFunction(); - checkSizeof.suspiciousSizeofCalculation(); - checkSizeof.checkSizeofForArrayParameter(); - checkSizeof.checkSizeofForPointerSize(); - checkSizeof.checkSizeofForNumericParameter(); - checkSizeof.sizeofVoid(); - } + void runChecks(const Tokenizer& tokenizer, ErrorLogger* errorLogger) override; /** @brief %Check for 'sizeof sizeof ..' */ void sizeofsizeof(); @@ -101,21 +89,7 @@ class CPPCHECKLIB CheckSizeof : public Check { void sizeofDereferencedVoidPointerError(const Token *tok, const std::string &varname); void arithOperationsOnVoidPointerError(const Token* tok, const std::string &varname, const std::string &vartype); - void getErrorMessages(ErrorLogger* errorLogger, const Settings* settings) const override { - CheckSizeof c(nullptr, settings, errorLogger); - c.sizeofForArrayParameterError(nullptr); - c.sizeofForPointerError(nullptr, "varname"); - c.divideBySizeofError(nullptr, "memset"); - c.sizeofForNumericParameterError(nullptr); - c.sizeofsizeofError(nullptr); - c.sizeofCalculationError(nullptr, false); - c.sizeofFunctionError(nullptr); - c.multiplySizeofError(nullptr); - c.divideSizeofError(nullptr); - c.sizeofVoidError(nullptr); - c.sizeofDereferencedVoidPointerError(nullptr, "varname"); - c.arithOperationsOnVoidPointerError(nullptr, "varname", "vartype"); - } + void getErrorMessages(ErrorLogger* errorLogger, const Settings* settings) const override; static std::string myName() { return "Sizeof"; diff --git a/lib/checkstl.cpp b/lib/checkstl.cpp index e26e7a16e7a..f3b83827bf9 100644 --- a/lib/checkstl.cpp +++ b/lib/checkstl.cpp @@ -30,6 +30,7 @@ #include "tokenize.h" #include "utils.h" #include "valueflow.h" +#include "vfvalue.h" #include "checknullpointer.h" @@ -3303,3 +3304,80 @@ void CheckStl::checkMutexes() } } +void CheckStl::runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLogger) +{ + if (!tokenizer.isCPP()) { + return; + } + + CheckStl checkStl(&tokenizer, &tokenizer.getSettings(), errorLogger); + checkStl.erase(); + checkStl.if_find(); + checkStl.checkFindInsert(); + checkStl.iterators(); + checkStl.missingComparison(); + checkStl.outOfBounds(); + checkStl.outOfBoundsIndexExpression(); + checkStl.redundantCondition(); + checkStl.string_c_str(); + checkStl.uselessCalls(); + checkStl.useStlAlgorithm(); + + checkStl.stlOutOfBounds(); + checkStl.negativeIndex(); + + checkStl.invalidContainer(); + checkStl.mismatchingContainers(); + checkStl.mismatchingContainerIterator(); + checkStl.knownEmptyContainer(); + checkStl.eraseIteratorOutOfBounds(); + + checkStl.stlBoundaries(); + checkStl.checkDereferenceInvalidIterator(); + checkStl.checkDereferenceInvalidIterator2(); + checkStl.checkMutexes(); + + // Style check + checkStl.size(); +} + +void CheckStl::getErrorMessages(ErrorLogger* errorLogger, const Settings* settings) const +{ + CheckStl c(nullptr, settings, errorLogger); + c.outOfBoundsError(nullptr, "container", nullptr, "x", nullptr); + c.invalidIteratorError(nullptr, "iterator"); + c.iteratorsError(nullptr, "container1", "container2"); + c.iteratorsError(nullptr, nullptr, "container0", "container1"); + c.iteratorsError(nullptr, nullptr, "container"); + c.invalidContainerLoopError(nullptr, nullptr, ErrorPath{}); + c.invalidContainerError(nullptr, nullptr, nullptr, ErrorPath{}); + c.mismatchingContainerIteratorError(nullptr, nullptr, nullptr); + c.mismatchingContainersError(nullptr, nullptr); + c.mismatchingContainerExpressionError(nullptr, nullptr); + c.sameIteratorExpressionError(nullptr); + c.dereferenceErasedError(nullptr, nullptr, "iter", false); + c.stlOutOfBoundsError(nullptr, "i", "foo", false); + c.negativeIndexError(nullptr, ValueFlow::Value(-1)); + c.stlBoundariesError(nullptr); + c.if_findError(nullptr, false); + c.if_findError(nullptr, true); + c.checkFindInsertError(nullptr); + c.string_c_strError(nullptr); + c.string_c_strReturn(nullptr); + c.string_c_strParam(nullptr, 0); + c.string_c_strThrowError(nullptr); + c.sizeError(nullptr); + c.missingComparisonError(nullptr, nullptr); + c.redundantIfRemoveError(nullptr); + c.uselessCallsReturnValueError(nullptr, "str", "find"); + c.uselessCallsSwapError(nullptr, "str"); + c.uselessCallsSubstrError(nullptr, SubstrErrorType::COPY); + c.uselessCallsEmptyError(nullptr); + c.uselessCallsRemoveError(nullptr, "remove"); + c.dereferenceInvalidIteratorError(nullptr, "i"); + c.eraseIteratorOutOfBoundsError(nullptr, nullptr); + c.useStlAlgorithmError(nullptr, emptyString); + c.knownEmptyContainerError(nullptr, emptyString); + c.globalLockGuardError(nullptr); + c.localMutexError(nullptr); +} diff --git a/lib/checkstl.h b/lib/checkstl.h index 60cb3c2cc23..7b57e96b5f3 100644 --- a/lib/checkstl.h +++ b/lib/checkstl.h @@ -25,8 +25,6 @@ #include "check.h" #include "config.h" #include "errortypes.h" -#include "tokenize.h" -#include "vfvalue.h" #include #include @@ -36,7 +34,11 @@ class Settings; class Token; class Variable; class ErrorLogger; - +class Tokenizer; +namespace ValueFlow +{ + class Value; +} /// @addtogroup Checks /// @{ @@ -54,41 +56,7 @@ class CPPCHECKLIB CheckStl : public Check { : Check(myName(), tokenizer, settings, errorLogger) {} /** run checks, the token list is not simplified */ - void runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLogger) override { - if (!tokenizer.isCPP()) { - return; - } - - CheckStl checkStl(&tokenizer, &tokenizer.getSettings(), errorLogger); - checkStl.erase(); - checkStl.if_find(); - checkStl.checkFindInsert(); - checkStl.iterators(); - checkStl.missingComparison(); - checkStl.outOfBounds(); - checkStl.outOfBoundsIndexExpression(); - checkStl.redundantCondition(); - checkStl.string_c_str(); - checkStl.uselessCalls(); - checkStl.useStlAlgorithm(); - - checkStl.stlOutOfBounds(); - checkStl.negativeIndex(); - - checkStl.invalidContainer(); - checkStl.mismatchingContainers(); - checkStl.mismatchingContainerIterator(); - checkStl.knownEmptyContainer(); - checkStl.eraseIteratorOutOfBounds(); - - checkStl.stlBoundaries(); - checkStl.checkDereferenceInvalidIterator(); - checkStl.checkDereferenceInvalidIterator2(); - checkStl.checkMutexes(); - - // Style check - checkStl.size(); - } + void runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLogger) override; /** Accessing container out of bounds using ValueFlow */ void outOfBounds(); @@ -243,45 +211,7 @@ class CPPCHECKLIB CheckStl : public Check { void globalLockGuardError(const Token *tok); void localMutexError(const Token *tok); - void getErrorMessages(ErrorLogger* errorLogger, const Settings* settings) const override { - CheckStl c(nullptr, settings, errorLogger); - c.outOfBoundsError(nullptr, "container", nullptr, "x", nullptr); - c.invalidIteratorError(nullptr, "iterator"); - c.iteratorsError(nullptr, "container1", "container2"); - c.iteratorsError(nullptr, nullptr, "container0", "container1"); - c.iteratorsError(nullptr, nullptr, "container"); - c.invalidContainerLoopError(nullptr, nullptr, ErrorPath{}); - c.invalidContainerError(nullptr, nullptr, nullptr, ErrorPath{}); - c.mismatchingContainerIteratorError(nullptr, nullptr, nullptr); - c.mismatchingContainersError(nullptr, nullptr); - c.mismatchingContainerExpressionError(nullptr, nullptr); - c.sameIteratorExpressionError(nullptr); - c.dereferenceErasedError(nullptr, nullptr, "iter", false); - c.stlOutOfBoundsError(nullptr, "i", "foo", false); - c.negativeIndexError(nullptr, ValueFlow::Value(-1)); - c.stlBoundariesError(nullptr); - c.if_findError(nullptr, false); - c.if_findError(nullptr, true); - c.checkFindInsertError(nullptr); - c.string_c_strError(nullptr); - c.string_c_strReturn(nullptr); - c.string_c_strParam(nullptr, 0); - c.string_c_strThrowError(nullptr); - c.sizeError(nullptr); - c.missingComparisonError(nullptr, nullptr); - c.redundantIfRemoveError(nullptr); - c.uselessCallsReturnValueError(nullptr, "str", "find"); - c.uselessCallsSwapError(nullptr, "str"); - c.uselessCallsSubstrError(nullptr, SubstrErrorType::COPY); - c.uselessCallsEmptyError(nullptr); - c.uselessCallsRemoveError(nullptr, "remove"); - c.dereferenceInvalidIteratorError(nullptr, "i"); - c.eraseIteratorOutOfBoundsError(nullptr, nullptr); - c.useStlAlgorithmError(nullptr, emptyString); - c.knownEmptyContainerError(nullptr, emptyString); - c.globalLockGuardError(nullptr); - c.localMutexError(nullptr); - } + void getErrorMessages(ErrorLogger* errorLogger, const Settings* settings) const override; static std::string myName() { return "STL usage"; diff --git a/lib/checkstring.cpp b/lib/checkstring.cpp index 7062a5805f7..462f053446a 100644 --- a/lib/checkstring.cpp +++ b/lib/checkstring.cpp @@ -474,3 +474,33 @@ void CheckString::sprintfOverlappingDataError(const Token *funcTok, const Token "\"If copying takes place between objects that overlap as a result of a call " "to sprintf() or snprintf(), the results are undefined.\"", CWE628, Certainty::normal); } + +void CheckString::runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLogger) +{ + CheckString checkString(&tokenizer, &tokenizer.getSettings(), errorLogger); + + // Checks + checkString.strPlusChar(); + checkString.checkSuspiciousStringCompare(); + checkString.stringLiteralWrite(); + checkString.overlappingStrcmp(); + checkString.checkIncorrectStringCompare(); + checkString.sprintfOverlappingData(); + checkString.checkAlwaysTrueOrFalseStringCompare(); +} + +void CheckString::getErrorMessages(ErrorLogger *errorLogger, const Settings *settings) const +{ + CheckString c(nullptr, settings, errorLogger); + c.stringLiteralWriteError(nullptr, nullptr); + c.sprintfOverlappingDataError(nullptr, nullptr, "varname"); + c.strPlusCharError(nullptr); + c.incorrectStringCompareError(nullptr, "substr", "\"Hello World\""); + c.suspiciousStringCompareError(nullptr, "foo", false); + c.suspiciousStringCompareError_char(nullptr, "foo"); + c.incorrectStringBooleanError(nullptr, "\"Hello World\""); + c.incorrectStringBooleanError(nullptr, "\'x\'"); + c.alwaysTrueFalseStringCompareError(nullptr, "str1", "str2"); + c.alwaysTrueStringVariableCompareError(nullptr, "varname1", "varname2"); + c.overlappingStrcmpError(nullptr, nullptr); +} diff --git a/lib/checkstring.h b/lib/checkstring.h index 8fb6efd697f..91cc88c4291 100644 --- a/lib/checkstring.h +++ b/lib/checkstring.h @@ -24,13 +24,13 @@ #include "check.h" #include "config.h" -#include "tokenize.h" #include class ErrorLogger; class Settings; class Token; +class Tokenizer; /// @addtogroup Checks /// @{ @@ -49,18 +49,7 @@ class CPPCHECKLIB CheckString : public Check { : Check(myName(), tokenizer, settings, errorLogger) {} /** @brief Run checks against the normal token list */ - void runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLogger) override { - CheckString checkString(&tokenizer, &tokenizer.getSettings(), errorLogger); - - // Checks - checkString.strPlusChar(); - checkString.checkSuspiciousStringCompare(); - checkString.stringLiteralWrite(); - checkString.overlappingStrcmp(); - checkString.checkIncorrectStringCompare(); - checkString.sprintfOverlappingData(); - checkString.checkAlwaysTrueOrFalseStringCompare(); - } + void runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLogger) override; /** @brief undefined behaviour, writing string literal */ void stringLiteralWrite(); @@ -94,20 +83,7 @@ class CPPCHECKLIB CheckString : public Check { void suspiciousStringCompareError_char(const Token* tok, const std::string& var); void overlappingStrcmpError(const Token* eq0, const Token *ne0); - void getErrorMessages(ErrorLogger *errorLogger, const Settings *settings) const override { - CheckString c(nullptr, settings, errorLogger); - c.stringLiteralWriteError(nullptr, nullptr); - c.sprintfOverlappingDataError(nullptr, nullptr, "varname"); - c.strPlusCharError(nullptr); - c.incorrectStringCompareError(nullptr, "substr", "\"Hello World\""); - c.suspiciousStringCompareError(nullptr, "foo", false); - c.suspiciousStringCompareError_char(nullptr, "foo"); - c.incorrectStringBooleanError(nullptr, "\"Hello World\""); - c.incorrectStringBooleanError(nullptr, "\'x\'"); - c.alwaysTrueFalseStringCompareError(nullptr, "str1", "str2"); - c.alwaysTrueStringVariableCompareError(nullptr, "varname1", "varname2"); - c.overlappingStrcmpError(nullptr, nullptr); - } + void getErrorMessages(ErrorLogger *errorLogger, const Settings *settings) const override; static std::string myName() { return "String"; diff --git a/lib/checktype.cpp b/lib/checktype.cpp index a9eda1b8a82..de0a69cf109 100644 --- a/lib/checktype.cpp +++ b/lib/checktype.cpp @@ -30,6 +30,7 @@ #include "token.h" #include "tokenize.h" #include "valueflow.h" +#include "vfvalue.h" #include #include @@ -521,3 +522,29 @@ void CheckType::floatToIntegerOverflowError(const Token *tok, const ValueFlow::V "floatConversionOverflow", errmsg.str(), CWE190, value.isInconclusive() ? Certainty::inconclusive : Certainty::normal); } + +void CheckType::runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLogger) +{ + // These are not "simplified" because casts can't be ignored + CheckType checkType(&tokenizer, &tokenizer.getSettings(), errorLogger); + checkType.checkTooBigBitwiseShift(); + checkType.checkIntegerOverflow(); + checkType.checkSignConversion(); + checkType.checkLongCast(); + checkType.checkFloatToIntegerOverflow(); +} + +void CheckType::getErrorMessages(ErrorLogger *errorLogger, const Settings *settings) const +{ + CheckType c(nullptr, settings, errorLogger); + c.tooBigBitwiseShiftError(nullptr, 32, ValueFlow::Value(64)); + c.tooBigSignedBitwiseShiftError(nullptr, 31, ValueFlow::Value(31)); + c.integerOverflowError(nullptr, ValueFlow::Value(1LL<<32)); + c.signConversionError(nullptr, nullptr, false); + c.longCastAssignError(nullptr); + c.longCastReturnError(nullptr); + ValueFlow::Value f; + f.valueType = ValueFlow::Value::ValueType::FLOAT; + f.floatValue = 1E100; + c.floatToIntegerOverflowError(nullptr, f); +} diff --git a/lib/checktype.h b/lib/checktype.h index e76276c4ccf..a621531bc81 100644 --- a/lib/checktype.h +++ b/lib/checktype.h @@ -24,8 +24,6 @@ #include "check.h" #include "config.h" -#include "tokenize.h" -#include "vfvalue.h" #include #include @@ -34,6 +32,11 @@ class ErrorLogger; class Settings; class Token; class ValueType; +class Tokenizer; +namespace ValueFlow +{ + class Value; +} /// @addtogroup Checks /// @{ @@ -52,15 +55,7 @@ class CPPCHECKLIB CheckType : public Check { : Check(myName(), tokenizer, settings, errorLogger) {} /** @brief Run checks against the normal token list */ - void runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLogger) override { - // These are not "simplified" because casts can't be ignored - CheckType checkType(&tokenizer, &tokenizer.getSettings(), errorLogger); - checkType.checkTooBigBitwiseShift(); - checkType.checkIntegerOverflow(); - checkType.checkSignConversion(); - checkType.checkLongCast(); - checkType.checkFloatToIntegerOverflow(); - } + void runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLogger) override; /** @brief %Check for bitwise shift with too big right operand */ void checkTooBigBitwiseShift(); @@ -87,19 +82,7 @@ class CPPCHECKLIB CheckType : public Check { void longCastReturnError(const Token *tok, const ValueType* src = nullptr, const ValueType* tgt = nullptr); void floatToIntegerOverflowError(const Token *tok, const ValueFlow::Value &value); - void getErrorMessages(ErrorLogger *errorLogger, const Settings *settings) const override { - CheckType c(nullptr, settings, errorLogger); - c.tooBigBitwiseShiftError(nullptr, 32, ValueFlow::Value(64)); - c.tooBigSignedBitwiseShiftError(nullptr, 31, ValueFlow::Value(31)); - c.integerOverflowError(nullptr, ValueFlow::Value(1LL<<32)); - c.signConversionError(nullptr, nullptr, false); - c.longCastAssignError(nullptr); - c.longCastReturnError(nullptr); - ValueFlow::Value f; - f.valueType = ValueFlow::Value::ValueType::FLOAT; - f.floatValue = 1E100; - c.floatToIntegerOverflowError(nullptr, f); - } + void getErrorMessages(ErrorLogger *errorLogger, const Settings *settings) const override; static std::string myName() { return "Type"; diff --git a/lib/checkuninitvar.cpp b/lib/checkuninitvar.cpp index 72a34bfc896..3fe012470bf 100644 --- a/lib/checkuninitvar.cpp +++ b/lib/checkuninitvar.cpp @@ -29,6 +29,7 @@ #include "symboldatabase.h" #include "token.h" #include "tokenize.h" +#include "vfvalue.h" #include "checknullpointer.h" // CheckNullPointer::isPointerDeref @@ -1781,3 +1782,21 @@ bool CheckUninitVar::analyseWholeProgram(const CTU::FileInfo *ctu, const std::li } return foundErrors; } + +void CheckUninitVar::runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLogger) +{ + CheckUninitVar checkUninitVar(&tokenizer, &tokenizer.getSettings(), errorLogger); + checkUninitVar.valueFlowUninit(); + checkUninitVar.check(); +} + +void CheckUninitVar::getErrorMessages(ErrorLogger* errorLogger, const Settings* settings) const +{ + CheckUninitVar c(nullptr, settings, errorLogger); + + ValueFlow::Value v{}; + + c.uninitvarError(nullptr, v); + c.uninitdataError(nullptr, "varname"); + c.uninitStructMemberError(nullptr, "a.b"); +} diff --git a/lib/checkuninitvar.h b/lib/checkuninitvar.h index cb31917139a..f8328462258 100644 --- a/lib/checkuninitvar.h +++ b/lib/checkuninitvar.h @@ -26,8 +26,6 @@ #include "config.h" #include "mathlib.h" #include "errortypes.h" -#include "tokenize.h" -#include "vfvalue.h" #include #include @@ -40,6 +38,11 @@ class Variable; class ErrorLogger; class Settings; class Library; +class Tokenizer; +namespace ValueFlow +{ + class Value; +} struct VariableValue { explicit VariableValue(MathLib::bigint val = 0) : value(val) {} @@ -71,11 +74,7 @@ class CPPCHECKLIB CheckUninitVar : public Check { : Check(myName(), tokenizer, settings, errorLogger) {} /** @brief Run checks against the normal token list */ - void runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLogger) override { - CheckUninitVar checkUninitVar(&tokenizer, &tokenizer.getSettings(), errorLogger); - checkUninitVar.valueFlowUninit(); - checkUninitVar.check(); - } + void runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLogger) override; bool diag(const Token* tok); /** Check for uninitialized variables */ @@ -120,16 +119,7 @@ class CPPCHECKLIB CheckUninitVar : public Check { std::set mUninitDiags; - void getErrorMessages(ErrorLogger* errorLogger, const Settings* settings) const override - { - CheckUninitVar c(nullptr, settings, errorLogger); - - ValueFlow::Value v{}; - - c.uninitvarError(nullptr, v); - c.uninitdataError(nullptr, "varname"); - c.uninitStructMemberError(nullptr, "a.b"); - } + void getErrorMessages(ErrorLogger* errorLogger, const Settings* settings) const override; static std::string myName() { return "Uninitialized variables"; diff --git a/lib/checkunusedvar.cpp b/lib/checkunusedvar.cpp index 194356652e1..a64f9071dc1 100644 --- a/lib/checkunusedvar.cpp +++ b/lib/checkunusedvar.cpp @@ -1773,3 +1773,22 @@ bool CheckUnusedVar::isFunctionWithoutSideEffects(const Function& func, const To return !sideEffectReturnFound; } + +void CheckUnusedVar::runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLogger) +{ + CheckUnusedVar checkUnusedVar(&tokenizer, &tokenizer.getSettings(), errorLogger); + + // Coding style checks + checkUnusedVar.checkStructMemberUsage(); + checkUnusedVar.checkFunctionVariableUsage(); +} + +void CheckUnusedVar::getErrorMessages(ErrorLogger *errorLogger, const Settings *settings) const +{ + CheckUnusedVar c(nullptr, settings, errorLogger); + c.unusedVariableError(nullptr, "varname"); + c.allocatedButUnusedVariableError(nullptr, "varname"); + c.unreadVariableError(nullptr, "varname", false); + c.unassignedVariableError(nullptr, "varname"); + c.unusedStructMemberError(nullptr, "structname", "variable"); +} diff --git a/lib/checkunusedvar.h b/lib/checkunusedvar.h index 8e4b214401c..676abbdfd4a 100644 --- a/lib/checkunusedvar.h +++ b/lib/checkunusedvar.h @@ -23,7 +23,6 @@ #include "check.h" #include "config.h" -#include "tokenize.h" #include #include @@ -37,6 +36,7 @@ class Type; class Variables; class Variable; class Function; +class Tokenizer; /// @addtogroup Checks /// @{ @@ -57,13 +57,7 @@ class CPPCHECKLIB CheckUnusedVar : public Check { : Check(myName(), tokenizer, settings, errorLogger) {} /** @brief Run checks against the normal token list */ - void runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLogger) override { - CheckUnusedVar checkUnusedVar(&tokenizer, &tokenizer.getSettings(), errorLogger); - - // Coding style checks - checkUnusedVar.checkStructMemberUsage(); - checkUnusedVar.checkFunctionVariableUsage(); - } + void runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLogger) override; /** @brief %Check for unused function variables */ void checkFunctionVariableUsage_iterateScopes(const Scope* scope, Variables& variables); @@ -85,14 +79,7 @@ class CPPCHECKLIB CheckUnusedVar : public Check { void unreadVariableError(const Token *tok, const std::string &varname, bool modified); void unassignedVariableError(const Token *tok, const std::string &varname); - void getErrorMessages(ErrorLogger *errorLogger, const Settings *settings) const override { - CheckUnusedVar c(nullptr, settings, errorLogger); - c.unusedVariableError(nullptr, "varname"); - c.allocatedButUnusedVariableError(nullptr, "varname"); - c.unreadVariableError(nullptr, "varname", false); - c.unassignedVariableError(nullptr, "varname"); - c.unusedStructMemberError(nullptr, "structname", "variable"); - } + void getErrorMessages(ErrorLogger *errorLogger, const Settings *settings) const override; static std::string myName() { return "UnusedVar"; diff --git a/lib/checkvaarg.cpp b/lib/checkvaarg.cpp index 7ad381e16d0..57b748c661d 100644 --- a/lib/checkvaarg.cpp +++ b/lib/checkvaarg.cpp @@ -180,3 +180,20 @@ void CheckVaarg::va_start_subsequentCallsError(const Token *tok, const std::stri reportError(tok, Severity::error, "va_start_subsequentCalls", "va_start() or va_copy() called subsequently on '" + varname + "' without va_end() in between.", CWE664, Certainty::normal); } + +void CheckVaarg::runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLogger) +{ + CheckVaarg check(&tokenizer, &tokenizer.getSettings(), errorLogger); + check.va_start_argument(); + check.va_list_usage(); +} + +void CheckVaarg::getErrorMessages(ErrorLogger *errorLogger, const Settings *settings) const +{ + CheckVaarg c(nullptr, settings, errorLogger); + c.wrongParameterTo_va_start_error(nullptr, "arg1", "arg2"); + c.referenceAs_va_start_error(nullptr, "arg1"); + c.va_end_missingError(nullptr, "vl"); + c.va_list_usedBeforeStartedError(nullptr, "vl"); + c.va_start_subsequentCallsError(nullptr, "vl"); +} diff --git a/lib/checkvaarg.h b/lib/checkvaarg.h index 63d7ddbe3c0..fdeb7f47ddf 100644 --- a/lib/checkvaarg.h +++ b/lib/checkvaarg.h @@ -24,13 +24,13 @@ #include "check.h" #include "config.h" -#include "tokenize.h" #include class ErrorLogger; class Settings; class Token; +class Tokenizer; /// @addtogroup Checks /// @{ @@ -47,11 +47,7 @@ class CPPCHECKLIB CheckVaarg : public Check { CheckVaarg(const Tokenizer *tokenizer, const Settings *settings, ErrorLogger *errorLogger) : Check(myName(), tokenizer, settings, errorLogger) {} - void runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLogger) override { - CheckVaarg check(&tokenizer, &tokenizer.getSettings(), errorLogger); - check.va_start_argument(); - check.va_list_usage(); - } + void runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLogger) override; void va_start_argument(); void va_list_usage(); @@ -62,14 +58,7 @@ class CPPCHECKLIB CheckVaarg : public Check { void va_list_usedBeforeStartedError(const Token *tok, const std::string& varname); void va_start_subsequentCallsError(const Token *tok, const std::string& varname); - void getErrorMessages(ErrorLogger *errorLogger, const Settings *settings) const override { - CheckVaarg c(nullptr, settings, errorLogger); - c.wrongParameterTo_va_start_error(nullptr, "arg1", "arg2"); - c.referenceAs_va_start_error(nullptr, "arg1"); - c.va_end_missingError(nullptr, "vl"); - c.va_list_usedBeforeStartedError(nullptr, "vl"); - c.va_start_subsequentCallsError(nullptr, "vl"); - } + void getErrorMessages(ErrorLogger *errorLogger, const Settings *settings) const override; static std::string myName() { return "Vaarg"; diff --git a/oss-fuzz/Makefile b/oss-fuzz/Makefile index b0791ec1f31..db4fa5cd6c5 100644 --- a/oss-fuzz/Makefile +++ b/oss-fuzz/Makefile @@ -144,7 +144,7 @@ simplecpp.o: ../externals/simplecpp/simplecpp.cpp ../externals/simplecpp/simplec tinyxml2.o: ../externals/tinyxml2/tinyxml2.cpp ../externals/tinyxml2/tinyxml2.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -w -D_LARGEFILE_SOURCE -c -o $@ ../externals/tinyxml2/tinyxml2.cpp -$(libcppdir)/valueflow.o: ../lib/valueflow.cpp ../lib/addoninfo.h ../lib/analyzer.h ../lib/astutils.h ../lib/calculate.h ../lib/check.h ../lib/checkuninitvar.h ../lib/color.h ../lib/config.h ../lib/errorlogger.h ../lib/errortypes.h ../lib/findtoken.h ../lib/forwardanalyzer.h ../lib/infer.h ../lib/library.h ../lib/mathlib.h ../lib/path.h ../lib/platform.h ../lib/programmemory.h ../lib/reverseanalyzer.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.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 ../lib/valueptr.h ../lib/vf_analyzers.h ../lib/vf_common.h ../lib/vf_settokenvalue.h ../lib/vfvalue.h +$(libcppdir)/valueflow.o: ../lib/valueflow.cpp ../lib/addoninfo.h ../lib/analyzer.h ../lib/astutils.h ../lib/calculate.h ../lib/check.h ../lib/checkuninitvar.h ../lib/color.h ../lib/config.h ../lib/errorlogger.h ../lib/errortypes.h ../lib/findtoken.h ../lib/forwardanalyzer.h ../lib/infer.h ../lib/library.h ../lib/mathlib.h ../lib/path.h ../lib/platform.h ../lib/programmemory.h ../lib/reverseanalyzer.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/suppressions.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/timer.h ../lib/token.h ../lib/tokenlist.h ../lib/utils.h ../lib/valueflow.h ../lib/valueptr.h ../lib/vf_analyzers.h ../lib/vf_common.h ../lib/vf_settokenvalue.h ../lib/vfvalue.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/valueflow.cpp $(libcppdir)/tokenize.o: ../lib/tokenize.cpp ../externals/simplecpp/simplecpp.h ../lib/addoninfo.h ../lib/astutils.h ../lib/color.h ../lib/config.h ../lib/errorlogger.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/path.h ../lib/platform.h ../lib/preprocessor.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/summaries.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 ../lib/vfvalue.h @@ -159,7 +159,7 @@ $(libcppdir)/addoninfo.o: ../lib/addoninfo.cpp ../externals/picojson/picojson.h $(libcppdir)/analyzerinfo.o: ../lib/analyzerinfo.cpp ../externals/tinyxml2/tinyxml2.h ../lib/analyzerinfo.h ../lib/color.h ../lib/config.h ../lib/errorlogger.h ../lib/errortypes.h ../lib/filesettings.h ../lib/mathlib.h ../lib/path.h ../lib/platform.h ../lib/standards.h ../lib/utils.h ../lib/xml.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/analyzerinfo.cpp -$(libcppdir)/astutils.o: ../lib/astutils.cpp ../lib/addoninfo.h ../lib/astutils.h ../lib/check.h ../lib/checkclass.h ../lib/config.h ../lib/errortypes.h ../lib/findtoken.h ../lib/infer.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/valueflow.h ../lib/valueptr.h ../lib/vfvalue.h +$(libcppdir)/astutils.o: ../lib/astutils.cpp ../lib/addoninfo.h ../lib/astutils.h ../lib/check.h ../lib/checkclass.h ../lib/config.h ../lib/errortypes.h ../lib/findtoken.h ../lib/infer.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/utils.h ../lib/valueflow.h ../lib/valueptr.h ../lib/vfvalue.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/astutils.cpp $(libcppdir)/check.o: ../lib/check.cpp ../lib/addoninfo.h ../lib/check.h ../lib/color.h ../lib/config.h ../lib/errorlogger.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/settings.h ../lib/standards.h ../lib/suppressions.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/vfvalue.h