diff --git a/.github/workflows/CI-cygwin.yml b/.github/workflows/CI-cygwin.yml new file mode 100644 index 00000000000..31557ecbcc7 --- /dev/null +++ b/.github/workflows/CI-cygwin.yml @@ -0,0 +1,51 @@ +# Some convenient links: +# - https://github.com/actions/virtual-environments/blob/master/images/win/Windows2019-Readme.md +# + +name: CI-cygwin + +on: [push,pull_request] + +permissions: + contents: read + +defaults: + run: + shell: cmd + +jobs: + build_cygwin: + strategy: + matrix: + os: [windows-2022] + arch: [x64] + include: + - platform: 'x86_64' + packages: | + gcc-g++ + python3 + fail-fast: false + + runs-on: ${{ matrix.os }} + + steps: + - uses: actions/checkout@v3 + + - name: Set up Cygwin + uses: cygwin/cygwin-install-action@master + with: + platform: ${{ matrix.arch }} + packages: ${{ matrix.packages }} + + # Cygwin will always link the binaries even if they already exist. The linking is also extremely slow. So just run the "check" target which includes all the binaries. + - name: Build all and run test + run: | + C:\cygwin\bin\bash.exe -l -c cd %GITHUB_WORKSPACE% && make VERBOSE=1 -j2 check + + - name: Extra test for misra + run: | + cd %GITHUB_WORKSPACE%\addons\test + ..\..\cppcheck.exe --dump -DDUMMY --suppress=uninitvar --inline-suppr misra\misra-test.c --std=c89 --platform=unix64 + python3 ..\misra.py -verify misra\misra-test.c.dump + ..\..\cppcheck.exe --addon=misra --enable=style --inline-suppr --enable=information --error-exitcode=1 misra\misra-ctu-1-test.c misra\misra-ctu-2-test.c + diff --git a/.github/workflows/CI-mingw.yml b/.github/workflows/CI-mingw.yml new file mode 100644 index 00000000000..152e84902c2 --- /dev/null +++ b/.github/workflows/CI-mingw.yml @@ -0,0 +1,37 @@ +# Some convenient links: +# - https://github.com/actions/virtual-environments/blob/master/images/win/Windows2019-Readme.md +# + +name: CI-mingw + +on: [push,pull_request] + +permissions: + contents: read + +defaults: + run: + shell: cmd + +jobs: + build_mingw: + strategy: + matrix: + os: [windows-2019] # fails to download with "windows-2022" + arch: [x64] # TODO: fix x86 build? + fail-fast: false + + runs-on: ${{ matrix.os }} + + steps: + - uses: actions/checkout@v3 + + - name: Set up MinGW + uses: egor-tensin/setup-mingw@v2 + with: + platform: ${{ matrix.arch }} + + # MinGW will always link the binaries even if they already exist. The linking is also extremely slow. So just run the "check" target which includes all the binaries. + - name: Build all and run test + run: | + mingw32-make VERBOSE=1 -j2 check diff --git a/.github/workflows/CI-unixish.yml b/.github/workflows/CI-unixish.yml new file mode 100644 index 00000000000..902417375a8 --- /dev/null +++ b/.github/workflows/CI-unixish.yml @@ -0,0 +1,481 @@ +# Syntax reference https://help.github.com/en/actions/reference/workflow-syntax-for-github-actions +# Environment reference https://help.github.com/en/actions/reference/virtual-environments-for-github-hosted-runners +name: CI-unixish + +on: [push, pull_request] + +permissions: + contents: read + +jobs: + build_cmake_tinyxml2: + + strategy: + matrix: + os: [ubuntu-20.04, ubuntu-22.04, macos-11, macos-12] + fail-fast: false # Prefer quick result + + runs-on: ${{ matrix.os }} + + env: + # TODO: figure out why there are cache misses with PCH enabled + CCACHE_SLOPPINESS: pch_defines,time_macros + + steps: + - uses: actions/checkout@v3 + + - name: ccache + uses: hendrikmuhs/ccache-action@v1.2 + with: + key: ${{ github.workflow }}-${{ github.job }}-${{ matrix.os }} + + - name: Install missing software on ubuntu + if: contains(matrix.os, 'ubuntu') + run: | + sudo apt-get update + sudo apt-get install libxml2-utils libtinyxml2-dev qtbase5-dev qttools5-dev libqt5charts5-dev qtchooser + + # coreutils contains "nproc" + - name: Install missing software on macos + if: contains(matrix.os, 'macos') + run: | + # pcre was removed from runner images in November 2022 + brew install coreutils qt@5 tinyxml2 pcre + + - name: CMake build on ubuntu (with GUI / system tinyxml2) + if: contains(matrix.os, 'ubuntu') + run: | + cmake -S . -B cmake.output.tinyxml2 -G "Unix Makefiles" -DHAVE_RULES=On -DBUILD_TESTS=On -DBUILD_GUI=On -DWITH_QCHART=On -DUSE_BUNDLED_TINYXML2=Off -DCMAKE_DISABLE_PRECOMPILE_HEADERS=On -DCMAKE_C_COMPILER_LAUNCHER=ccache -DCMAKE_CXX_COMPILER_LAUNCHER=ccache + cmake --build cmake.output.tinyxml2 -- -j$(nproc) + + - name: CMake build on macos (with GUI / system tinyxml2) + if: contains(matrix.os, 'macos') + run: | + cmake -S . -B cmake.output.tinyxml2 -G "Unix Makefiles" -DHAVE_RULES=On -DBUILD_TESTS=On -DBUILD_GUI=On -DWITH_QCHART=On -DUSE_BUNDLED_TINYXML2=Off -DCMAKE_DISABLE_PRECOMPILE_HEADERS=On -DCMAKE_C_COMPILER_LAUNCHER=ccache -DCMAKE_CXX_COMPILER_LAUNCHER=ccache -DQt5_DIR=$(brew --prefix qt@5)/lib/cmake/Qt5 + cmake --build cmake.output.tinyxml2 -- -j$(nproc) + + - name: Run CMake test (system tinyxml2) + run: | + cmake --build cmake.output.tinyxml2 --target check -- -j$(nproc) + + build_cmake: + + strategy: + matrix: + os: [ubuntu-20.04, ubuntu-22.04, macos-11, macos-12] + fail-fast: false # Prefer quick result + + runs-on: ${{ matrix.os }} + + env: + # TODO: figure out why there are cache misses with PCH enabled + CCACHE_SLOPPINESS: pch_defines,time_macros + + steps: + - uses: actions/checkout@v3 + + - name: ccache + uses: hendrikmuhs/ccache-action@v1.2 + with: + key: ${{ github.workflow }}-${{ github.job }}-${{ matrix.os }} + + - name: Install missing software on ubuntu + if: contains(matrix.os, 'ubuntu') + run: | + sudo apt-get update + sudo apt-get install libxml2-utils qtbase5-dev qttools5-dev libqt5charts5-dev qtchooser + + - name: Set up GCC + uses: egor-tensin/setup-gcc@v1 + if: matrix.os == 'ubuntu-22.04' + with: + version: 13 + platform: x64 + + - name: Select compiler + run: | + echo "CXX=g++-13" >> $GITHUB_ENV + if: matrix.os == 'ubuntu-22.04' + + # coreutils contains "nproc" + - name: Install missing software on macos + if: contains(matrix.os, 'macos') + run: | + # pcre was removed from runner images in November 2022 + brew install coreutils qt@5 pcre + + - name: CMake build on ubuntu (with GUI) + if: contains(matrix.os, 'ubuntu') + run: | + cmake -S . -B cmake.output -G "Unix Makefiles" -DHAVE_RULES=On -DBUILD_TESTS=On -DBUILD_GUI=On -DWITH_QCHART=On -DCMAKE_DISABLE_PRECOMPILE_HEADERS=On -DCMAKE_C_COMPILER_LAUNCHER=ccache -DCMAKE_CXX_COMPILER_LAUNCHER=ccache + cmake --build cmake.output -- -j$(nproc) + + - name: CMake build on macos (with GUI) + if: contains(matrix.os, 'macos') + run: | + cmake -S . -B cmake.output -G "Unix Makefiles" -DHAVE_RULES=On -DBUILD_TESTS=On -DBUILD_GUI=On -DWITH_QCHART=On -DCMAKE_DISABLE_PRECOMPILE_HEADERS=On -DCMAKE_C_COMPILER_LAUNCHER=ccache -DCMAKE_CXX_COMPILER_LAUNCHER=ccache -DQt5_DIR=$(brew --prefix qt@5)/lib/cmake/Qt5 + cmake --build cmake.output -- -j$(nproc) + + - name: Run CMake test + run: | + cmake --build cmake.output --target check -- -j$(nproc) + + - name: Run CTest + run: | + pushd cmake.output + ctest --output-on-failure -j$(nproc) + + build_uchar: + + strategy: + matrix: + os: [ubuntu-20.04, ubuntu-22.04, macos-11, macos-12] + fail-fast: false # Prefer quick result + + runs-on: ${{ matrix.os }} + + steps: + - uses: actions/checkout@v3 + + - name: ccache + uses: hendrikmuhs/ccache-action@v1.2 + with: + key: ${{ github.workflow }}-${{ github.job }}-${{ matrix.os }} + + # coreutils contains "nproc" + - name: Install missing software on macos + if: contains(matrix.os, 'macos') + run: | + brew install coreutils + + - name: Build with Unsigned char + run: | + export PATH="/usr/lib/ccache:/usr/local/opt/ccache/libexec:$PATH" + make -j$(nproc) CXXFLAGS=-funsigned-char testrunner + + - name: Test with Unsigned char + run: | + ./testrunner TestSymbolDatabase + + build_mathlib: + + strategy: + matrix: + os: [ubuntu-20.04, ubuntu-22.04, macos-11, macos-12] + fail-fast: false # Prefer quick result + + runs-on: ${{ matrix.os }} + + steps: + - uses: actions/checkout@v3 + + - name: ccache + uses: hendrikmuhs/ccache-action@v1.2 + with: + key: ${{ github.workflow }}-${{ github.job }}-${{ matrix.os }} + + # coreutils contains "nproc" + - name: Install missing software on macos + if: contains(matrix.os, 'macos') + run: | + brew install coreutils + + - name: Build with TEST_MATHLIB_VALUE + run: | + export PATH="/usr/lib/ccache:/usr/local/opt/ccache/libexec:$PATH" + make -j$(nproc) CPPFLAGS=-DTEST_MATHLIB_VALUE all + + - name: Test with TEST_MATHLIB_VALUE + run: | + make -j$(nproc) CPPFLAGS=-DTEST_MATHLIB_VALUE check + + check_nonneg: + + strategy: + matrix: + os: [ubuntu-20.04, ubuntu-22.04, macos-11, macos-12] + fail-fast: false # Prefer quick result + + runs-on: ${{ matrix.os }} + + steps: + - uses: actions/checkout@v3 + + # coreutils contains "g++" (default is "c++") and "nproc" + - name: Install missing software on macos + if: contains(matrix.os, 'macos') + run: | + brew install coreutils + + - name: Check syntax with NONNEG + run: | + ls lib/*.cpp | xargs -n 1 -P $(nproc) g++ -fsyntax-only -std=c++0x -Ilib -Iexternals -Iexternals/picojson -Iexternals/simplecpp -Iexternals/tinyxml2 -DNONNEG + + build_qmake: + + strategy: + matrix: + os: [ubuntu-20.04, ubuntu-22.04, macos-11, macos-12] + fail-fast: false # Prefer quick result + + runs-on: ${{ matrix.os }} + + steps: + - uses: actions/checkout@v3 + + - name: Install missing software on ubuntu + if: contains(matrix.os, 'ubuntu') + run: | + sudo apt-get update + sudo apt-get install qtbase5-dev qttools5-dev libqt5charts5-dev qtchooser + + # coreutils contains "nproc" + - name: Install missing software on macos + if: contains(matrix.os, 'macos') + run: | + brew install coreutils qt@5 + # expose qmake + brew link qt@5 --force + + - name: ccache + uses: hendrikmuhs/ccache-action@v1.2 + with: + key: ${{ github.workflow }}-${{ github.job }}-${{ matrix.os }} + + - name: Build GUI + run: | + export PATH="$(brew --prefix)/opt/ccache/libexec:/usr/lib/ccache:/usr/local/opt/ccache/libexec:$PATH" + pushd gui + qmake CONFIG+=debug CONFIG+=ccache HAVE_QCHART=yes + make -j$(nproc) + + # TODO: binaries are in a different location on macos + - name: Build and Run GUI tests + if: contains(matrix.os, 'ubuntu') + run: | + export PATH="$(brew --prefix)/opt/ccache/libexec:/usr/lib/ccache:/usr/local/opt/ccache/libexec:$PATH" + pushd gui/test/cppchecklibrarydata + qmake CONFIG+=debug CONFIG+=ccache + make -j$(nproc) + ./test-cppchecklibrarydata + popd + pushd gui/test/filelist + qmake CONFIG+=debug CONFIG+=ccache + make -j$(nproc) + ./test-filelist + popd + pushd gui/test/projectfile + qmake CONFIG+=debug CONFIG+=ccache + make -j$(nproc) + ./test-projectfile + popd + pushd gui/test/translationhandler + qmake CONFIG+=debug CONFIG+=ccache + make -j$(nproc) + # TODO: requires X session because of QApplication dependency in translationhandler.cpp + #./test-translationhandler + popd + pushd gui/test/xmlreportv2 + qmake CONFIG+=debug CONFIG+=ccache + make -j$(nproc) + ./test-xmlreportv2 + + - name: Generate Qt help file + run: | + pushd gui/help + qhelpgenerator online-help.qhcp -o online-help.qhc + + - name: Build triage + run: | + export PATH="$(brew --prefix)/opt/ccache/libexec:/usr/lib/ccache:/usr/local/opt/ccache/libexec:$PATH" + pushd tools/triage + qmake CONFIG+=debug CONFIG+=ccache + make -j$(nproc) + + build: + + strategy: + matrix: + os: [ubuntu-20.04, ubuntu-22.04, macos-11, macos-12] + fail-fast: false # Prefer quick result + + runs-on: ${{ matrix.os }} + + steps: + - uses: actions/checkout@v3 + + - name: ccache + uses: hendrikmuhs/ccache-action@v1.2 + with: + key: ${{ github.workflow }}-${{ github.job }}-${{ matrix.os }} + + - name: Install missing software on ubuntu + if: contains(matrix.os, 'ubuntu') + run: | + sudo apt-get update + sudo apt-get install libxml2-utils + + # packages for strict cfg checks + - name: Install missing software on ubuntu 22.04 (cfg) + if: matrix.os == 'ubuntu-22.04' + run: | + sudo apt-get install libcairo2-dev libcurl4-openssl-dev liblua5.3-dev libssl-dev libsqlite3-dev libcppunit-dev libsigc++-2.0-dev libgtk-3-dev libboost-all-dev libwxgtk3.0-gtk3-dev xmlstarlet qtbase5-dev + + # coreutils contains "nproc" + - name: Install missing software on macos + if: contains(matrix.os, 'macos') + run: | + # pcre was removed from runner images in November 2022 + brew install coreutils python3 pcre gnu-sed + + - name: Install missing Python packages + run: | + python3 -m pip install pip --upgrade + python3 -m pip install pytest + + - name: Build cppcheck + run: | + export PATH="/usr/lib/ccache:/usr/local/opt/ccache/libexec:$PATH" + make -j$(nproc) HAVE_RULES=yes + + - name: Build test + run: | + export PATH="/usr/lib/ccache:/usr/local/opt/ccache/libexec:$PATH" + make -j$(nproc) testrunner HAVE_RULES=yes + + - name: Run test + run: | + make -j$(nproc) check HAVE_RULES=yes + + # requires "gnu-sed" installed on macos + - name: Run extra tests + run: | + tools/generate_and_run_more_tests.sh + + # do not use pushd in this step since we go below the working directory + - name: Run test/cli + run: | + cd test/cli + python3 -m pytest test-*.py + cd ../../.. + ln -s cppcheck 'cpp check' + cd 'cpp check/test/cli' + python3 -m pytest test-*.py + + - name: Run cfg tests + if: matrix.os != 'ubuntu-22.04' + run: | + make -j$(nproc) checkcfg + + - name: Run cfg tests (strict) + if: matrix.os == 'ubuntu-22.04' + run: | + make -j$(nproc) checkcfg + env: + STRICT: 1 + + - name: Run showtimetop5 tests + run: | + ./tools/test_showtimetop5.sh + + - name: Run --dump test + run: | + ./cppcheck test/testpreprocessor.cpp --dump + xmllint --noout test/testpreprocessor.cpp.dump + + - name: Validate + run: | + make -j$(nproc) checkCWEEntries validateXML + + # TODO: move to scriptcheck.yml so these are tested with all Python versions? + - name: Test addons + run: | + ./cppcheck --error-exitcode=1 --inline-suppr --addon=threadsafety addons/test/threadsafety + ./cppcheck --error-exitcode=1 --inline-suppr --addon=threadsafety --std=c++03 addons/test/threadsafety + ./cppcheck --error-exitcode=1 --inline-suppr --addon=misra addons/test/misra/crash*.c + ./cppcheck --addon=misra --enable=style --inline-suppr --enable=information --error-exitcode=1 addons/test/misra/misra-ctu-*-test.c + pushd addons/test + # We'll force C89 standard to enable an additional verification for + # rules 5.4 and 5.5 which have standard-dependent options. + ../../cppcheck --dump -DDUMMY --suppress=uninitvar --inline-suppr misra/misra-test.c --std=c89 --platform=unix64 + python3 ../misra.py -verify misra/misra-test.c.dump + # TODO: do we need to verify something here? + ../../cppcheck --dump -DDUMMY --suppress=uninitvar --suppress=uninitStructMember --std=c89 misra/misra-test.h + ../../cppcheck --dump misra/misra-test.cpp + python3 ../misra.py -verify misra/misra-test.cpp.dump + python3 ../misra.py --rule-texts=misra/misra2012_rules_dummy_ascii.txt -verify misra/misra-test.cpp.dump + python3 ../misra.py --rule-texts=misra/misra2012_rules_dummy_utf8.txt -verify misra/misra-test.cpp.dump + python3 ../misra.py --rule-texts=misra/misra2012_rules_dummy_windows1250.txt -verify misra/misra-test.cpp.dump + ../../cppcheck --addon=misra --enable=style --platform=avr8 --error-exitcode=1 misra/misra-test-avr8.c + ../../cppcheck --dump misc-test.cpp + python3 ../misc.py -verify misc-test.cpp.dump + ../../cppcheck --dump naming_test.c + python3 ../naming.py --var='[a-z].*' --function='[a-z].*' naming_test.c.dump + ../../cppcheck --dump naming_test.cpp + python3 ../naming.py --var='[a-z].*' --function='[a-z].*' naming_test.cpp.dump + ../../cppcheck --dump namingng_test.c + python3 ../namingng.py --configfile ../naming.json --verify namingng_test.c.dump + + - name: Build democlient + if: matrix.os == 'ubuntu-22.04' + run: | + warnings="-pedantic -Wall -Wextra -Wcast-qual -Wno-deprecated-declarations -Wfloat-equal -Wmissing-declarations -Wmissing-format-attribute -Wno-long-long -Wpacked -Wredundant-decls -Wundef -Wno-shadow -Wno-missing-field-initializers -Wno-missing-braces -Wno-sign-compare -Wno-multichar" + g++ $warnings -c -Ilib -Iexternals/tinyxml2 democlient/democlient.cpp + + selfcheck: + needs: build # wait for all tests to be successful first + + runs-on: ubuntu-22.04 # run on the latest image only + + steps: + - uses: actions/checkout@v3 + + - name: ccache + uses: hendrikmuhs/ccache-action@v1.2 + with: + key: ${{ github.workflow }}-${{ github.job }}-${{ matrix.os }} + + - name: Install missing software on ubuntu + run: | + sudo apt-get update + sudo apt-get install qtbase5-dev qttools5-dev libqt5charts5-dev libboost-container-dev + + - name: Self check (build) + run: | + export PATH="/usr/lib/ccache:/usr/local/opt/ccache/libexec:$PATH" + # compile with verification and ast matchers + make -j$(nproc) -s CPPFLAGS="-DCHECK_INTERNAL" CXXFLAGS="-g -O2 -DHAVE_BOOST" MATCHCOMPILER=yes VERIFY=1 + + - name: Generate UI files + run: | + pushd gui + qmake CONFIG+=debug HAVE_QCHART=yes + make -j$(nproc) compiler_uic_make_all mocables + + - name: Generate triage UI files + run: | + pushd tools/triage + qmake CONFIG+=debug + make -j$(nproc) compiler_uic_make_all mocables + + - name: Self check + run: | + selfcheck_options="-q -j$(nproc) --std=c++11 --template=selfcheck --showtime=top5 -D__CPPCHECK__ -DCHECK_INTERNAL -DHAVE_RULES --error-exitcode=1 --inline-suppr --suppressions-list=.selfcheck_suppressions --library=cppcheck-lib -Ilib -Iexternals/simplecpp/ -Iexternals/tinyxml2/ --inconclusive --enable=style,performance,portability,warning,missingInclude,internal --exception-handling --debug-warnings --check-level=exhaustive" + ec=0 + + # early exit + if [ $ec -eq 1 ]; then + exit $ec + fi + + # self check lib/cli + mkdir b1 + ./cppcheck $selfcheck_options --cppcheck-build-dir=b1 --addon=naming.json -DCHECK_INTERNAL cli lib || ec=1 + # check gui with qt settings + mkdir b2 + ./cppcheck $selfcheck_options --cppcheck-build-dir=b2 -DQT_VERSION=0x050000 -DQ_MOC_OUTPUT_REVISION=67 -DQT_CHARTS_LIB --library=qt --addon=naming.json -Igui/temp -Igui gui/*.cpp gui/temp/*.cpp || ec=1 + # self check test and tools + ./cppcheck $selfcheck_options -Icli test/*.cpp tools/*.cpp || ec=1 + # triage + ./cppcheck $selfcheck_options -DQ_MOC_OUTPUT_REVISION=67 -DQT_CHARTS_LIB --library=qt -Itools/triage/temp -Igui tools/triage/*.cpp tools/triage/temp/*.cpp || ec=1 + exit $ec diff --git a/.github/workflows/CI-windows.yml b/.github/workflows/CI-windows.yml new file mode 100644 index 00000000000..4da98719ded --- /dev/null +++ b/.github/workflows/CI-windows.yml @@ -0,0 +1,205 @@ +# Some convenient links: +# - https://github.com/actions/virtual-environments/blob/master/images/win/Windows2019-Readme.md +# + +name: CI-windows + +on: [push,pull_request] + +permissions: + contents: read + +defaults: + run: + shell: cmd + +jobs: + + build_qt: + strategy: + matrix: + os: [windows-2019, windows-2022] + qt_ver: [5.15.2, 6.2.4, 6.5.0] + fail-fast: false + + runs-on: ${{ matrix.os }} + + steps: + - uses: actions/checkout@v3 + + - name: Set up Visual Studio environment + uses: ilammy/msvc-dev-cmd@v1 + with: + arch: x64 # no 32-bit Qt available + + - name: Install Qt ${{ matrix.qt_ver }} + uses: jurplel/install-qt-action@v3 + with: + version: ${{ matrix.qt_ver }} + modules: 'qtcharts' + cache: true + + - name: Build GUI release (qmake) + if: startsWith(matrix.qt_ver, '5') + run: | + cd gui || exit /b !errorlevel! + qmake HAVE_QCHART=yes || exit /b !errorlevel! + nmake release || exit /b !errorlevel! + env: + CL: /MP + + - name: Deploy GUI + if: startsWith(matrix.qt_ver, '5') + run: | + windeployqt Build\gui || exit /b !errorlevel! + del Build\gui\cppcheck-gui.ilk || exit /b !errorlevel! + del Build\gui\cppcheck-gui.pdb || exit /b !errorlevel! + + - name: Build GUI release (CMake) + if: startsWith(matrix.qt_ver, '6') + run: | + cmake -S . -B build -DBUILD_GUI=On -DWITH_QCHART=On -DUSE_QT6=On || exit /b !errorlevel! + cmake --build build --target cppcheck-gui || exit /b !errorlevel! + + # TODO: deploy with CMake/Qt6 + + build: + strategy: + matrix: + os: [windows-2019, windows-2022] + arch: [x64, x86] + fail-fast: false + + runs-on: ${{ matrix.os }} + + env: + # see https://www.pcre.org/original/changelog.txt + PCRE_VERSION: 8.45 + + steps: + - uses: actions/checkout@v3 + + - name: Set up Python 3.11 + uses: actions/setup-python@v4 + with: + python-version: '3.11' + check-latest: true + + - name: Set up Visual Studio environment + uses: ilammy/msvc-dev-cmd@v1 + with: + arch: ${{ matrix.arch }} + + - name: Cache PCRE + id: cache-pcre + uses: actions/cache@v3 + with: + path: | + externals\pcre.h + externals\pcre.lib + externals\pcre64.lib + key: pcre-${{ env.PCRE_VERSION }}-${{ matrix.arch }}-bin-win + + - name: Download PCRE + if: steps.cache-pcre.outputs.cache-hit != 'true' + run: | + curl -fsSL https://github.com/pfultz2/pcre/archive/refs/tags/%PCRE_VERSION%.zip -o pcre-%PCRE_VERSION%.zip || exit /b !errorlevel! + + - name: Install PCRE + if: steps.cache-pcre.outputs.cache-hit != 'true' + run: | + 7z x pcre-%PCRE_VERSION%.zip || exit /b !errorlevel! + cd pcre-%PCRE_VERSION% || exit /b !errorlevel! + cmake . -G "NMake Makefiles" -DCMAKE_BUILD_TYPE=Release -DPCRE_BUILD_PCRECPP=Off -DPCRE_BUILD_TESTS=Off -DPCRE_BUILD_PCREGREP=Off || exit /b !errorlevel! + nmake || exit /b !errorlevel! + copy pcre.h ..\externals || exit /b !errorlevel! + if "${{ matrix.arch }}" == "x86" ( + copy pcre.lib ..\externals\pcre.lib || exit /b !errorlevel! + ) else ( + copy pcre.lib ..\externals\pcre64.lib || exit /b !errorlevel! + ) + env: + CL: /MP + + - name: Install missing Python packages + run: | + python -m pip install pip --upgrade || exit /b !errorlevel! + python -m pip install pytest || exit /b !errorlevel! + python -m pip install pytest-custom_exit_code || exit /b !errorlevel! + + - name: Run CMake + if: false # TODO: enable + run: | + set ARCH=${{ matrix.arch }} + if "${{ matrix.arch }}" == "x86" ( + set ARCH=Win32 + ) + cmake -S . -B build -DBUILD_TESTS=On || exit /b !errorlevel! + + - name: Build CLI debug configuration using MSBuild + run: | + set ARCH=${{ matrix.arch }} + if "${{ matrix.arch }}" == "x86" ( + set ARCH=Win32 + ) + :: cmake --build build --target check --config Debug || exit /b !errorlevel! + msbuild -m cppcheck.sln /p:Configuration=Debug-PCRE;Platform=%ARCH% -maxcpucount || exit /b !errorlevel! + + - name: Run Debug test + run: .\bin\debug\testrunner.exe || exit /b !errorlevel! + + - name: Build CLI release configuration using MSBuild + run: | + set ARCH=${{ matrix.arch }} + if "${{ matrix.arch }}" == "x86" ( + set ARCH=Win32 + ) + :: cmake --build build --target check --config Release || exit /b !errorlevel! + msbuild -m cppcheck.sln /p:Configuration=Release-PCRE;Platform=%ARCH% -maxcpucount || exit /b !errorlevel! + + - name: Run Release test + run: .\bin\testrunner.exe || exit /b !errorlevel! + + - name: Run test/cli + run: | + :: since FILESDIR is not set copy the binary to the root so the addons are found + :: copy .\build\bin\Release\cppcheck.exe .\cppcheck.exe || exit /b !errorlevel! + copy .\bin\cppcheck.exe .\cppcheck.exe || exit /b !errorlevel! + copy .\bin\cppcheck-core.dll .\cppcheck-core.dll || exit /b !errorlevel! + cd test/cli || exit /b !errorlevel! + :: python -m pytest --suppress-no-test-exit-code test-clang-import.py || exit /b !errorlevel! + python -m pytest test-helloworld.py || exit /b !errorlevel! + python -m pytest test-inline-suppress.py || exit /b !errorlevel! + python -m pytest test-more-projects.py || exit /b !errorlevel! + python -m pytest test-other.py || exit /b !errorlevel! + python -m pytest test-proj2.py || exit /b !errorlevel! + python -m pytest test-suppress-syntaxError.py || exit /b !errorlevel! + + - name: Test addons + run: | + .\cppcheck --addon=threadsafety addons\test\threadsafety || exit /b !errorlevel! + .\cppcheck --addon=threadsafety --std=c++03 addons\test\threadsafety || exit /b !errorlevel! + .\cppcheck --addon=misra --enable=style --inline-suppr --enable=information --error-exitcode=1 addons\test\misra\misra-ctu-*-test.c || exit /b !errorlevel! + cd addons\test + rem We'll force C89 standard to enable an additional verification for + rem rules 5.4 and 5.5 which have standard-dependent options. + ..\..\cppcheck --dump -DDUMMY --suppress=uninitvar --inline-suppr misra\misra-test.c --std=c89 --platform=unix64 || exit /b !errorlevel! + python3 ..\misra.py -verify misra\misra-test.c.dump || exit /b !errorlevel! + rem TODO: do we need to verify something here? + ..\..\cppcheck --dump -DDUMMY --suppress=uninitvar --suppress=uninitStructMember --std=c89 misra\misra-test.h || exit /b !errorlevel! + ..\..\cppcheck --dump misra\misra-test.cpp || exit /b !errorlevel! + python3 ..\misra.py -verify misra\misra-test.cpp.dump || exit /b !errorlevel! + python3 ..\misra.py --rule-texts=misra\misra2012_rules_dummy_ascii.txt -verify misra\misra-test.cpp.dump || exit /b !errorlevel! + python3 ..\misra.py --rule-texts=misra\misra2012_rules_dummy_utf8.txt -verify misra\misra-test.cpp.dump || exit /b !errorlevel! + python3 ..\misra.py --rule-texts=misra\misra2012_rules_dummy_windows1250.txt -verify misra\misra-test.cpp.dump || exit /b !errorlevel! + ..\..\cppcheck --addon=misra --enable=style --platform=avr8 --error-exitcode=1 misra\misra-test-avr8.c || exit /b !errorlevel! + ..\..\cppcheck --dump misc-test.cpp || exit /b !errorlevel! + python3 ..\misc.py -verify misc-test.cpp.dump || exit /b !errorlevel! + ..\..\cppcheck --dump naming_test.c || exit /b !errorlevel! + rem TODO: fix this - does not fail on Linux + rem python3 ..\naming.py --var='[a-z].*' --function='[a-z].*' naming_test.c.dump || exit /b !errorlevel! + ..\..\cppcheck --dump naming_test.cpp || exit /b !errorlevel! + python3 ..\naming.py --var='[a-z].*' --function='[a-z].*' naming_test.cpp.dump || exit /b !errorlevel! + ..\..\cppcheck --dump namingng_test.c || exit /b !errorlevel! + python3 ..\namingng.py --configfile ..\naming.json --verify namingng_test.c.dump || exit /b !errorlevel! + diff --git a/.github/workflows/asan.yml b/.github/workflows/asan.yml new file mode 100644 index 00000000000..fdc029ad9f8 --- /dev/null +++ b/.github/workflows/asan.yml @@ -0,0 +1,91 @@ +# Syntax reference https://help.github.com/en/actions/reference/workflow-syntax-for-github-actions +# Environment reference https://help.github.com/en/actions/reference/virtual-environments-for-github-hosted-runners +name: address sanitizer + +on: [push, pull_request] + +permissions: + contents: read + +jobs: + build: + + runs-on: ubuntu-22.04 + + env: + QT_VERSION: 5.15.2 + ASAN_OPTIONS: detect_stack_use_after_return=1 + # TODO: figure out why there are cache misses with PCH enabled + CCACHE_SLOPPINESS: pch_defines,time_macros + + steps: + - uses: actions/checkout@v3 + + - name: ccache + uses: hendrikmuhs/ccache-action@v1.2 + with: + key: ${{ github.workflow }}-${{ github.job }}-${{ matrix.os }} + + - name: Set up Python 3.11 + uses: actions/setup-python@v4 + with: + python-version: '3.11' + check-latest: true + + - name: Install missing software on ubuntu + run: | + sudo apt-get update + sudo apt-get install -y cmake make libpcre3-dev libboost-container-dev + + - name: Install clang + run: | + sudo apt-get purge --auto-remove llvm python3-lldb-14 llvm-14 + wget https://apt.llvm.org/llvm.sh + chmod +x llvm.sh + sudo ./llvm.sh 16 + + - name: Install Qt ${{ env.QT_VERSION }} + if: false + uses: jurplel/install-qt-action@v3 + with: + version: ${{ env.QT_VERSION }} + modules: 'qtcharts' + cache: true + + - name: CMake + run: | + cmake -S . -B cmake.output -DCMAKE_BUILD_TYPE=RelWithDebInfo -DHAVE_RULES=On -DBUILD_TESTS=On -DBUILD_GUI=Off -DWITH_QCHART=Off -DUSE_MATCHCOMPILER=Verify -DANALYZE_ADDRESS=On -DENABLE_CHECK_INTERNAL=On -DUSE_BOOST=On -DCPPCHK_GLIBCXX_DEBUG=Off -DCMAKE_DISABLE_PRECOMPILE_HEADERS=On -DCMAKE_GLOBAL_AUTOGEN_TARGET=Off -DDISABLE_DMAKE=On -DCMAKE_C_COMPILER_LAUNCHER=ccache -DCMAKE_CXX_COMPILER_LAUNCHER=ccache + env: + CC: clang-16 + CXX: clang++-16 + + - name: Build cppcheck + run: | + cmake --build cmake.output --target cppcheck -- -j $(nproc) + + - name: Build test + run: | + cmake --build cmake.output --target testrunner -- -j $(nproc) + + - name: Run tests + run: ./cmake.output/bin/testrunner + + - name: Generate dependencies + if: false + run: | + # make sure auto-generated GUI files exist + make -C cmake.output autogen + make -C cmake.output gui-build-deps triage-build-ui-deps + + # TODO: this is currently way too slow (~60 minutes) to enable it + # TODO: only fail the step on sanitizer issues - since we use processes it will only fail the underlying process which will result in an cppcheckError + - name: Self check + if: false + run: | + selfcheck_options="-q -j$(nproc) --std=c++11 --template=selfcheck --showtime=top5 -D__CPPCHECK__ -DCHECK_INTERNAL -DHAVE_RULES --error-exitcode=1 --inline-suppr --suppressions-list=.selfcheck_suppressions --library=cppcheck-lib -Ilib -Iexternals/simplecpp/ -Iexternals/tinyxml2/ --inconclusive --enable=style,performance,portability,warning,missingInclude,internal --exception-handling --debug-warnings" + ec=0 + ./cmake.output/bin/cppcheck $selfcheck_options --addon=naming.json cli lib || ec=1 + ./cmake.output/bin/cppcheck $selfcheck_options -DQT_VERSION=0x050000 -DQ_MOC_OUTPUT_REVISION=67 -DQT_CHARTS_LIB --library=qt --addon=naming.json -Icmake.output/gui -Igui gui/*.cpp cmake.output/gui/*.cpp || ec=1 + ./cmake.output/bin/cppcheck $selfcheck_options -Icli test/*.cpp tools/*.cpp || ec=1 + ./cmake.output/bin/cppcheck $selfcheck_options -DQ_MOC_OUTPUT_REVISION=67 -DQT_CHARTS_LIB --library=qt -Icmake.output/tools/triage -Igui tools/triage/*.cpp cmake.output/tools/triage/*.cpp || ec=1 + exit $ec diff --git a/.github/workflows/buildman.yml b/.github/workflows/buildman.yml new file mode 100644 index 00000000000..4bbdf779661 --- /dev/null +++ b/.github/workflows/buildman.yml @@ -0,0 +1,28 @@ +name: Build manual + +on: [push, pull_request] + +permissions: + contents: read + +jobs: + convert_via_pandoc: + runs-on: ubuntu-22.04 + steps: + - uses: actions/checkout@v3 + + - run: | + mkdir output + + - uses: docker://pandoc/latex:2.9 + with: + args: --output=output/manual.html man/manual.md + + - uses: docker://pandoc/latex:2.9 + with: + args: --output=output/manual.pdf man/manual.md + + - uses: actions/upload-artifact@v3 + with: + name: output + path: output diff --git a/.github/workflows/cifuzz.yml b/.github/workflows/cifuzz.yml new file mode 100644 index 00000000000..19c40de61c9 --- /dev/null +++ b/.github/workflows/cifuzz.yml @@ -0,0 +1,26 @@ +name: CIFuzz +on: [pull_request] +jobs: + Fuzzing: + runs-on: ubuntu-latest + steps: + - name: Build Fuzzers + id: build + uses: google/oss-fuzz/infra/cifuzz/actions/build_fuzzers@master + with: + oss-fuzz-project-name: 'cppcheck' + dry-run: false + language: c++ + - name: Run Fuzzers + uses: google/oss-fuzz/infra/cifuzz/actions/run_fuzzers@master + with: + oss-fuzz-project-name: 'cppcheck' + fuzz-seconds: 300 + dry-run: false + language: c++ + - name: Upload Crash + uses: actions/upload-artifact@v3 + if: failure() && steps.build.outcome == 'success' + with: + name: artifacts + path: ./out/artifacts diff --git a/.github/workflows/clang-tidy.yml b/.github/workflows/clang-tidy.yml new file mode 100644 index 00000000000..c8546db9ab2 --- /dev/null +++ b/.github/workflows/clang-tidy.yml @@ -0,0 +1,66 @@ +# Syntax reference https://help.github.com/en/actions/reference/workflow-syntax-for-github-actions +# Environment reference https://help.github.com/en/actions/reference/virtual-environments-for-github-hosted-runners +name: clang-tidy + +on: [push, pull_request] + +permissions: + contents: read + +jobs: + build: + + runs-on: ubuntu-22.04 + + env: + QT_VERSION: 5.15.2 + + steps: + - uses: actions/checkout@v3 + + - name: Install missing software + run: | + sudo apt-get update + sudo apt-get install -y cmake make + sudo apt-get install -y libpcre3-dev + sudo apt-get install -y libffi7 # work around missing dependency for Qt install step + + - name: Install clang + run: | + sudo apt-get purge --auto-remove llvm python3-lldb-14 llvm-14 + wget https://apt.llvm.org/llvm.sh + chmod +x llvm.sh + sudo ./llvm.sh 16 + sudo apt-get install -y clang-tidy-16 + + - name: Install Qt ${{ env.QT_VERSION }} + uses: jurplel/install-qt-action@v3 + with: + version: ${{ env.QT_VERSION }} + modules: 'qtcharts' + cache: true + + - name: Verify clang-tidy configuration + run: | + clang-tidy-16 --verify-config + + - name: Prepare CMake + run: | + cmake -S . -B cmake.output -G "Unix Makefiles" -DHAVE_RULES=On -DBUILD_TESTS=On -DBUILD_GUI=On -DWITH_QCHART=On -DENABLE_CHECK_INTERNAL=On -DCMAKE_GLOBAL_AUTOGEN_TARGET=On -DCPPCHK_GLIBCXX_DEBUG=Off + env: + CC: clang-16 + CXX: clang++-16 + + - name: Prepare CMake dependencies + run: | + # make sure the precompiled headers exist + make -C cmake.output/cli cmake_pch.hxx.pch + make -C cmake.output/gui cmake_pch.hxx.pch + make -C cmake.output/lib cmake_pch.hxx.pch + make -C cmake.output/test cmake_pch.hxx.pch + # make sure the auto-generated GUI sources exist + make -C cmake.output autogen + + - name: Clang-Tidy + run: | + cmake --build cmake.output --target run-clang-tidy 2> /dev/null diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml new file mode 100644 index 00000000000..12d15855527 --- /dev/null +++ b/.github/workflows/codeql-analysis.yml @@ -0,0 +1,47 @@ +name: "CodeQL" + +on: [push, pull_request] + +permissions: + contents: read + security-events: write + +jobs: + analyze: + name: Analyze + runs-on: ubuntu-22.04 + + strategy: + fail-fast: false + matrix: + # Override automatic language detection by changing the below list + # Supported options are ['csharp', 'cpp', 'go', 'java', 'javascript', 'python'] + language: ['cpp', 'python'] + # Learn more... + # https://docs.github.com/en/github/finding-security-vulnerabilities-and-errors-in-your-code/configuring-code-scanning#overriding-automatic-language-detection + + steps: + - name: Checkout repository + uses: actions/checkout@v3 + + - name: Install missing software on ubuntu + run: | + sudo apt-get update + sudo apt-get install libxml2-utils + + # Initializes the CodeQL tools for scanning. + - name: Initialize CodeQL + uses: github/codeql-action/init@v2 + with: + languages: ${{ matrix.language }} + # If you wish to specify custom queries, you can do so here or in a config file. + # By default, queries listed here will override any specified in a config file. + # Prefix the list here with "+" to use these queries and those in the config file. + # queries: ./path/to/local/query, your-org/your-repo/queries@main + setup-python-dependencies: false + + - run: | + make -j$(nproc) HAVE_RULES=yes cppcheck + + - name: Perform CodeQL Analysis + uses: github/codeql-action/analyze@v2 diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml new file mode 100644 index 00000000000..b07c15811cd --- /dev/null +++ b/.github/workflows/coverage.yml @@ -0,0 +1,61 @@ +# Syntax reference https://help.github.com/en/actions/reference/workflow-syntax-for-github-actions +# Environment reference https://help.github.com/en/actions/reference/virtual-environments-for-github-hosted-runners +name: Coverage + +on: [push, pull_request] + +permissions: + contents: read + +jobs: + build: + + runs-on: ubuntu-22.04 + + steps: + - uses: actions/checkout@v3 + + - name: ccache + uses: hendrikmuhs/ccache-action@v1.2 + with: + key: ${{ github.workflow }}-${{ runner.os }} + + - name: Install missing software on ubuntu + run: | + sudo apt-get update + sudo apt-get install libxml2-utils lcov + + - name: Install missing Python packages on ubuntu + run: | + python -m pip install pip --upgrade + python -m pip install lcov_cobertura + + - name: Compile instrumented + run: | + export PATH="/usr/lib/ccache:/usr/local/opt/ccache/libexec:$PATH" + make -j$(nproc) all CXXFLAGS="-g -fprofile-arcs -ftest-coverage" HAVE_RULES=yes + + - name: Run instrumented tests + run: | + ./testrunner + test/cfg/runtests.sh + + - name: Generate coverage report + run: | + gcov lib/*.cpp -o lib/ + lcov --directory ./ --capture --output-file lcov_tmp.info -b ./ + lcov --extract lcov_tmp.info "$(pwd)/*" --output-file lcov.info + genhtml lcov.info -o coverage_report --frame --legend --demangle-cpp + + - uses: actions/upload-artifact@v3 + with: + name: Coverage results + path: coverage_report + + - uses: codecov/codecov-action@v3 + with: + # token: ${{ secrets.CODECOV_TOKEN }} # not required for public repos + # file: ./coverage.xml # optional + flags: unittests # optional + name: ${{ github.repository }} # optional + fail_ci_if_error: true # optional (default = false): diff --git a/.github/workflows/format.yml b/.github/workflows/format.yml new file mode 100644 index 00000000000..ff3134b7ed5 --- /dev/null +++ b/.github/workflows/format.yml @@ -0,0 +1,40 @@ +# Syntax reference https://help.github.com/en/actions/reference/workflow-syntax-for-github-actions +# Environment reference https://help.github.com/en/actions/reference/virtual-environments-for-github-hosted-runners +name: format + +on: [push, pull_request] + +permissions: + contents: read + +jobs: + build: + + runs-on: ubuntu-22.04 + + steps: + - uses: actions/checkout@v3 + + - name: Cache uncrustify + uses: actions/cache@v3 + id: cache-uncrustify + with: + path: | + ~/uncrustify + key: ${{ runner.os }}-uncrustify + + - name: build uncrustify + if: steps.cache-uncrustify.outputs.cache-hit != 'true' + run: | + wget https://github.com/uncrustify/uncrustify/archive/refs/tags/uncrustify-0.72.0.tar.gz + tar xzvf uncrustify-0.72.0.tar.gz && cd uncrustify-uncrustify-0.72.0 + cmake -S . -B build -DCMAKE_BUILD_TYPE=Release + cmake --build build -- -j$(nproc) -s + mkdir ~/uncrustify + cd build && cp uncrustify ~/uncrustify/ + + - name: Uncrustify check + run: | + ~/uncrustify/uncrustify -c .uncrustify.cfg -l CPP --no-backup --replace */*.cpp */*.h + git diff + git diff | diff - /dev/null &> /dev/null diff --git a/.github/workflows/iwyu.yml b/.github/workflows/iwyu.yml new file mode 100644 index 00000000000..1daa54ce203 --- /dev/null +++ b/.github/workflows/iwyu.yml @@ -0,0 +1,164 @@ +# Syntax reference https://help.github.com/en/actions/reference/workflow-syntax-for-github-actions +# Environment reference https://help.github.com/en/actions/reference/virtual-environments-for-github-hosted-runners +name: include-what-you-use + +on: workflow_dispatch + +permissions: + contents: read + +jobs: + iwyu: + + strategy: + matrix: + image: ["fedora:latest"] # "debian:unstable" / "archlinux:latest" + + runs-on: ubuntu-22.04 + + container: + image: "fedora:latest" + + steps: + - uses: actions/checkout@v3 + + # TODO: the necessary packages are excessive - mostly because of Qt - use a pre-built image + - name: Install missing software on debian/ubuntu + if: contains(matrix.image, 'debian') + run: | + apt-get update + apt-get install -y cmake g++ make libpcre3-dev + apt-get install -y qtbase5-dev qttools5-dev libqt5charts5-dev + apt-get install -y wget iwyu + ln -s ../x86_64-linux-gnu/qt5 /usr/include/qt + + - name: Install missing software on archlinux + if: contains(matrix.image, 'archlinux') + run: | + set -x + pacman -Sy + pacman -S cmake make gcc qt5-base qt5-tools qt5-charts pcre wget --noconfirm + pacman-key --init + pacman-key --recv-key 3056513887B78AEB --keyserver keyserver.ubuntu.com + pacman-key --lsign-key 3056513887B78AEB + pacman -U 'https://cdn-mirror.chaotic.cx/chaotic-aur/chaotic-keyring.pkg.tar.zst' 'https://cdn-mirror.chaotic.cx/chaotic-aur/chaotic-mirrorlist.pkg.tar.zst' --noconfirm + echo "[chaotic-aur]" >> /etc/pacman.conf + echo "Include = /etc/pacman.d/chaotic-mirrorlist" >> /etc/pacman.conf + pacman -Sy + pacman -S include-what-you-use --noconfirm + ln -s iwyu-tool /usr/sbin/iwyu_tool + + # TODO: the necessary packages are excessive - mostly because of Qt - use a pre-built image + - name: Install missing software on Fedora + if: contains(matrix.image, 'fedora') + run: | + dnf install -y cmake gcc-c++ qt5-qtbase-devel qt5-linguist qt5-qttools-devel qt5-qtcharts-devel pcre-devel + dnf install -y wget iwyu + ln -s iwyu_tool.py /usr/bin/iwyu_tool + ln -s qt5 /usr/include/qt + + - name: Prepare CMake + run: | + cmake -S . -B cmake.output -G "Unix Makefiles" -DCMAKE_BUILD_TYPE=Release -DHAVE_RULES=On -DBUILD_TESTS=On -DBUILD_GUI=On -DWITH_QCHART=On -DENABLE_CHECK_INTERNAL=On -DCMAKE_GLOBAL_AUTOGEN_TARGET=On -DCMAKE_DISABLE_PRECOMPILE_HEADERS=On -DCPPCHK_GLIBCXX_DEBUG=Off -DUSE_MATCHCOMPILER=Off + + - name: Prepare CMake dependencies + run: | + # make sure the precompiled headers exist + #make -C cmake.output/cli cmake_pch.hxx.pch + #make -C cmake.output/gui cmake_pch.hxx.pch + #make -C cmake.output/lib cmake_pch.hxx.pch + #make -C cmake.output/test cmake_pch.hxx.pch + # make sure the auto-generated GUI sources exist + make -C cmake.output autogen + # make sure the auto-generated GUI dependencies exist + make -C cmake.output gui-build-deps + make -C cmake.output triage-build-ui-deps + + - name: Build Qt mappings + run: | + wget https://raw.githubusercontent.com/include-what-you-use/include-what-you-use/master/mapgen/iwyu-mapgen-qt.py + python3 iwyu-mapgen-qt.py /usr/include/qt/ > qt5.imp + + - name: iwyu_tool + run: | + PWD=$(pwd) + iwyu_tool -p cmake.output -j $(nproc) -- -w -Xiwyu --mapping_file=$PWD/qt5.imp > iwyu.log + + - uses: actions/upload-artifact@v3 + if: success() || failure() + with: + name: Compilation Database + path: ./cmake.output/compile_commands.json + + - uses: actions/upload-artifact@v3 + if: success() || failure() + with: + name: Qt Mappings + path: ./qt5.imp + + - uses: actions/upload-artifact@v3 + if: success() || failure() + with: + name: Logs (include-what-you-use) + path: ./*.log + + clang-include-cleaner: + + runs-on: ubuntu-22.04 + + env: + QT_VERSION: 5.15.2 + + steps: + - uses: actions/checkout@v3 + + - name: Install missing software + run: | + sudo apt-get update + sudo apt-get install -y cmake make + sudo apt-get install -y libpcre3-dev + sudo apt-get install -y libffi7 # work around missing dependency for Qt install step + + - name: Install clang + run: | + sudo apt-get purge --auto-remove llvm python3-lldb-14 llvm-14 + wget https://apt.llvm.org/llvm.sh + chmod +x llvm.sh + sudo ./llvm.sh 17 + sudo apt-get install -y clang-tools-17 + + - name: Install Qt ${{ env.QT_VERSION }} + uses: jurplel/install-qt-action@v3 + with: + version: ${{ env.QT_VERSION }} + modules: 'qtcharts' + cache: true + + - name: Prepare CMake + run: | + cmake -S . -B cmake.output -G "Unix Makefiles" -DCMAKE_BUILD_TYPE=Release -DHAVE_RULES=On -DBUILD_TESTS=On -DBUILD_GUI=On -DBUILD_TESTS=On -DBUILD_GUI=On -DWITH_QCHART=On -DENABLE_CHECK_INTERNAL=On -DCMAKE_GLOBAL_AUTOGEN_TARGET=On -DCMAKE_DISABLE_PRECOMPILE_HEADERS=On -DCPPCHK_GLIBCXX_DEBUG=Off -DUSE_MATCHCOMPILER=Off + env: + CC: clang-17 + CXX: clang++-17 + + - name: Prepare CMake dependencies + run: | + # make sure the precompiled headers exist + #make -C cmake.output/cli cmake_pch.hxx.pch + #make -C cmake.output/gui cmake_pch.hxx.pch + #make -C cmake.output/lib cmake_pch.hxx.pch + #make -C cmake.output/test cmake_pch.hxx.pch + # make sure the auto-generated GUI sources exist + make -C cmake.output autogen + # make sure the auto-generated GUI dependencies exist + make -C cmake.output gui-build-deps + + - name: clang-include-cleaner + run: | + # TODO: run multi-threaded + find $PWD/cli $PWD/lib $PWD/test -maxdepth 1 -name "*.cpp" | xargs -t -n 1 clang-include-cleaner-17 --print=changes --extra-arg=-w -p cmake.output > clang-include-cleaner.log 2>&1 + + - uses: actions/upload-artifact@v3 + with: + name: Logs (clang-include-cleaner) + path: ./*.log \ No newline at end of file diff --git a/.github/workflows/release-windows.yml b/.github/workflows/release-windows.yml new file mode 100644 index 00000000000..ab6836c9559 --- /dev/null +++ b/.github/workflows/release-windows.yml @@ -0,0 +1,145 @@ +# Some convenient links: +# - https://github.com/actions/virtual-environments/blob/master/images/win/Windows2019-Readme.md +# + +name: release-windows + +on: + push: + tags: + - '2.*' + schedule: + - cron: '0 0 * * *' + workflow_dispatch: + +permissions: + contents: read + +defaults: + run: + shell: cmd + +jobs: + + build: + + runs-on: windows-2022 + + env: + # see https://www.pcre.org/original/changelog.txt + PCRE_VERSION: 8.45 + QT_VERSION: 5.15.2 + + steps: + - uses: actions/checkout@v3 + + - name: Set up Visual Studio environment + uses: ilammy/msvc-dev-cmd@v1 + + - name: Cache PCRE + id: cache-pcre + uses: actions/cache@v3 + with: + path: | + externals\pcre.h + externals\pcre64.lib + key: pcre-${{ env.PCRE_VERSION }}-bin-x64-win-release-job + + - name: Download PCRE + if: steps.cache-pcre.outputs.cache-hit != 'true' + run: | + curl -fsSL https://github.com/pfultz2/pcre/archive/refs/tags/%PCRE_VERSION%.zip -o pcre-%PCRE_VERSION%.zip || exit /b !errorlevel! + + - name: Install PCRE + if: steps.cache-pcre.outputs.cache-hit != 'true' + run: | + 7z x pcre-%PCRE_VERSION%.zip || exit /b !errorlevel! + cd pcre-%PCRE_VERSION% || exit /b !errorlevel! + cmake . -G "Visual Studio 17 2022" -A x64 -DPCRE_BUILD_PCRECPP=OFF -DPCRE_BUILD_PCREGREP=OFF -DPCRE_BUILD_TESTS=OFF || exit /b !errorlevel! + msbuild -m PCRE.sln -p:Configuration=Release -p:Platform=x64 || exit /b !errorlevel! + copy pcre.h ..\externals || exit /b !errorlevel! + copy Release\pcre.lib ..\externals\pcre64.lib || exit /b !errorlevel! + + # available modules: https://github.com/miurahr/aqtinstall/blob/master/docs/getting_started.rst#installing-modules + # available tools: https://github.com/miurahr/aqtinstall/blob/master/docs/getting_started.rst#installing-tools + - name: Install Qt ${{ env.QT_VERSION }} + uses: jurplel/install-qt-action@v3 + with: + version: ${{ env.QT_VERSION }} + modules: 'qtcharts' + tools: 'tools_openssl_x64,qt.tools.openssl.win_x64' + cache: true + + - name: Create .qm + run: | + cd gui || exit /b !errorlevel! + lupdate gui.pro -no-obsolete || exit /b !errorlevel! + lrelease gui.pro -removeidentical || exit /b !errorlevel! + + - name: Matchcompiler + run: python tools\matchcompiler.py --write-dir lib || exit /b !errorlevel! + + - name: Build x64 release GUI + run: | + cd gui || exit /b !errorlevel! + qmake HAVE_QCHART=yes || exit /b !errorlevel! + nmake release || exit /b !errorlevel! + env: + CL: /MP + + - name: Deploy app + run: | + windeployqt Build\gui || exit /b !errorlevel! + del Build\gui\cppcheck-gui.ilk || exit /b !errorlevel! + del Build\gui\cppcheck-gui.pdb || exit /b !errorlevel! + + # TODO: build with boost enabled + - name: Build CLI x64 release configuration using MSBuild + run: msbuild -m cppcheck.sln -t:cli -p:Configuration=Release-PCRE -p:Platform=x64 || exit /b !errorlevel! + + - name: Compile misra.py executable + run: | + pip install -U pyinstaller || exit /b !errorlevel! + cd addons || exit /b !errorlevel! + pyinstaller --hidden-import xml --hidden-import xml.etree --hidden-import xml.etree.ElementTree misra.py || exit /b !errorlevel! + del *.spec || exit /b !errorlevel! + + - name: Collect files + run: | + move Build\gui win_installer\files || exit /b !errorlevel! + mkdir win_installer\files\addons || exit /b !errorlevel! + copy addons\*.* win_installer\files\addons || exit /b !errorlevel! + copy addons\dist\misra\*.* win_installer\files\addons || exit /b !errorlevel! + mkdir win_installer\files\cfg || exit /b !errorlevel! + copy cfg\*.cfg win_installer\files\cfg || exit /b !errorlevel! + :: "platforms" is a folder used by Qt as well so it already exists + :: mkdir win_installer\files\platforms || exit /b !errorlevel! + copy platforms\*.xml win_installer\files\platforms || exit /b !errorlevel! + copy bin\cppcheck.exe win_installer\files || exit /b !errorlevel! + copy bin\cppcheck-core.dll win_installer\files || exit /b !errorlevel! + mkdir win_installer\files\help || exit /b !errorlevel! + xcopy /s gui\help win_installer\files\help || exit /b !errorlevel! + del win_installer\files\translations\*.qm || exit /b !errorlevel! + move gui\*.qm win_installer\files\translations || exit /b !errorlevel! + :: copy libcrypto-1_1-x64.dll and libssl-1_1-x64.dll + copy %RUNNER_WORKSPACE%\Qt\Tools\OpenSSL\Win_x64\bin\lib*.dll win_installer\files || exit /b !errorlevel! + + - name: Build Installer + run: | + cd win_installer || exit /b !errorlevel! + REM Read ProductVersion + for /f "tokens=4 delims= " %%a in ('find "ProductVersion" productInfo.wxi') do set PRODUCTVER=%%a + REM Remove double quotes + set PRODUCTVER=%PRODUCTVER:"=% + echo ProductVersion="%PRODUCTVER%" || exit /b !errorlevel! + msbuild -m cppcheck.wixproj -p:Platform=x64,ProductVersion=%PRODUCTVER%.${{ github.run_number }} || exit /b !errorlevel! + + - uses: actions/upload-artifact@v3 + with: + name: installer + path: win_installer/Build/ + + - uses: actions/upload-artifact@v3 + with: + name: deploy + path: win_installer\files diff --git a/.github/workflows/scriptcheck.yml b/.github/workflows/scriptcheck.yml new file mode 100644 index 00000000000..6ef6d90ee4c --- /dev/null +++ b/.github/workflows/scriptcheck.yml @@ -0,0 +1,167 @@ +# Syntax reference https://help.github.com/en/actions/reference/workflow-syntax-for-github-actions +# Environment reference https://help.github.com/en/actions/reference/virtual-environments-for-github-hosted-runners +name: scriptcheck + +on: [push, pull_request] + +permissions: + contents: read + +jobs: + build: + + # 'ubuntu-22.04' removes Python 2.7, 3.6 and 3.6 so keep the previous LTS version + runs-on: ubuntu-20.04 + + steps: + - uses: actions/checkout@v3 + + - name: ccache + uses: hendrikmuhs/ccache-action@v1.2 + with: + key: ${{ github.workflow }}-${{ runner.os }} + + - name: Cache Cppcheck + uses: actions/cache@v3 + with: + path: cppcheck + key: ${{ runner.os }}-scriptcheck-cppcheck-${{ github.sha }} + + - name: build cppcheck + run: | + export PATH="/usr/lib/ccache:/usr/local/opt/ccache/libexec:$PATH" + make -j$(nproc) -s + strip -s ./cppcheck + + scriptcheck: + + needs: build + # 'ubuntu-22.04' removes Python 2.7, 3.5 and 3.6 so keep the previous LTS version + # 'ubutunu-20.04' no longer works on 2.7 - TODO: re-added in a different way or remove support for it? + runs-on: ubuntu-20.04 + strategy: + matrix: + python-version: [3.5, 3.6, 3.7, 3.8, 3.9, '3.10', '3.11'] + fail-fast: false + + steps: + - uses: actions/checkout@v3 + + - name: Restore Cppcheck + uses: actions/cache@v3 + with: + path: cppcheck + key: ${{ runner.os }}-scriptcheck-cppcheck-${{ github.sha }} + + - name: Set up Python ${{ matrix.python-version }} + uses: actions/setup-python@v4 + with: + python-version: ${{ matrix.python-version }} + check-latest: true + + - name: Install missing software on ubuntu + run: | + sudo apt-get update + sudo apt-get install tidy libxml2-utils + + - name: Install missing software on ubuntu (Python 2) + if: matrix.python-version == '2.7' + run: | + python -m pip install pip --upgrade + python -m pip install pathlib + python -m pip install pytest + python -m pip install pygments + + - name: Install missing software on ubuntu (Python 3) + if: matrix.python-version != '2.7' + run: | + # shellcheck cannot be installed via pip + # ERROR: Could not find a version that satisfies the requirement shellcheck (from versions: none) + # ERROR: No matching distribution found for shellcheck + sudo apt-get install shellcheck + python -m pip install pip --upgrade + python -m pip install natsort + python -m pip install pexpect + python -m pip install pylint + python -m pip install unittest2 + python -m pip install pytest + python -m pip install pygments + python -m pip install requests + python -m pip install psutil + + - name: run Shellcheck + if: matrix.python-version == '3.11' + run: | + find . -name "*.sh" | xargs shellcheck --exclude SC2002,SC2013,SC2034,SC2035,SC2043,SC2046,SC2086,SC2089,SC2090,SC2129,SC2211,SC2231 + + - name: run pylint + if: matrix.python-version == '3.11' + run: | + echo "FIXME pylint is disabled for now because it fails to import files:" + echo "FIXME addons/runaddon.py:1:0: E0401: Unable to import 'cppcheckdata' (import-error)" + echo "FIXME addons/runaddon.py:1:0: E0401: Unable to import 'cppcheck' (import-error)" + # pylint --rcfile=pylintrc_travis --jobs $(nproc) addons/*.py htmlreport/cppcheck-htmlreport htmlreport/*.py tools/*.py + + - name: check .json files + if: matrix.python-version == '3.11' + run: | + find . -name '*.json' | xargs -n 1 python -m json.tool > /dev/null + + - name: Validate + if: matrix.python-version == '3.11' + run: | + make -j$(nproc) validateCFG validatePlatforms validateRules + + - name: check python syntax + if: matrix.python-version != '2.7' + run: | + python -m py_compile addons/*.py + python -m py_compile htmlreport/cppcheck-htmlreport + python -m py_compile htmlreport/*.py + python -m py_compile tools/*.py + + - name: compile addons + run: | + python -m compileall ./addons + + - name: test matchcompiler + run: | + python tools/test_matchcompiler.py + + - name: test addons + run: | + python -m pytest -v addons/test/test-*.py + env: + PYTHONPATH: ./addons + + - name: test htmlreport + run: | + htmlreport/test_htmlreport.py + cd htmlreport + ./check.sh + + - name: test reduce + run: | + python -m pytest -v tools/test_reduce.py + env: + PYTHONPATH: ./tools + + - name: test donate_cpu_lib + if: matrix.python-version != '2.7' + run: | + python -m pytest -v tools/test_donate_cpu_lib.py + env: + PYTHONPATH: ./tools + + - name: test donate_cpu_server + if: matrix.python-version != '2.7' + run: | + python -m pytest -v tools/test_donate_cpu_server.py + env: + PYTHONPATH: ./tools + + - name: dmake + if: matrix.python-version == '3.11' + run: | + make -j$(nproc) run-dmake + git diff --exit-code diff --git a/.github/workflows/selfcheck.yml b/.github/workflows/selfcheck.yml new file mode 100644 index 00000000000..8cd028f9af9 --- /dev/null +++ b/.github/workflows/selfcheck.yml @@ -0,0 +1,128 @@ +# Syntax reference https://help.github.com/en/actions/reference/workflow-syntax-for-github-actions +# Environment reference https://help.github.com/en/actions/reference/virtual-environments-for-github-hosted-runners +name: selfcheck + +on: [push, pull_request] + +permissions: + contents: read + +jobs: + build: + + runs-on: ubuntu-22.04 + + env: + QT_VERSION: 5.15.2 + + steps: + - uses: actions/checkout@v3 + + - name: Install missing software + run: | + sudo apt-get update + sudo apt-get install libboost-container-dev + + - name: ccache + uses: hendrikmuhs/ccache-action@v1.2 + with: + key: ${{ github.workflow }}-${{ runner.os }} + + - name: Install missing software + run: | + sudo apt-get update + sudo apt-get install clang-14 valgrind + + - name: Install Qt ${{ env.QT_VERSION }} + uses: jurplel/install-qt-action@v3 + with: + version: ${{ env.QT_VERSION }} + modules: 'qtcharts' + cache: true + + # TODO: cache this - perform same build as for the other self check + - name: Self check (build) + run: | + export PATH="/usr/lib/ccache:/usr/local/opt/ccache/libexec:$PATH" + # valgrind cannot handle DWARF 5 yet so force version 4 + # work around performance regression with -inline-deferral + make -j$(nproc) -s CXXFLAGS="-O2 -w -DHAVE_BOOST -gdwarf-4 -mllvm -inline-deferral" MATCHCOMPILER=yes + env: + CC: clang-14 + CXX: clang++-14 + + - name: CMake + run: | + cmake -S . -B cmake.output -G "Unix Makefiles" -DHAVE_RULES=On -DBUILD_TESTS=On -DBUILD_GUI=ON -DWITH_QCHART=ON -DENABLE_CHECK_INTERNAL=On -DCMAKE_GLOBAL_AUTOGEN_TARGET=On + + - name: Generate dependencies + run: | + # make sure the precompiled headers exist + make -C cmake.output lib/CMakeFiles/cppcheck-core.dir/cmake_pch.hxx.cxx + make -C cmake.output test/CMakeFiles/testrunner.dir/cmake_pch.hxx.cxx + # make sure auto-generated GUI files exist + make -C cmake.output autogen + make -C cmake.output gui-build-deps + + # TODO: find a way to report unmatched suppressions without need to add information checks + - name: Self check (unusedFunction) + if: false # TODO: fails with preprocessorErrorDirective - see #10667 + run: | + ./cppcheck -q --template=selfcheck --error-exitcode=1 --library=cppcheck-lib --library=qt -D__CPPCHECK__ -D__GNUC__ -DQT_VERSION=0x050000 -DQ_MOC_OUTPUT_REVISION=67 -DQT_CHARTS_LIB --enable=unusedFunction --exception-handling -rp=. --project=cmake.output/compile_commands.json --suppressions-list=.selfcheck_unused_suppressions --inline-suppr + env: + DISABLE_VALUEFLOW: 1 + UNUSEDFUNCTION_ONLY: 1 + + # the following steps are duplicated from above since setting up the build node in a parallel step takes longer than the actual steps + - name: CMake (no test) + run: | + cmake -S . -B cmake.output.notest -G "Unix Makefiles" -DHAVE_RULES=On -DBUILD_TESTS=Off -DBUILD_GUI=ON -DWITH_QCHART=ON -DENABLE_CHECK_INTERNAL=On -DCMAKE_GLOBAL_AUTOGEN_TARGET=On + + - name: Generate dependencies (no test) + run: | + # make sure the precompiled headers exist + make -C cmake.output.notest lib/CMakeFiles/cppcheck-core.dir/cmake_pch.hxx.cxx + # make sure auto-generated GUI files exist + make -C cmake.output.notest autogen + make -C cmake.output.notest gui-build-deps + + # TODO: find a way to report unmatched suppressions without need to add information checks + - name: Self check (unusedFunction / no test) + run: | + ./cppcheck -q --template=selfcheck --error-exitcode=1 --library=cppcheck-lib --library=qt -D__CPPCHECK__ -D__GNUC__ -DQT_VERSION=0x050000 -DQ_MOC_OUTPUT_REVISION=67 -DQT_CHARTS_LIB --enable=unusedFunction --exception-handling -rp=. --project=cmake.output.notest/compile_commands.json --suppressions-list=.selfcheck_unused_suppressions --inline-suppr + env: + DISABLE_VALUEFLOW: 1 + UNUSEDFUNCTION_ONLY: 1 + + - name: Fetch corpus + run: | + wget https://github.com/danmar/cppcheck/archive/refs/tags/2.8.tar.gz + tar xvf 2.8.tar.gz + + - name: CMake (corpus / no test) + run: | + cmake -S cppcheck-2.8 -B cmake.output.corpus -G "Unix Makefiles" -DHAVE_RULES=On -DBUILD_TESTS=Off -DBUILD_GUI=ON -DWITH_QCHART=ON -DENABLE_CHECK_INTERNAL=On -DCMAKE_GLOBAL_AUTOGEN_TARGET=On + + - 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 sure auto-generated GUI files exist + make -C cmake.output.corpus autogen + make -C cmake.output.corpus gui-build-deps + + # TODO: find a way to report unmatched suppressions without need to add information checks + - name: Self check (unusedFunction / corpus / no test / callgrind) + run: | + # TODO: fix -rp so the suppressions actually work + valgrind --tool=callgrind ./cppcheck --template=selfcheck --error-exitcode=0 --library=cppcheck-lib --library=qt -D__GNUC__ -DQT_VERSION=0x050000 -DQ_MOC_OUTPUT_REVISION=67 -DQT_CHARTS_LIB --enable=unusedFunction --exception-handling -rp=. --project=cmake.output.corpus/compile_commands.json --suppressions-list=.selfcheck_unused_suppressions --inline-suppr 2>callgrind.log || (cat callgrind.log && false) + cat callgrind.log + callgrind_annotate --auto=no > callgrind.annotated.log + head -50 callgrind.annotated.log + env: + DISABLE_VALUEFLOW: 1 + + - uses: actions/upload-artifact@v3 + with: + name: Callgrind Output + path: ./callgrind.* diff --git a/.github/workflows/tsan.yml b/.github/workflows/tsan.yml new file mode 100644 index 00000000000..5a5aaa2c900 --- /dev/null +++ b/.github/workflows/tsan.yml @@ -0,0 +1,91 @@ +# Syntax reference https://help.github.com/en/actions/reference/workflow-syntax-for-github-actions +# Environment reference https://help.github.com/en/actions/reference/virtual-environments-for-github-hosted-runners +name: thread sanitizer + +on: [push, pull_request] + +permissions: + contents: read + +jobs: + build: + + runs-on: ubuntu-22.04 + + env: + QT_VERSION: 5.15.2 + TSAN_OPTIONS: halt_on_error=1 + # TODO: figure out why there are cache misses with PCH enabled + CCACHE_SLOPPINESS: pch_defines,time_macros + + steps: + - uses: actions/checkout@v3 + + - name: ccache + uses: hendrikmuhs/ccache-action@v1.2 + with: + key: ${{ github.workflow }}-${{ github.job }}-${{ matrix.os }} + + - name: Set up Python 3.11 + uses: actions/setup-python@v4 + with: + python-version: '3.11' + check-latest: true + + - name: Install missing software on ubuntu + run: | + sudo apt-get update + sudo apt-get install -y cmake make libpcre3-dev libboost-container-dev + + - name: Install clang + run: | + sudo apt-get purge --auto-remove llvm python3-lldb-14 llvm-14 + wget https://apt.llvm.org/llvm.sh + chmod +x llvm.sh + sudo ./llvm.sh 16 + + - name: Install Qt ${{ env.QT_VERSION }} + if: false + uses: jurplel/install-qt-action@v3 + with: + version: ${{ env.QT_VERSION }} + modules: 'qtcharts' + cache: true + + - name: CMake + run: | + cmake -S . -B cmake.output -DCMAKE_BUILD_TYPE=RelWithDebInfo -DHAVE_RULES=On -DBUILD_TESTS=On -DBUILD_GUI=Off -DWITH_QCHART=Off -DUSE_MATCHCOMPILER=Verify -DANALYZE_THREAD=On -DUSE_THREADS=On -DENABLE_CHECK_INTERNAL=On -DUSE_BOOST=On -DCPPCHK_GLIBCXX_DEBUG=Off -DCMAKE_DISABLE_PRECOMPILE_HEADERS=On -DCMAKE_GLOBAL_AUTOGEN_TARGET=Off -DDISABLE_DMAKE=On -DCMAKE_C_COMPILER_LAUNCHER=ccache -DCMAKE_CXX_COMPILER_LAUNCHER=ccache + env: + CC: clang-16 + CXX: clang++-16 + + - name: Build cppcheck + run: | + cmake --build cmake.output --target cppcheck -- -j $(nproc) + + - name: Build test + run: | + cmake --build cmake.output --target testrunner -- -j $(nproc) + + - name: Run tests + run: ./cmake.output/bin/testrunner + + - name: Generate dependencies + if: false + run: | + # make sure auto-generated GUI files exist + make -C cmake.output autogen + make -C cmake.output gui-build-deps triage-build-ui-deps + + # TODO: disabled for now as it takes around 40 minutes to finish + # set --error-exitcode=0 so we only fail on sanitizer issues - since it uses threads for execution it will exit the whole process on the first issue + - name: Self check + if: false + run: | + selfcheck_options="-q -j$(nproc) --std=c++11 --template=selfcheck --showtime=top5 -D__CPPCHECK__ -DCHECK_INTERNAL -DHAVE_RULES --error-exitcode=0 --inline-suppr --suppressions-list=.selfcheck_suppressions --library=cppcheck-lib -Ilib -Iexternals/simplecpp/ -Iexternals/tinyxml2/ --inconclusive --enable=style,performance,portability,warning,missingInclude,internal --exception-handling --debug-warnings" + ec=0 + ./cmake.output/bin/cppcheck $selfcheck_options --addon=naming.json -DCHECK_INTERNAL cli lib || ec=1 + ./cmake.output/bin/cppcheck $selfcheck_options -DQT_VERSION=0x050000 -DQ_MOC_OUTPUT_REVISION=67 -DQT_CHARTS_LIB --library=qt --addon=naming.json -Icmake.output/gui -Igui gui/*.cpp cmake.output/gui/*.cpp || ec=1 + ./cmake.output/bin/cppcheck $selfcheck_options -Icli test/*.cpp tools/*.cpp || ec=1 + ./cmake.output/bin/cppcheck $selfcheck_options -DQ_MOC_OUTPUT_REVISION=67 -DQT_CHARTS_LIB --library=qt -Icmake.output/tools/triage -Igui tools/triage/*.cpp cmake.output/tools/triage/*.cpp || ec=1 + exit $ec diff --git a/.github/workflows/ubsan.yml b/.github/workflows/ubsan.yml new file mode 100644 index 00000000000..ed6d4e61f6c --- /dev/null +++ b/.github/workflows/ubsan.yml @@ -0,0 +1,87 @@ +# Syntax reference https://help.github.com/en/actions/reference/workflow-syntax-for-github-actions +# Environment reference https://help.github.com/en/actions/reference/virtual-environments-for-github-hosted-runners +name: undefined behaviour sanitizers + +on: [push, pull_request] + +permissions: + contents: read + +jobs: + build: + + runs-on: ubuntu-22.04 + + env: + QT_VERSION: 5.15.2 + UBSAN_OPTIONS: print_stacktrace=1:halt_on_error=1:report_error_type=1 + # TODO: figure out why there are cache misses with PCH enabled + CCACHE_SLOPPINESS: pch_defines,time_macros + + steps: + - uses: actions/checkout@v3 + + - name: ccache + uses: hendrikmuhs/ccache-action@v1.2 + with: + key: ${{ github.workflow }}-${{ github.job }}-${{ matrix.os }} + + - name: Set up Python 3.11 + uses: actions/setup-python@v4 + with: + python-version: '3.11' + check-latest: true + + - name: Install missing software on ubuntu + run: | + sudo apt-get update + sudo apt-get install -y cmake make libpcre3-dev libboost-container-dev + + - name: Install clang + run: | + sudo apt-get purge --auto-remove llvm python3-lldb-14 llvm-14 + wget https://apt.llvm.org/llvm.sh + chmod +x llvm.sh + sudo ./llvm.sh 16 + + - name: Install Qt ${{ env.QT_VERSION }} + uses: jurplel/install-qt-action@v3 + with: + version: ${{ env.QT_VERSION }} + modules: 'qtcharts' + cache: true + + - name: CMake + run: | + cmake -S . -B cmake.output -DCMAKE_BUILD_TYPE=RelWithDebInfo -DHAVE_RULES=On -DBUILD_TESTS=On -DBUILD_GUI=ON -DWITH_QCHART=ON -DUSE_MATCHCOMPILER=Verify -DANALYZE_UNDEFINED=On -DENABLE_CHECK_INTERNAL=On -DUSE_BOOST=On -DCPPCHK_GLIBCXX_DEBUG=Off -DCMAKE_DISABLE_PRECOMPILE_HEADERS=On -DCMAKE_GLOBAL_AUTOGEN_TARGET=On -DDISABLE_DMAKE=On -DCMAKE_C_COMPILER_LAUNCHER=ccache -DCMAKE_CXX_COMPILER_LAUNCHER=ccache + env: + CC: clang-16 + CXX: clang++-16 + + - name: Build cppcheck + run: | + cmake --build cmake.output --target cppcheck -- -j $(nproc) + + - name: Build test + run: | + cmake --build cmake.output --target testrunner -- -j $(nproc) + + - name: Run tests + run: ./cmake.output/bin/testrunner + + - name: Generate dependencies + run: | + # make sure auto-generated GUI files exist + make -C cmake.output autogen + make -C cmake.output gui-build-deps triage-build-ui-deps + + # TODO: only fail the step on sanitizer issues - since we use processes it will only fail the underlying process which will result in an cppcheckError + - name: Self check + run: | + selfcheck_options="-q -j$(nproc) --std=c++11 --template=selfcheck --showtime=top5 -D__CPPCHECK__ -DCHECK_INTERNAL -DHAVE_RULES --error-exitcode=1 --inline-suppr --suppressions-list=.selfcheck_suppressions --library=cppcheck-lib -Ilib -Iexternals/simplecpp/ -Iexternals/tinyxml2/ --inconclusive --enable=style,performance,portability,warning,missingInclude,internal --exception-handling --debug-warnings" + ec=0 + ./cmake.output/bin/cppcheck $selfcheck_options --addon=naming.json cli lib || ec=1 + ./cmake.output/bin/cppcheck $selfcheck_options -DQT_VERSION=0x050000 -DQ_MOC_OUTPUT_REVISION=67 -DQT_CHARTS_LIB --library=qt --addon=naming.json -Icmake.output/gui -Igui gui/*.cpp cmake.output/gui/*.cpp || ec=1 + ./cmake.output/bin/cppcheck $selfcheck_options -Icli test/*.cpp tools/*.cpp || ec=1 + ./cmake.output/bin/cppcheck $selfcheck_options -DQ_MOC_OUTPUT_REVISION=67 -DQT_CHARTS_LIB --library=qt -Icmake.output/tools/triage -Igui tools/triage/*.cpp cmake.output/tools/triage/*.cpp || ec=1 + exit $ec diff --git a/.github/workflows/valgrind.yml b/.github/workflows/valgrind.yml new file mode 100644 index 00000000000..1753e6f0acd --- /dev/null +++ b/.github/workflows/valgrind.yml @@ -0,0 +1,54 @@ +# Syntax reference https://help.github.com/en/actions/reference/workflow-syntax-for-github-actions +# Environment reference https://help.github.com/en/actions/reference/virtual-environments-for-github-hosted-runners +name: valgrind + +on: [push, pull_request] + +permissions: + contents: read + +jobs: + build: + + runs-on: ubuntu-22.04 + + steps: + - uses: actions/checkout@v3 + + - name: ccache + uses: hendrikmuhs/ccache-action@v1.2 + with: + key: ${{ github.workflow }}-${{ runner.os }} + + - name: Install missing software + run: | + sudo apt-get update + sudo apt-get install libxml2-utils + sudo apt-get install valgrind + sudo apt-get install libboost-container-dev + sudo apt-get install debuginfod + + - name: Build cppcheck + run: | + export PATH="/usr/lib/ccache:/usr/local/opt/ccache/libexec:$PATH" + CXXFLAGS="-O1 -g -DHAVE_BOOST" make -j$(nproc) HAVE_RULES=yes MATCHCOMPILER=yes + + - name: Build test + run: | + export PATH="/usr/lib/ccache:/usr/local/opt/ccache/libexec:$PATH" + CXXFLAGS="-O1 -g -DHAVE_BOOST" make -j$(nproc) testrunner HAVE_RULES=yes MATCHCOMPILER=yes + + - name: Run valgrind + run: | + ec=0 + valgrind --error-limit=yes --leak-check=full --num-callers=50 --show-reachable=yes --track-origins=yes --suppressions=valgrind/testrunner.supp --gen-suppressions=all --log-fd=9 --error-exitcode=42 ./testrunner TestGarbage TestOther TestSimplifyTemplate 9>memcheck.log || ec=1 + cat memcheck.log + exit $ec + env: + DEBUGINFOD_URLS: https://debuginfod.ubuntu.com + + - uses: actions/upload-artifact@v3 + if: success() || failure() + with: + name: Logs + path: ./*.log diff --git a/cfg/std.cfg b/cfg/std.cfg index 8bacbc3a413..97f5ce0152e 100644 --- a/cfg/std.cfg +++ b/cfg/std.cfg @@ -3815,7 +3815,7 @@ The obsolete function 'gets' is called. With 'gets' you'll get a buffer overrun false - + @@ -3838,7 +3838,7 @@ The obsolete function 'gets' is called. With 'gets' you'll get a buffer overrun false - + @@ -4851,7 +4851,7 @@ The obsolete function 'gets' is called. With 'gets' you'll get a buffer overrun 0:255 - + @@ -8263,7 +8263,7 @@ initializer list (7) string& replace (const_iterator i1, const_iterator i2, init false - + diff --git a/test/cfg/posix.c b/test/cfg/posix.c index a8dcc811902..90e9c6389b6 100644 --- a/test/cfg/posix.c +++ b/test/cfg/posix.c @@ -1302,8 +1302,7 @@ void dl(const char* libname, const char* func) void asctime_r_test(const struct tm * tm, char * bufSizeUnknown) { struct tm tm_uninit_data; - // cppcheck-suppress constVariablePointer - struct tm * tm_uninit_pointer; + const struct tm * tm_uninit_pointer; char bufSize5[5]; char bufSize25[25]; char bufSize26[26]; @@ -1334,8 +1333,7 @@ void asctime_r_test(const struct tm * tm, char * bufSizeUnknown) void ctime_r_test(const time_t * timep, char * bufSizeUnknown) { time_t time_t_uninit_data; - // cppcheck-suppress constVariablePointer - time_t * time_t_uninit_pointer; + const time_t * time_t_uninit_pointer; char bufSize5[5]; char bufSize25[25]; char bufSize26[26]; diff --git a/test/cfg/std.c b/test/cfg/std.c index 04bf39cedad..5f5a2c5096c 100644 --- a/test/cfg/std.c +++ b/test/cfg/std.c @@ -4527,8 +4527,7 @@ void uninitvar_c16rtomb(void) void uninitvar_mbrtoc16(void) { char16_t * pc16; - // cppcheck-suppress constVariablePointer - char * pmb; + const char * pmb; size_t max; mbstate_t * ps; // cppcheck-suppress uninitvar @@ -4549,8 +4548,7 @@ void uninitvar_c32rtomb(void) void uninitvar_mbrtoc32(void) { char32_t * pc32; - // cppcheck-suppress constVariablePointer - char * pmb; + const char * pmb; size_t max; mbstate_t * ps; // cppcheck-suppress uninitvar diff --git a/test/cfg/std.cpp b/test/cfg/std.cpp index 2598b8f898e..c6a04412543 100644 --- a/test/cfg/std.cpp +++ b/test/cfg/std.cpp @@ -575,9 +575,9 @@ void nullPointer_vfwprintf(FILE *Stream, const wchar_t *Format, va_list Arg) (void)std::vfwprintf(Stream, Format, Arg); } -void *bufferAccessOutOfBounds_memchr(const void *s, int c, size_t n) +void *bufferAccessOutOfBounds_memchr(void *s, int c, size_t n) { - const char buf[42]={0}; + char buf[42]={0}; (void)std::memchr(buf,c,42); // cppcheck-suppress bufferAccessOutOfBounds (void)std::memchr(buf,c,43); @@ -1156,8 +1156,8 @@ void uninitvar_asinh(void) void uninitvar_wcsftime(wchar_t* ptr) { size_t maxsize; - wchar_t* format; - struct tm* timeptr; + const wchar_t* format; + const struct tm* timeptr; // cppcheck-suppress uninitvar (void)std::wcsftime(ptr, maxsize, format, timeptr); } @@ -1269,14 +1269,14 @@ void uninitvar_atan2(void) void uninitvar_atof(void) { - char * c; + const char * c; // cppcheck-suppress uninitvar (void)std::atof(c); } void uninitvar_atol(void) { - char * c1, *c2, *c3; + const char * c1, *c2, *c3; // cppcheck-suppress uninitvar (void)std::atoi(c1); @@ -1392,7 +1392,7 @@ void uninitvar_feclearexcept(void) void uninitvar_fesetenv(void) { - fenv_t* envp; + const fenv_t* envp; // cppcheck-suppress uninitvar (void)std::fesetenv(envp); } @@ -1413,14 +1413,14 @@ void uninitvar_fetestexcept(void) void uninitvar_feupdateenv(void) { - fenv_t* envp; + const fenv_t* envp; // cppcheck-suppress uninitvar (void)std::feupdateenv(envp); } void uninitvar_ctime(void) { - time_t *tp; + const time_t *tp; // cppcheck-suppress uninitvar (void)std::ctime(tp); } @@ -1689,8 +1689,8 @@ void uninitvar_fmod(void) void uninitar_fopen(void) { - char *filename; - char *mode; + const char *filename; + const char *mode; // cppcheck-suppress uninitvar FILE * fp = std::fopen(filename, mode); fclose(fp); @@ -1699,7 +1699,7 @@ void uninitar_fopen(void) void uninitar_fprintf(FILE *Stream, const char *Format, int Argument) { FILE *stream1, *stream2; - char *format1, *format2; + const char *format1, *format2; int argument1, argument2; // cppcheck-suppress uninitvar (void)std::fprintf(stream1, format1, argument1); @@ -1717,7 +1717,7 @@ void uninitar_fprintf(FILE *Stream, const char *Format, int Argument) void uninitar_vfprintf(FILE *Stream, const char *Format, va_list Arg) { FILE *stream1, *stream2; - char *format1, *format2; + const char *format1, *format2; va_list arg; // cppcheck-suppress va_list_usedBeforeStarted // cppcheck-suppress uninitvar @@ -1736,7 +1736,7 @@ void uninitar_vfprintf(FILE *Stream, const char *Format, va_list Arg) void uninitar_vfwprintf(FILE *Stream, const wchar_t *Format, va_list Arg) { FILE *stream1, *stream2; - wchar_t *format1, *format2; + const wchar_t *format1, *format2; va_list arg; // cppcheck-suppress va_list_usedBeforeStarted // cppcheck-suppress uninitvar @@ -1770,7 +1770,7 @@ void uninitvar_fputwc(void) void uninitvar_fputs(void) { - char *string; + const char *string; FILE *stream; // cppcheck-suppress uninitvar (void)std::fputs(string,stream); @@ -1778,7 +1778,7 @@ void uninitvar_fputs(void) void uninitvar_fputws(void) { - wchar_t *string; + const wchar_t *string; FILE *stream; // cppcheck-suppress uninitvar (void)std::fputws(string,stream); @@ -1803,8 +1803,8 @@ void uninitvar_free(void) void uninitvar_freopen(void) { - char *filename; - char *mode; + const char *filename; + const char *mode; FILE *stream; // cppcheck-suppress uninitvar FILE * p = std::freopen(filename,mode,stream); @@ -1847,7 +1847,7 @@ void uninitvar_hypot(void) void uninitvar_fscanf(void) { FILE *stream; - char *format; + const char *format; int i; // cppcheck-suppress uninitvar (void)std::fscanf(stream,format,i); @@ -1856,7 +1856,7 @@ void uninitvar_fscanf(void) void uninitvar_vfscanf(void) { FILE *stream; - char *format; + const char *format; va_list arg; // cppcheck-suppress va_list_usedBeforeStarted // cppcheck-suppress uninitvar @@ -1866,7 +1866,7 @@ void uninitvar_vfscanf(void) void uninitvar_vfwscanf(void) { FILE *stream; - wchar_t *format; + const wchar_t *format; va_list arg; // cppcheck-suppress va_list_usedBeforeStarted // cppcheck-suppress uninitvar @@ -1910,7 +1910,7 @@ void invalidFunctionArgBool_fseek(FILE* stream, long int offset, int origin) void uninitvar_fsetpos(void) { FILE* stream; - fpos_t *ptr; + const fpos_t *ptr; // cppcheck-suppress uninitvar (void)std::fsetpos(stream,ptr); } @@ -2040,7 +2040,7 @@ void uninitvar_fwide(void) void uninitvar_fwrite(void) { - void *ptr; + const void *ptr; size_t size; size_t nobj; FILE *stream; @@ -2050,7 +2050,7 @@ void uninitvar_fwrite(void) void uninitvar_mblen(void) { - char *string; + const char *string; size_t size; // cppcheck-suppress uninitvar (void)std::mblen(string,size); @@ -2059,7 +2059,7 @@ void uninitvar_mblen(void) void uninitvar_mbtowc(void) { wchar_t* pwc; - char* pmb; + const char* pmb; size_t max; // cppcheck-suppress uninitvar (void)std::mbtowc(pwc,pmb,max); @@ -2067,7 +2067,7 @@ void uninitvar_mbtowc(void) void uninitvar_mbrlen(const char* p, size_t m, mbstate_t* s) { - char* pmb1, *pmb2; + const char* pmb1, *pmb2; size_t max1, max2; mbstate_t* ps1, *ps2; // cppcheck-suppress uninitvar @@ -2100,7 +2100,7 @@ void uninitvar_btowc(void) void uninitvar_mbsinit(void) { - mbstate_t* ps; + const mbstate_t* ps; // cppcheck-suppress uninitvar (void)std::mbsinit(ps); } @@ -2108,7 +2108,7 @@ void uninitvar_mbsinit(void) void uninitvar_mbstowcs(void) { wchar_t *ws; - char *s; + const char *s; size_t n; // cppcheck-suppress uninitvar (void)std::mbstowcs(ws,s,n); @@ -2142,7 +2142,7 @@ void uninitvar_wctomb(void) void uninitvar_wcstombs(void) { char *mbstr; - wchar_t *wcstr; + const wchar_t *wcstr; size_t n; // cppcheck-suppress uninitvar (void)std::wcstombs(mbstr,wcstr,n); @@ -2180,14 +2180,14 @@ void uninitvar_ungetwc(void) void uninitvar_getenv(void) { - char *name; + const char *name; // cppcheck-suppress uninitvar (void)std::getenv(name); } void uninitvar_gmtime(void) { - time_t *tp; + const time_t *tp; // cppcheck-suppress uninitvar (void)std::gmtime(tp); } @@ -2322,14 +2322,14 @@ void uninitvar_towupper(void) void uninitvar_wctrans(void) { - char* property; + const char* property; // cppcheck-suppress uninitvar (void)std::wctrans(property); } void uninitvar_wctype(void) { - char* property; + const char* property; // cppcheck-suppress uninitvar (void)std::wctype(property); } @@ -2475,7 +2475,7 @@ void uninitvar_ldiv(void) void uninitvar_localtime(void) { - time_t *tp; + const time_t *tp; // cppcheck-suppress uninitvar (void)std::localtime(tp); } @@ -2624,7 +2624,7 @@ void uninitvar_islessgreater(void) void uninitvar_nan(void) { - char *tagp1, *tagp2, *tagp3; + const char *tagp1, *tagp2, *tagp3; // cppcheck-suppress uninitvar (void)std::nanf(tagp1); // cppcheck-suppress uninitvar @@ -3332,7 +3332,7 @@ void uninivar_wcrtomb(void) void uninivar_strchr(void) { - char *cs; + const char *cs; int c; // cppcheck-suppress uninitvar (void)std::strchr(cs,c); @@ -3340,7 +3340,7 @@ void uninivar_strchr(void) void uninivar_wcschr(void) { - wchar_t *cs; + const wchar_t *cs; wchar_t c; // cppcheck-suppress uninitvar (void)std::wcschr(cs,c); @@ -3383,7 +3383,7 @@ void uninivar_strftime(void) char *s; size_t max; const char *fmt; - struct tm *p; + const struct tm *p; // cppcheck-suppress uninitvar (void)std::strftime(s,max,fmt,p); } @@ -3413,7 +3413,7 @@ void uninivar_strncpy(void) void uninivar_strpbrk(void) { - char *cs; + const char *cs; const char *ct; // cppcheck-suppress uninitvar (void)std::strpbrk(cs,ct); @@ -3455,7 +3455,7 @@ void uninivar_wcsncat(wchar_t *Ct, const wchar_t *S, size_t N) (void)std::wcsncat(Ct,S,N); } -void uninivar_strncmp(char *Ct, const char *S, size_t N) +void uninivar_strncmp(const char *Ct, const char *S, size_t N) { const char *ct1, *ct2; const char *s1, *s2; @@ -3581,7 +3581,7 @@ void uninivar_wcspbrk(void) void uninivar_wcsncpy(void) { - const wchar_t *cs; + wchar_t *cs; const wchar_t *ct; size_t n; // cppcheck-suppress uninitvar @@ -4062,7 +4062,7 @@ void uninitvar_system(void) #ifndef __STDC_NO_THREADS__ -void nullPointer_mtx_destroy(const mtx_t *mutex ) +void nullPointer_mtx_destroy(mtx_t *mutex ) { // cppcheck-suppress nullPointer mtx_destroy(nullptr);