diff --git a/Makefile b/Makefile index 9ba42bb6bb1..8e25da3014e 100644 --- a/Makefile +++ b/Makefile @@ -564,7 +564,7 @@ $(libcppdir)/clangimport.o: lib/clangimport.cpp lib/addoninfo.h lib/checkers.h l $(libcppdir)/color.o: lib/color.cpp lib/color.h lib/config.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/color.cpp -$(libcppdir)/cppcheck.o: lib/cppcheck.cpp externals/picojson/picojson.h externals/simplecpp/simplecpp.h externals/tinyxml2/tinyxml2.h lib/addoninfo.h lib/analyzerinfo.h lib/check.h lib/checkers.h lib/checkunusedfunctions.h lib/clangimport.h lib/color.h lib/config.h lib/cppcheck.h lib/ctu.h lib/errorlogger.h lib/errortypes.h lib/filesettings.h lib/json.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/preprocessor.h lib/settings.h lib/standards.h lib/suppressions.h lib/templatesimplifier.h lib/timer.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/valueflow.h lib/version.h lib/vfvalue.h lib/xml.h +$(libcppdir)/cppcheck.o: lib/cppcheck.cpp externals/picojson/picojson.h externals/simplecpp/simplecpp.h externals/tinyxml2/tinyxml2.h lib/addoninfo.h lib/analyzerinfo.h lib/check.h lib/checkers.h lib/checkunusedfunctions.h lib/clangimport.h lib/color.h lib/config.h lib/cppcheck.h lib/ctu.h lib/errorlogger.h lib/errortypes.h lib/filesettings.h lib/json.h lib/library.h lib/mathlib.h lib/path.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/timer.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/valueflow.h lib/version.h lib/vfvalue.h lib/xml.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/cppcheck.cpp $(libcppdir)/ctu.o: lib/ctu.cpp externals/tinyxml2/tinyxml2.h lib/addoninfo.h lib/astutils.h lib/check.h lib/checkers.h lib/config.h lib/ctu.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h lib/xml.h diff --git a/lib/checkbufferoverrun.cpp b/lib/checkbufferoverrun.cpp index 5886ccbf640..a43d5b26ee8 100644 --- a/lib/checkbufferoverrun.cpp +++ b/lib/checkbufferoverrun.cpp @@ -1235,4 +1235,7 @@ void CheckBufferOverrun::getErrorMessages(ErrorLogger *errorLogger, const Settin c.argumentSizeError(nullptr, "function", 1, "buffer", nullptr, nullptr); c.negativeMemoryAllocationSizeError(nullptr, nullptr); c.negativeArraySizeError(nullptr); + c.terminateStrncpyError(nullptr, "var_name"); + // TODO: ctuArrayIndex + // TODO: ctuPointerArith } diff --git a/lib/checkclass.cpp b/lib/checkclass.cpp index 3c7816a9479..8ae5565a246 100644 --- a/lib/checkclass.cpp +++ b/lib/checkclass.cpp @@ -3887,4 +3887,5 @@ void CheckClass::getErrorMessages(ErrorLogger *errorLogger, const Settings *sett c.virtualFunctionCallInConstructorError(nullptr, std::list(), "f"); c.thisUseAfterFree(nullptr, nullptr, nullptr); c.unsafeClassRefMemberError(nullptr, "UnsafeClass::var"); + // TODO: ctuOneDefinitionRuleViolation } diff --git a/lib/checkfunctions.cpp b/lib/checkfunctions.cpp index 26ff9736f43..8884a03fc48 100644 --- a/lib/checkfunctions.cpp +++ b/lib/checkfunctions.cpp @@ -865,6 +865,7 @@ void CheckFunctions::getErrorMessages(ErrorLogger *errorLogger, const Settings * c.invalidFunctionArgBoolError(nullptr, "func_name", 1); c.invalidFunctionArgStrError(nullptr, "func_name", 1); c.ignoredReturnValueError(nullptr, "malloc"); + c.ignoredReturnErrorCode(nullptr, "func_name"); c.mathfunctionCallWarning(nullptr); c.mathfunctionCallWarning(nullptr, "1 - erf(x)", "erfc(x)"); c.memsetZeroBytesError(nullptr); @@ -873,4 +874,5 @@ void CheckFunctions::getErrorMessages(ErrorLogger *errorLogger, const Settings * c.missingReturnError(nullptr); c.copyElisionError(nullptr); c.useStandardLibraryError(nullptr, "memcpy"); + // TODO: allocaCalled, Called } diff --git a/lib/checknullpointer.cpp b/lib/checknullpointer.cpp index 7defd07cf04..0214eceedd1 100644 --- a/lib/checknullpointer.cpp +++ b/lib/checknullpointer.cpp @@ -720,5 +720,9 @@ void CheckNullPointer::getErrorMessages(ErrorLogger *errorLogger, const Settings CheckNullPointer c(nullptr, settings, errorLogger); c.nullPointerError(nullptr, "pointer", nullptr, false); c.pointerArithmeticError(nullptr, nullptr, false); + // TODO: nullPointerArithmeticOutOfMemory c.redundantConditionWarning(nullptr, nullptr, nullptr, false); + // TODO: ctunullpointer + // TODO: ctunullpointerOutOfMemory + // TODO: ctunullpointerOutOfResources } diff --git a/lib/checkother.cpp b/lib/checkother.cpp index 5af22c7b2c5..7a06f66f644 100644 --- a/lib/checkother.cpp +++ b/lib/checkother.cpp @@ -4583,6 +4583,8 @@ void CheckOther::getErrorMessages(ErrorLogger *errorLogger, const Settings *sett c.intToPointerCastError(nullptr, "decimal"); c.suspiciousFloatingPointCastError(nullptr); c.passedByValueError(nullptr, false); + // TODO: iterateByValue + // TODO: passedByValueCallback c.constVariableError(nullptr, nullptr); c.constStatementError(nullptr, "type", false); c.signedCharArrayIndexError(nullptr); @@ -4626,8 +4628,10 @@ void CheckOther::getErrorMessages(ErrorLogger *errorLogger, const Settings *sett c.knownArgumentError(nullptr, nullptr, nullptr, "x", false); c.knownPointerToBoolError(nullptr, nullptr); c.comparePointersError(nullptr, nullptr, nullptr); + // TODO: subtractPointers c.redundantAssignmentError(nullptr, nullptr, "var", false); c.redundantInitializationError(nullptr, nullptr, "var", false); + c.redundantContinueError(nullptr); const std::vector nullvec; c.funcArgOrderDifferent("function", nullptr, nullptr, nullvec, nullvec); diff --git a/lib/checkstl.cpp b/lib/checkstl.cpp index b07b1809bb1..a88591a904a 100644 --- a/lib/checkstl.cpp +++ b/lib/checkstl.cpp @@ -2350,7 +2350,8 @@ void CheckStl::uselessCallsSubstrError(const Token *tok, SubstrErrorType type) void CheckStl::uselessCallsConstructorError(const Token *tok) { - const std::string msg = "Inefficient constructor call: container '" + tok->str() + "' is assigned a partial copy of itself. Use erase() or resize() instead."; + const std::string container = tok ? tok->str() : ""; + const std::string msg = "Inefficient constructor call: container '" + container + "' is assigned a partial copy of itself. Use erase() or resize() instead."; reportError(tok, Severity::performance, "uselessCallsConstructor", msg, CWE398, Certainty::normal); } @@ -3456,6 +3457,7 @@ void CheckStl::getErrorMessages(ErrorLogger* errorLogger, const Settings* settin c.iteratorsError(nullptr, nullptr, "container"); c.invalidContainerLoopError(nullptr, nullptr, ErrorPath{}); c.invalidContainerError(nullptr, nullptr, nullptr, ErrorPath{}); + c.invalidContainerReferenceError(nullptr, nullptr, ErrorPath{}); c.mismatchingContainerIteratorError(nullptr, nullptr, nullptr); c.mismatchingContainersError(nullptr, nullptr); c.mismatchingContainerExpressionError(nullptr, nullptr); @@ -3470,6 +3472,10 @@ void CheckStl::getErrorMessages(ErrorLogger* errorLogger, const Settings* settin c.string_c_strError(nullptr); c.string_c_strReturn(nullptr); c.string_c_strParam(nullptr, 0); + c.string_c_strConstructor(nullptr); + c.string_c_strAssignment(nullptr); + c.string_c_strConcat(nullptr); + c.string_c_strStream(nullptr); c.string_c_strThrowError(nullptr); c.sizeError(nullptr); c.missingComparisonError(nullptr, nullptr); @@ -3477,12 +3483,15 @@ void CheckStl::getErrorMessages(ErrorLogger* errorLogger, const Settings* settin c.uselessCallsReturnValueError(nullptr, "str", "find"); c.uselessCallsSwapError(nullptr, "str"); c.uselessCallsSubstrError(nullptr, SubstrErrorType::COPY); + c.uselessCallsConstructorError(nullptr); c.uselessCallsEmptyError(nullptr); c.uselessCallsRemoveError(nullptr, "remove"); c.dereferenceInvalidIteratorError(nullptr, "i"); + // TODO: derefInvalidIteratorRedundantCheck c.eraseIteratorOutOfBoundsError(nullptr, nullptr); c.useStlAlgorithmError(nullptr, ""); c.knownEmptyContainerError(nullptr, ""); c.globalLockGuardError(nullptr); c.localMutexError(nullptr); + c.outOfBoundsIndexExpressionError(nullptr, nullptr); } diff --git a/lib/checktype.cpp b/lib/checktype.cpp index 4b025d026e5..aa72013b7ed 100644 --- a/lib/checktype.cpp +++ b/lib/checktype.cpp @@ -544,7 +544,9 @@ void CheckType::getErrorMessages(ErrorLogger *errorLogger, const Settings *setti c.tooBigBitwiseShiftError(nullptr, 32, ValueFlow::Value(64)); c.tooBigSignedBitwiseShiftError(nullptr, 31, ValueFlow::Value(31)); c.integerOverflowError(nullptr, ValueFlow::Value(1LL<<32)); + // TODO: integerOverflowCond c.signConversionError(nullptr, nullptr, false); + // TODO: signConversionCond c.longCastAssignError(nullptr); c.longCastReturnError(nullptr); ValueFlow::Value f; diff --git a/lib/checkuninitvar.cpp b/lib/checkuninitvar.cpp index 2c01613f1bf..d0217f9c075 100644 --- a/lib/checkuninitvar.cpp +++ b/lib/checkuninitvar.cpp @@ -1814,7 +1814,7 @@ void CheckUninitVar::getErrorMessages(ErrorLogger* errorLogger, const Settings* ValueFlow::Value v{}; - c.uninitvarError(nullptr, v); + c.uninitvarError(nullptr, v); // TODO: does not produce any output c.uninitdataError(nullptr, "varname"); c.uninitStructMemberError(nullptr, "a.b"); } diff --git a/lib/checkunusedfunctions.cpp b/lib/checkunusedfunctions.cpp index 5798d7d5ca3..55547b8e2d3 100644 --- a/lib/checkunusedfunctions.cpp +++ b/lib/checkunusedfunctions.cpp @@ -341,12 +341,9 @@ static bool isOperatorFunction(const std::string & funcName) return std::find(additionalOperators.cbegin(), additionalOperators.cend(), funcName.substr(operatorPrefix.length())) != additionalOperators.cend(); } -static void staticFunctionError(ErrorLogger& errorLogger, - const std::string &filename, - nonneg int fileIndex, - nonneg int lineNumber, - nonneg int column, - const std::string &funcname) +void CheckUnusedFunctions::staticFunctionError(ErrorLogger& errorLogger, + const std::string &filename, nonneg int fileIndex, nonneg int lineNumber, nonneg int column, + const std::string &funcname) { std::list locationList; if (!filename.empty()) { diff --git a/lib/checkunusedfunctions.h b/lib/checkunusedfunctions.h index b835b505ebd..b3b0bd4429c 100644 --- a/lib/checkunusedfunctions.h +++ b/lib/checkunusedfunctions.h @@ -58,6 +58,7 @@ class CPPCHECKLIB CheckUnusedFunctions { static void getErrorMessages(ErrorLogger &errorLogger) { unusedFunctionError(errorLogger, "", 0, 0, 0, "funcName"); + staticFunctionError(errorLogger, "", 0, 0, 0, "funcName"); } // Return true if an error is reported. @@ -70,6 +71,10 @@ class CPPCHECKLIB CheckUnusedFunctions { const std::string &filename, nonneg int fileIndex, nonneg int lineNumber, nonneg int column, const std::string &funcname); + static void staticFunctionError(ErrorLogger& errorLogger, + const std::string &filename, nonneg int fileIndex, nonneg int lineNumber, nonneg int column, + const std::string &funcname); + struct CPPCHECKLIB FunctionUsage { std::string filename; nonneg int lineNumber{}; diff --git a/lib/cppcheck.cpp b/lib/cppcheck.cpp index 181551e05f6..bb00ce8c6a1 100644 --- a/lib/cppcheck.cpp +++ b/lib/cppcheck.cpp @@ -35,6 +35,7 @@ #include "settings.h" #include "standards.h" #include "suppressions.h" +#include "symboldatabase.h" #include "timer.h" #include "token.h" #include "tokenize.h" @@ -1934,6 +1935,7 @@ void CppCheck::getErrorMessages(ErrorLogger &errorlogger) CheckUnusedFunctions::getErrorMessages(errorlogger); Preprocessor::getErrorMessages(errorlogger, s); Tokenizer::getErrorMessages(errorlogger, s); + SymbolDatabase::getErrorMessages(errorlogger); } void CppCheck::analyseClangTidy(const FileSettings &fileSettings) diff --git a/lib/symboldatabase.cpp b/lib/symboldatabase.cpp index 3ded75c8682..f547d028bbc 100644 --- a/lib/symboldatabase.cpp +++ b/lib/symboldatabase.cpp @@ -8421,3 +8421,10 @@ ValueType::MatchResult ValueType::matchParameter(const ValueType *call, const Va } return res; } + +void SymbolDatabase::getErrorMessages(ErrorLogger& /*errorLogger*/) +{ + // TODO + //SymbolDatabase symdb; + //symdb.returnImplicitIntError(nullptr); +} diff --git a/lib/symboldatabase.h b/lib/symboldatabase.h index d640eba9bec..03be22fa49d 100644 --- a/lib/symboldatabase.h +++ b/lib/symboldatabase.h @@ -1419,6 +1419,8 @@ class CPPCHECKLIB SymbolDatabase { /* returns the opening { if tok points to enum */ static const Token* isEnumDefinition(const Token* tok); + static void getErrorMessages(ErrorLogger &errorLogger); + private: friend class Scope; friend class Function; diff --git a/oss-fuzz/Makefile b/oss-fuzz/Makefile index 4d218a111a7..b5a853f80ab 100644 --- a/oss-fuzz/Makefile +++ b/oss-fuzz/Makefile @@ -252,7 +252,7 @@ $(libcppdir)/clangimport.o: ../lib/clangimport.cpp ../lib/addoninfo.h ../lib/che $(libcppdir)/color.o: ../lib/color.cpp ../lib/color.h ../lib/config.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/color.cpp -$(libcppdir)/cppcheck.o: ../lib/cppcheck.cpp ../externals/picojson/picojson.h ../externals/simplecpp/simplecpp.h ../externals/tinyxml2/tinyxml2.h ../lib/addoninfo.h ../lib/analyzerinfo.h ../lib/check.h ../lib/checkers.h ../lib/checkunusedfunctions.h ../lib/clangimport.h ../lib/color.h ../lib/config.h ../lib/cppcheck.h ../lib/ctu.h ../lib/errorlogger.h ../lib/errortypes.h ../lib/filesettings.h ../lib/json.h ../lib/library.h ../lib/mathlib.h ../lib/path.h ../lib/platform.h ../lib/preprocessor.h ../lib/settings.h ../lib/standards.h ../lib/suppressions.h ../lib/templatesimplifier.h ../lib/timer.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/valueflow.h ../lib/version.h ../lib/vfvalue.h ../lib/xml.h +$(libcppdir)/cppcheck.o: ../lib/cppcheck.cpp ../externals/picojson/picojson.h ../externals/simplecpp/simplecpp.h ../externals/tinyxml2/tinyxml2.h ../lib/addoninfo.h ../lib/analyzerinfo.h ../lib/check.h ../lib/checkers.h ../lib/checkunusedfunctions.h ../lib/clangimport.h ../lib/color.h ../lib/config.h ../lib/cppcheck.h ../lib/ctu.h ../lib/errorlogger.h ../lib/errortypes.h ../lib/filesettings.h ../lib/json.h ../lib/library.h ../lib/mathlib.h ../lib/path.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/timer.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/valueflow.h ../lib/version.h ../lib/vfvalue.h ../lib/xml.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/cppcheck.cpp $(libcppdir)/ctu.o: ../lib/ctu.cpp ../externals/tinyxml2/tinyxml2.h ../lib/addoninfo.h ../lib/astutils.h ../lib/check.h ../lib/checkers.h ../lib/config.h ../lib/ctu.h ../lib/errorlogger.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/path.h ../lib/platform.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/vfvalue.h ../lib/xml.h diff --git a/tools/check-errorids.sh b/tools/check-errorids.sh new file mode 100755 index 00000000000..ffef62fea42 --- /dev/null +++ b/tools/check-errorids.sh @@ -0,0 +1,31 @@ +#!/bin/bash + +#set -x + +SCRIPT_DIR="$(dirname "$(realpath "$0")")" + +# TODO: exclude testinternal.cpp +echo 'no --errorlist entry:' +grep -h -o -P '\[[a-zA-Z0-9_]+\]\\n\"' $SCRIPT_DIR/../test/*.cpp | tr -d '[]\"' | sed 's/\\n$//' | sort -u | \ +while read -r id; do + if [ ${#id} -lt 4 ]; then + continue + fi + $SCRIPT_DIR/../cppcheck --errorlist | grep "id=\"$id\"" > /dev/null + # shellcheck disable=SC2181 + if [ $? -ne 0 ]; then + echo $id + fi +done + +echo '' + +echo 'no test coverage:' +$SCRIPT_DIR/../cppcheck --errorlist | grep -h -o -P 'id=\"[a-zA-Z0-9_]*\"' | sed 's/\id=//' | tr -d '\"' | sort -u | \ +while read -r id; do + grep -h -o -P "\[$id\]\\\\n\"" $SCRIPT_DIR/../test/*.cpp > /dev/null + # shellcheck disable=SC2181 + if [ $? -ne 0 ]; then + echo $id + fi +done \ No newline at end of file diff --git a/tools/readme.md b/tools/readme.md index 436f3322b1d..4f914b3cce6 100644 --- a/tools/readme.md +++ b/tools/readme.md @@ -78,3 +78,8 @@ Script to compare result of working Cppcheck from your branch with main branch. This tool lets you comfortably look at Cppcheck analysis results for daca packages. It automatically downloads the package, extracts it and jumps to the corresponding source code for a Cppcheck message. + +### * tools/check-errorids.sh + +Script to compare the error IDs in the expected `testrunner` output (without executing it) with the `--errorlist` output. +It will report missing test coverage for an ID and missing IDs in the `--errorlist` output.