diff --git a/.github/workflows/CI-unixish.yml b/.github/workflows/CI-unixish.yml index a66bbca8a85..6161f7019f8 100644 --- a/.github/workflows/CI-unixish.yml +++ b/.github/workflows/CI-unixish.yml @@ -112,13 +112,13 @@ jobs: # TODO: bail out on warnings with latest GCC - name: Set up GCC uses: egor-tensin/setup-gcc@v1 - if: matrix.os == 'ubuntu-22.04' + if: false # matrix.os == 'ubuntu-22.04' with: version: 13 platform: x64 - name: Select compiler - if: matrix.os == 'ubuntu-22.04' + if: false # matrix.os == 'ubuntu-22.04' run: | echo "CXX=g++-13" >> $GITHUB_ENV diff --git a/.github/workflows/selfcheck.yml b/.github/workflows/selfcheck.yml index 9ef696858eb..6241f3851d7 100644 --- a/.github/workflows/selfcheck.yml +++ b/.github/workflows/selfcheck.yml @@ -58,6 +58,7 @@ jobs: CC: clang-14 CXX: clang++-14 + # unusedFunction - start - name: CMake run: | cmake -S . -B cmake.output -G "Unix Makefiles" -DHAVE_RULES=On -DBUILD_TESTS=On -DBUILD_GUI=ON -DUSE_QT6=On -DWITH_QCHART=ON -DENABLE_CHECK_INTERNAL=On -DCMAKE_GLOBAL_AUTOGEN_TARGET=On @@ -79,8 +80,11 @@ jobs: env: DISABLE_VALUEFLOW: 1 UNUSEDFUNCTION_ONLY: 1 + # unusedFunction - end # the following steps are duplicated from above since setting up the build node in a parallel step takes longer than the actual steps + + # unusedFunction notest - start - name: CMake (no test) run: | cmake -S . -B cmake.output.notest -G "Unix Makefiles" -DHAVE_RULES=On -DBUILD_TESTS=Off -DBUILD_GUI=ON -DUSE_QT6=On -DWITH_QCHART=ON -DENABLE_CHECK_INTERNAL=On -DCMAKE_GLOBAL_AUTOGEN_TARGET=On @@ -100,6 +104,49 @@ jobs: env: DISABLE_VALUEFLOW: 1 UNUSEDFUNCTION_ONLY: 1 + # unusedFunction notest - end + + # unusedFunction notest nogui - start + - name: CMake (no test / no gui) + run: | + cmake -S . -B cmake.output.notest_nogui -G "Unix Makefiles" -DHAVE_RULES=On -DBUILD_TESTS=Off -DENABLE_CHECK_INTERNAL=On + + - name: Generate dependencies (no test / no gui) + run: | + # make sure the precompiled headers exist + make -C cmake.output.notest_nogui lib/CMakeFiles/cppcheck-core.dir/cmake_pch.hxx.cxx + + # TODO: find a way to report unmatched suppressions without need to add information checks + - name: Self check (unusedFunction / no test / no gui) + run: | + ./cppcheck -q --template=selfcheck --error-exitcode=1 --library=cppcheck-lib -D__CPPCHECK__ -D__GNUC__ --enable=unusedFunction --exception-handling -rp=. --project=cmake.output.notest_nogui/compile_commands.json --suppressions-list=.selfcheck_unused_suppressions --inline-suppr + env: + DISABLE_VALUEFLOW: 1 + UNUSEDFUNCTION_ONLY: 1 + # unusedFunction notest nogui - end + + # unusedFunction notest nocli - start + - name: CMake (no test / no cli) + run: | + cmake -S . -B cmake.output.notest_nocli -G "Unix Makefiles" -DHAVE_RULES=On -DBUILD_TESTS=Off -DBUILD_CLI=Off -DBUILD_GUI=ON -DUSE_QT6=On -DWITH_QCHART=ON -DENABLE_CHECK_INTERNAL=On -DCMAKE_GLOBAL_AUTOGEN_TARGET=On + + - name: Generate dependencies (no test / no cli) + run: | + # make sure the precompiled headers exist + make -C cmake.output.notest_nocli lib/CMakeFiles/cppcheck-core.dir/cmake_pch.hxx.cxx + # make sure auto-generated GUI files exist + make -C cmake.output.notest_nocli autogen + make -C cmake.output.notest_nocli gui-build-deps + + # TODO: find a way to report unmatched suppressions without need to add information checks + - name: Self check (unusedFunction / no test / no cli) + if: false # TODO: the findings are currently too intrusive + run: | + ./cppcheck -q --template=selfcheck --error-exitcode=1 --library=cppcheck-lib --library=qt -D__CPPCHECK__ -D__GNUC__ -DQT_VERSION=0x060000 -DQ_MOC_OUTPUT_REVISION=68 -DQT_CHARTS_LIB -DQT_MOC_HAS_STRINGDATA --enable=unusedFunction --exception-handling -rp=. --project=cmake.output.notest_nocli/compile_commands.json --suppressions-list=.selfcheck_unused_suppressions --inline-suppr + env: + DISABLE_VALUEFLOW: 1 + UNUSEDFUNCTION_ONLY: 1 + # unusedFunction notest nocli - end - name: Fetch corpus run: | @@ -113,7 +160,7 @@ jobs: - name: Generate dependencies (corpus) run: | # make sure the precompiled headers exist - make -C cmake.output.notest lib/CMakeFiles/cppcheck-core.dir/cmake_pch.hxx.cxx + make -C cmake.output.corpus lib/CMakeFiles/lib_objs.dir/cmake_pch.hxx.cxx # make sure auto-generated GUI files exist make -C cmake.output.corpus autogen make -C cmake.output.corpus gui-build-deps diff --git a/Makefile b/Makefile index 56fd1b69ae3..ae59722df1f 100644 --- a/Makefile +++ b/Makefile @@ -500,10 +500,10 @@ $(libcppdir)/checkbool.o: lib/checkbool.cpp lib/addoninfo.h lib/astutils.h lib/c $(libcppdir)/checkboost.o: lib/checkboost.cpp lib/check.h lib/checkboost.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.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 $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkboost.cpp -$(libcppdir)/checkbufferoverrun.o: lib/checkbufferoverrun.cpp externals/tinyxml2/tinyxml2.h lib/addoninfo.h lib/astutils.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/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/vfvalue.h lib/xml.h +$(libcppdir)/checkbufferoverrun.o: lib/checkbufferoverrun.cpp externals/tinyxml2/tinyxml2.h lib/addoninfo.h lib/astutils.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/path.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/vfvalue.h lib/xml.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkbufferoverrun.cpp -$(libcppdir)/checkclass.o: lib/checkclass.cpp externals/tinyxml2/tinyxml2.h lib/addoninfo.h lib/astutils.h lib/check.h lib/checkclass.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/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/vfvalue.h lib/xml.h +$(libcppdir)/checkclass.o: lib/checkclass.cpp externals/tinyxml2/tinyxml2.h lib/addoninfo.h lib/astutils.h lib/check.h lib/checkclass.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/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/vfvalue.h lib/xml.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkclass.cpp $(libcppdir)/checkcondition.o: lib/checkcondition.cpp lib/addoninfo.h lib/astutils.h lib/check.h lib/checkcondition.h lib/checkother.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/suppressions.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h @@ -533,7 +533,7 @@ $(libcppdir)/checkleakautovar.o: lib/checkleakautovar.cpp lib/addoninfo.h lib/as $(libcppdir)/checkmemoryleak.o: lib/checkmemoryleak.cpp lib/addoninfo.h lib/astutils.h lib/check.h lib/checkmemoryleak.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/smallvector.h lib/sourcelocation.h lib/standards.h lib/suppressions.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkmemoryleak.cpp -$(libcppdir)/checknullpointer.o: lib/checknullpointer.cpp lib/addoninfo.h lib/astutils.h lib/check.h lib/checknullpointer.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/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/vfvalue.h +$(libcppdir)/checknullpointer.o: lib/checknullpointer.cpp lib/addoninfo.h lib/astutils.h lib/check.h lib/checknullpointer.h lib/color.h lib/config.h lib/ctu.h lib/errorlogger.h lib/errortypes.h lib/findtoken.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/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checknullpointer.cpp $(libcppdir)/checkother.o: lib/checkother.cpp lib/addoninfo.h lib/astutils.h lib/check.h lib/checkother.h lib/config.h lib/errortypes.h lib/fwdanalysis.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/vfvalue.h @@ -557,7 +557,7 @@ $(libcppdir)/checktype.o: lib/checktype.cpp lib/addoninfo.h lib/check.h lib/chec $(libcppdir)/checkuninitvar.o: lib/checkuninitvar.cpp lib/addoninfo.h lib/astutils.h lib/check.h lib/checknullpointer.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/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/suppressions.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkuninitvar.cpp -$(libcppdir)/checkunusedfunctions.o: lib/checkunusedfunctions.cpp externals/tinyxml2/tinyxml2.h lib/addoninfo.h lib/astutils.h lib/checkunusedfunctions.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/smallvector.h lib/sourcelocation.h lib/standards.h lib/suppressions.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h lib/xml.h +$(libcppdir)/checkunusedfunctions.o: lib/checkunusedfunctions.cpp externals/tinyxml2/tinyxml2.h lib/addoninfo.h lib/astutils.h lib/checkunusedfunctions.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/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/suppressions.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h lib/xml.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkunusedfunctions.cpp $(libcppdir)/checkunusedvar.o: lib/checkunusedvar.cpp lib/addoninfo.h lib/astutils.h lib/check.h lib/checkunusedvar.h lib/config.h lib/errortypes.h lib/fwdanalysis.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/vfvalue.h @@ -575,7 +575,7 @@ $(libcppdir)/color.o: lib/color.cpp lib/color.h lib/config.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/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 $(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/color.h lib/config.h lib/ctu.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/suppressions.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h lib/xml.h +$(libcppdir)/ctu.o: lib/ctu.cpp externals/tinyxml2/tinyxml2.h lib/addoninfo.h lib/astutils.h lib/check.h lib/color.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/suppressions.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 $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/ctu.cpp $(libcppdir)/errorlogger.o: lib/errorlogger.cpp externals/tinyxml2/tinyxml2.h lib/addoninfo.h lib/analyzerinfo.h lib/check.h lib/color.h lib/config.h lib/cppcheck.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/suppressions.h lib/templatesimplifier.h lib/token.h lib/tokenlist.h lib/utils.h lib/vfvalue.h lib/xml.h @@ -698,7 +698,7 @@ cli/stacktrace.o: cli/stacktrace.cpp cli/stacktrace.h lib/config.h lib/utils.h cli/threadexecutor.o: cli/threadexecutor.cpp cli/executor.h cli/threadexecutor.h lib/addoninfo.h lib/analyzerinfo.h lib/check.h lib/color.h lib/config.h lib/cppcheck.h lib/errorlogger.h lib/errortypes.h lib/filesettings.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/suppressions.h lib/timer.h lib/utils.h $(CXX) ${INCLUDE_FOR_CLI} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ cli/threadexecutor.cpp -test/fixture.o: test/fixture.cpp externals/simplecpp/simplecpp.h externals/tinyxml2/tinyxml2.h lib/addoninfo.h lib/analyzerinfo.h lib/check.h lib/color.h lib/config.h lib/cppcheck.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/xml.h test/fixture.h test/helpers.h test/options.h test/redirect.h +test/fixture.o: test/fixture.cpp externals/simplecpp/simplecpp.h externals/tinyxml2/tinyxml2.h lib/addoninfo.h lib/analyzerinfo.h lib/check.h lib/color.h lib/config.h lib/cppcheck.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/standards.h lib/suppressions.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/xml.h test/fixture.h test/helpers.h test/options.h test/redirect.h $(CXX) ${INCLUDE_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/fixture.cpp test/helpers.o: test/helpers.cpp cli/filelister.h externals/simplecpp/simplecpp.h externals/tinyxml2/tinyxml2.h lib/addoninfo.h lib/config.h lib/errortypes.h lib/filesettings.h lib/library.h lib/mathlib.h lib/path.h lib/pathmatch.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/xml.h test/helpers.h @@ -761,7 +761,7 @@ test/testconstructors.o: test/testconstructors.cpp externals/simplecpp/simplecpp test/testcppcheck.o: test/testcppcheck.cpp externals/simplecpp/simplecpp.h lib/addoninfo.h lib/analyzerinfo.h lib/check.h lib/color.h lib/config.h lib/cppcheck.h lib/errorlogger.h lib/errortypes.h lib/filesettings.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/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testcppcheck.cpp -test/testerrorlogger.o: test/testerrorlogger.cpp externals/tinyxml2/tinyxml2.h lib/addoninfo.h lib/analyzerinfo.h lib/check.h lib/color.h lib/config.h lib/cppcheck.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 lib/xml.h test/fixture.h +test/testerrorlogger.o: test/testerrorlogger.cpp externals/tinyxml2/tinyxml2.h lib/addoninfo.h lib/analyzerinfo.h lib/check.h lib/color.h lib/config.h lib/cppcheck.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/suppressions.h lib/utils.h lib/xml.h test/fixture.h $(CXX) ${INCLUDE_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testerrorlogger.cpp test/testexceptionsafety.o: test/testexceptionsafety.cpp externals/simplecpp/simplecpp.h lib/addoninfo.h lib/check.h lib/checkexceptionsafety.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 @@ -818,7 +818,7 @@ test/testpath.o: test/testpath.cpp externals/simplecpp/simplecpp.h lib/addoninfo test/testpathmatch.o: test/testpathmatch.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/pathmatch.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/testpathmatch.cpp -test/testplatform.o: test/testplatform.cpp externals/tinyxml2/tinyxml2.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/settings.h lib/standards.h lib/suppressions.h lib/utils.h lib/xml.h test/fixture.h +test/testplatform.o: test/testplatform.cpp externals/tinyxml2/tinyxml2.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/path.h lib/platform.h lib/settings.h lib/standards.h lib/suppressions.h lib/utils.h lib/xml.h test/fixture.h $(CXX) ${INCLUDE_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testplatform.cpp test/testpostfixoperator.o: test/testpostfixoperator.cpp externals/simplecpp/simplecpp.h lib/addoninfo.h lib/check.h lib/checkpostfixoperator.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 diff --git a/addons/cppcheckdata.py b/addons/cppcheckdata.py index b516ef51f9d..2de7a3512e3 100755 --- a/addons/cppcheckdata.py +++ b/addons/cppcheckdata.py @@ -1281,6 +1281,9 @@ def iterconfigurations(self): # Iterating iter_typedef_info = False + # Iterating + iter_directive = False + # Use iterable objects to traverse XML tree for dump files incrementally. # Iterative approach is required to avoid large memory consumption. # Calling .clear() is necessary to let the element be garbage collected. @@ -1312,8 +1315,12 @@ def iterconfigurations(self): cfg.standards.set_posix(node) # Parse directives list - elif node.tag == 'directive' and event == 'start': - cfg.directives.append(Directive(node)) + elif node.tag == 'directive': + if event == 'start': + cfg.directives.append(Directive(node)) + iter_directive = True + elif event == 'end': + iter_directive = False # Parse macro usage elif node.tag == 'macro' and event == 'start': cfg.macro_usage.append(MacroUsage(node)) @@ -1325,7 +1332,7 @@ def iterconfigurations(self): # Parse tokens elif node.tag == 'tokenlist' and event == 'start': continue - elif node.tag == 'token' and event == 'start': + elif node.tag == 'token' and event == 'start' and not iter_directive: cfg.tokenlist.append(Token(node)) # Parse scopes diff --git a/cfg/boost.cfg b/cfg/boost.cfg index fc6836da757..3a09f2a778d 100644 --- a/cfg/boost.cfg +++ b/cfg/boost.cfg @@ -35,7 +35,7 @@ - + @@ -43,7 +43,7 @@ - + @@ -51,7 +51,7 @@ - + @@ -84,6 +84,7 @@ + diff --git a/cfg/std.cfg b/cfg/std.cfg index 774e4dbf1c7..8af76755bb3 100644 --- a/cfg/std.cfg +++ b/cfg/std.cfg @@ -3318,11 +3318,7 @@ The obsolete function 'gets' is called. With 'gets' you'll get a buffer overrun - - - - - + @@ -3333,8 +3329,23 @@ The obsolete function 'gets' is called. With 'gets' you'll get a buffer overrun + + + + + + + + + false + + + + + + - + arg1>arg2?1:0 @@ -3347,8 +3358,22 @@ The obsolete function 'gets' is called. With 'gets' you'll get a buffer overrun + + + + + arg1>arg2?1:0 + false + + + + + + + + - + arg1 >= arg2?1:0 @@ -3361,12 +3386,22 @@ The obsolete function 'gets' is called. With 'gets' you'll get a buffer overrun + + + + + arg1 >= arg2?1:0 + false + + + + + + + + - - - - - + @@ -3377,6 +3412,21 @@ The obsolete function 'gets' is called. With 'gets' you'll get a buffer overrun + + + + + + + + + false + + + + + + diff --git a/cfg/windows.cfg b/cfg/windows.cfg index 26448004810..e061752ca66 100644 --- a/cfg/windows.cfg +++ b/cfg/windows.cfg @@ -7119,8 +7119,8 @@ HFONT CreateFont( - - + + @@ -7131,6 +7131,10 @@ HFONT CreateFont( + + + + @@ -14178,6 +14182,10 @@ HFONT CreateFont( + + + + diff --git a/cli/CMakeLists.txt b/cli/CMakeLists.txt index 38a060df0d3..3859d35a13c 100644 --- a/cli/CMakeLists.txt +++ b/cli/CMakeLists.txt @@ -1,86 +1,89 @@ -file(GLOB hdrs "*.h") -file(GLOB srcs "*.cpp") -file(GLOB mainfile "main.cpp") -list(REMOVE_ITEM srcs ${mainfile}) +if (BUILD_CLI) -add_library(cli_objs OBJECT ${hdrs} ${srcs}) -target_include_directories(cli_objs PRIVATE ${PROJECT_SOURCE_DIR}/lib/) -if(USE_BUNDLED_TINYXML2) - target_externals_include_directories(cli_objs PRIVATE ${PROJECT_SOURCE_DIR}/externals/tinyxml2/) -else() - target_include_directories(cli_objs SYSTEM PRIVATE ${tinyxml2_INCLUDE_DIRS}) -endif() -target_externals_include_directories(cli_objs PRIVATE ${PROJECT_SOURCE_DIR}/externals/simplecpp/) -if (NOT CMAKE_DISABLE_PRECOMPILE_HEADERS) - target_precompile_headers(cli_objs PRIVATE precompiled.h) -endif() -if (BUILD_CORE_DLL) - target_compile_definitions(cli_objs PRIVATE CPPCHECKLIB_IMPORT TINYXML2_IMPORT) -endif() + file(GLOB hdrs "*.h") + file(GLOB srcs "*.cpp") + file(GLOB mainfile "main.cpp") + list(REMOVE_ITEM srcs ${mainfile}) -if (CMAKE_CXX_COMPILER_ID MATCHES "Clang" AND CMAKE_CXX_COMPILER_VERSION VERSION_EQUAL 13) - # false positive warning in Clang 13 - caused by FD_ZERO macro - set_source_files_properties(processexecutor.cpp PROPERTIES COMPILE_FLAGS -Wno-reserved-identifier) -endif() - -list(APPEND cppcheck_SOURCES ${hdrs} ${mainfile} $) -if (NOT BUILD_CORE_DLL) - list(APPEND cppcheck_SOURCES $) - list(APPEND cppcheck_SOURCES $) + add_library(cli_objs OBJECT ${hdrs} ${srcs}) + target_include_directories(cli_objs PRIVATE ${PROJECT_SOURCE_DIR}/lib/) if(USE_BUNDLED_TINYXML2) - list(APPEND cppcheck_SOURCES $) + target_externals_include_directories(cli_objs PRIVATE ${PROJECT_SOURCE_DIR}/externals/tinyxml2/) + else() + target_include_directories(cli_objs SYSTEM PRIVATE ${tinyxml2_INCLUDE_DIRS}) + endif() + target_externals_include_directories(cli_objs PRIVATE ${PROJECT_SOURCE_DIR}/externals/simplecpp/) + if (NOT CMAKE_DISABLE_PRECOMPILE_HEADERS) + target_precompile_headers(cli_objs PRIVATE precompiled.h) + endif() + if (BUILD_CORE_DLL) + target_compile_definitions(cli_objs PRIVATE CPPCHECKLIB_IMPORT TINYXML2_IMPORT) endif() -endif() -if (WIN32) - list(APPEND cppcheck_SOURCES version.rc) -endif() -add_executable(cppcheck ${cppcheck_SOURCES}) -target_include_directories(cppcheck PRIVATE ${PROJECT_SOURCE_DIR}/lib/) -if(USE_BUNDLED_TINYXML2) - target_externals_include_directories(cppcheck PRIVATE ${PROJECT_SOURCE_DIR}/externals/tinyxml2/) -else() - target_include_directories(cppcheck SYSTEM PRIVATE ${tinyxml2_INCLUDE_DIRS}) -endif() -target_externals_include_directories(cppcheck PRIVATE ${PROJECT_SOURCE_DIR}/externals/simplecpp/) -if (HAVE_RULES) - target_link_libraries(cppcheck ${PCRE_LIBRARY}) -endif() -if (WIN32 AND NOT BORLAND) - if(NOT MINGW) - target_link_libraries(cppcheck Shlwapi.lib) + if (CMAKE_CXX_COMPILER_ID MATCHES "Clang" AND CMAKE_CXX_COMPILER_VERSION VERSION_EQUAL 13) + # false positive warning in Clang 13 - caused by FD_ZERO macro + set_source_files_properties(processexecutor.cpp PROPERTIES COMPILE_FLAGS -Wno-reserved-identifier) + endif() + + list(APPEND cppcheck_SOURCES ${hdrs} ${mainfile} $) + if (NOT BUILD_CORE_DLL) + list(APPEND cppcheck_SOURCES $) + list(APPEND cppcheck_SOURCES $) + if(USE_BUNDLED_TINYXML2) + list(APPEND cppcheck_SOURCES $) + endif() + endif() + if (WIN32) + list(APPEND cppcheck_SOURCES version.rc) + endif() + + add_executable(cppcheck ${cppcheck_SOURCES}) + target_include_directories(cppcheck PRIVATE ${PROJECT_SOURCE_DIR}/lib/) + if(USE_BUNDLED_TINYXML2) + target_externals_include_directories(cppcheck PRIVATE ${PROJECT_SOURCE_DIR}/externals/tinyxml2/) else() - target_link_libraries(cppcheck shlwapi) + target_include_directories(cppcheck SYSTEM PRIVATE ${tinyxml2_INCLUDE_DIRS}) + endif() + target_externals_include_directories(cppcheck PRIVATE ${PROJECT_SOURCE_DIR}/externals/simplecpp/) + if (HAVE_RULES) + target_link_libraries(cppcheck ${PCRE_LIBRARY}) + endif() + if (WIN32 AND NOT BORLAND) + if(NOT MINGW) + target_link_libraries(cppcheck Shlwapi.lib) + else() + target_link_libraries(cppcheck shlwapi) + endif() + endif() + if(tinyxml2_FOUND AND NOT USE_BUNDLED_TINYXML2) + target_link_libraries(cppcheck ${tinyxml2_LIBRARIES}) + endif() + target_link_libraries(cppcheck ${CMAKE_THREAD_LIBS_INIT}) + if (BUILD_CORE_DLL) + target_link_libraries(cppcheck cppcheck-core) endif() -endif() -if(tinyxml2_FOUND AND NOT USE_BUNDLED_TINYXML2) - target_link_libraries(cppcheck ${tinyxml2_LIBRARIES}) -endif() -target_link_libraries(cppcheck ${CMAKE_THREAD_LIBS_INIT}) -if (BUILD_CORE_DLL) - target_link_libraries(cppcheck cppcheck-core) -endif() -add_dependencies(cppcheck copy_cfg) -add_dependencies(cppcheck copy_addons) -add_dependencies(cppcheck copy_platforms) -if (NOT DISABLE_DMAKE) - add_dependencies(cppcheck run-dmake) -endif() + add_dependencies(cppcheck copy_cfg) + add_dependencies(cppcheck copy_addons) + add_dependencies(cppcheck copy_platforms) + if (NOT DISABLE_DMAKE) + add_dependencies(cppcheck run-dmake) + endif() -install(TARGETS cppcheck - RUNTIME DESTINATION ${CMAKE_INSTALL_FULL_BINDIR} - COMPONENT applications) + install(TARGETS cppcheck + RUNTIME DESTINATION ${CMAKE_INSTALL_FULL_BINDIR} + COMPONENT applications) -install(FILES ${addons} - DESTINATION ${FILESDIR}/addons - COMPONENT headers) + install(FILES ${addons} + DESTINATION ${FILESDIR}/addons + COMPONENT headers) -install(FILES ${cfgs} - DESTINATION ${FILESDIR}/cfg - COMPONENT headers) + install(FILES ${cfgs} + DESTINATION ${FILESDIR}/cfg + COMPONENT headers) -install(FILES ${platforms} - DESTINATION ${FILESDIR}/platforms - COMPONENT headers) + install(FILES ${platforms} + DESTINATION ${FILESDIR}/platforms + COMPONENT headers) +endif() \ No newline at end of file diff --git a/cmake/options.cmake b/cmake/options.cmake index a0402862dc6..90c753358b0 100644 --- a/cmake/options.cmake +++ b/cmake/options.cmake @@ -51,6 +51,8 @@ option(ENABLE_CHECK_INTERNAL "Enable internal checks" option(DISABLE_DMAKE "Disable run-dmake dependencies" OFF) option(BUILD_MANPAGE "Enable man target to build manpage" OFF) +option(BUILD_CLI "Build the cli application" ON) + option(BUILD_GUI "Build the qt application" OFF) option(WITH_QCHART "Enable QtCharts usage in the GUI" OFF) option(USE_QT6 "Prefer Qt6 when available" OFF) diff --git a/cmake/printInfo.cmake b/cmake/printInfo.cmake index c99fc205b22..bb633650b7d 100644 --- a/cmake/printInfo.cmake +++ b/cmake/printInfo.cmake @@ -58,6 +58,8 @@ message(STATUS "ENABLE_CHECK_INTERNAL = ${ENABLE_CHECK_INTERNAL}") message(STATUS "DISABLE_DMAKE = ${DISABLE_DMAKE}") message(STATUS "BUILD_MANPAGE = ${BUILD_MANPAGE}") message(STATUS) +message(STATUS "BUILD_CLI = ${BUILD_CLI}") +message(STATUS) message(STATUS "BUILD_GUI = ${BUILD_GUI}") if(BUILD_GUI) message(STATUS "REGISTER_GUI_TESTS = ${REGISTER_GUI_TESTS}") diff --git a/gui/checkthread.cpp b/gui/checkthread.cpp index 13e3c1dc2fe..40ec77a8c86 100644 --- a/gui/checkthread.cpp +++ b/gui/checkthread.cpp @@ -132,16 +132,17 @@ void CheckThread::run() file = mResult.getNextFile(); } - FileSettings fileSettings = mResult.getNextFileSettings(); - while (!fileSettings.filename().empty() && mState == Running) { - file = QString::fromStdString(fileSettings.filename()); + const FileSettings* fileSettings = nullptr; + mResult.getNextFileSettings(fileSettings); + while (fileSettings && mState == Running) { + file = QString::fromStdString(fileSettings->filename()); qDebug() << "Checking file" << file; - mCppcheck.check(fileSettings); - runAddonsAndTools(&fileSettings, QString::fromStdString(fileSettings.filename())); + mCppcheck.check(*fileSettings); + runAddonsAndTools(fileSettings, QString::fromStdString(fileSettings->filename())); emit fileChecked(file); if (mState == Running) - fileSettings = mResult.getNextFileSettings(); + mResult.getNextFileSettings(fileSettings); } if (mState == Running) diff --git a/gui/cppcheck_ka.ts b/gui/cppcheck_ka.ts new file mode 100644 index 00000000000..e2c299a5052 --- /dev/null +++ b/gui/cppcheck_ka.ts @@ -0,0 +1,3051 @@ + + + + + About + + + About Cppcheck + Cppcheck-ის შესახებ + + + + Version %1 + ვერსია %1 + + + + Cppcheck - A tool for static C/C++ code analysis. + Cppcheck - ხელსაწყო სტატიკური C/C++ კოდის ანალიზისთვის. + + + + Copyright © 2007-%1 Cppcheck team. + Copyright © 2007-2021 Cppcheck team. + Copyright © 2007-%1 Cppcheck-ის გუნდი. ყველა უფლება დაცულია. + + + + This program is licensed under the terms +of the GNU General Public License version 3 + ვრცელდება GNU-ის საჯარო ლიცენზიის, +ვერსია 3, პირობებით + + + + Visit Cppcheck homepage at %1 + ეწვიეთ Cppcheck-ის ვებგვერდს მისამართზე %1 + + + + <html><head/><body><p>Many thanks to these libraries that we use:</p><ul style="margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; -qt-list-indent: 1;"><li style=" margin-top:12px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">PCRE</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">PicoJSON</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Qt</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">TinyXML2</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Boost</li></ul></body></html> + <html><head/><body><p>Many thanks to these libraries that we use:</p><ul style="margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; -qt-list-indent: 1;"><li style=" margin-top:12px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">pcre</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">picojson</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">qt</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">tinyxml2</li></ul></body></html> + <html><head/><body><p>დიდი მადლობა ამ ბიბლიოთეკებს, რომლებსაც ვიყენებთ::</p><ul style="margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; -qt-list-indent: 1;"><li style=" margin-top:12px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">PCRE</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">PicoJSON</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Qt</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">TinyXML2</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Boost</li></ul></body></html> + + + + ApplicationDialog + + + Add an application + აპლიკაციის დამატება + + + + Here you can add an application that can open error files. Specify a name for the application, the application executable and command line parameters for the application. + +The following texts in parameters are replaced with appropriate values when application is executed: +(file) - Filename containing the error +(line) - Line number containing the error +(message) - Error message +(severity) - Error severity + +Example opening a file with Kate and make Kate scroll to the correct line: +Executable: kate +Parameters: -l(line) (file) + + + + + &Name: + &სახელი: + + + + &Executable: + &გამშვები ფაილი: + + + + &Parameters: + &პარამეტრები: + + + + Browse + დათვალიერება + + + + Executable files (*.exe);;All files(*.*) + შესრულებადი ფაილები (*.exe);;ყველა ფაილი(*.*) + + + + Select viewer application + აირჩიეთ აპლიკაცია + + + + Cppcheck + Cppcheck + + + + You must specify a name, a path and optionally parameters for the application! + აპლიკაციისთვის უნდა მიუთითოთ სახელი, ბილიკი და არასავალდებულო პარამეტრები! + + + + ComplianceReportDialog + + + Compliance Report + შესაბამისობის ანგარიში + + + + Project name + პროექტის სახელი + + + + Project version + პროექტის ვერსია + + + + Coding Standard + კოდირების სტანდარტი + + + + Misra C + Misra C + + + + Cert C + Cert C + + + + Cert C++ + Cert C++ + + + + List of files with md5 checksums + MD5 საკონტროლო ჯამების მქონე ფაილების სია + + + + Compliance report + შესაბამისობის ანგარიში + + + + HTML files (*.html) + HTML ფაილები (*.html) + + + + + Save compliance report + შესაბამისობის ანგარიშის შენახვა + + + + Failed to import '%1' (%2), can not show files in compliance report + '%1'-ის (%2) შემოტანა ჩავარდა. შესაბამისობის ანგარიშში ფაილებს ვერ ვაჩვენებ + + + + FileViewDialog + + + Could not find the file: %1 + Could not find the file: + + ვერ ვიპოვე ფაილი: %1 + + + + + Cppcheck + Cppcheck + + + + Could not read the file: %1 + ვერ წავიკითხე ფაილი: %1 + + + + HelpDialog + + + Cppcheck GUI help + Cppcheck-ის გრაფიკული ინტერფეისის დახმარება + + + + Contents + შემცველობა + + + + Index + ინდექსი + + + + Helpfile '%1' was not found + დახმარების ფაილი '%1' ვერ ვიპოვე + + + + Cppcheck + Cppcheck + + + + LibraryAddFunctionDialog + + + Add function + ფუნქციის დამატება + + + + Function name(s) + ფუნქციის სახელ(ებ)-ი + + + + Number of arguments + არგუმენტების რაოდენობა + + + + LibraryDialog + + + Library Editor + ბიბლიოთეკის რედაქტორი + + + + Open + გახსნა + + + + Save + შენახვა + + + + Save as + შენახვა, როგორც + + + + Functions + ფუნქციები + + + + Sort + დალაგება + + + + Add + დამატება + + + + Filter: + ფილტრი: + + + + Comments + კომენტარები + + + + noreturn + noreturn + + + + False + მცდარი + + + + True + სიმართლე + + + + Unknown + უცნობი + + + + return value must be used + უნდა გამოიყენოთ დაბრუნებული მნიშვნელობა + + + + ignore function in leaks checking + ფუნქციების გამოტოვება გაჟონვები შემოწმებისას + + + + Arguments + არგუმენტები + + + + Edit + ჩასწორება + + + + + Library files (*.cfg) + ბიბლიოთეკის ფაილები (*.cfg) + + + + Open library file + ბიბლიოთეკის ფაილის გახსნა + + + + + + Cppcheck + Cppcheck + + + + Cannot open file %1. + Can not open file %1. + ფაილის '%1' გახსნის შეცდომა. + + + + Failed to load %1. %2. + %1-ის ჩატვირთვის შეცდომა. %2. + + + + Cannot save file %1. + ფაილის შენახვის შეცდომა: %1 . + + + + Save the library as + ბიბლიოთეკის შენახვა, როგორც + + + + LibraryEditArgDialog + + + Edit argument + არგუმენტის ჩასწორება + + + + <html><head/><body> +<p>Is bool value allowed? For instance result from comparison or from '!' operator.</p> +<p>Typically, set this if the argument is a pointer, size, etc.</p> +<p>Example:</p> +<pre> memcmp(x, y, i == 123); // last argument should not have a bool value</pre> +</body></html> + + + + + Not bool + ლოგიკური მნ. არაა + + + + <html><head/><body> +<p>Is a null parameter value allowed?</p> +<p>Typically this should be used on any pointer parameter that does not allow null.</p> +<p>Example:</p> +<pre> strcpy(x,y); // neither x or y is allowed to be null.</pre> +</body></html> + + + + + Not null + ნულოვანი არაა + + + + Not uninit + Uninit არაა + + + + String + სტრიქონი + + + + Format string + სტრიქონის ფორმატი + + + + Min size of buffer + ბუფერის მინ. ზომა + + + + + Type + ტიპი + + + + + None + არაფერი + + + + + argvalue + argvalue + + + + + mul + mul + + + + + strlen + strlen + + + + + Arg + არგ + + + + + Arg2 + Arg2 + + + + and + და + + + + Valid values + სწორი მნიშვნელობები + + + + MainWindow + + + + + + + + + + + + + + + + + Cppcheck + Cppcheck + + + + A&nalyze + ა&ნალიზი + + + + Standard + სტანდარტული + + + + &File + &ფაილი + + + + &View + &ხედი + + + + &Toolbars + &ხელსაწყოთა ზოლები + + + + C++ standard + C++-ის სტანდარტი + + + + &C standard + C standard + &C-ის სტანდარტი + + + + &Edit + &ჩასწორება + + + + &License... + &ლიცენზია... + + + + A&uthors... + &ავტორები... + + + + &About... + &შესახებ... + + + + &Files... + ფაილ&ები... + + + + + Analyze files + Check files + ფაილების ანალიზი + + + + Ctrl+F + Ctrl+F + + + + &Directory... + &საქაღალდე.... + + + + + Analyze directory + Check directory + საქაღალდის ანალიზი + + + + Ctrl+D + Ctrl+D + + + + Ctrl+R + Ctrl+R + + + + &Stop + &გაჩერება + + + + + Stop analysis + Stop checking + ანალიზის გაჩერება + + + + Esc + Esc + + + + &Save results to file... + შედეგები&ს შენახვა ფაილში.... + + + + Ctrl+S + Ctrl+S + + + + &Quit + გამოსვლა + + + + &Clear results + შედეგების &გასუფთავება + + + + &Preferences + &გამართვა + + + + + Show errors + შეცდომების ჩვენება + + + + + Show warnings + გაფრთხილების ჩვენება + + + + + Show performance warnings + წარმადობის გაფრთხილებების ჩვენება + + + + Show &hidden + დამალულის &ჩვენება + + + + + Information + ინფორმაცია + + + + Show information messages + ინფორმაციის შეტყობინებების ჩვენება + + + + Show portability warnings + გადატანადობის გაფრთხილებების ჩვენება + + + + Show Cppcheck results + Cppcheck-ის შედეგები ჩვენება + + + + Clang + Clang + + + + Show Clang results + Clang-ის შედეგები ჩვენება + + + + &Filter + &ფილტრი + + + + Filter results + შედეგების გაფილტვრა + + + + Windows 32-bit ANSI + Windows 32-bit ANSI + + + + Windows 32-bit Unicode + Windows 32-bit Unicode + + + + Unix 32-bit + Unix 32-bit + + + + Unix 64-bit + Unix 64-bit + + + + Windows 64-bit + Windows 64-bit + + + + &Print... + &ბეჭდვა… + + + + Print the Current Report + მიმდინარე ანგარიშის დაბეჭდვა + + + + Print Pre&view... + საბეჭდის &გადახედვა... + + + + Open a Print Preview Dialog for the Current Results + მიმდინარე შედეგების დაბეჭდვის მინიატურის დიალოგის ჩვენება + + + + Open library editor + ბიბლიოთეკის რედაქტორის გახსნა + + + + &Check all + &ყველას ჩართვა + + + + Checking for updates + განახლებების შემოწმება + + + + Hide + დამალვა + + + + Filter + ფილტრი + + + + &Reanalyze modified files + &Recheck modified files + ყველა შეცვლილი ფაილის თავიდან ანალი&ზი + + + + Reanal&yze all files + &ყველა ფაილის თავიდან ანალიზი + + + + Ctrl+Q + Ctrl+Q + + + + Style war&nings + ს&ტილის გაფრთხილებები + + + + E&rrors + &შეცდომები + + + + &Uncheck all + ყველას ჩამოყ&რა + + + + Collapse &all + ყველას ჩაკეცვ&ა + + + + &Expand all + &ყველას ამოკეცვა + + + + &Standard + &სტანდარტული + + + + Standard items + სტანდარტული ელემენტები + + + + Toolbar + ხელსაწყოთა ზოლი + + + + &Categories + &კატეგორიები + + + + Error categories + შეცდომის კატეგორიები + + + + &Open XML... + &XML-ის გახსნა... + + + + Open P&roject File... + პ&პროექტის ფაილის გახსნა... + + + + Ctrl+Shift+O + Ctrl+Shift+O + + + + Sh&ow Scratchpad... + ბლ&ოკნოტის ჩვენება... + + + + &New Project File... + &ახალი პროექტის ფაილი... + + + + Ctrl+Shift+N + Ctrl+Shift+N + + + + &Log View + ჟურნა&ლის ხედი + + + + Log View + ჟურნალის ხედი + + + + C&lose Project File + პროექტის ფაი&ლის დახურვა + + + + &Edit Project File... + პროექტის ფაილის ჩასწორ&ება... + + + + &Statistics + &სტატისტიკა + + + + &Warnings + &გაფრთხილებები + + + + Per&formance warnings + წარმატების გა&ფრთხილებები + + + + &Information + &ინფორმაცია + + + + &Portability + &გადატანადობა + + + + P&latforms + პ&ლატფორმები + + + + C++&11 + C++&11 + + + + C&99 + C&99 + + + + &Posix + &Posix + + + + C&11 + C&11 + + + + &C89 + &C89 + + + + &C++03 + &C++03 + + + + &Library Editor... + ბიბ&ლიოთეკის რედაქტორი... + + + + &Auto-detect language + ენის &ავტოდადგენა + + + + &Enforce C++ + ძ&ალით C++ + + + + E&nforce C + ძა&ლით C + + + + C++14 + C++14 + + + + Reanalyze and check library + ბიბლიოთეკის თავიდან ანალიზი და შემოწმება + + + + Check configuration (defines, includes) + კონფიგურაციის შემოწმება (defines, includes) + + + + C++17 + C++17 + + + + C++20 + C++20 + + + + Compliance report... + შესაბამისობის ანგარიში... + + + + &Contents + &შემცველობა + + + + Categories + კატეგორიები + + + + + Show style warnings + სტილის გაფრთხილების ჩვენება + + + + Open the help contents + დახმარების შემცველობის გახსნა + + + + F1 + F1 + + + + &Help + &დახმარება + + + + + Quick Filter: + სწრაფი ფილტრი: + + + + Select configuration + აირჩიეთ კონფიგურაცია + + + + Found project file: %1 + +Do you want to load this project file instead? + ვიპოვე პროექტის ფაილი: %1 + +გნებავთ, სამაგიეროდ, ეს პროექტის ფაილი ჩატვირთოთ? + + + + File not found + ფაილი ნაპოვნი არაა + + + + Bad XML + არასწორი XML + + + + Missing attribute + აკლია ატრიბუტი + + + + Bad attribute value + არასწორი ატრიბუტის მნიშვნელობა + + + + Unsupported format + მხარდაუჭერელი ფორმატი + + + + Duplicate define + გამეორებული აღწერა + + + + Failed to load the selected library '%1'. +%2 + ჩავარდა ჩატვირთვა მონიშნული ბიბლიოთეკისთვის '%1'. +%2 + + + + File not found: '%1' + ფაილი ვერ ვიპოვე: '%1' + + + + Failed to load/setup addon %1: %2 + დამატების (%1) ჩატვირთვა/მორგება ჩავარდა: %2 + + + + Failed to load %1. Your Cppcheck installation is broken. You can use --data-dir=<directory> at the command line to specify where this file is located. Please note that --data-dir is supposed to be used by installation scripts and therefore the GUI does not start when it is used, all that happens is that the setting is configured. + +Analysis is aborted. + + + + + Failed to load %1 - %2 + +Analysis is aborted. + %1-ის ჩატვირთვა ჩავარდა - %2 + +ანალიზი შეწყდა. + + + + + %1 + +Analysis is aborted. + %1 + +ანალიზი შეწყვეტილია. + + + + License + ლიცენზია + + + + Authors + ავტორები + + + + Save the report file + ანგარიშის ფაილში ჩაწერა + + + + + XML files (*.xml) + XML ფაილები (*.xml) + + + + There was a problem with loading the editor application settings. + +This is probably because the settings were changed between the Cppcheck versions. Please check (and fix) the editor application settings, otherwise the editor program might not start correctly. + + + + + You must close the project file before selecting new files or directories! + ახალი ფაილების ან საქაღალდეების არჩევამდე პრორექტის ფაილი უნდა დახუროთ! + + + + The library '%1' contains unknown elements: +%2 + ბიბლიოთეკა '%1' უცნობ ელემენტებს შეიცავს: +%2 + + + + Duplicate platform type + გამეორებული პლატფორმის ტიპი + + + + Platform type redefined + პლატფორმის ტიპი თავდან აღიწერა + + + + Unknown element + უცნობი ელემენტი + + + + Unknown issue + უცნობი პრობლემა + + + + + + + Error + შეცდომა + + + + Open the report file + ანგარიშის ფაილის გახსნა + + + + Text files (*.txt) + ტექსტური ფაილები (*.txt) + + + + CSV files (*.csv) + CSV ფაილები (*.csv) + + + + Project files (*.cppcheck);;All files(*.*) + პროექტის ფაილები (*.cppcheck);;ყველა ფაილი(*.*) + + + + Select Project File + აირჩიეთ პროექტის ფაილი + + + + + + + Project: + პროექტი: + + + + No suitable files found to analyze! + ანალიზისათვის შესაფერისი ფაილები აღმოჩენილი არაა! + + + + C/C++ Source + C/C++ საწყისი კოდი + + + + Compile database + მონაცემთა ბაზის კომპილაცია + + + + Visual Studio + Visual Studio + + + + Borland C++ Builder 6 + Borland C++ Builder 6 + + + + Select files to analyze + აირჩეთ ფაილები ანალიზისთვის + + + + Select directory to analyze + აირჩიეთ საქაღალდე ანალიზისთვის + + + + Select the configuration that will be analyzed + აირჩიეთ კონფიგურაცია ანალიზისთვის + + + + Found project files from the directory. + +Do you want to proceed analysis without using any of these project files? + აღმოჩენილია პროექტის ფაილები საქაღალდიდან. + +გნებავთ, გააგრძელოთ ანალიზი ამ პროექტის ფაილების გამოყენების გარეშე? + + + + Current results will be cleared. + +Opening a new XML file will clear current results. +Do you want to proceed? + მიმდინარე შედეგები გასუფთავდება. + +ახალი XML ფაილის გახსნა მიმდინარე შედეგებს გაასუფთავებს. +გნებავთ, გააგრძელოთ? + + + + Analyzer is running. + +Do you want to stop the analysis and exit Cppcheck? + ანალიზატორი გაშვებულია. + +გნებავთ, გააჩეროთ ანალიზი და გახვიდეთ Cppcheck-დან? + + + + About + შესახებ + + + + XML files (*.xml);;Text files (*.txt);;CSV files (*.csv) + XML ფაილები (*.xml);;ტექსტური ფაილები (*.txt);;CSV ფაილები (*.csv) + + + + Cannot generate a compliance report right now, an analysis must finish successfully. Try to reanalyze the code and ensure there are no critical errors. + შესაბამისობის ანგარიშის გენერაცია ახლა შეუძლებელია, რადგან ჯერ ანალიზი წარმატებით უნდა დასრულდეს. სცადეთ, კოდის ანალიზი თავიდან გაუშვათ და დარწმუნდეთ, რომ კრიტიკული შეცდომები არ არსებობს. + + + + Build dir '%1' does not exist, create it? + აგების საქაღალდე (%1) არ არსებობს. შევქმნა? + + + + To check the project using addons, you need a build directory. + პროექტის დამატებებით შესამოწმებლად აგების საქაღალდე გჭირდებათ. + + + + Failed to open file + ფაილის გახსნის შეცდომა + + + + Unknown project file format + უცნობი პროექტის ფაილის ფორმატი + + + + Failed to import project file + პროექტის ფაილის შემოტანა ჩავარდა + + + + Failed to import '%1': %2 + +Analysis is stopped. + '%1'-ის შემოტანა ჩავარდა: %2 + +ანალიზი შეწყდა. + + + + Failed to import '%1' (%2), analysis is stopped + '%1'-ის (%2) შემოტანა ჩავარდა. ანალიზი შეწყდა + + + + Project files (*.cppcheck) + პროექტის ფაილები (*.cppcheck) + + + + Select Project Filename + აირჩიეთ პროექტის ფაილის სახელი + + + + No project file loaded + პროექტის ფაილი ჩატვირთული არაა + + + + The project file + +%1 + + could not be found! + +Do you want to remove the file from the recently used projects -list? + პროექტის ფაილი + +%1 + +ვერ ვიპოვე! + +გნებავთ წაშალოთ ეს ფაილი ახლახან გამოყენებული პროექტების სიიდან? + + + + Install + დაყენება + + + + New version available: %1. %2 + ხელმისაწვდომია ახალი ვერსია: %1. %2 + + + + Cppcheck GUI. + +Syntax: + cppcheck-gui [OPTIONS] [files or paths] + +Options: + -h, --help Print this help + -p <file> Open given project file and start checking it + -l <file> Open given results xml file + -d <directory> Specify the directory that was checked to generate the results xml specified with -l + -v, --version Show program version + --data-dir=<directory> This option is for installation scripts so they can configure the directory where + datafiles are located (translations, cfg). The GUI is not started when this option + is used. + Cppcheck GUI. + +Syntax: + cppcheck-gui [OPTIONS] [files or paths] + +Options: + -h, --help Print this help + -p <file> Open given project file and start checking it + -l <file> Open given results xml file + -d <directory> Specify the directory that was checked to generate the results xml specified with -l + -v, --version Show program version + --data-dir=<directory> Specify directory where GUI datafiles are located (translations, cfg) + Cppcheck GUI. + +სინტაქსი: + cppcheck-gui [პარამეტრები] [ფაილები ან ბილიკები] + +პარამეტრები: + -h, --help ამ დახმარების დაბეჭდვა + -p <file> მითითებული პროექტის გახსნა და შემოწმების დაწყება + -l <file> მითითებული შედეგების xml ფაილის გახსნა + -d <directory> მიუთითეთ საქაღალდე, რომელიც შემოწმებული იყო, -l-ით მითითებული xml ფაილის გენერაცისთვის + -v, --version პროგრამის ვერსიის ჩვენება + --data-dir=<directory> ეს პარამეტრი დაყენების სკრიპტებისთვისაა, რომ დააყენონ საქაღალდე, სადაა + მონაცემები (თარგმანები, კონფიგურაცია) მოთავსებული. როცა ეს პარამეტრი მითითებულია, გრაფიკული ინტერფეისი + არ გამოიყენება. + + + + Cppcheck GUI - Command line parameters + Cppcheck GUI - ბრძანების სტრიქონის პარამეტრები + + + + NewSuppressionDialog + + + New suppression + ახალი ჩახშობა + + + + Error ID + შეცდომის ID + + + + File name + ფაილის სახელი + + + + Line number + ხაზის ნომერი + + + + Symbol name + სიმბოლოს სახელი + + + + Edit suppression + ჩახშობის ჩასწორება + + + + Platforms + + + Native + საკუთარი + + + + Unix 32-bit + Unix 32-bit + + + + Unix 64-bit + Unix 64-bit + + + + Windows 32-bit ANSI + Windows 32-bit ANSI + + + + Windows 32-bit Unicode + Windows 32-bit Unicode + + + + Windows 64-bit + Windows 64-bit + + + + ProjectFile + + + Project File + პროექტის ფაილი + + + + Paths and Defines + ბილიკები და აღწერები + + + + Import Project (Visual studio / compile database/ Borland C++ Builder 6) + Import Project (Visual studio / compile database) + პროექტის შემოტანა (Visual studio / მონაცემთა ბაზი კომპილაცია / Borland C++ Builder 6) + + + + Defines must be separated by a semicolon. Example: DEF1;DEF2=5;DEF3=int + Defines must be separated by a semicolon ';' + აღწერები წერტილმძიმით უნდა იყოს გამოყოფილი. მაგ: DEF1;DEF2=5;DEF3=int + + + + Note: Put your own custom .cfg files in the same folder as the project file. You should see them above. + შენიშვნა: ჩადეთ თქვენი .cfg ფაილები იგივე საქაღალდეში, სადაც პროექტის ფაილია. მათ ზემოთ დაინახავთ. + + + + Clang (experimental) + Clang (ექსპერიმენტული) + + + + If you want to design your classes to be as flexible and robust as possible then the public interface must be very robust. Cppcheck will asumme that arguments can take *any* value. + + + + + Check code in headers (should be ON normally. if you want a limited quick analysis then turn this OFF) + თავსართის ფაილებში არსებული კოდის შეწმება (ნაგულისხმევად, ეს ჩართულია. თუ გნებავთ შეზღუდული სწრაფი ანალიზი, მაშინ გამორთეთ ეს) + + + + Max recursion in template instantiation + + + + + Filepaths in warnings will be relative to this path + ფაილის ბილიკები ამ ბილიკის ფარდობითი იქნება + + + + If tags are added, you will be able to right click on warnings and set one of these tags. You can manually categorize warnings. + თუ ჭდეები დამატებულია, შეგიძლიათ, გაფრთხილებებზე მარჯვენა ღილაკით დააწკაპუნოთ და დააყენოთ ერთ-ერთი ჭდე. გაფრთხილებების კატეგორიებად დალაგება ხელით შეგიძლიათ. + + + + Exclude source files + კოდის ფაილების ამოღება + + + + Exclude folder... + საქაღალდის ამოღება... + + + + Exclude file... + ფაილის ამოღება... + + + + MISRA rule texts + MISRA-ის წესის ტექსტები + + + + <html><head/><body><p>Copy/paste the text from Appendix A &quot;Summary of guidelines&quot; from the MISRA C 2012 pdf to a text file.</p></body></html> + + + + + ... + ... + + + + <html><head/><body><p>You have a choice:</p><p> * Analyze all Debug and Release configurations</p><p> * Only analyze the first matching Debug configuration</p><p><br/></p></body></html> + + + + + + Browse... + ნუსხა... + + + + Analyze all Visual Studio configurations + ყველა Visual Studio-ის კონფიგურაციის ანალიზი + + + + Selected VS Configurations + არჩეული VS-ის კონფიგურაციები + + + + Paths: + ბილიკები: + + + + + Add... + დამატება... + + + + + + Edit + ჩასწორება + + + + + + + Remove + წაშლა + + + + Undefines: + წაშლილი მაკროაღწერები: + + + + Undefines must be separated by a semicolon. Example: UNDEF1;UNDEF2;UNDEF3 + წაშლილი მაკროაღწერები წერტილმძიმით უნდა იყოს გამოყოფილი. მაგ: UNDEF1;UNDEF2;UNDEF3 + + + + Include Paths: + ჩასმის ბილიკები: + + + + Types and Functions + ტიპები და ფუნქციები + + + + + Analysis + ანალიზი + + + + This is a workfolder that Cppcheck will use for various purposes. + ეს სამუშაო საქაღალდეა, რომელსაც Cppcheck სხვადასხვა მიზნებისთვის გამოიყენებს. + + + + Parser + ანალიზატორი + + + + Cppcheck (built in) + Cppcheck (ჩაშენებული) + + + + Check level + შემოწმების დონე + + + + Normal -- meant for normal analysis in CI. Analysis should finish in reasonable time. + ნორმალური -- ნიშნავს ნორმალურ ანალიზს CI-ში. ანალიზი მისაღებ დროში დასრულდება. + + + + Exhaustive -- meant for nightly builds etc. Analysis time can be longer (10x slower than compilation is OK). + ამომწურავი -- განკუთვნილია ღამის აგებებისთვის და ა.შ. ანალიზის დრო, შეიძლება, უფრო მეტიც იყოს (კომპილაციაზე 10x მეტი დრო ჩვეულებრივი ამბავია). + + + + Check that each class has a safe public interface + შემოწმება, აქვს თუ არა ყველა კლასს უსაფრთხო საჯარო ინტერფეისი + + + + Limit analysis + ანალიზის შეზღუდვა + + + + Check code in unused templates (should be ON normally, however in theory you can safely ignore warnings in unused templates) + Check code in unused templates (slower and less accurate analysis) + + + + + Max CTU depth + CTU-ის მაქსიმალური სიღრმე + + + + Enable inline suppressions + შეცდომების ხაზშივე ჩახშობის ჩართვა + + + + Misra C++ + Misra C++ + + + + 2008 + 2008 + + + + Cert C + Cert C + + + + CERT-INT35-C: int precision (if size equals precision, you can leave empty) + CERT-INT35-C: მთელი რიცხვის სიზუსტე (თუ ზომა სიზუსტეს ემთხვევა, შეგიძლიათ, ცარიელი დატოვოთ) + + + + Autosar + + + + + Bug hunting + შეცდომებზე ნადირობა + + + + External tools + გარე ხელსაწყოები + + + + Up + მაღლა + + + + Down + ქვემოთ + + + + Platform + პლატფორმა + + + + Warning options + გაფრთხილების მორგება + + + + Root path: + Root ბილიკი: + + + + Warning tags (separated by semicolon) + გაფრთხილების ჭდეები (წერტილმძიმით გამოყოფილი) + + + + Cppcheck build dir (whole program analysis, incremental analysis, statistics, etc) + Cppcheck-ის აგების საქაღალდე (მთელი პროგრამის ანალიზი, ინკრემენტული ანალიზი, სტატისტიკა და ა.შ.) + + + + Libraries + ბიბლიოთეკები + + + + Suppressions + ჩახშობები + + + + Add + დამატება + + + + + Addons + დამატებები + + + + Note: Addons require <a href="https://www.python.org/">Python</a> being installed. + შენიშვნა: დამატებას დაყენებული <a href="https://www.python.org/">Python</a> სჭირდება. + + + + Y2038 + Y2038 + + + + Thread safety + ნაკადების უსაფრთხოება + + + + Coding standards + კოდირების სტანდარტები + + + + Misra C + Misra C + + + + 2012 + 2012 + + + + + 2023 + 2023 + + + + Cert C++ + Cert C++ + + + + Bug hunting (Premium) + შეცდომებზე ნადირობა (ფასიანი) + + + + Clang analyzer + Clang-ის ანალიზატორი + + + + Clang-tidy + Clang-tidy + + + + Defines: + მაკროაღწრები: + + + + ProjectFileDialog + + + Project file: %1 + პროექტის ფაილი: %1 + + + + Select Cppcheck build dir + აირჩიეთ Cppcheck-ის აგების საქაღალდე + + + + Select include directory + აირჩიეთ ჩასასმელი საქაღალდე + + + + Select a directory to check + აირჩიეთ შესამოწმებელი საქაღალდე + + + + Clang-tidy (not found) + Clang-tidy (ვერ ვიპოვე) + + + + Visual Studio + Visual Studio + + + + Compile database + მონაცემთა ბაზის კომპილაცია + + + + Borland C++ Builder 6 + Borland C++ Builder 6 + + + + Import Project + პროექტის შემოტანა + + + + Select directory to ignore + აირჩიეთ გამოსატოვებელი საქაღალდე + + + + Source files + კოდის ფაილები + + + + All files + ყველა ფაილი + + + + Exclude file + ფაილის ამოღება + + + + Select MISRA rule texts file + აირჩიეთ MISRA-ის წესების ტექსტის ფაილი + + + + MISRA rule texts file (%1) + MISRA-ის წესის ტექსტების ფაილი (%1) + + + + QObject + + + Unknown language specified! + მითითებული ენა უცნობია! + + + + Language file %1 not found! + Language file %1.qm not found! + ენის ფაილი %1 ვერ ვიპოვე! + + + + Failed to load translation for language %1 from file %2 + Failed to load translation for language %1 from file %2.qm + ჩავარდა თარგმანის ჩატვირთვა ენისთვის %1 ფაილიდან %2 + + + + line %1: Unhandled element %2 + + + + + line %1: Mandatory attribute '%2' missing in '%3' + ხაზი %1: აუცილებელი ატრიბუტი '%2' '%3'-ში აღმოჩენილი არაა + + + + (Not found) + (ვერ ვიპოვე) + + + + Thin + თხელი + + + + ExtraLight + ძალიან მსუბუქი + + + + Light + ღია + + + + Normal + ნორმალური + + + + Medium + საშუალო + + + + DemiBold + საშუალოდ სქელი + + + + Bold + გასქელება + + + + ExtraBold + ძალიან სქელი + + + + Black + შავი + + + + Editor Foreground Color + რედაქტორის წინა პლანის ფერი + + + + Editor Background Color + რედაქტორის ფონის ფერი + + + + Highlight Background Color + ფონის ფერის გაოკვეთა + + + + Line Number Foreground Color + ხაზის ნომრის წინა პლანის ფერი + + + + Line Number Background Color + ხაზის ნომრის ფონის ფერი + + + + Keyword Foreground Color + საკვანძო სიტყვის წინა პლანის ფერი + + + + Keyword Font Weight + საკვანძო სიტყვის ფონტის სიმძიმე + + + + Class Foreground Color + Class ForegroundColor + კლასის წინა პლანის ფერი + + + + Class Font Weight + კლასის ფონტის სიმძიმე + + + + Quote Foreground Color + ციტატის წინა პლანის ფერი + + + + Quote Font Weight + ციტატის ფონტის სიმძიმე + + + + Comment Foreground Color + კომენტარის წინა პლანს ფერი + + + + Comment Font Weight + კომენტარის ფონტის სიმძიმე + + + + Symbol Foreground Color + სიმბოლოს წინა პლანის ფერი + + + + Symbol Background Color + სიმბოლოს ფონის ფერი + + + + Symbol Font Weight + სიმბოლოს ფონტის სიმძიმე + + + + Set to Default Light + ნაგულისხმევად ღიას დაყენება + + + + Set to Default Dark + ნაგულისხმევად მუქის დაყენება + + + + QPlatformTheme + + + OK + დიახ + + + + Cancel + შეწყვეტა + + + + Close + დახურვა + + + + Save + შენახვა + + + + ResultsTree + + + File + ფაილი + + + + Severity + სიმძიმე + + + + Line + ხაზი + + + + Summary + შეჯამება + + + + Undefined file + გაურკვეველი ფაილი + + + + Copy + კოპირება + + + + Could not find file: + ვერ ვიპოვე ფაილი: + + + + Please select the folder '%1' + აირჩიეთ საქაღალდე '%1' + + + + Select Directory '%1' + აირჩიეთ საქაღალდე '%1' + + + + Please select the directory where file is located. + აირჩიეთ საქაღალდე, სადაც ფაილია მოთავსებული. + + + + debug + შეცდომების მოძებნა + + + + note + ნოტა + + + + Recheck + თავიდან შემოწმება + + + + Hide + დამალვა + + + + Hide all with id + დამალვა ყველასი id-ით + + + + Suppress selected id(s) + მონიშნული id(ებ)-ის ჩახშობა + + + + Open containing folder + შემცველი საქაღალდის გახსნა + + + + internal + შიდა + + + + + Tag + იარლიყი + + + + No tag + ჭდის გარეშე + + + + + Cppcheck + Cppcheck + + + + No editor application configured. + +Configure the editor application for Cppcheck in preferences/Applications. + Configure the text file viewer program in Cppcheck preferences/Applications. + რედაქტორის აპლიკაცია მითითებული არაა. + +მიუთითეთ რედაქტორის აპლიკაცია Cppcheck-სთვის მენიუში მორგება/აპლიკაციები. + + + + No default editor application selected. + +Please select the default editor application in preferences/Applications. + ნაგულისხმევი რედაქტორის აპლიკაცია არჩეული არაა. + +აირჩიეთ ნაგულისხმევი რედაქტორის აპლიკაცია მენიუში მორგება/აპლიკაციები. + + + + Could not find the file! + ფაილი ვერ ვიპოვე! + + + + Could not start %1 + +Please check the application path and parameters are correct. + %1 ვერ გავუშვი + +შეამოწმეთ, სწორია, თუ არა აპლიკაციის ბილიკი და მისი პარამეტრები. + + + + Select Directory + აირჩიეთ საქაღალდე + + + + Id + Id + + + + Inconclusive + არადამაჯერებელი + + + + Since date + თარიღიდან + + + + style + სტილი + + + + error + შეცდომა + + + + warning + გაფრთხილება + + + + performance + წარმადობა + + + + portability + გადატანადობა + + + + information + ინფორმაცია + + + + ResultsView + + + Print Report + ანგარიშის დაბეჭდვა + + + + No errors found, nothing to print. + შეცდომები ვერ ვიპოვე. დასაბეჭდი არაფერია. + + + + %p% (%1 of %2 files checked) + %p% (შემოწმებულია %1 ფაილი %2-დან) + + + + + Cppcheck + Cppcheck + + + + No errors found. + შეცდომების გარეშე. + + + + Errors were found, but they are configured to be hidden. +To toggle what kind of errors are shown, open view menu. + აღმოჩენილია შეცდომები, მაგრამ მითითებულია, რომ ისინი დაიმალოს. +იმისათვის, რომ გადართოთ, რა სახის შეცდომებია ნაჩვენები, გახსენით მენიუ 'ხედი'. + + + + + Failed to read the report. + ანგარიშის წაკითხვა ჩავარდა. + + + + XML format version 1 is no longer supported. + XML-ის ფორმატის პირველი ვერსია მხარდაჭერილი აღარაა. + + + + First included by + პირველად ჩასმულია ფაილში + + + + Id + Id + + + + Bug hunting analysis is incomplete + შეცდომებზე ნადირობის ანალიზი დაუსრულებელია + + + + Clear Log + ჟურნალის გასუფთავება + + + + Copy this Log entry + ამ ჟურნალის ჩანაწერის კოპირება + + + + Copy complete Log + სრული ჟურნალის კოპირება + + + + Analysis was stopped + ანალიზი გაუქმებულია + + + + There was a critical error with id '%1' + აღმოჩენილია კრიტიკული შეცდომა id-ით '%1' + + + + when checking %1 + %1-ის შემოწმებისას + + + + when checking a file + ფაილის შემოწმებისას + + + + Analysis was aborted. + ანალიზი შეწყვეტილია. + + + + + Failed to save the report. + ანგარიშის შენახვა ჩავარდა. + + + + Results + შედეგები + + + + Critical errors + კრიტიკული შეცდომები + + + + Analysis Log + ანალიზის ჟურნალი + + + + Warning Details + გაფრთხილების დეტალები + + + + ScratchPad + + + Scratchpad + მონახაზი + + + + Copy or write some C/C++ code here: + დააკოპირეთ ან დაწერეთ C/C++ კოდი აქ: + + + + Optionally enter a filename (mainly for automatic language detection) and click on "Check": + შეიყვანეთ არასავალდებულო ფაილის სახელი (ძირითადად ავტომატური ენის დადგენისთვის) და დააწკაპუნეთ ღილაკზე "შემოწმება": + + + + filename + ფაილის სახელი + + + + Check + შემოწმება + + + + Settings + + + Preferences + მორგება + + + + General + ზოგადი + + + + Add... + დამატება... + + + + Number of threads: + ნაკადების რაოდენობა: + + + + Ideal count: + რეკომენდებული მნიშვნელობა: + + + + Force checking all #ifdef configurations + Check all #ifdef configurations + ყველა #ifdef კონფიგურაციის ნაძალადევი შემოწმება + + + + Show full path of files + ფაილების სრული ბილიკის ჩვენება + + + + Show "No errors found" message when no errors found + "შეცდომები ნაპოვნი არაა" შეტყობინების ჩვენება, როცა შეცდომები აღმოჩენილი არა + + + + Display error Id in column "Id" + სვეტში "Id" შეცდომის Id-ის ჩვენება + + + + Enable inline suppressions + შეცდომების ხაზშივე ჩახშობის ჩართვა + + + + Check for inconclusive errors also + ასევე, ნაჩვენები იქნება საკამათო შეცდომებიც + + + + Show statistics on check completion + სტატისტიკის ჩვენება შემოწმების დასრულებისას + + + + Check for updates + განახლებების შემოწმება + + + + Show internal warnings in log + ჟურნალში შიდა გაფრთხილებების ჩვენება + + + + Addons + დამატებები + + + + Python binary (leave this empty to use python in the PATH) + ბილიკი python-ის ინტერპრეტატორამდე. (PATH-ში არსებული python-ის გამოსაყენებლად ცარიელი დატოვეთ) + + + + + + ... + ... + + + + MISRA addon + MISRA-ის დამატება + + + + MISRA rule texts file + MISRA-ის წესის ტექსტების ფაილი + + + + <html><head/><body><p>Copy/paste the text from Appendix A &quot;Summary of guidelines&quot; from the MISRA C 2012 pdf to a text file.</p></body></html> + + + + + Clang + Clang + + + + Clang path (leave empty to use system PATH) + ბილიკი Clang-ის ინტერპრეტატორამდე. (PATH-ში არსებულის გამოსაყენებლად ცარიელი დატოვეთ) + + + + Visual Studio headers + Visual Studio-ის თავსართები + + + + <html><head/><body><p>Paths to Visual Studio headers, separated by semicolon ';'.</p><p>You can open a Visual Studio command prompt, write &quot;SET INCLUDE&quot;. Then copy/paste the paths.</p></body></html> + + + + + Code Editor + კოდის რედაქტორი + + + + Code Editor Style + კოდის რედაქტორის სტილი + + + + System Style + სისტემის მიყოლა + + + + Default Light Style + ნაგულისხმევი ღია სტილი + + + + Default Dark Style + ნაგულისხმევი მუქი სტილი + + + + Custom + მომხმარებლის + + + + Remove + წაშლა + + + + Applications + აპლიკაციები + + + + + Edit... + რედაქტირება... + + + + Set as default + ნაგულისხმებად დაყენება + + + + Reports + ანგარიში + + + + Save all errors when creating report + ყველა შეცდომის შენახვა ანგარიშის შექმნისას + + + + Save full path to files in reports + ფაილების სრული ბილიკის ჩვენება ანგარიშებში + + + + Language + ენა + + + + SettingsDialog + + + N/A + N/A + + + + The executable file "%1" is not available + გამშვები ფაილი "%1" ხელმისაწვდომი არაა + + + + Add a new application + ახალი აპლიკაციის დამატება + + + + Modify an application + აპლიკაციის შეცვლა + + + + [Default] + [ნაგულისხმევი] + + + + [Default] + [ნაგულისხმევი] + + + + Select python binary + აირჩიეთ python-ის გამშვები ფაილი + + + + Select MISRA File + აირჩიეთ MISA ფაილი + + + + Select clang path + აირჩიეთ clang-ის ბილიკი + + + + StatsDialog + + + + + + Statistics + სტატისტიკა + + + + + Project + პროექტი + + + + Project: + პროექტი: + + + + Paths: + ბილიკები: + + + + Include paths: + თავსართის ფაილის ბილიკები: + + + + Defines: + მაკროაღწრები: + + + + Undefines: + წაშლილი მაკროაღწერები: + + + + + Previous Scan + წინა სკანირება + + + + Path Selected: + არჩეული ბილიკი: + + + + Number of Files Scanned: + დასკანერებულია ფაილების რაოდენობა: + + + + Scan Duration: + სკანირების ხანგრძლივობა: + + + + Errors: + შეცდომები: + + + + Warnings: + გაფრთხილებები: + + + + Stylistic warnings: + სტილისტური გაფრთხილებები: + + + + Portability warnings: + გადატანადობის გაფრთხილებები: + + + + Performance issues: + წარმადობის პრობლემები: + + + + Information messages: + ინფორმაციის შეტყობინებები: + + + + Active checkers: + აქტიური შემმოწმებლები: + + + + Checkers + შაში + + + + History + ისტორია + + + + File: + ფაილი: + + + + Copy to Clipboard + ბუფერში კოპირება + + + + Pdf Export + PDF-ად გატანა + + + + 1 day + 1 დღე + + + + %1 days + %1 დღე + + + + 1 hour + %1 საათი + + + + %1 hours + %1 საათი + + + + 1 minute + %1 წუთი + + + + %1 minutes + %1 წთ + + + + 1 second + 1 წამი + + + + %1 seconds + %1 წამი + + + + 0.%1 seconds + 0.%1 წამი + + + + and + და + + + + Export PDF + PDF-ში გატანა + + + + Project Settings + პროექტის პარამეტრები + + + + Paths + ბილიკები + + + + Include paths + ჩასმის ბილიკები + + + + Defines + აღწერები + + + + Undefines + წაშლილი მაკროაღწერები + + + + Path selected + არჩეული ბილიკი + + + + Number of files scanned + დასკანერებულია ფაილების რაოდენობა + + + + Scan duration + სკანირების ხანგრძლივობა + + + + + Errors + შედომები + + + + File: + ფაილი: + + + + No cppcheck build dir + Cppcheck-ის აგების საქაღალდის გარეშე + + + + + Warnings + გაფრთხილებები + + + + + Style warnings + სტილის გაფრთხილებები + + + + + Portability warnings + გადატანადობის გაფრთხილებები + + + + + Performance warnings + წარმადობის გაფრთხილებები + + + + + Information messages + საინფორმაციო შეტყობინებები + + + + ThreadResult + + + %1 of %2 files checked + შემოწმებულია %1 ფაილი %2-დან + + + + TranslationHandler + + + Failed to change the user interface language: + +%1 + +The user interface language has been reset to English. Open the Preferences-dialog to select any of the available languages. + ჩავარდა მომხმარებლის ინტერფეისის ენის გარდართვა ენაზე: + +%1 + +მომხმარებლის ინტერფეისი ინგლისურზე გადაირთო. გახსენით მორგების დიალოგი, რომ ხელმისაწვდომი ენებიდან სასურველი აირჩიოთ. + + + + Cppcheck + Cppcheck + + + + TxtReport + + + inconclusive + არადამაჯერებელი + + + + toFilterString + + + All supported files (%1) + ყველა მხარდაჭერილი ფაილი (%1) + + + + All files (%1) + ყველა ფაილი (%1) + + + diff --git a/gui/gui.pro b/gui/gui.pro index b3d4c9da97e..338be751fd2 100644 --- a/gui/gui.pro +++ b/gui/gui.pro @@ -86,6 +86,7 @@ TRANSLATIONS = cppcheck_de.ts \ cppcheck_fr.ts \ cppcheck_it.ts \ cppcheck_ja.ts \ + cppcheck_ka.ts \ cppcheck_ko.ts \ cppcheck_nl.ts \ cppcheck_ru.ts \ diff --git a/gui/mainwindow.cpp b/gui/mainwindow.cpp index d4b28c43c04..07048c429f6 100644 --- a/gui/mainwindow.cpp +++ b/gui/mainwindow.cpp @@ -836,7 +836,7 @@ void MainWindow::addIncludeDirs(const QStringList &includeDirs, Settings &result } } -Library::Error MainWindow::loadLibrary(Library &library, const QString &filename, bool debug) +Library::Error MainWindow::loadLibrary(Library &library, const QString &filename) { Library::Error ret; @@ -844,8 +844,7 @@ Library::Error MainWindow::loadLibrary(Library &library, const QString &filename if (mProjectFile) { QString path = QFileInfo(mProjectFile->getFilename()).canonicalPath(); QString libpath = path+"/"+filename; - if (debug) - std::cout << "looking for library '" + libpath.toStdString() + "'" << std::endl; + qDebug().noquote() << "looking for library '" + libpath + "'"; ret = library.load(nullptr, libpath.toLatin1()); if (ret.errorcode != Library::ErrorCode::FILE_NOT_FOUND) return ret; @@ -854,14 +853,12 @@ Library::Error MainWindow::loadLibrary(Library &library, const QString &filename // Try to load the library from the application folder.. const QString appPath = QFileInfo(QCoreApplication::applicationFilePath()).canonicalPath(); QString libpath = appPath+"/"+filename; - if (debug) - std::cout << "looking for library '" + libpath.toStdString() + "'" << std::endl; + qDebug().noquote() << "looking for library '" + libpath + "'"; ret = library.load(nullptr, libpath.toLatin1()); if (ret.errorcode != Library::ErrorCode::FILE_NOT_FOUND) return ret; libpath = appPath+"/cfg/"+filename; - if (debug) - std::cout << "looking for library '" + libpath.toStdString() + "'" << std::endl; + qDebug().noquote() << "looking for library '" + libpath + "'"; ret = library.load(nullptr, libpath.toLatin1()); if (ret.errorcode != Library::ErrorCode::FILE_NOT_FOUND) return ret; @@ -871,14 +868,12 @@ Library::Error MainWindow::loadLibrary(Library &library, const QString &filename const QString filesdir = FILESDIR; if (!filesdir.isEmpty()) { libpath = filesdir+"/cfg/"+filename; - if (debug) - std::cout << "looking for library '" + libpath.toStdString() + "'" << std::endl; + qDebug().noquote() << "looking for library '" + libpath + "'"; ret = library.load(nullptr, libpath.toLatin1()); if (ret.errorcode != Library::ErrorCode::FILE_NOT_FOUND) return ret; - libpath = filesdir+filename; - if (debug) - std::cout << "looking for library '" + libpath.toStdString() + "'" << std::endl; + libpath = filesdir+"/"+filename; + qDebug().noquote() << "looking for library '" + libpath + "'"; ret = library.load(nullptr, libpath.toLatin1()); if (ret.errorcode != Library::ErrorCode::FILE_NOT_FOUND) return ret; @@ -889,21 +884,18 @@ Library::Error MainWindow::loadLibrary(Library &library, const QString &filename const QString datadir = getDataDir(); if (!datadir.isEmpty()) { libpath = datadir+"/"+filename; - if (debug) - std::cout << "looking for library '" + libpath.toStdString() + "'" << std::endl; + qDebug().noquote() << "looking for library '" + libpath + "'"; ret = library.load(nullptr, libpath.toLatin1()); if (ret.errorcode != Library::ErrorCode::FILE_NOT_FOUND) return ret; libpath = datadir+"/cfg/"+filename; - if (debug) - std::cout << "looking for library '" + libpath.toStdString() + "'" << std::endl; + qDebug().noquote() << "looking for library '" + libpath + "'"; ret = library.load(nullptr, libpath.toLatin1()); if (ret.errorcode != Library::ErrorCode::FILE_NOT_FOUND) return ret; } - if (debug) - std::cout << "library not found: '" + filename.toStdString() + "'" << std::endl; + qDebug().noquote() << "library not found: '" + filename + "'"; return ret; } diff --git a/gui/mainwindow.h b/gui/mainwindow.h index 37005e1ccd0..36785474839 100644 --- a/gui/mainwindow.h +++ b/gui/mainwindow.h @@ -394,7 +394,7 @@ private slots: * @param filename filename (no path) * @return error code */ - Library::Error loadLibrary(Library &library, const QString &filename, bool debug = false); + Library::Error loadLibrary(Library &library, const QString &filename); /** * @brief Tries to load library file, prints message on error diff --git a/gui/threadresult.cpp b/gui/threadresult.cpp index bbb373e9519..008d201c42d 100644 --- a/gui/threadresult.cpp +++ b/gui/threadresult.cpp @@ -68,15 +68,15 @@ QString ThreadResult::getNextFile() return mFiles.takeFirst(); } -FileSettings ThreadResult::getNextFileSettings() +void ThreadResult::getNextFileSettings(const FileSettings*& fs) { std::lock_guard locker(mutex); - if (mFileSettings.empty()) { - return FileSettings(""); + fs = nullptr; + if (mItNextFileSettings == mFileSettings.cend()) { + return; } - const FileSettings fs = mFileSettings.front(); - mFileSettings.pop_front(); - return fs; + fs = &(*mItNextFileSettings); + ++mItNextFileSettings; } void ThreadResult::setFiles(const QStringList &files) @@ -100,6 +100,7 @@ void ThreadResult::setProject(const ImportProject &prj) std::lock_guard locker(mutex); mFiles.clear(); mFileSettings = prj.fileSettings; + mItNextFileSettings = mFileSettings.cbegin(); mProgress = 0; mFilesChecked = 0; mTotalFiles = prj.fileSettings.size(); @@ -116,6 +117,7 @@ void ThreadResult::clearFiles() std::lock_guard locker(mutex); mFiles.clear(); mFileSettings.clear(); + mItNextFileSettings = mFileSettings.cend(); mFilesChecked = 0; mTotalFiles = 0; } diff --git a/gui/threadresult.h b/gui/threadresult.h index faea466d44d..f9611eac2d4 100644 --- a/gui/threadresult.h +++ b/gui/threadresult.h @@ -54,7 +54,7 @@ class ThreadResult : public QObject, public ErrorLogger { */ QString getNextFile(); - FileSettings getNextFileSettings(); + void getNextFileSettings(const FileSettings*& fs); /** * @brief Set list of files to check @@ -137,6 +137,7 @@ public slots: QStringList mFiles; std::list mFileSettings; + std::list::const_iterator mItNextFileSettings; /** * @brief Max progress diff --git a/lib/checkleakautovar.cpp b/lib/checkleakautovar.cpp index 1cd3ffa4de5..80a3a862893 100644 --- a/lib/checkleakautovar.cpp +++ b/lib/checkleakautovar.cpp @@ -104,47 +104,6 @@ static bool isVarTokComparison(const Token * tok, const Token ** vartok, //--------------------------------------------------------------------------- -void VarInfo::print() -{ - std::cout << "size=" << alloctype.size() << std::endl; - for (std::map::const_iterator it = alloctype.cbegin(); it != alloctype.cend(); ++it) { - std::string strusage; - const auto use = possibleUsage.find(it->first); - if (use != possibleUsage.end()) - strusage = use->second.first->str(); - - std::string status; - switch (it->second.status) { - case OWNED: - status = "owned"; - break; - case DEALLOC: - status = "dealloc"; - break; - case ALLOC: - status = "alloc"; - break; - case NOALLOC: - status = "noalloc"; - break; - case REALLOC: - status = "realloc"; - break; - default: - status = "?"; - break; - } - - std::cout << "status=" << status << " " - << "alloctype='" << it->second.type << "' " - << "possibleUsage='" << strusage << "' " - << "conditionalAlloc=" << (conditionalAlloc.find(it->first) != conditionalAlloc.end() ? "yes" : "no") << " " - << "referenced=" << (referenced.find(it->first) != referenced.end() ? "yes" : "no") << " " - << "reallocedFrom=" << it->second.reallocedFromType - << std::endl; - } -} - void VarInfo::possibleUsageAll(const std::pair& functionUsage) { possibleUsage.clear(); diff --git a/lib/checkleakautovar.h b/lib/checkleakautovar.h index 1e41ce31558..225763572ed 100644 --- a/lib/checkleakautovar.h +++ b/lib/checkleakautovar.h @@ -94,8 +94,6 @@ class CPPCHECKLIB VarInfo { /** set possible usage for all variables */ void possibleUsageAll(const std::pair& functionUsage); - - void print(); }; diff --git a/lib/checknullpointer.cpp b/lib/checknullpointer.cpp index 8c9cc1eb160..234d0c83e8f 100644 --- a/lib/checknullpointer.cpp +++ b/lib/checknullpointer.cpp @@ -24,6 +24,7 @@ #include "ctu.h" #include "errorlogger.h" #include "errortypes.h" +#include "findtoken.h" #include "library.h" #include "mathlib.h" #include "settings.h" @@ -279,47 +280,54 @@ static bool isNullablePointer(const Token* tok) return false; } -void CheckNullPointer::nullPointerByDeRefAndChec() +void CheckNullPointer::nullPointerByDeRefAndCheck() { const bool printInconclusive = (mSettings->certainty.isEnabled(Certainty::inconclusive)); - for (const Token *tok = mTokenizer->tokens(); tok; tok = tok->next()) { - if (isUnevaluated(tok)) { - tok = tok->linkAt(1); - continue; - } + const SymbolDatabase *symbolDatabase = mTokenizer->getSymbolDatabase(); + for (const Scope * scope : symbolDatabase->functionScopes) { + auto pred = [printInconclusive](const Token* tok) -> bool { + if (!tok) + return false; - if (Token::Match(tok, "%num%|%char%|%str%")) - continue; + if (Token::Match(tok, "%num%|%char%|%str%")) + return false; - if (!isNullablePointer(tok) || - (tok->str() == "." && isNullablePointer(tok->astOperand2()) && tok->astOperand2()->getValue(0))) // avoid duplicate warning - continue; + if (!isNullablePointer(tok) || + (tok->str() == "." && isNullablePointer(tok->astOperand2()) && tok->astOperand2()->getValue(0))) // avoid duplicate warning + return false; - // Can pointer be NULL? - const ValueFlow::Value *value = tok->getValue(0); - if (!value) - continue; + // Can pointer be NULL? + const ValueFlow::Value *value = tok->getValue(0); + if (!value) + return false; - if (!printInconclusive && value->isInconclusive()) - continue; + if (!printInconclusive && value->isInconclusive()) + return false; - // Pointer dereference. - bool unknown = false; - if (!isPointerDeRef(tok,unknown)) { - if (unknown) - nullPointerError(tok, tok->expressionString(), value, true); - continue; - } + return true; + }; + std::vector tokens = findTokensSkipDeadAndUnevaluatedCode(mSettings->library, scope->bodyStart, scope->bodyEnd, pred); + for (const Token *tok : tokens) { + const ValueFlow::Value *value = tok->getValue(0); + + // Pointer dereference. + bool unknown = false; + if (!isPointerDeRef(tok, unknown)) { + if (unknown) + nullPointerError(tok, tok->expressionString(), value, true); + continue; + } - nullPointerError(tok, tok->expressionString(), value, value->isInconclusive()); + nullPointerError(tok, tok->expressionString(), value, value->isInconclusive()); + } } } void CheckNullPointer::nullPointer() { logChecker("CheckNullPointer::nullPointer"); - nullPointerByDeRefAndChec(); + nullPointerByDeRefAndCheck(); } namespace { diff --git a/lib/checknullpointer.h b/lib/checknullpointer.h index f797a8f6d20..2b01c6b72a5 100644 --- a/lib/checknullpointer.h +++ b/lib/checknullpointer.h @@ -137,7 +137,7 @@ class CPPCHECKLIB CheckNullPointer : public Check { * @brief Does one part of the check for nullPointer(). * Dereferencing a pointer and then checking if it's NULL.. */ - void nullPointerByDeRefAndChec(); + void nullPointerByDeRefAndCheck(); /** undefined null pointer arithmetic */ void arithmetic(); diff --git a/lib/checkother.cpp b/lib/checkother.cpp index 6ab1894a84b..43dfde0c401 100644 --- a/lib/checkother.cpp +++ b/lib/checkother.cpp @@ -1163,6 +1163,9 @@ bool CheckOther::checkInnerScope(const Token *tok, const Variable* var, bool& us } } } + const auto yield = astContainerYield(tok); + if (yield == Library::Container::Yield::BUFFER || yield == Library::Container::Yield::BUFFER_NT) + return false; } } @@ -2603,7 +2606,7 @@ void CheckOther::checkDuplicateExpression() followVar, &errorPath) && isWithoutSideEffects(tok->astOperand2())) - duplicateExpressionError(tok->astOperand2(), tok->astOperand1()->astOperand2(), tok, errorPath); + duplicateExpressionError(tok->astOperand2(), tok->astOperand1()->astOperand2(), tok, std::move(errorPath)); else if (tok->astOperand2() && isConstExpression(tok->astOperand1(), mSettings->library)) { auto checkDuplicate = [&](const Token* exp1, const Token* exp2, const Token* ast1) { if (isSameExpression(true, exp1, exp2, *mSettings, true, true, &errorPath) && @@ -3692,7 +3695,7 @@ void CheckOther::checkShadowVariables() continue; if (functionScope && functionScope->type == Scope::ScopeType::eFunction && functionScope->function) { - const auto argList = functionScope->function->argumentList; + const auto & argList = functionScope->function->argumentList; auto it = std::find_if(argList.cbegin(), argList.cend(), [&](const Variable& arg) { return arg.nameToken() && var.name() == arg.name(); }); diff --git a/lib/checkunusedfunctions.cpp b/lib/checkunusedfunctions.cpp index f538b3a3544..3fc19d340d7 100644 --- a/lib/checkunusedfunctions.cpp +++ b/lib/checkunusedfunctions.cpp @@ -59,6 +59,11 @@ static std::string stripTemplateParameters(const std::string& funcName) { // FUNCTION USAGE - Check for unused functions etc //--------------------------------------------------------------------------- +static bool isRecursiveCall(const Token* ftok) +{ + return ftok->function() && ftok->function() == Scope::nestedInFunction(ftok->scope()); +} + void CheckUnusedFunctions::parseTokens(const Tokenizer &tokenizer, const Settings &settings) { const char * const FileName = tokenizer.list.getFiles().front().c_str(); @@ -245,6 +250,8 @@ void CheckUnusedFunctions::parseTokens(const Tokenizer &tokenizer, const Setting } if (funcname) { + if (isRecursiveCall(funcname)) + continue; const auto baseName = stripTemplateParameters(funcname->str()); FunctionUsage &func = mFunctions[baseName]; const std::string& called_from_file = tokenizer.list.getFiles()[funcname->fileIndex()]; diff --git a/lib/clangimport.cpp b/lib/clangimport.cpp index 430771cdea2..984b297a8b0 100644 --- a/lib/clangimport.cpp +++ b/lib/clangimport.cpp @@ -330,7 +330,7 @@ namespace clangimport { void dumpAst(int num = 0, int indent = 0) const; void createTokens1(TokenList &tokenList) { - //dumpAst(); + //dumpAst(); // TODO: reactivate or remove if (!tokenList.back()) { setLocations(tokenList, 0, 1, 1); // FIXME: treat as C++ if no filename (i.e. no lang) is specified for now @@ -486,6 +486,7 @@ std::string clangimport::AstNode::getTemplateParameters() const return templateParameters + ">"; } +// cppcheck-suppress unusedFunction // only used in comment void clangimport::AstNode::dumpAst(int num, int indent) const { (void)num; diff --git a/lib/cppcheck.cpp b/lib/cppcheck.cpp index 9cbe1245fd3..45fbb89678d 100644 --- a/lib/cppcheck.cpp +++ b/lib/cppcheck.cpp @@ -1463,7 +1463,7 @@ void CppCheck::executeAddons(const std::vector& files, const std::s } } -void CppCheck::executeAddonsWholeProgram(const std::list &files) +void CppCheck::executeAddonsWholeProgram(const std::list &files, const std::list& fileSettings) { if (mSettings.addons.empty()) return; @@ -1474,6 +1474,11 @@ void CppCheck::executeAddonsWholeProgram(const std::list &files ctuInfoFiles.push_back(getCtuInfoFileName(dumpFileName)); } + for (const auto &f: fileSettings) { + const std::string &dumpFileName = getDumpFileName(mSettings, f.filename()); + ctuInfoFiles.push_back(getCtuInfoFileName(dumpFileName)); + } + try { executeAddons(ctuInfoFiles, ""); } catch (const InternalError& e) { @@ -1629,7 +1634,7 @@ void CppCheck::reportErr(const ErrorMessage &msg) if (!remark.empty()) { ErrorMessage msg2(msg); - msg2.remark = remark; + msg2.remark = std::move(remark); mErrorLogger.reportErr(msg2); } else { mErrorLogger.reportErr(msg); @@ -1779,7 +1784,7 @@ bool CppCheck::analyseWholeProgram() unsigned int CppCheck::analyseWholeProgram(const std::string &buildDir, const std::list &files, const std::list& fileSettings) { - executeAddonsWholeProgram(files); // TODO: pass FileSettings + executeAddonsWholeProgram(files, fileSettings); if (buildDir.empty()) { removeCtuInfoFiles(files, fileSettings); return mExitCode; diff --git a/lib/cppcheck.h b/lib/cppcheck.h index 5d677a80c09..50281bee8e2 100644 --- a/lib/cppcheck.h +++ b/lib/cppcheck.h @@ -195,7 +195,7 @@ class CPPCHECKLIB CppCheck : ErrorLogger { /** * Execute addons */ - void executeAddonsWholeProgram(const std::list &files); + void executeAddonsWholeProgram(const std::list &files, const std::list& fileSettings); #ifdef HAVE_RULES /** diff --git a/lib/errorlogger.h b/lib/errorlogger.h index e936fae748f..6da1c4cade8 100644 --- a/lib/errorlogger.h +++ b/lib/errorlogger.h @@ -186,6 +186,7 @@ class CPPCHECKLIB ErrorMessage { } /** Verbose message (may be the same as the short message) */ + // cppcheck-suppress unusedFunction - used by GUI only const std::string &verboseMessage() const { return mVerboseMessage; } diff --git a/lib/findtoken.h b/lib/findtoken.h index 73b4f0894f1..afb38a682f7 100644 --- a/lib/findtoken.h +++ b/lib/findtoken.h @@ -84,7 +84,8 @@ bool findTokensSkipDeadCodeImpl(const Library& library, const Token* end, const Predicate& pred, Found found, - const Evaluate& evaluate) + const Evaluate& evaluate, + bool skipUnevaluated) { for (T* tok = start; precedes(tok, end); tok = tok->next()) { if (pred(tok)) { @@ -98,7 +99,7 @@ bool findTokensSkipDeadCodeImpl(const Library& library, auto result = evaluate(condTok); if (result.empty()) continue; - if (findTokensSkipDeadCodeImpl(library, tok->next(), tok->linkAt(1), pred, found, evaluate)) + if (findTokensSkipDeadCodeImpl(library, tok->next(), tok->linkAt(1), pred, found, evaluate, skipUnevaluated)) return true; T* thenStart = tok->linkAt(1)->next(); T* elseStart = nullptr; @@ -108,7 +109,7 @@ bool findTokensSkipDeadCodeImpl(const Library& library, int r = result.front(); if (r == 0) { if (elseStart) { - if (findTokensSkipDeadCodeImpl(library, elseStart, elseStart->link(), pred, found, evaluate)) + if (findTokensSkipDeadCodeImpl(library, elseStart, elseStart->link(), pred, found, evaluate, skipUnevaluated)) return true; if (isReturnScope(elseStart->link(), library)) return true; @@ -117,7 +118,7 @@ bool findTokensSkipDeadCodeImpl(const Library& library, tok = thenStart->link(); } } else { - if (findTokensSkipDeadCodeImpl(library, thenStart, thenStart->link(), pred, found, evaluate)) + if (findTokensSkipDeadCodeImpl(library, thenStart, thenStart->link(), pred, found, evaluate, skipUnevaluated)) return true; if (isReturnScope(thenStart->link(), library)) return true; @@ -137,7 +138,7 @@ bool findTokensSkipDeadCodeImpl(const Library& library, if (!cond) { next = colon; } else { - if (findTokensSkipDeadCodeImpl(library, tok->astParent()->next(), colon, pred, found, evaluate)) + if (findTokensSkipDeadCodeImpl(library, tok->astParent()->next(), colon, pred, found, evaluate, skipUnevaluated)) return true; next = nextAfterAstRightmostLeaf(colon); } @@ -164,6 +165,12 @@ bool findTokensSkipDeadCodeImpl(const Library& library, else tok = afterCapture; } + if (skipUnevaluated && isUnevaluated(tok)) { + T *next = tok->linkAt(1); + if (!next) + continue; + tok = next; + } } return false; } @@ -185,7 +192,8 @@ std::vector findTokensSkipDeadCode(const Library& library, result.push_back(tok); return false; }, - evaluate); + evaluate, + false); return result; } @@ -195,6 +203,35 @@ std::vector findTokensSkipDeadCode(const Library& library, T* start, const T return findTokensSkipDeadCode(library, start, end, pred, &evaluateKnownValues); } +template )> +std::vector findTokensSkipDeadAndUnevaluatedCode(const Library& library, + T* start, + const Token* end, + const Predicate& pred, + const Evaluate& evaluate) +{ + std::vector result; + (void)findTokensSkipDeadCodeImpl( + library, + start, + end, + pred, + [&](T* tok) { + result.push_back(tok); + return false; + }, + evaluate, + true); + return result; +} + +template )> +std::vector findTokensSkipDeadAndUnevaluatedCode(const Library& library, T* start, const Token* end, const Predicate& pred) +{ + return findTokensSkipDeadAndUnevaluatedCode(library, start, end, pred, &evaluateKnownValues); +} + + template )> T* findTokenSkipDeadCode(const Library& library, T* start, const Token* end, const Predicate& pred, const Evaluate& evaluate) { @@ -208,7 +245,8 @@ T* findTokenSkipDeadCode(const Library& library, T* start, const Token* end, con result = tok; return true; }, - evaluate); + evaluate, + false); return result; } diff --git a/lib/importproject.cpp b/lib/importproject.cpp index 1af0fe0cc70..336e25744c8 100644 --- a/lib/importproject.cpp +++ b/lib/importproject.cpp @@ -1324,6 +1324,7 @@ void ImportProject::selectOneVsConfig(Platform::Type platform) } } +// cppcheck-suppress unusedFunction - used by GUI only void ImportProject::selectVsConfigurations(Platform::Type platform, const std::vector &configurations) { for (std::list::iterator it = fileSettings.begin(); it != fileSettings.end();) { @@ -1348,6 +1349,7 @@ void ImportProject::selectVsConfigurations(Platform::Type platform, const std::v } } +// cppcheck-suppress unusedFunction - used by GUI only std::list ImportProject::getVSConfigs() { return std::list(mAllVSConfigs.cbegin(), mAllVSConfigs.cend()); diff --git a/lib/library.cpp b/lib/library.cpp index ae780f0ffe0..62e94876859 100644 --- a/lib/library.cpp +++ b/lib/library.cpp @@ -94,13 +94,7 @@ Library::Error Library::load(const char exename[], const char path[], bool debug tinyxml2::XMLDocument doc; if (debug) std::cout << "looking for library '" + std::string(path) + "'" << std::endl; - tinyxml2::XMLError error = doc.LoadFile(path); - // TODO: do not ignore read errors - if (error == tinyxml2::XML_ERROR_FILE_READ_ERROR && Path::getFilenameExtension(path).empty()) - { - // Reading file failed, try again... - error = tinyxml2::XML_ERROR_FILE_NOT_FOUND; - } + tinyxml2::XMLError error = xml_LoadFile(doc, path); if (error == tinyxml2::XML_ERROR_FILE_NOT_FOUND) { // failed to open file.. is there no extension? std::string fullfilename(path); @@ -108,7 +102,7 @@ Library::Error Library::load(const char exename[], const char path[], bool debug fullfilename += ".cfg"; if (debug) std::cout << "looking for library '" + std::string(fullfilename) + "'" << std::endl; - error = doc.LoadFile(fullfilename.c_str()); + error = xml_LoadFile(doc, fullfilename.c_str()); if (error != tinyxml2::XML_ERROR_FILE_NOT_FOUND) absolute_path = Path::getAbsoluteFilePath(fullfilename); } @@ -134,7 +128,7 @@ Library::Error Library::load(const char exename[], const char path[], bool debug const std::string filename(cfgfolder + sep + fullfilename); if (debug) std::cout << "looking for library '" + std::string(filename) + "'" << std::endl; - error = doc.LoadFile(filename.c_str()); + error = xml_LoadFile(doc, filename.c_str()); if (error != tinyxml2::XML_ERROR_FILE_NOT_FOUND) absolute_path = Path::getAbsoluteFilePath(filename); } diff --git a/lib/mathlib.cpp b/lib/mathlib.cpp index 242d6ef2cef..e2d618d1061 100644 --- a/lib/mathlib.cpp +++ b/lib/mathlib.cpp @@ -1274,44 +1274,6 @@ bool MathLib::isOctalDigit(char c) return (c >= '0' && c <= '7'); } -bool MathLib::isDigitSeparator(const std::string& iCode, std::string::size_type iPos) -{ - if (iPos == 0 || iPos >= iCode.size() || iCode[iPos] != '\'') - return false; - std::string::size_type i = iPos - 1; - while (std::isxdigit(iCode[i])) { - if (i == 0) - return true; // Only xdigits before ' - --i; - } - if (i == iPos - 1) // No xdigit before ' - return false; - - switch (iCode[i]) { - case ' ': - case '.': - case ',': - case 'x': - case '(': - case '{': - case '+': - case '-': - case '*': - case '%': - case '/': - case '&': - case '|': - case '^': - case '~': - case '=': - return true; - case '\'': - return isDigitSeparator(iCode, i); - default: - return false; - } -} - MathLib::value operator+(const MathLib::value &v1, const MathLib::value &v2) { return MathLib::value::calc('+',v1,v2); diff --git a/lib/mathlib.h b/lib/mathlib.h index 5a3ec0c5f69..9075cdcc811 100644 --- a/lib/mathlib.h +++ b/lib/mathlib.h @@ -126,13 +126,6 @@ class CPPCHECKLIB MathLib { static bool isOctalDigit(char c); static unsigned int encodeMultiChar(const std::string& str); - - /** - * \param[in] iCode Code being considered - * \param[in] iPos A posision within iCode - * \return Whether iCode[iPos] is a C++14 digit separator - */ - static bool isDigitSeparator(const std::string& iCode, std::string::size_type iPos); }; MathLib::value operator+(const MathLib::value &v1, const MathLib::value &v2); diff --git a/lib/preprocessor.cpp b/lib/preprocessor.cpp index 06d01cd1406..58fb06ff0bf 100644 --- a/lib/preprocessor.cpp +++ b/lib/preprocessor.cpp @@ -43,10 +43,22 @@ static bool sameline(const simplecpp::Token *tok1, const simplecpp::Token *tok2) return tok1 && tok2 && tok1->location.sameline(tok2->location); } -Directive::Directive(std::string _file, const int _linenr, const std::string &_str) : +Directive::Directive(const simplecpp::Location & _loc, std::string _str) : + file(_loc.file()), + linenr(_loc.line), + str(std::move(_str)) +{} + +Directive::Directive(std::string _file, const int _linenr, std::string _str) : file(std::move(_file)), linenr(_linenr), - str(trim(_str)) + str(std::move(_str)) +{} + +Directive::DirectiveToken::DirectiveToken(const simplecpp::Token & _tok) : + line(_tok.location.line), + column(_tok.location.col), + tokStr(_tok.str()) {} char Preprocessor::macroChar = char(1); @@ -163,7 +175,7 @@ static std::string getRelativeFilename(const simplecpp::Token* tok, const Settin } } } - return Path::simplifyPath(relativeFilename); + return Path::simplifyPath(std::move(relativeFilename)); } static void addInlineSuppressions(const simplecpp::TokenList &tokens, const Settings &settings, SuppressionList &suppressions, std::list &bad) @@ -328,7 +340,7 @@ std::list Preprocessor::createDirectives(const simplecpp::TokenList & continue; if (tok->next && tok->next->str() == "endfile") continue; - Directive directive(tok->location.file(), tok->location.line, emptyString); + Directive directive(tok->location, emptyString); for (const simplecpp::Token *tok2 = tok; tok2 && tok2->location.line == directive.linenr; tok2 = tok2->next) { if (tok2->comment) continue; @@ -338,6 +350,8 @@ std::list Preprocessor::createDirectives(const simplecpp::TokenList & directive.str += "include"; else directive.str += tok2->str(); + + directive.strTokens.emplace_back(*tok2); } directives.push_back(std::move(directive)); } diff --git a/lib/preprocessor.h b/lib/preprocessor.h index 97116e157be..e186ce03761 100644 --- a/lib/preprocessor.h +++ b/lib/preprocessor.h @@ -43,7 +43,7 @@ class SuppressionList; * Each preprocessor directive (\#include, \#define, \#undef, \#if, \#ifdef, \#else, \#endif) * will be recorded as an instance of this class. * - * file and linenr denote the location where where the directive is defined. + * file and linenr denote the location where the directive is defined. * */ @@ -57,8 +57,18 @@ struct CPPCHECKLIB Directive { /** the actual directive text */ std::string str; + struct DirectiveToken { + explicit DirectiveToken(const simplecpp::Token & _tok); + int line; + int column; + std::string tokStr; + }; + + std::vector strTokens; + /** record a directive (possibly filtering src) */ - Directive(std::string _file, const int _linenr, const std::string &_str); + Directive(const simplecpp::Location & _loc, std::string _str); + Directive(std::string _file, const int _linenr, std::string _str); }; class CPPCHECKLIB RemarkComment { diff --git a/lib/suppressions.cpp b/lib/suppressions.cpp index aaccaff3fae..71481f324a5 100644 --- a/lib/suppressions.cpp +++ b/lib/suppressions.cpp @@ -390,6 +390,7 @@ bool SuppressionList::Suppression::isMatch(const SuppressionList::ErrorMessage & return true; } +// cppcheck-suppress unusedFunction - used by GUI only std::string SuppressionList::Suppression::getText() const { std::string ret; diff --git a/lib/symboldatabase.cpp b/lib/symboldatabase.cpp index 1ee239a9e74..31e54535512 100644 --- a/lib/symboldatabase.cpp +++ b/lib/symboldatabase.cpp @@ -1152,7 +1152,7 @@ void SymbolDatabase::createSymbolDatabaseSetFunctionPointers(bool firstPass) inTemplateArg = tok->link(); if (inTemplateArg == tok) inTemplateArg = nullptr; - if (tok->isName() && !tok->function() && tok->varId() == 0 && ((tok->astParent() && tok->astParent()->isComparisonOp()) || Token::Match(tok, "%name% [{(,)>;]]")) && !isReservedName(tok)) { + if (tok->isName() && !tok->function() && tok->varId() == 0 && ((tok->astParent() && tok->astParent()->isComparisonOp()) || Token::Match(tok, "%name% [{(,)>;:]]")) && !isReservedName(tok)) { if (tok->strAt(1) == ">" && !tok->linkAt(1)) continue; @@ -1565,82 +1565,84 @@ namespace { }; using ExprIdMap = std::map; void setParentExprId(Token* tok, ExprIdMap& exprIdMap, nonneg int &id) { - if (!tok->astParent() || tok->astParent()->isControlFlowKeyword()) - return; - const Token* op1 = tok->astParent()->astOperand1(); - if (op1 && op1->exprId() == 0 && !Token::Match(op1, "[{[]")) - return; - const Token* op2 = tok->astParent()->astOperand2(); - if (op2 && op2->exprId() == 0 && - !((tok->astParent()->astParent() && tok->astParent()->isAssignmentOp() && tok->astParent()->astParent()->isAssignmentOp()) || - isLambdaCaptureList(op2) || - (op2->str() == "(" && isLambdaCaptureList(op2->astOperand1())) || - Token::simpleMatch(op2, "{ }"))) - return; + for (;;) { + if (!tok->astParent() || tok->astParent()->isControlFlowKeyword()) + break; + const Token* op1 = tok->astParent()->astOperand1(); + if (op1 && op1->exprId() == 0 && !Token::Match(op1, "[{[]")) + break; + const Token* op2 = tok->astParent()->astOperand2(); + if (op2 && op2->exprId() == 0 && + !((tok->astParent()->astParent() && tok->astParent()->isAssignmentOp() && tok->astParent()->astParent()->isAssignmentOp()) || + isLambdaCaptureList(op2) || + (op2->str() == "(" && isLambdaCaptureList(op2->astOperand1())) || + Token::simpleMatch(op2, "{ }"))) + break; - if (tok->astParent()->isExpandedMacro() || Token::Match(tok->astParent(), "++|--")) { - tok->astParent()->exprId(id); - ++id; - setParentExprId(tok->astParent(), exprIdMap, id); - return; - } + if (tok->astParent()->isExpandedMacro() || Token::Match(tok->astParent(), "++|--")) { + tok->astParent()->exprId(id); + ++id; + tok = tok->astParent(); + continue; + } - ExprIdKey key; - key.parentOp = tok->astParent()->str(); - key.operand1 = op1 ? op1->exprId() : 0; - key.operand2 = op2 ? op2->exprId() : 0; + ExprIdKey key; + key.parentOp = tok->astParent()->str(); + key.operand1 = op1 ? op1->exprId() : 0; + key.operand2 = op2 ? op2->exprId() : 0; - if (tok->astParent()->isCast() && tok->astParent()->str() == "(") { - const Token* typeStartToken; - const Token* typeEndToken; - if (tok->astParent()->astOperand2()) { - typeStartToken = tok->astParent()->astOperand1(); - typeEndToken = tok; - } else { - typeStartToken = tok->astParent()->next(); - typeEndToken = tok->astParent()->link(); - } - std::string type; - for (const Token* t = typeStartToken; t != typeEndToken; t = t->next()) { - type += " " + t->str(); + if (tok->astParent()->isCast() && tok->astParent()->str() == "(") { + const Token* typeStartToken; + const Token* typeEndToken; + if (tok->astParent()->astOperand2()) { + typeStartToken = tok->astParent()->astOperand1(); + typeEndToken = tok; + } else { + typeStartToken = tok->astParent()->next(); + typeEndToken = tok->astParent()->link(); + } + std::string type; + for (const Token* t = typeStartToken; t != typeEndToken; t = t->next()) { + type += " " + t->str(); + } + key.parentOp += type; } - key.parentOp += type; - } - for (const auto& ref: followAllReferences(op1)) { - if (ref.token->exprId() != 0) { // cppcheck-suppress useStlAlgorithm - key.operand1 = ref.token->exprId(); - break; + for (const auto& ref: followAllReferences(op1)) { + if (ref.token->exprId() != 0) { // cppcheck-suppress useStlAlgorithm + key.operand1 = ref.token->exprId(); + break; + } } - } - for (const auto& ref: followAllReferences(op2)) { - if (ref.token->exprId() != 0) { // cppcheck-suppress useStlAlgorithm - key.operand2 = ref.token->exprId(); - break; + for (const auto& ref: followAllReferences(op2)) { + if (ref.token->exprId() != 0) { // cppcheck-suppress useStlAlgorithm + key.operand2 = ref.token->exprId(); + break; + } } - } - if (key.operand1 > key.operand2 && key.operand2 && - Token::Match(tok->astParent(), "%or%|%oror%|+|*|&|&&|^|==|!=")) { - // In C++ the order of operands of + might matter - if (!tok->isCpp() || - key.parentOp != "+" || - !tok->astParent()->valueType() || - tok->astParent()->valueType()->isIntegral() || - tok->astParent()->valueType()->isFloat() || - tok->astParent()->valueType()->pointer > 0) - std::swap(key.operand1, key.operand2); - } + if (key.operand1 > key.operand2 && key.operand2 && + Token::Match(tok->astParent(), "%or%|%oror%|+|*|&|&&|^|==|!=")) { + // In C++ the order of operands of + might matter + if (!tok->isCpp() || + key.parentOp != "+" || + !tok->astParent()->valueType() || + tok->astParent()->valueType()->isIntegral() || + tok->astParent()->valueType()->isFloat() || + tok->astParent()->valueType()->pointer > 0) + std::swap(key.operand1, key.operand2); + } - const auto it = exprIdMap.find(key); - if (it == exprIdMap.end()) { - exprIdMap[key] = id; - tok->astParent()->exprId(id); - ++id; - } else { - tok->astParent()->exprId(it->second); + const auto it = exprIdMap.find(key); + if (it == exprIdMap.end()) { + exprIdMap[key] = id; + tok->astParent()->exprId(id); + ++id; + } else { + tok->astParent()->exprId(it->second); + } + tok = tok->astParent(); } - setParentExprId(tok->astParent(), exprIdMap, id); } } diff --git a/lib/token.cpp b/lib/token.cpp index e7e925f421b..aee3150bd19 100644 --- a/lib/token.cpp +++ b/lib/token.cpp @@ -1702,6 +1702,7 @@ std::string Token::astStringVerbose() const return ret; } +// cppcheck-suppress unusedFunction // used in test std::string Token::astStringZ3() const { if (!astOperand1()) diff --git a/lib/tokenize.cpp b/lib/tokenize.cpp index 195924e7191..a8b41b5b176 100644 --- a/lib/tokenize.cpp +++ b/lib/tokenize.cpp @@ -860,6 +860,10 @@ namespace { Token::createMutualLinks(tok3->next(), after->previous()); } } + if (!after) { + mReplaceFailed = true; + return; + } bool useAfterVarRange = true; if (Token::simpleMatch(mRangeAfterVar.first, "[")) { @@ -906,6 +910,9 @@ namespace { Token* const tok4 = useAfterVarRange ? insertTokens(after->previous(), mRangeAfterVar)->next() : tok3->next(); + if (tok->next() == tok4) + throw InternalError(tok, "Failed to simplify typedef. Is the code valid?"); + tok->deleteThis(); // Unsplit variable declarations @@ -1124,7 +1131,9 @@ void Tokenizer::simplifyTypedef() { // remove typedefs for (auto &t: typedefs) { - if (!t.second.replaceFailed()) { + if (t.second.replaceFailed()) { + syntaxError(t.second.getTypedefToken()); + } else { const Token* const typedefToken = t.second.getTypedefToken(); TypedefInfo typedefInfo; typedefInfo.name = t.second.name(); @@ -4838,7 +4847,7 @@ void Tokenizer::setVarIdPass1() } // function declaration inside executable scope? Function declaration is of form: type name "(" args ")" - if (scopeStack.top().isExecutable && Token::Match(tok, "%name% [,)[]")) { + if (scopeStack.top().isExecutable && !scopeStack.top().isStructInit && Token::Match(tok, "%name% [,)[]")) { bool par = false; const Token* start; Token* end; @@ -5107,6 +5116,8 @@ void Tokenizer::setVarIdPass2() classnameTokens.push_back(tokStart->next()); tokStart = tokStart->tokAt(2); } + if (!tokStart) + syntaxError(tok); } std::string classname; @@ -5957,7 +5968,19 @@ void Tokenizer::dump(std::ostream &out) const // could result in invalid XML, so run it through toxml(). outs += "str=\""; outs += ErrorLogger::toxml(dir.str); - outs +="\"/>"; + outs +="\">"; + outs += '\n'; + for (const auto & strToken : dir.strTokens) { + outs += " "; + outs += '\n'; + } + outs += " "; outs += '\n'; } outs += " "; @@ -8675,10 +8698,16 @@ void Tokenizer::findGarbageCode() const } if (Token::Match(tok, "%num%|%bool%|%char%|%str% %num%|%bool%|%char%|%str%") && !Token::Match(tok, "%str% %str%")) syntaxError(tok); + if (Token::Match(tok, "%num%|%bool%|%char%|%str% {") && + !(tok->tokType() == Token::Type::eString && Token::simpleMatch(tok->tokAt(-1), "extern")) && + !(tok->tokType() == Token::Type::eBoolean && cpp && Token::simpleMatch(tok->tokAt(-1), "requires"))) + syntaxError(tok); if (Token::Match(tok, "%assign% typename|class %assign%")) syntaxError(tok); if (Token::Match(tok, "%assign% [;)}]") && (!cpp || !Token::simpleMatch(tok->previous(), "operator"))) syntaxError(tok); + if (Token::Match(tok, "; %assign%")) + syntaxError(tok); if (Token::Match(tok, "%cop%|=|,|[ %or%|%oror%|/|%")) syntaxError(tok); if (Token::Match(tok, "[;([{] %comp%|%oror%|%or%|%|/")) diff --git a/lib/valueflow.cpp b/lib/valueflow.cpp index cdb57afb56c..fe6b4d045d4 100644 --- a/lib/valueflow.cpp +++ b/lib/valueflow.cpp @@ -8020,7 +8020,7 @@ static void valueFlowContainerSize(const TokenList& tokenlist, ValueFlow::Value value(Token::getStrLength(containerTok->tokAt(2))); value.valueType = ValueFlow::Value::ValueType::CONTAINER_SIZE; value.setKnown(); - valueFlowForward(containerTok->next(), containerTok, value, tokenlist, errorLogger, settings); + valueFlowForward(containerTok->next(), containerTok, std::move(value), tokenlist, errorLogger, settings); } } else if (Token::Match(tok->previous(), ">|return (|{") && astIsContainer(tok) && getLibraryContainer(tok)->size_templateArgNo < 0) { std::vector values; @@ -8084,7 +8084,7 @@ static void valueFlowContainerSize(const TokenList& tokenlist, Token* next = nextAfterAstRightmostLeaf(tok); if (!next) next = tok->next(); - valueFlowForward(next, containerTok, value, tokenlist, errorLogger, settings); + valueFlowForward(next, containerTok, std::move(value), tokenlist, errorLogger, settings); } } } diff --git a/lib/vf_settokenvalue.cpp b/lib/vf_settokenvalue.cpp index 5d1137bd2dd..b869c5427fa 100644 --- a/lib/vf_settokenvalue.cpp +++ b/lib/vf_settokenvalue.cpp @@ -445,7 +445,7 @@ namespace ValueFlow else if (astIsPointer(tok) && Token::Match(parent, "+|-") && (parent->astOperand2() == nullptr || !astIsPointer(parent->astOperand2())) && value.isIntValue() && value.isImpossible() && value.intvalue == 0) { - setTokenValue(parent, value, settings); + setTokenValue(parent, std::move(value), settings); } // Calculations.. diff --git a/lib/xml.h b/lib/xml.h index c8c258d973a..8c720466201 100644 --- a/lib/xml.h +++ b/lib/xml.h @@ -20,6 +20,7 @@ #define xmlH #include "config.h" +#include "path.h" SUPPRESS_WARNING_CLANG_PUSH("-Wzero-as-null-pointer-constant") SUPPRESS_WARNING_CLANG_PUSH("-Wsuggest-destructor-override") @@ -31,4 +32,12 @@ SUPPRESS_WARNING_CLANG_POP SUPPRESS_WARNING_CLANG_POP SUPPRESS_WARNING_CLANG_POP +inline static tinyxml2::XMLError xml_LoadFile(tinyxml2::XMLDocument& doc, const char* filename) +{ + // tinyxml2 will fail with a misleading XML_ERROR_FILE_READ_ERROR when you try to load a directory as a XML file + if (Path::isDirectory(filename)) + return tinyxml2::XMLError::XML_ERROR_FILE_NOT_FOUND; + return doc.LoadFile(filename); +} + #endif // xmlH diff --git a/oss-fuzz/Makefile b/oss-fuzz/Makefile index 9f3250394ba..6262eca078a 100644 --- a/oss-fuzz/Makefile +++ b/oss-fuzz/Makefile @@ -179,10 +179,10 @@ $(libcppdir)/checkbool.o: ../lib/checkbool.cpp ../lib/addoninfo.h ../lib/astutil $(libcppdir)/checkboost.o: ../lib/checkboost.cpp ../lib/check.h ../lib/checkboost.h ../lib/config.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.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 $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkboost.cpp -$(libcppdir)/checkbufferoverrun.o: ../lib/checkbufferoverrun.cpp ../externals/tinyxml2/tinyxml2.h ../lib/addoninfo.h ../lib/astutils.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/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/vfvalue.h ../lib/xml.h +$(libcppdir)/checkbufferoverrun.o: ../lib/checkbufferoverrun.cpp ../externals/tinyxml2/tinyxml2.h ../lib/addoninfo.h ../lib/astutils.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/path.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/vfvalue.h ../lib/xml.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkbufferoverrun.cpp -$(libcppdir)/checkclass.o: ../lib/checkclass.cpp ../externals/tinyxml2/tinyxml2.h ../lib/addoninfo.h ../lib/astutils.h ../lib/check.h ../lib/checkclass.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/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/vfvalue.h ../lib/xml.h +$(libcppdir)/checkclass.o: ../lib/checkclass.cpp ../externals/tinyxml2/tinyxml2.h ../lib/addoninfo.h ../lib/astutils.h ../lib/check.h ../lib/checkclass.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/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/vfvalue.h ../lib/xml.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkclass.cpp $(libcppdir)/checkcondition.o: ../lib/checkcondition.cpp ../lib/addoninfo.h ../lib/astutils.h ../lib/check.h ../lib/checkcondition.h ../lib/checkother.h ../lib/config.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/suppressions.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/vfvalue.h @@ -212,7 +212,7 @@ $(libcppdir)/checkleakautovar.o: ../lib/checkleakautovar.cpp ../lib/addoninfo.h $(libcppdir)/checkmemoryleak.o: ../lib/checkmemoryleak.cpp ../lib/addoninfo.h ../lib/astutils.h ../lib/check.h ../lib/checkmemoryleak.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/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/suppressions.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/vfvalue.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkmemoryleak.cpp -$(libcppdir)/checknullpointer.o: ../lib/checknullpointer.cpp ../lib/addoninfo.h ../lib/astutils.h ../lib/check.h ../lib/checknullpointer.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/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/vfvalue.h +$(libcppdir)/checknullpointer.o: ../lib/checknullpointer.cpp ../lib/addoninfo.h ../lib/astutils.h ../lib/check.h ../lib/checknullpointer.h ../lib/color.h ../lib/config.h ../lib/ctu.h ../lib/errorlogger.h ../lib/errortypes.h ../lib/findtoken.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/vfvalue.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checknullpointer.cpp $(libcppdir)/checkother.o: ../lib/checkother.cpp ../lib/addoninfo.h ../lib/astutils.h ../lib/check.h ../lib/checkother.h ../lib/config.h ../lib/errortypes.h ../lib/fwdanalysis.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/vfvalue.h @@ -236,7 +236,7 @@ $(libcppdir)/checktype.o: ../lib/checktype.cpp ../lib/addoninfo.h ../lib/check.h $(libcppdir)/checkuninitvar.o: ../lib/checkuninitvar.cpp ../lib/addoninfo.h ../lib/astutils.h ../lib/check.h ../lib/checknullpointer.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/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/suppressions.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/vfvalue.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkuninitvar.cpp -$(libcppdir)/checkunusedfunctions.o: ../lib/checkunusedfunctions.cpp ../externals/tinyxml2/tinyxml2.h ../lib/addoninfo.h ../lib/astutils.h ../lib/checkunusedfunctions.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/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/suppressions.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/vfvalue.h ../lib/xml.h +$(libcppdir)/checkunusedfunctions.o: ../lib/checkunusedfunctions.cpp ../externals/tinyxml2/tinyxml2.h ../lib/addoninfo.h ../lib/astutils.h ../lib/checkunusedfunctions.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/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/suppressions.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/vfvalue.h ../lib/xml.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkunusedfunctions.cpp $(libcppdir)/checkunusedvar.o: ../lib/checkunusedvar.cpp ../lib/addoninfo.h ../lib/astutils.h ../lib/check.h ../lib/checkunusedvar.h ../lib/config.h ../lib/errortypes.h ../lib/fwdanalysis.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/vfvalue.h @@ -254,7 +254,7 @@ $(libcppdir)/color.o: ../lib/color.cpp ../lib/color.h ../lib/config.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/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 $(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/color.h ../lib/config.h ../lib/ctu.h ../lib/errorlogger.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/suppressions.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/vfvalue.h ../lib/xml.h +$(libcppdir)/ctu.o: ../lib/ctu.cpp ../externals/tinyxml2/tinyxml2.h ../lib/addoninfo.h ../lib/astutils.h ../lib/check.h ../lib/color.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/suppressions.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 $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/ctu.cpp $(libcppdir)/errorlogger.o: ../lib/errorlogger.cpp ../externals/tinyxml2/tinyxml2.h ../lib/addoninfo.h ../lib/analyzerinfo.h ../lib/check.h ../lib/color.h ../lib/config.h ../lib/cppcheck.h ../lib/errorlogger.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/path.h ../lib/platform.h ../lib/settings.h ../lib/standards.h ../lib/suppressions.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenlist.h ../lib/utils.h ../lib/vfvalue.h ../lib/xml.h diff --git a/test/cfg/boost.cpp b/test/cfg/boost.cpp index eb4e742227a..52d2e1be80b 100644 --- a/test/cfg/boost.cpp +++ b/test/cfg/boost.cpp @@ -17,6 +17,7 @@ #include #include #include +#include BOOST_FORCEINLINE void boost_forceinline_test() {} @@ -104,4 +105,25 @@ void lock_guard_finiteLifetime(boost::mutex& m) { // cppcheck-suppress unusedScopedObject boost::lock_guard{ m }; -} \ No newline at end of file +} + +BOOST_AUTO_TEST_SUITE(my_auto_test_suite) + +BOOST_AUTO_TEST_CASE(test_message_macros) +{ + bool my_bool = false; + BOOST_WARN_MESSAGE(my_bool, "warn"); + BOOST_CHECK_MESSAGE(my_bool, "check"); + BOOST_REQUIRE_MESSAGE(my_bool, "require"); + + BOOST_WARN_MESSAGE(my_bool, "my_bool was: " << my_bool); +} + +using test_types_w_tuples = std::tuple; +BOOST_AUTO_TEST_CASE_TEMPLATE(my_tuple_test, T, test_types_w_tuples) +{ + // cppcheck-suppress valueFlowBailoutIncompleteVar + BOOST_TEST(sizeof(T) == 4U); +} + +BOOST_AUTO_TEST_SUITE_END() \ No newline at end of file diff --git a/test/cfg/std.cpp b/test/cfg/std.cpp index 627d2d68bbc..18e14e7d92e 100644 --- a/test/cfg/std.cpp +++ b/test/cfg/std.cpp @@ -2685,6 +2685,14 @@ void uninitvar_fpclassify(void) (void)std::fpclassify(ld); } +void bool_isfinite(float f) +{ + // cppcheck-suppress compareBoolExpressionWithInt + // cppcheck-suppress compareValueOutOfTypeRangeError + // cppcheck-suppress knownConditionTrueFalse + if (std::isfinite(f)==123) {} +} + void uninitvar_isfinite(void) { float f; @@ -2700,6 +2708,14 @@ void uninitvar_isfinite(void) (void)std::isfinite(ld); } +void bool_isgreater(float f1, float f2) +{ + // cppcheck-suppress compareBoolExpressionWithInt + // cppcheck-suppress compareValueOutOfTypeRangeError + // cppcheck-suppress knownConditionTrueFalse + if (std::isgreater(f1,f2)==123) {} +} + void uninitvar_isgreater(void) { float f1,f2; @@ -2715,6 +2731,14 @@ void uninitvar_isgreater(void) (void)std::isgreater(ld1,ld2); } +void bool_isgreaterequal(float f1, float f2) +{ + // cppcheck-suppress compareBoolExpressionWithInt + // cppcheck-suppress compareValueOutOfTypeRangeError + // cppcheck-suppress knownConditionTrueFalse + if (std::isgreaterequal(f1, f2)==123) {} +} + void uninitvar_isgreaterequal(void) { float f1,f2; @@ -2730,6 +2754,14 @@ void uninitvar_isgreaterequal(void) (void)std::isgreaterequal(ld1,ld2); } +void bool_isinf(float f) +{ + // cppcheck-suppress compareBoolExpressionWithInt + // cppcheck-suppress compareValueOutOfTypeRangeError + // cppcheck-suppress knownConditionTrueFalse + if (std::isinf(f)==123) {} +} + void uninitvar_isinf(void) { double d; @@ -5085,4 +5117,14 @@ void constParameterReference_assign(std::vector& v, int& r) { void constParameterReference_insert(std::list& l, int& r) { l.insert(l.end(), r); l.insert(l.end(), 5, r); -} \ No newline at end of file +} + +const char* variableScope_cstr_dummy(const char* q); // #12812 +std::size_t variableScope_cstr(const char* p) { + std::string s; + if (!p) { + s = "abc"; + p = variableScope_cstr_dummy(s.c_str()); + } + return std::strlen(p); +} diff --git a/test/cfg/windows.cpp b/test/cfg/windows.cpp index 5f2e6555ead..1e25ccfd5e5 100644 --- a/test/cfg/windows.cpp +++ b/test/cfg/windows.cpp @@ -22,6 +22,26 @@ #include #include +void invalidHandle_CreateFile(LPCWSTR lpFileName) +{ + HANDLE file = CreateFile(lpFileName, GENERIC_READ, 0, nullptr, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, nullptr); + + // INVALID_HANDLE_VALUE is not the same as 0 + if (file != INVALID_HANDLE_VALUE && file) {} + + // cppcheck-suppress resourceLeak +} + +void invalid_socket() +{ + SOCKET sock = socket(AF_INET, SOCK_RAW, IPPROTO_TCP); + + // INVALID_SOCKET is not the same as 0 + if (sock != INVALID_SOCKET && sock) {} + + // cppcheck-suppress resourceLeak +} + void resourceLeak_OpenThread(const DWORD dwDesiredAccess, const BOOL bInheritHandle, const DWORD dwThreadId) { HANDLE proc = OpenThread(dwDesiredAccess, bInheritHandle, dwThreadId); @@ -1161,3 +1181,17 @@ void invalidPrintfArgType_StructMember(double d) { // #9672 BOOL MyEnableWindow(HWND hWnd, BOOL bEnable) { return EnableWindow(hWnd, bEnable); } + +int SEH_filter(unsigned int code, struct _EXCEPTION_POINTERS* ep); +int SEH_throwing_func(); + +void SEH_knownConditionTrueFalse() { // #8434 + int r = 0; + __try { + r = SEH_throwing_func(); + } + __except (SEH_filter(GetExceptionCode(), GetExceptionInformation())) { + r = 1; + } + if (r == 0) {} +} diff --git a/test/cli/fuzz-crash/crash-44b5d1f53328660cbcb6e90793eae2ff8ffc4893 b/test/cli/fuzz-crash/crash-44b5d1f53328660cbcb6e90793eae2ff8ffc4893 new file mode 100644 index 00000000000..c45497a8601 --- /dev/null +++ b/test/cli/fuzz-crash/crash-44b5d1f53328660cbcb6e90793eae2ff8ffc4893 @@ -0,0 +1 @@ +typedef q r[];r A \ No newline at end of file diff --git a/test/cli/fuzz-crash/crash-772965250be2580c7c52f024c15fd5c8a9bb13c7 b/test/cli/fuzz-crash/crash-772965250be2580c7c52f024c15fd5c8a9bb13c7 new file mode 100644 index 00000000000..a010a5fcfcc --- /dev/null +++ b/test/cli/fuzz-crash/crash-772965250be2580c7c52f024c15fd5c8a9bb13c7 @@ -0,0 +1 @@ +enum{C=e;=U}; \ No newline at end of file diff --git a/test/cli/fuzz-crash/crash-c021b973c9f8692ff1ea73710209a4129dc7a834 b/test/cli/fuzz-crash/crash-c021b973c9f8692ff1ea73710209a4129dc7a834 new file mode 100644 index 00000000000..411936bf04e --- /dev/null +++ b/test/cli/fuzz-crash/crash-c021b973c9f8692ff1ea73710209a4129dc7a834 @@ -0,0 +1 @@ +typedef const C;C(public C + + + + + + + + + + +""".format(in_file_a, in_file_b, in_file_c, in_file_d, in_file_e, in_file_f, tmpdir)) + + args = ['--project={}'.format(project_file)] + args.append('-j1') # TODO: remove when fixed + + exitcode, stdout, stderr = cppcheck(args, cwd=tmpdir) + assert exitcode == 0 + lines = stdout.splitlines() + # TODO: only a single file should be checked + if sys.platform == 'win32': + assert lines == [ + 'Checking {} ...'.format(test_file_a), + '1/3 files checked 0% done', + 'Checking {} ...'.format(test_file_a), + '2/3 files checked 0% done', + 'Checking {} ...'.format(test_file_a), + '3/3 files checked 0% done' + ] + else: + assert lines == [ + 'Checking {} ...'.format(test_file_a), + '1/2 files checked 0% done', + 'Checking {} ...'.format(test_file_a), + '2/2 files checked 0% done' + ] + assert stderr == '' + + +@pytest.mark.skipif(sys.platform != 'win32', reason="requires Windows") +def test_project_file_duplicate_4(tmpdir): + test_file_a = os.path.join(tmpdir, 'a.c') + with open(test_file_a, 'wt'): + pass + + # multiple ways to specify the same file + in_file_a = 'a.c' + in_file_b = os.path.join('.', 'a.c') + in_file_c = os.path.join('dummy', '..', 'a.c') + in_file_d = os.path.join(tmpdir, 'a.c') + in_file_e = os.path.join(tmpdir, '.', 'a.c') + in_file_f = os.path.join(tmpdir, 'dummy', '..', 'a.c') + + args1 = [in_file_a, in_file_b, in_file_c, in_file_d, in_file_e, in_file_f, str(tmpdir)] + args2 = [] + for a in args1: + args2.append(a.replace('\\', '/')) + + project_file = os.path.join(tmpdir, 'test.cppcheck') + with open(project_file, 'wt') as f: + f.write( + """ + + + + + + + + + + + + + + + + + +""".format(in_file_a, in_file_b, in_file_c, in_file_d, in_file_e, in_file_f, tmpdir, + args2[0], args2[1], args2[2], args2[3], args2[4], args2[5], args2[6])) + + args = ['--project={}'.format(project_file)] + args.append('-j1') # TODO: remove when fixed + + exitcode, stdout, stderr = cppcheck(args, cwd=tmpdir) + assert exitcode == 0 + lines = stdout.splitlines() + # TODO: only a single file should be checked + assert lines == [ + 'Checking {} ...'.format(test_file_a), + '1/3 files checked 0% done', + 'Checking {} ...'.format(test_file_a), + '2/3 files checked 0% done', + 'Checking {} ...'.format(test_file_a), + '3/3 files checked 0% done' + ] + assert stderr == '' + def test_project_file_ignore(tmpdir): test_file = os.path.join(tmpdir, 'test.cpp') with open(test_file, 'wt') as f: diff --git a/test/cli/other_test.py b/test/cli/other_test.py index 95199c15fc5..a5ed79effed 100644 --- a/test/cli/other_test.py +++ b/test/cli/other_test.py @@ -1138,6 +1138,97 @@ def test_file_duplicate_2(tmpdir): assert stderr == '' +def test_file_duplicate_3(tmpdir): + test_file_a = os.path.join(tmpdir, 'a.c') + with open(test_file_a, 'wt'): + pass + + # multiple ways to specify the same file + in_file_a = 'a.c' + in_file_b = os.path.join('.', 'a.c') + in_file_c = os.path.join('dummy', '..', 'a.c') + in_file_d = os.path.join(tmpdir, 'a.c') + in_file_e = os.path.join(tmpdir, '.', 'a.c') + in_file_f = os.path.join(tmpdir, 'dummy', '..', 'a.c') + + args = [in_file_a, in_file_b, in_file_c, in_file_d, in_file_e, in_file_f, str(tmpdir)] + args.append('-j1') # TODO: remove when fixed + + exitcode, stdout, stderr = cppcheck(args, cwd=tmpdir) + assert exitcode == 0 + lines = stdout.splitlines() + # TODO: only a single file should be checked + if sys.platform == 'win32': + assert lines == [ + 'Checking {} ...'.format('a.c'), + '1/6 files checked 0% done', + 'Checking {} ...'.format('a.c'), + '2/6 files checked 0% done', + 'Checking {} ...'.format('a.c'), + '3/6 files checked 0% done', + 'Checking {} ...'.format(test_file_a), + '4/6 files checked 0% done', + 'Checking {} ...'.format(test_file_a), + '5/6 files checked 0% done', + 'Checking {} ...'.format(test_file_a), + '6/6 files checked 0% done' + ] + else: + assert lines == [ + 'Checking {} ...'.format('a.c'), + '1/4 files checked 0% done', + 'Checking {} ...'.format('a.c'), + '2/4 files checked 0% done', + 'Checking {} ...'.format(test_file_a), + '3/4 files checked 0% done', + 'Checking {} ...'.format(test_file_a), + '4/4 files checked 0% done' + ] + assert stderr == '' + + +@pytest.mark.skipif(sys.platform != 'win32', reason="requires Windows") +def test_file_duplicate_4(tmpdir): + test_file_a = os.path.join(tmpdir, 'a.c') + with open(test_file_a, 'wt'): + pass + + # multiple ways to specify the same file + in_file_a = 'a.c' + in_file_b = os.path.join('.', 'a.c') + in_file_c = os.path.join('dummy', '..', 'a.c') + in_file_d = os.path.join(tmpdir, 'a.c') + in_file_e = os.path.join(tmpdir, '.', 'a.c') + in_file_f = os.path.join(tmpdir, 'dummy', '..', 'a.c') + + args1 = [in_file_a, in_file_b, in_file_c, in_file_d, in_file_e, in_file_f, str(tmpdir)] + args2 = [] + for a in args1: + args2.append(a.replace('\\', '/')) + args = args1 + args2 + args.append('-j1') # TODO: remove when fixed + + exitcode, stdout, stderr = cppcheck(args, cwd=tmpdir) + assert exitcode == 0 + lines = stdout.splitlines() + # TODO: only a single file should be checked + assert lines == [ + 'Checking {} ...'.format('a.c'), + '1/6 files checked 0% done', + 'Checking {} ...'.format('a.c'), + '2/6 files checked 0% done', + 'Checking {} ...'.format('a.c'), + '3/6 files checked 0% done', + 'Checking {} ...'.format(test_file_a), + '4/6 files checked 0% done', + 'Checking {} ...'.format(test_file_a), + '5/6 files checked 0% done', + 'Checking {} ...'.format(test_file_a), + '6/6 files checked 0% done' + ] + assert stderr == '' + + def test_file_ignore(tmpdir): test_file = os.path.join(tmpdir, 'test.cpp') with open(test_file, 'wt'): @@ -1614,3 +1705,30 @@ def test_lib_lookup_absolute_notfound(tmpdir): "library not found: '{}'".format(cfg_file), "cppcheck: Failed to load library configuration file '{}'. File not found".format(cfg_file) ] + + +def test_lib_lookup_nofile(tmpdir): + test_file = os.path.join(tmpdir, 'test.c') + with open(test_file, 'wt'): + pass + + # make sure we do not produce an error when the attempted lookup path is a directory and not a file + gtk_dir = os.path.join(tmpdir, 'gtk') + os.mkdir(gtk_dir) + gtk_cfg_dir = os.path.join(tmpdir, 'gtk.cfg') + os.mkdir(gtk_cfg_dir) + + exitcode, stdout, _, exe = cppcheck_ex(['--library=gtk', '--debug-lookup', test_file], cwd=tmpdir) + exepath = os.path.dirname(exe) + if sys.platform == 'win32': + exepath = exepath.replace('\\', '/') + assert exitcode == 0, stdout + lines = __remove_std_lookup_log(stdout.splitlines(), exepath) + assert lines == [ + "looking for library 'gtk'", + "looking for library 'gtk.cfg'", + "looking for library '{}/gtk.cfg'".format(exepath), + "looking for library '{}/../cfg/gtk.cfg'".format(exepath), + "looking for library '{}/cfg/gtk.cfg'".format(exepath), + 'Checking {} ...'.format(test_file) + ] diff --git a/test/cli/performance_test.py b/test/cli/performance_test.py index 4dc23f9efe5..f79203377c5 100644 --- a/test/cli/performance_test.py +++ b/test/cli/performance_test.py @@ -219,3 +219,22 @@ def test_slow_many_scopes(tmpdir): return EXIT_SUCCESS; }""") cppcheck([filename]) # should not take more than ~1 second + +@pytest.mark.timeout(20) +def test_crash_array_in_namespace(tmpdir): + # 12847 + filename = os.path.join(tmpdir, 'hang.cpp') + with open(filename, 'wt') as f: + f.write(r""" + #define ROW A, A, A, A, A, A, A, A, + #define ROW8 ROW ROW ROW ROW ROW ROW ROW ROW + #define ROW64 ROW8 ROW8 ROW8 ROW8 ROW8 ROW8 ROW8 ROW8 + #define ROW512 ROW64 ROW64 ROW64 ROW64 ROW64 ROW64 ROW64 ROW64 + #define ROW4096 ROW512 ROW512 ROW512 ROW512 ROW512 ROW512 ROW512 ROW512 + namespace N { + static const char A = 'a'; + const char a[] = { + ROW4096 ROW4096 ROW4096 ROW4096 + }; + }""") + cppcheck([filename]) # should not take more than ~5 seconds diff --git a/test/cli/whole-program_test.py b/test/cli/whole-program_test.py index 6f137ec77a9..a256d3d7b28 100644 --- a/test/cli/whole-program_test.py +++ b/test/cli/whole-program_test.py @@ -78,7 +78,6 @@ def __test_addon_suppress_inline_project(tmpdir, extra_args): assert ret == 0, stdout -@pytest.mark.xfail(strict=True) def test_addon_suppress_inline_project(tmpdir): __test_addon_suppress_inline_project(tmpdir, ['-j1']) diff --git a/test/testcmdlineparser.cpp b/test/testcmdlineparser.cpp index 5748fc9ad27..16d47740e33 100644 --- a/test/testcmdlineparser.cpp +++ b/test/testcmdlineparser.cpp @@ -268,6 +268,7 @@ class TestCmdlineParser : public TestFixture { TEST_CASE(xmlverinvalid); TEST_CASE(doc); TEST_CASE(docExclusive); + TEST_CASE(showtimeSummary); TEST_CASE(showtimeFile); TEST_CASE(showtimeFileTotal); TEST_CASE(showtimeTop5); diff --git a/test/testmathlib.cpp b/test/testmathlib.cpp index 1c7e631bb1d..3c441b8da2b 100644 --- a/test/testmathlib.cpp +++ b/test/testmathlib.cpp @@ -60,7 +60,6 @@ class TestMathLib : public TestFixture { TEST_CASE(tan); TEST_CASE(abs); TEST_CASE(toString); - TEST_CASE(CPP14DigitSeparators); } void isGreater() const { @@ -1475,24 +1474,6 @@ class TestMathLib : public TestFixture { ASSERT_EQUALS("2.22507385851e-308", MathLib::toString(std::numeric_limits::min())); ASSERT_EQUALS("1.79769313486e+308", MathLib::toString(std::numeric_limits::max())); } - - void CPP14DigitSeparators() const { // Ticket #7137, #7565 - ASSERT(MathLib::isDigitSeparator("'", 0) == false); - ASSERT(MathLib::isDigitSeparator("123'0;", 3)); - ASSERT(MathLib::isDigitSeparator("foo(1'2);", 5)); - ASSERT(MathLib::isDigitSeparator("foo(1,1'2);", 7)); - ASSERT(MathLib::isDigitSeparator("int a=1'234-1'2-'0';", 7)); - ASSERT(MathLib::isDigitSeparator("int a=1'234-1'2-'0';", 13)); - ASSERT(MathLib::isDigitSeparator("int a=1'234-1'2-'0';", 16) == false); - ASSERT(MathLib::isDigitSeparator("int b=1+9'8;", 9)); - ASSERT(MathLib::isDigitSeparator("if (1'2) { char c = 'c'; }", 5)); - ASSERT(MathLib::isDigitSeparator("if (120%1'2) { char c = 'c'; }", 9)); - ASSERT(MathLib::isDigitSeparator("if (120&1'2) { char c = 'c'; }", 9)); - ASSERT(MathLib::isDigitSeparator("if (120|1'2) { char c = 'c'; }", 9)); - ASSERT(MathLib::isDigitSeparator("if (120%1'2) { char c = 'c'; }", 24) == false); - ASSERT(MathLib::isDigitSeparator("if (120%1'2) { char c = 'c'; }", 26) == false); - ASSERT(MathLib::isDigitSeparator("0b0000001'0010'01110", 14)); - } }; REGISTER_TEST(TestMathLib) diff --git a/test/testnullpointer.cpp b/test/testnullpointer.cpp index 432b50fab9c..a9a2a82043d 100644 --- a/test/testnullpointer.cpp +++ b/test/testnullpointer.cpp @@ -158,6 +158,7 @@ class TestNullPointer : public TestFixture { TEST_CASE(nullpointer_in_typeid); TEST_CASE(nullpointer_in_alignof); // #11401 TEST_CASE(nullpointer_in_for_loop); + TEST_CASE(nullpointerDeadCode); // #11311 TEST_CASE(nullpointerDelete); TEST_CASE(nullpointerSubFunction); TEST_CASE(nullpointerExit); @@ -3657,6 +3658,47 @@ class TestNullPointer : public TestFixture { ASSERT_EQUALS("", errout_str()); } + void nullpointerDeadCode() { + // Ticket #11311 + check ("void f() {\n" + " if (0)\n" + " *(int *)0 = 1;\n" + " else\n" + " ;\n" + "}\n"); + ASSERT_EQUALS("", errout_str()); + + check ("void f() {\n" + " if (0)\n" + " *(int *)0 = 1;\n" + " else {\n" + " if (0)\n" + " *(int *)0 = 2;\n" + " else\n" + " ;\n" + " }\n" + "}\n"); + ASSERT_EQUALS("", errout_str()); + + check ("void f() {\n" + " while(0)\n" + " *(int*)0 = 1;\n" + " do {\n" + " } while(0);\n" + "}\n"); + ASSERT_EQUALS("", errout_str()); + + check ("int f() {\n" + " return 0 ? *(int*)0 = 1 : 1;\n" + "}\n"); + ASSERT_EQUALS("", errout_str()); + + check ("int f() {\n" + " return 1 ? 1 : *(int*)0 = 1;\n" + "}\n"); + ASSERT_EQUALS("", errout_str()); + } + void nullpointerDelete() { check("void f() {\n" " K *k = getK();\n" diff --git a/test/testtokenize.cpp b/test/testtokenize.cpp index 7d2b9e64216..a0f8699dcfd 100644 --- a/test/testtokenize.cpp +++ b/test/testtokenize.cpp @@ -8075,19 +8075,80 @@ class TestTokenizer : public TestFixture { "#warning some warning message\n" "#error some error message\n"; const char dumpdata[] = " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" " \n" " \n" " \n"; @@ -8108,17 +8169,49 @@ class TestTokenizer : public TestFixture { "#endfile\n" "#define macro5 val\n"; const char dumpdata[] = " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" " \n" " \n" " \n"; - std::ostringstream ostr; directiveDump(filedata, ostr); ASSERT_EQUALS(dumpdata, ostr.str()); @@ -8129,9 +8222,19 @@ class TestTokenizer : public TestFixture { "#else /* this will be removed too */\n" "#endif /* this will also be removed */\n"; const char dumpdata[] = " \n" - " \n" - " \n" - " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" " \n" " \n" " \n"; @@ -8144,7 +8247,12 @@ class TestTokenizer : public TestFixture { void testDirectiveRelativePath() { const char filedata[] = "#define macro 1\n"; const char dumpdata[] = " \n" - " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" " \n" " \n" " \n"; diff --git a/test/testunusedfunctions.cpp b/test/testunusedfunctions.cpp index 91f1c1e11bf..2b1773f2f66 100644 --- a/test/testunusedfunctions.cpp +++ b/test/testunusedfunctions.cpp @@ -67,6 +67,7 @@ class TestUnusedFunctions : public TestFixture { TEST_CASE(member_function_ternary); TEST_CASE(boost); TEST_CASE(enumValues); + TEST_CASE(recursive); TEST_CASE(multipleFiles); // same function name in multiple files @@ -116,7 +117,7 @@ class TestUnusedFunctions : public TestFixture { " if (f1())\n" " { }\n" "}"); - ASSERT_EQUALS("", errout_str()); + ASSERT_EQUALS("[test.cpp:1]: (style) The function 'f1' is never used.\n", errout_str()); } void return1() { @@ -124,15 +125,15 @@ class TestUnusedFunctions : public TestFixture { "{\n" " return f1();\n" "}"); - ASSERT_EQUALS("", errout_str()); + ASSERT_EQUALS("[test.cpp:1]: (style) The function 'f1' is never used.\n", errout_str()); } void return2() { check("char * foo()\n" "{\n" - " return *foo();\n" + " return foo();\n" "}"); - ASSERT_EQUALS("", errout_str()); + ASSERT_EQUALS("[test.cpp:1]: (style) The function 'foo' is never used.\n", errout_str()); } void return3() { @@ -158,7 +159,7 @@ class TestUnusedFunctions : public TestFixture { "{\n" " void (*f)() = cond ? f1 : NULL;\n" "}"); - ASSERT_EQUALS("", errout_str()); + ASSERT_EQUALS("[test.cpp:1]: (style) The function 'f1' is never used.\n", errout_str()); } void callback2() { // #8677 @@ -180,7 +181,7 @@ class TestUnusedFunctions : public TestFixture { " if (cond) ;\n" " else f1();\n" "}"); - ASSERT_EQUALS("", errout_str()); + ASSERT_EQUALS("[test.cpp:1]: (style) The function 'f1' is never used.\n", errout_str()); } void functionpointer() { @@ -255,7 +256,7 @@ class TestUnusedFunctions : public TestFixture { "}\n" "\n" "void h() { g(); h(); }"); - ASSERT_EQUALS("", errout_str()); + ASSERT_EQUALS("[test.cpp:8]: (style) The function 'h' is never used.\n", errout_str()); } void template3() { // #4701 @@ -286,7 +287,7 @@ class TestUnusedFunctions : public TestFixture { " test();\n" " }\n" "};"); - ASSERT_EQUALS("", errout_str()); + ASSERT_EQUALS("[test.cpp:11]: (style) The function 'test' is never used.\n", errout_str()); } void template5() { // #9220 @@ -322,7 +323,7 @@ class TestUnusedFunctions : public TestFixture { "};\n"); ASSERT_EQUALS("[test.cpp:3]: (style) The function 'tf' is never used.\n", errout_str()); - check("struct S {\n" + check("struct C {\n" " template\n" " void tf(const T&) { }\n" "};\n" @@ -332,7 +333,7 @@ class TestUnusedFunctions : public TestFixture { "}\n"); ASSERT_EQUALS("", errout_str()); - check("struct S {\n" + check("struct C {\n" " template\n" " void tf(const T&) { }\n" "};\n" @@ -523,10 +524,11 @@ class TestUnusedFunctions : public TestFixture { } void boost() { - check("static void _xy(const char *b, const char *e)\n" - "{}\n" - "parse(line, blanks_p >> ident[&_xy] >> blanks_p >> eol_p).full"); - ASSERT_EQUALS("", errout_str()); + check("static void _xy(const char *b, const char *e) {}\n" + "void f() {\n" + " parse(line, blanks_p >> ident[&_xy] >> blanks_p >> eol_p).full;\n" + "}\n"); + ASSERT_EQUALS("[test.cpp:2]: (style) The function 'f' is never used.\n", errout_str()); } void enumValues() { // #11486 @@ -541,6 +543,14 @@ class TestUnusedFunctions : public TestFixture { errout_str()); } + void recursive() { + check("void f() {\n" // #8159 + " f();\n" + "}\n"); + ASSERT_EQUALS("[test.cpp:1]: (style) The function 'f' is never used.\n", + errout_str()); + } + void multipleFiles() { CheckUnusedFunctions c; @@ -576,7 +586,7 @@ class TestUnusedFunctions : public TestFixture { ASSERT_EQUALS("[test.cpp:2]: (style) The function 'f' is never used.\n", errout_str()); check("void f(void) {}\n" - "void (*list[])(void) = {f}"); + "void (*list[])(void) = {f};"); ASSERT_EQUALS("", errout_str()); }