Remove bug hunting. This feature will be provided in Cppcheck premium.
This commit is contained in:
parent
98f84e34c6
commit
8f386e15fd
|
@ -22,18 +22,13 @@ jobs:
|
||||||
run: |
|
run: |
|
||||||
sudo apt-get update
|
sudo apt-get update
|
||||||
sudo apt-get install libxml2-utils
|
sudo apt-get install libxml2-utils
|
||||||
sudo apt-get install libz3-dev libtinyxml2-dev
|
sudo apt-get install libtinyxml2-dev
|
||||||
sudo apt-get install qtbase5-dev qttools5-dev libqt5charts5-dev qt5-default
|
sudo apt-get install qtbase5-dev qttools5-dev libqt5charts5-dev qt5-default
|
||||||
|
|
||||||
- name: Fix missing z3_version.h
|
|
||||||
if: matrix.os == 'ubuntu-18.04'
|
|
||||||
run: |
|
|
||||||
cp externals/z3_version_old.h externals/z3_version.h
|
|
||||||
|
|
||||||
- name: Install missing software on macos
|
- name: Install missing software on macos
|
||||||
if: contains(matrix.os, 'macos')
|
if: contains(matrix.os, 'macos')
|
||||||
run: |
|
run: |
|
||||||
brew install coreutils python3 z3 qt@5
|
brew install coreutils python3 qt@5
|
||||||
|
|
||||||
- name: Install missing Python packages
|
- name: Install missing Python packages
|
||||||
run: |
|
run: |
|
||||||
|
@ -45,7 +40,7 @@ jobs:
|
||||||
run: |
|
run: |
|
||||||
mkdir cmake.output.tinyxml2
|
mkdir cmake.output.tinyxml2
|
||||||
cd cmake.output.tinyxml2
|
cd cmake.output.tinyxml2
|
||||||
cmake -G "Unix Makefiles" -DUSE_Z3=On -DHAVE_RULES=On -DBUILD_TESTS=On -DBUILD_GUI=On -DWITH_QCHART=On -DUSE_BUNDLED_TINYXML2=Off ..
|
cmake -G "Unix Makefiles" -DHAVE_RULES=On -DBUILD_TESTS=On -DBUILD_GUI=On -DWITH_QCHART=On -DUSE_BUNDLED_TINYXML2=Off ..
|
||||||
cmake --build . -- -j$(nproc)
|
cmake --build . -- -j$(nproc)
|
||||||
cd ..
|
cd ..
|
||||||
|
|
||||||
|
@ -59,7 +54,7 @@ jobs:
|
||||||
run: |
|
run: |
|
||||||
mkdir cmake.output
|
mkdir cmake.output
|
||||||
cd cmake.output
|
cd cmake.output
|
||||||
cmake -G "Unix Makefiles" -DUSE_Z3=On -DHAVE_RULES=On -DBUILD_TESTS=On -DBUILD_GUI=On -DWITH_QCHART=On ..
|
cmake -G "Unix Makefiles" -DHAVE_RULES=On -DBUILD_TESTS=On -DBUILD_GUI=On -DWITH_QCHART=On ..
|
||||||
cmake --build . -- -j$(nproc)
|
cmake --build . -- -j$(nproc)
|
||||||
cd ..
|
cd ..
|
||||||
|
|
||||||
|
@ -68,7 +63,7 @@ jobs:
|
||||||
run: |
|
run: |
|
||||||
mkdir cmake.output
|
mkdir cmake.output
|
||||||
cd cmake.output
|
cd cmake.output
|
||||||
cmake -G "Unix Makefiles" -DUSE_Z3=On -DHAVE_RULES=On -DBUILD_TESTS=On -DBUILD_GUI=On -DWITH_QCHART=On -DQt5_DIR=$(brew --prefix qt@5)/lib/cmake/Qt5 ..
|
cmake -G "Unix Makefiles" -DHAVE_RULES=On -DBUILD_TESTS=On -DBUILD_GUI=On -DWITH_QCHART=On -DQt5_DIR=$(brew --prefix qt@5)/lib/cmake/Qt5 ..
|
||||||
cmake --build . -- -j$(nproc)
|
cmake --build . -- -j$(nproc)
|
||||||
cd ..
|
cd ..
|
||||||
|
|
||||||
|
@ -95,15 +90,15 @@ jobs:
|
||||||
- name: Build cppcheck
|
- name: Build cppcheck
|
||||||
run: |
|
run: |
|
||||||
make clean
|
make clean
|
||||||
make -j$(nproc) USE_Z3=yes HAVE_RULES=yes
|
make -j$(nproc) HAVE_RULES=yes
|
||||||
|
|
||||||
- name: Build test
|
- name: Build test
|
||||||
run: |
|
run: |
|
||||||
make -j$(nproc) testrunner USE_Z3=yes HAVE_RULES=yes
|
make -j$(nproc) testrunner HAVE_RULES=yes
|
||||||
|
|
||||||
- name: Run test
|
- name: Run test
|
||||||
run: |
|
run: |
|
||||||
make -j$(nproc) check USE_Z3=yes HAVE_RULES=yes
|
make -j$(nproc) check HAVE_RULES=yes
|
||||||
|
|
||||||
# the script uses sed parameters not supported by MacOS
|
# the script uses sed parameters not supported by MacOS
|
||||||
- name: Run extra tests
|
- name: Run extra tests
|
||||||
|
|
|
@ -25,8 +25,6 @@ jobs:
|
||||||
env:
|
env:
|
||||||
# see https://www.pcre.org/original/changelog.txt
|
# see https://www.pcre.org/original/changelog.txt
|
||||||
PCRE_VERSION: 8.45
|
PCRE_VERSION: 8.45
|
||||||
# see https://github.com/Z3Prover/z3/releases:
|
|
||||||
Z3_VERSION: 4.8.15
|
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v2
|
||||||
|
@ -72,25 +70,6 @@ jobs:
|
||||||
env:
|
env:
|
||||||
CL: /MP
|
CL: /MP
|
||||||
|
|
||||||
- name: Cache Z3 Library
|
|
||||||
id: cache-z3
|
|
||||||
uses: actions/cache@v2
|
|
||||||
if: matrix.arch == 'x64' || matrix.qt_ver == ''
|
|
||||||
with:
|
|
||||||
path: z3-${{ env.Z3_VERSION }}-${{ matrix.arch }}-win.zip
|
|
||||||
key: z3-${{ env.Z3_VERSION }}-${{ matrix.arch }}-win
|
|
||||||
|
|
||||||
- name: Download Z3 library
|
|
||||||
if: (matrix.arch == 'x64' || matrix.qt_ver == '') && steps.cache-z3.outputs.cache-hit != 'true'
|
|
||||||
run: |
|
|
||||||
curl -fsSL https://github.com/Z3Prover/z3/releases/download/z3-%Z3_VERSION%/z3-%Z3_VERSION%-${{ matrix.arch }}-win.zip -o z3-%Z3_VERSION%-${{ matrix.arch }}-win.zip || exit /b !errorlevel!
|
|
||||||
|
|
||||||
- name: Install Z3 library
|
|
||||||
if: matrix.arch == 'x64' || matrix.qt_ver == ''
|
|
||||||
run: |
|
|
||||||
7z x z3-%Z3_VERSION%-${{ matrix.arch }}-win.zip -oexternals -r -y || exit /b !errorlevel!
|
|
||||||
move externals\z3-%Z3_VERSION%-${{ matrix.arch }}-win externals\z3 || exit /b !errorlevel!
|
|
||||||
|
|
||||||
- name: Cache Qt ${{ matrix.qt_ver }}
|
- name: Cache Qt ${{ matrix.qt_ver }}
|
||||||
if: matrix.qt_ver != '' && matrix.arch == 'x64'
|
if: matrix.qt_ver != '' && matrix.arch == 'x64'
|
||||||
id: cache-qt
|
id: cache-qt
|
||||||
|
|
|
@ -26,11 +26,11 @@ jobs:
|
||||||
- name: Install missing software on ubuntu
|
- name: Install missing software on ubuntu
|
||||||
run: |
|
run: |
|
||||||
apt-get update
|
apt-get update
|
||||||
apt-get install -y make libz3-dev libpcre3-dev
|
apt-get install -y make libpcre3-dev
|
||||||
apt-get install -y clang-13
|
apt-get install -y clang-13
|
||||||
|
|
||||||
- name: Build
|
- name: Build
|
||||||
run: make -j$(nproc) cppcheck testrunner USE_Z3=yes HAVE_RULES=yes MATCHCOMPILER=yes VERIFY=1
|
run: make -j$(nproc) cppcheck testrunner HAVE_RULES=yes MATCHCOMPILER=yes VERIFY=1
|
||||||
env:
|
env:
|
||||||
CC: clang-13
|
CC: clang-13
|
||||||
CXX: clang++-13
|
CXX: clang++-13
|
||||||
|
@ -47,7 +47,3 @@ jobs:
|
||||||
# ./cppcheck -q -j$(nproc) --std=c++11 --template=selfcheck -D__CPPCHECK__ -DQT_VERSION=0x050000 --error-exitcode=1 --inline-suppr --suppressions-list=.travis_suppressions --library=qt -Ilib -Iexternals/simplecpp/ -Iexternals/tinyxml2/ --enable=style,performance,portability,warning,internal --exception-handling --debug-warnings gui/*.cpp
|
# ./cppcheck -q -j$(nproc) --std=c++11 --template=selfcheck -D__CPPCHECK__ -DQT_VERSION=0x050000 --error-exitcode=1 --inline-suppr --suppressions-list=.travis_suppressions --library=qt -Ilib -Iexternals/simplecpp/ -Iexternals/tinyxml2/ --enable=style,performance,portability,warning,internal --exception-handling --debug-warnings gui/*.cpp
|
||||||
# ./cppcheck -q -j$(nproc) --std=c++11 --template=selfcheck -D__CPPCHECK__ --error-exitcode=1 --inline-suppr --suppressions-list=.travis_suppressions --library=cppcheck-lib -Ilib -Iexternals/simplecpp/ -Iexternals/tinyxml2/ -Icli -Igui --inconclusive --enable=style,performance,portability,warning,internal --exception-handling --debug-warnings test/*.cpp tools
|
# ./cppcheck -q -j$(nproc) --std=c++11 --template=selfcheck -D__CPPCHECK__ --error-exitcode=1 --inline-suppr --suppressions-list=.travis_suppressions --library=cppcheck-lib -Ilib -Iexternals/simplecpp/ -Iexternals/tinyxml2/ -Icli -Igui --inconclusive --enable=style,performance,portability,warning,internal --exception-handling --debug-warnings test/*.cpp tools
|
||||||
|
|
||||||
# TODO: This does takes too long to run
|
|
||||||
# - name: Bughunting lib
|
|
||||||
# run: ./cppcheck -D__CPPCHECK__ --bug-hunting -j$(nproc) lib
|
|
||||||
|
|
||||||
|
|
|
@ -1,47 +0,0 @@
|
||||||
# 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: bughunting
|
|
||||||
|
|
||||||
# TODO: enable this when
|
|
||||||
on: workflow_dispatch
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
build:
|
|
||||||
|
|
||||||
runs-on: ubuntu-20.04
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v2
|
|
||||||
|
|
||||||
- name: Set up Python 3.10
|
|
||||||
uses: actions/setup-python@v2
|
|
||||||
with:
|
|
||||||
python-version: '3.10'
|
|
||||||
|
|
||||||
- name: Install missing software
|
|
||||||
run: |
|
|
||||||
sudo apt-get update
|
|
||||||
sudo apt-get install z3 libz3-dev
|
|
||||||
|
|
||||||
- name: Build cppcheck
|
|
||||||
run: |
|
|
||||||
make -j$(nproc) USE_Z3=yes HAVE_RULES=yes MATCHCOMPILER=yes
|
|
||||||
env:
|
|
||||||
CXXFLAGS: "-O2 -march=native"
|
|
||||||
|
|
||||||
# currently to slow to execute it in the CI
|
|
||||||
- name: Run CVE suite
|
|
||||||
run: |
|
|
||||||
python test/bug-hunting/cve.py
|
|
||||||
|
|
||||||
- name: Run ITC suite
|
|
||||||
run: |
|
|
||||||
git clone https://github.com/regehr/itc-benchmarks.git ~/itc
|
|
||||||
python test/bug-hunting/itc.py
|
|
||||||
|
|
||||||
- name: Run juliet
|
|
||||||
run: |
|
|
||||||
mkdir ~/juliet
|
|
||||||
curl https://samate.nist.gov/SARD/testsuites/juliet/Juliet_Test_Suite_v1.3_for_C_Cpp.zip -o ~/juliet/juliet.zip
|
|
||||||
cd ~/juliet && unzip -qq ~/juliet/juliet.zip
|
|
||||||
python test/bug-hunting/juliet.py
|
|
|
@ -22,7 +22,6 @@ jobs:
|
||||||
run: |
|
run: |
|
||||||
apt-get update
|
apt-get update
|
||||||
apt-get install -y cmake g++ make
|
apt-get install -y cmake g++ make
|
||||||
apt-get install -y libz3-dev
|
|
||||||
apt-get install -y libpcre3-dev
|
apt-get install -y libpcre3-dev
|
||||||
apt-get install -y libffi7 # work around missing dependency for Qt install step
|
apt-get install -y libffi7 # work around missing dependency for Qt install step
|
||||||
apt-get install -y clang-tidy-13
|
apt-get install -y clang-tidy-13
|
||||||
|
@ -46,7 +45,7 @@ jobs:
|
||||||
run: |
|
run: |
|
||||||
mkdir cmake.output
|
mkdir cmake.output
|
||||||
cd cmake.output
|
cd cmake.output
|
||||||
cmake -G "Unix Makefiles" -DUSE_Z3=On -DHAVE_RULES=On -DBUILD_TESTS=On -DBUILD_GUI=On -DWITH_QCHART=On -DCMAKE_GLOBAL_AUTOGEN_TARGET=On -DCPPCHK_GLIBCXX_DEBUG=Off ..
|
cmake -G "Unix Makefiles" -DHAVE_RULES=On -DBUILD_TESTS=On -DBUILD_GUI=On -DWITH_QCHART=On -DCMAKE_GLOBAL_AUTOGEN_TARGET=On -DCPPCHK_GLIBCXX_DEBUG=Off ..
|
||||||
cd ..
|
cd ..
|
||||||
|
|
||||||
- name: Prepare CMake dependencies
|
- name: Prepare CMake dependencies
|
||||||
|
|
|
@ -24,7 +24,6 @@ jobs:
|
||||||
run: |
|
run: |
|
||||||
sudo apt-get update
|
sudo apt-get update
|
||||||
sudo apt-get install libxml2-utils
|
sudo apt-get install libxml2-utils
|
||||||
sudo apt-get install libz3-dev libz3-4
|
|
||||||
|
|
||||||
# Initializes the CodeQL tools for scanning.
|
# Initializes the CodeQL tools for scanning.
|
||||||
- name: Initialize CodeQL
|
- name: Initialize CodeQL
|
||||||
|
@ -38,7 +37,7 @@ jobs:
|
||||||
setup-python-dependencies: false
|
setup-python-dependencies: false
|
||||||
|
|
||||||
- run: |
|
- run: |
|
||||||
make -j$(nproc) USE_Z3=yes HAVE_RULES=yes cppcheck
|
make -j$(nproc) HAVE_RULES=yes cppcheck
|
||||||
|
|
||||||
- name: Perform CodeQL Analysis
|
- name: Perform CodeQL Analysis
|
||||||
uses: github/codeql-action/analyze@v1
|
uses: github/codeql-action/analyze@v1
|
||||||
|
|
|
@ -16,7 +16,6 @@ jobs:
|
||||||
run: |
|
run: |
|
||||||
sudo apt-get update
|
sudo apt-get update
|
||||||
sudo apt-get install libxml2-utils
|
sudo apt-get install libxml2-utils
|
||||||
sudo apt-get install libz3-dev libz3-4
|
|
||||||
sudo apt-get install lcov
|
sudo apt-get install lcov
|
||||||
sudo apt-get install libcppunit-dev
|
sudo apt-get install libcppunit-dev
|
||||||
python -m pip install pip --upgrade
|
python -m pip install pip --upgrade
|
||||||
|
@ -24,7 +23,7 @@ jobs:
|
||||||
|
|
||||||
- name: Compile instrumented
|
- name: Compile instrumented
|
||||||
run: |
|
run: |
|
||||||
make -j$(nproc) test CXXFLAGS="-g -fprofile-arcs -ftest-coverage" USE_Z3=yes HAVE_RULES=yes
|
make -j$(nproc) test CXXFLAGS="-g -fprofile-arcs -ftest-coverage" HAVE_RULES=yes
|
||||||
|
|
||||||
- name: Generate coverage report
|
- name: Generate coverage report
|
||||||
run: |
|
run: |
|
||||||
|
|
|
@ -19,7 +19,7 @@ jobs:
|
||||||
- name: Install missing software
|
- name: Install missing software
|
||||||
run: |
|
run: |
|
||||||
apt-get update
|
apt-get update
|
||||||
apt-get install -y cmake g++ make libz3-dev libpcre3-dev
|
apt-get install -y cmake g++ make libpcre3-dev
|
||||||
apt-get install -y qtbase5-dev qttools5-dev libqt5charts5-dev
|
apt-get install -y qtbase5-dev qttools5-dev libqt5charts5-dev
|
||||||
apt-get install -y wget iwyu
|
apt-get install -y wget iwyu
|
||||||
|
|
||||||
|
@ -27,7 +27,7 @@ jobs:
|
||||||
run: |
|
run: |
|
||||||
mkdir cmake.output
|
mkdir cmake.output
|
||||||
cd cmake.output
|
cd cmake.output
|
||||||
cmake -G "Unix Makefiles" -DCMAKE_BUILD_TYPE=Release -DUSE_Z3=On -DHAVE_RULES=On -DBUILD_TESTS=On -DBUILD_GUI=On -DBUILD_TESTS=On -DBUILD_GUI=On -DWITH_QCHART=On -DCMAKE_GLOBAL_AUTOGEN_TARGET=On -DCMAKE_DISABLE_PRECOMPILE_HEADERS=On -DCPPCHK_GLIBCXX_DEBUG=Off -DUSE_MATCHCOMPILER=Off ..
|
cmake -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 -DCMAKE_GLOBAL_AUTOGEN_TARGET=On -DCMAKE_DISABLE_PRECOMPILE_HEADERS=On -DCPPCHK_GLIBCXX_DEBUG=Off -DUSE_MATCHCOMPILER=Off ..
|
||||||
cd ..
|
cd ..
|
||||||
|
|
||||||
- name: Prepare CMake dependencies
|
- name: Prepare CMake dependencies
|
||||||
|
|
|
@ -25,8 +25,6 @@ jobs:
|
||||||
env:
|
env:
|
||||||
# see https://www.pcre.org/original/changelog.txt
|
# see https://www.pcre.org/original/changelog.txt
|
||||||
PCRE_VERSION: 8.45
|
PCRE_VERSION: 8.45
|
||||||
# see https://github.com/Z3Prover/z3/releases:
|
|
||||||
Z3_VERSION: 4.8.15
|
|
||||||
QT_VERSION: 5.15.2
|
QT_VERSION: 5.15.2
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
|
@ -56,23 +54,6 @@ jobs:
|
||||||
copy pcre.h ..\externals
|
copy pcre.h ..\externals
|
||||||
copy Release\pcre.lib ..\externals\pcre64.lib
|
copy Release\pcre.lib ..\externals\pcre64.lib
|
||||||
|
|
||||||
- name: Cache Z3 Library
|
|
||||||
id: cache-z3
|
|
||||||
uses: actions/cache@v2
|
|
||||||
with:
|
|
||||||
path: z3-${{ env.Z3_VERSION }}-x64-win.zip
|
|
||||||
key: z3-${{ env.Z3_VERSION }}-x64-win
|
|
||||||
|
|
||||||
- name: Download Z3 library
|
|
||||||
if: steps.cache-z3.outputs.cache-hit != 'true'
|
|
||||||
run: |
|
|
||||||
curl -fsSL https://github.com/Z3Prover/z3/releases/download/z3-%Z3_VERSION%/z3-%Z3_VERSION%-x64-win.zip -o z3-%Z3_VERSION%-x64-win.zip
|
|
||||||
|
|
||||||
- name: Install Z3 library
|
|
||||||
run: |
|
|
||||||
7z x z3-%Z3_VERSION%-x64-win.zip -oexternals -r -y
|
|
||||||
move externals\z3-%Z3_VERSION%-x64-win externals\z3
|
|
||||||
|
|
||||||
- name: Cache Qt ${{ env.QT_VERSION }}
|
- name: Cache Qt ${{ env.QT_VERSION }}
|
||||||
id: cache-qt
|
id: cache-qt
|
||||||
uses: actions/cache@v1 # not v2!
|
uses: actions/cache@v1 # not v2!
|
||||||
|
@ -125,7 +106,6 @@ jobs:
|
||||||
copy platforms\*.xml win_installer\files\platforms
|
copy platforms\*.xml win_installer\files\platforms
|
||||||
copy bin\cppcheck.exe win_installer\files
|
copy bin\cppcheck.exe win_installer\files
|
||||||
copy bin\cppcheck-core.dll win_installer\files
|
copy bin\cppcheck-core.dll win_installer\files
|
||||||
copy externals\z3\bin\libz3.dll win_installer\files
|
|
||||||
mkdir win_installer\files\help
|
mkdir win_installer\files\help
|
||||||
xcopy /s gui\help win_installer\files\help
|
xcopy /s gui\help win_installer\files\help
|
||||||
del win_installer\files\translations\*.qm
|
del win_installer\files\translations\*.qm
|
||||||
|
|
|
@ -15,11 +15,6 @@ jobs:
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v2
|
||||||
|
|
||||||
- name: Install missing software
|
|
||||||
run: |
|
|
||||||
sudo apt-get update
|
|
||||||
sudo apt-get install libz3-dev
|
|
||||||
|
|
||||||
- name: Cache Qt ${{ env.QT_VERSION }}
|
- name: Cache Qt ${{ env.QT_VERSION }}
|
||||||
id: cache-qt
|
id: cache-qt
|
||||||
uses: actions/cache@v1 # not v2!
|
uses: actions/cache@v1 # not v2!
|
||||||
|
@ -44,7 +39,7 @@ jobs:
|
||||||
run: |
|
run: |
|
||||||
mkdir cmake.output
|
mkdir cmake.output
|
||||||
pushd cmake.output
|
pushd cmake.output
|
||||||
cmake -G "Unix Makefiles" -DUSE_Z3=On -DHAVE_RULES=On -DBUILD_TESTS=On -DBUILD_GUI=ON -DWITH_QCHART=ON -DCMAKE_GLOBAL_AUTOGEN_TARGET=On ..
|
cmake -G "Unix Makefiles" -DHAVE_RULES=On -DBUILD_TESTS=On -DBUILD_GUI=ON -DWITH_QCHART=ON -DCMAKE_GLOBAL_AUTOGEN_TARGET=On ..
|
||||||
|
|
||||||
- name: Generate dependencies
|
- name: Generate dependencies
|
||||||
run: |
|
run: |
|
||||||
|
@ -68,7 +63,7 @@ jobs:
|
||||||
run: |
|
run: |
|
||||||
mkdir cmake.output.notest
|
mkdir cmake.output.notest
|
||||||
pushd cmake.output.notest
|
pushd cmake.output.notest
|
||||||
cmake -G "Unix Makefiles" -DUSE_Z3=On -DHAVE_RULES=On -DBUILD_TESTS=0 -DBUILD_GUI=ON -DWITH_QCHART=ON -DCMAKE_GLOBAL_AUTOGEN_TARGET=On ..
|
cmake -G "Unix Makefiles" -DHAVE_RULES=On -DBUILD_TESTS=0 -DBUILD_GUI=ON -DWITH_QCHART=ON -DCMAKE_GLOBAL_AUTOGEN_TARGET=On ..
|
||||||
|
|
||||||
- name: Generate dependencies (no test)
|
- name: Generate dependencies (no test)
|
||||||
run: |
|
run: |
|
||||||
|
|
|
@ -26,11 +26,11 @@ jobs:
|
||||||
- name: Install missing software on ubuntu
|
- name: Install missing software on ubuntu
|
||||||
run: |
|
run: |
|
||||||
apt-get update
|
apt-get update
|
||||||
apt-get install -y make libz3-dev libpcre3-dev
|
apt-get install -y make libpcre3-dev
|
||||||
apt-get install -y clang-13
|
apt-get install -y clang-13
|
||||||
|
|
||||||
- name: Build
|
- name: Build
|
||||||
run: make -j$(nproc) cppcheck testrunner USE_Z3=yes HAVE_RULES=yes MATCHCOMPILER=yes VERIFY=1
|
run: make -j$(nproc) cppcheck testrunner HAVE_RULES=yes MATCHCOMPILER=yes VERIFY=1
|
||||||
env:
|
env:
|
||||||
CC: clang-13
|
CC: clang-13
|
||||||
CXX: clang++-13
|
CXX: clang++-13
|
||||||
|
@ -46,7 +46,3 @@ jobs:
|
||||||
./cppcheck -q -j$(nproc) --std=c++11 --template=selfcheck -D__CPPCHECK__ -DQT_VERSION=0x050000 --error-exitcode=1 --inline-suppr --suppressions-list=.travis_suppressions --library=qt -Ilib -Iexternals/simplecpp/ -Iexternals/tinyxml2/ --enable=style,performance,portability,warning,internal --exception-handling --debug-warnings gui/*.cpp
|
./cppcheck -q -j$(nproc) --std=c++11 --template=selfcheck -D__CPPCHECK__ -DQT_VERSION=0x050000 --error-exitcode=1 --inline-suppr --suppressions-list=.travis_suppressions --library=qt -Ilib -Iexternals/simplecpp/ -Iexternals/tinyxml2/ --enable=style,performance,portability,warning,internal --exception-handling --debug-warnings gui/*.cpp
|
||||||
./cppcheck -q -j$(nproc) --std=c++11 --template=selfcheck -D__CPPCHECK__ --error-exitcode=1 --inline-suppr --suppressions-list=.travis_suppressions --library=cppcheck-lib -Ilib -Iexternals/simplecpp/ -Iexternals/tinyxml2/ -Icli -Igui --inconclusive --enable=style,performance,portability,warning,internal --exception-handling --debug-warnings test/*.cpp tools
|
./cppcheck -q -j$(nproc) --std=c++11 --template=selfcheck -D__CPPCHECK__ --error-exitcode=1 --inline-suppr --suppressions-list=.travis_suppressions --library=cppcheck-lib -Ilib -Iexternals/simplecpp/ -Iexternals/tinyxml2/ -Icli -Igui --inconclusive --enable=style,performance,portability,warning,internal --exception-handling --debug-warnings test/*.cpp tools
|
||||||
|
|
||||||
# TODO: This does takes too long to run
|
|
||||||
# - name: Bughunting lib
|
|
||||||
# run: ./cppcheck -D__CPPCHECK__ --bug-hunting -j$(nproc) lib
|
|
||||||
|
|
||||||
|
|
|
@ -30,16 +30,15 @@ jobs:
|
||||||
sudo apt-get update
|
sudo apt-get update
|
||||||
sudo apt-get install libxml2-utils
|
sudo apt-get install libxml2-utils
|
||||||
sudo apt-get install valgrind
|
sudo apt-get install valgrind
|
||||||
sudo apt-get install libz3-dev libz3-4 libz3-4-dbgsym
|
|
||||||
sudo apt-get install libc6-dbg-amd64-cross
|
sudo apt-get install libc6-dbg-amd64-cross
|
||||||
|
|
||||||
- name: Build cppcheck
|
- name: Build cppcheck
|
||||||
run: |
|
run: |
|
||||||
CXXFLAGS="-O1 -g" make -j$(nproc) USE_Z3=yes HAVE_RULES=yes MATCHCOMPILER=yes
|
CXXFLAGS="-O1 -g" make -j$(nproc) HAVE_RULES=yes MATCHCOMPILER=yes
|
||||||
|
|
||||||
- name: Build test
|
- name: Build test
|
||||||
run: |
|
run: |
|
||||||
CXXFLAGS="-O1 -g" make -j$(nproc) testrunner USE_Z3=yes HAVE_RULES=yes MATCHCOMPILER=yes
|
CXXFLAGS="-O1 -g" make -j$(nproc) testrunner HAVE_RULES=yes MATCHCOMPILER=yes
|
||||||
|
|
||||||
- name: Run valgrind
|
- name: Run valgrind
|
||||||
run: |
|
run: |
|
||||||
|
|
|
@ -18,7 +18,7 @@ env:
|
||||||
before_install:
|
before_install:
|
||||||
# install needed deps
|
# install needed deps
|
||||||
- travis_retry sudo apt-get update -qq
|
- travis_retry sudo apt-get update -qq
|
||||||
- travis_retry sudo apt-get install -qq python3-pip libxml2-utils libpcre3 gdb unzip wx-common xmlstarlet python3-dev liblua5.3-dev libcurl3 libcairo2-dev libsigc++-2.0-dev tidy libopencv-dev libz3-dev
|
- travis_retry sudo apt-get install -qq python3-pip libxml2-utils libpcre3 gdb unzip wx-common xmlstarlet python3-dev liblua5.3-dev libcurl3 libcairo2-dev libsigc++-2.0-dev tidy libopencv-dev
|
||||||
# Python 2 modules
|
# Python 2 modules
|
||||||
- travis_retry python2 -m pip install --user pytest==4.6.4
|
- travis_retry python2 -m pip install --user pytest==4.6.4
|
||||||
- travis_retry python2 -m pip install --user unittest2
|
- travis_retry python2 -m pip install --user unittest2
|
||||||
|
@ -32,7 +32,6 @@ before_install:
|
||||||
- travis_retry python3 -m pip install --user requests # imported by tools/pr.py
|
- travis_retry python3 -m pip install --user requests # imported by tools/pr.py
|
||||||
- travis_retry python3 -m pip install --user pygments
|
- travis_retry python3 -m pip install --user pygments
|
||||||
- travis_retry python3 -m pip install --user natsort
|
- travis_retry python3 -m pip install --user natsort
|
||||||
- cp externals/z3_version_old.h externals/z3_version.h # because travis z3 version is old
|
|
||||||
|
|
||||||
matrix:
|
matrix:
|
||||||
# do notify immediately about it when a job of a build fails.
|
# do notify immediately about it when a job of a build fails.
|
||||||
|
|
26
Makefile
26
Makefile
|
@ -5,14 +5,6 @@ ifndef HAVE_RULES
|
||||||
HAVE_RULES=no
|
HAVE_RULES=no
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifndef USE_Z3
|
|
||||||
USE_Z3=no
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifeq ($(USE_Z3),yes)
|
|
||||||
CPPFLAGS += -DUSE_Z3
|
|
||||||
LIBS += -lz3
|
|
||||||
endif
|
|
||||||
# use match compiler
|
# use match compiler
|
||||||
ifeq ($(SRCDIR),build)
|
ifeq ($(SRCDIR),build)
|
||||||
$(warning Usage of SRCDIR to activate match compiler is deprecated. Use MATCHCOMPILER=yes instead.)
|
$(warning Usage of SRCDIR to activate match compiler is deprecated. Use MATCHCOMPILER=yes instead.)
|
||||||
|
@ -154,7 +146,6 @@ MAN_SOURCE=man/cppcheck.1.xml
|
||||||
|
|
||||||
LIBOBJ = $(libcppdir)/analyzerinfo.o \
|
LIBOBJ = $(libcppdir)/analyzerinfo.o \
|
||||||
$(libcppdir)/astutils.o \
|
$(libcppdir)/astutils.o \
|
||||||
$(libcppdir)/bughuntingchecks.o \
|
|
||||||
$(libcppdir)/check.o \
|
$(libcppdir)/check.o \
|
||||||
$(libcppdir)/check64bit.o \
|
$(libcppdir)/check64bit.o \
|
||||||
$(libcppdir)/checkassert.o \
|
$(libcppdir)/checkassert.o \
|
||||||
|
@ -187,7 +178,6 @@ LIBOBJ = $(libcppdir)/analyzerinfo.o \
|
||||||
$(libcppdir)/ctu.o \
|
$(libcppdir)/ctu.o \
|
||||||
$(libcppdir)/errorlogger.o \
|
$(libcppdir)/errorlogger.o \
|
||||||
$(libcppdir)/errortypes.o \
|
$(libcppdir)/errortypes.o \
|
||||||
$(libcppdir)/exprengine.o \
|
|
||||||
$(libcppdir)/forwardanalyzer.o \
|
$(libcppdir)/forwardanalyzer.o \
|
||||||
$(libcppdir)/importproject.o \
|
$(libcppdir)/importproject.o \
|
||||||
$(libcppdir)/infer.o \
|
$(libcppdir)/infer.o \
|
||||||
|
@ -229,7 +219,6 @@ TESTOBJ = test/options.o \
|
||||||
test/testbool.o \
|
test/testbool.o \
|
||||||
test/testboost.o \
|
test/testboost.o \
|
||||||
test/testbufferoverrun.o \
|
test/testbufferoverrun.o \
|
||||||
test/testbughuntingchecks.o \
|
|
||||||
test/testcharvar.o \
|
test/testcharvar.o \
|
||||||
test/testclangimport.o \
|
test/testclangimport.o \
|
||||||
test/testclass.o \
|
test/testclass.o \
|
||||||
|
@ -239,7 +228,6 @@ TESTOBJ = test/options.o \
|
||||||
test/testcppcheck.o \
|
test/testcppcheck.o \
|
||||||
test/testerrorlogger.o \
|
test/testerrorlogger.o \
|
||||||
test/testexceptionsafety.o \
|
test/testexceptionsafety.o \
|
||||||
test/testexprengine.o \
|
|
||||||
test/testfilelister.o \
|
test/testfilelister.o \
|
||||||
test/testfunctions.o \
|
test/testfunctions.o \
|
||||||
test/testgarbage.o \
|
test/testgarbage.o \
|
||||||
|
@ -410,9 +398,6 @@ $(libcppdir)/analyzerinfo.o: lib/analyzerinfo.cpp externals/tinyxml2/tinyxml2.h
|
||||||
$(libcppdir)/astutils.o: lib/astutils.cpp lib/astutils.h lib/check.h lib/checkclass.h lib/config.h lib/errortypes.h lib/importproject.h lib/infer.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/standards.h lib/suppressions.h lib/symboldatabase.h lib/templatesimplifier.h lib/timer.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/valueflow.h lib/valueptr.h
|
$(libcppdir)/astutils.o: lib/astutils.cpp lib/astutils.h lib/check.h lib/checkclass.h lib/config.h lib/errortypes.h lib/importproject.h lib/infer.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/standards.h lib/suppressions.h lib/symboldatabase.h lib/templatesimplifier.h lib/timer.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/valueflow.h lib/valueptr.h
|
||||||
$(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CPPFILESDIR) $(CXXFLAGS) $(UNDEF_STRICT_ANSI) -c -o $(libcppdir)/astutils.o $(libcppdir)/astutils.cpp
|
$(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CPPFILESDIR) $(CXXFLAGS) $(UNDEF_STRICT_ANSI) -c -o $(libcppdir)/astutils.o $(libcppdir)/astutils.cpp
|
||||||
|
|
||||||
$(libcppdir)/bughuntingchecks.o: lib/bughuntingchecks.cpp lib/astutils.h lib/bughuntingchecks.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/exprengine.h lib/importproject.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/standards.h lib/suppressions.h lib/symboldatabase.h lib/templatesimplifier.h lib/timer.h lib/token.h lib/utils.h lib/valueflow.h
|
|
||||||
$(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CPPFILESDIR) $(CXXFLAGS) $(UNDEF_STRICT_ANSI) -c -o $(libcppdir)/bughuntingchecks.o $(libcppdir)/bughuntingchecks.cpp
|
|
||||||
|
|
||||||
$(libcppdir)/check.o: lib/check.cpp lib/check.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/importproject.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/standards.h lib/suppressions.h lib/templatesimplifier.h lib/timer.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/valueflow.h
|
$(libcppdir)/check.o: lib/check.cpp lib/check.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/importproject.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/standards.h lib/suppressions.h lib/templatesimplifier.h lib/timer.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/valueflow.h
|
||||||
$(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CPPFILESDIR) $(CXXFLAGS) $(UNDEF_STRICT_ANSI) -c -o $(libcppdir)/check.o $(libcppdir)/check.cpp
|
$(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CPPFILESDIR) $(CXXFLAGS) $(UNDEF_STRICT_ANSI) -c -o $(libcppdir)/check.o $(libcppdir)/check.cpp
|
||||||
|
|
||||||
|
@ -497,7 +482,7 @@ $(libcppdir)/clangimport.o: lib/clangimport.cpp lib/clangimport.h lib/config.h l
|
||||||
$(libcppdir)/color.o: lib/color.cpp lib/color.h lib/config.h
|
$(libcppdir)/color.o: lib/color.cpp lib/color.h lib/config.h
|
||||||
$(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CPPFILESDIR) $(CXXFLAGS) $(UNDEF_STRICT_ANSI) -c -o $(libcppdir)/color.o $(libcppdir)/color.cpp
|
$(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CPPFILESDIR) $(CXXFLAGS) $(UNDEF_STRICT_ANSI) -c -o $(libcppdir)/color.o $(libcppdir)/color.cpp
|
||||||
|
|
||||||
$(libcppdir)/cppcheck.o: lib/cppcheck.cpp externals/picojson/picojson.h externals/simplecpp/simplecpp.h externals/tinyxml2/tinyxml2.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/exprengine.h lib/importproject.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
|
$(libcppdir)/cppcheck.o: lib/cppcheck.cpp externals/picojson/picojson.h externals/simplecpp/simplecpp.h externals/tinyxml2/tinyxml2.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/importproject.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
|
||||||
$(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CPPFILESDIR) $(CXXFLAGS) $(UNDEF_STRICT_ANSI) -c -o $(libcppdir)/cppcheck.o $(libcppdir)/cppcheck.cpp
|
$(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CPPFILESDIR) $(CXXFLAGS) $(UNDEF_STRICT_ANSI) -c -o $(libcppdir)/cppcheck.o $(libcppdir)/cppcheck.cpp
|
||||||
|
|
||||||
$(libcppdir)/ctu.o: lib/ctu.cpp externals/tinyxml2/tinyxml2.h lib/astutils.h lib/check.h lib/color.h lib/config.h lib/ctu.h lib/errorlogger.h lib/errortypes.h lib/importproject.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/standards.h lib/suppressions.h lib/symboldatabase.h lib/templatesimplifier.h lib/timer.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/valueflow.h
|
$(libcppdir)/ctu.o: lib/ctu.cpp externals/tinyxml2/tinyxml2.h lib/astutils.h lib/check.h lib/color.h lib/config.h lib/ctu.h lib/errorlogger.h lib/errortypes.h lib/importproject.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/standards.h lib/suppressions.h lib/symboldatabase.h lib/templatesimplifier.h lib/timer.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/valueflow.h
|
||||||
|
@ -509,9 +494,6 @@ $(libcppdir)/errorlogger.o: lib/errorlogger.cpp externals/tinyxml2/tinyxml2.h li
|
||||||
$(libcppdir)/errortypes.o: lib/errortypes.cpp lib/config.h lib/errortypes.h
|
$(libcppdir)/errortypes.o: lib/errortypes.cpp lib/config.h lib/errortypes.h
|
||||||
$(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CPPFILESDIR) $(CXXFLAGS) $(UNDEF_STRICT_ANSI) -c -o $(libcppdir)/errortypes.o $(libcppdir)/errortypes.cpp
|
$(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CPPFILESDIR) $(CXXFLAGS) $(UNDEF_STRICT_ANSI) -c -o $(libcppdir)/errortypes.o $(libcppdir)/errortypes.cpp
|
||||||
|
|
||||||
$(libcppdir)/exprengine.o: lib/exprengine.cpp lib/astutils.h lib/bughuntingchecks.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/exprengine.h lib/importproject.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/standards.h lib/suppressions.h lib/symboldatabase.h lib/templatesimplifier.h lib/timer.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/valueflow.h
|
|
||||||
$(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CPPFILESDIR) $(CXXFLAGS) $(UNDEF_STRICT_ANSI) -c -o $(libcppdir)/exprengine.o $(libcppdir)/exprengine.cpp
|
|
||||||
|
|
||||||
$(libcppdir)/forwardanalyzer.o: lib/forwardanalyzer.cpp lib/analyzer.h lib/astutils.h lib/config.h lib/errortypes.h lib/forwardanalyzer.h lib/importproject.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/standards.h lib/suppressions.h lib/symboldatabase.h lib/templatesimplifier.h lib/timer.h lib/token.h lib/utils.h lib/valueflow.h lib/valueptr.h
|
$(libcppdir)/forwardanalyzer.o: lib/forwardanalyzer.cpp lib/analyzer.h lib/astutils.h lib/config.h lib/errortypes.h lib/forwardanalyzer.h lib/importproject.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/standards.h lib/suppressions.h lib/symboldatabase.h lib/templatesimplifier.h lib/timer.h lib/token.h lib/utils.h lib/valueflow.h lib/valueptr.h
|
||||||
$(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CPPFILESDIR) $(CXXFLAGS) $(UNDEF_STRICT_ANSI) -c -o $(libcppdir)/forwardanalyzer.o $(libcppdir)/forwardanalyzer.cpp
|
$(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CPPFILESDIR) $(CXXFLAGS) $(UNDEF_STRICT_ANSI) -c -o $(libcppdir)/forwardanalyzer.o $(libcppdir)/forwardanalyzer.cpp
|
||||||
|
|
||||||
|
@ -620,9 +602,6 @@ test/testboost.o: test/testboost.cpp lib/check.h lib/checkboost.h lib/color.h li
|
||||||
test/testbufferoverrun.o: test/testbufferoverrun.cpp externals/simplecpp/simplecpp.h externals/tinyxml2/tinyxml2.h lib/check.h lib/checkbufferoverrun.h lib/color.h lib/config.h lib/ctu.h lib/errorlogger.h lib/errortypes.h lib/importproject.h lib/library.h lib/mathlib.h lib/platform.h lib/preprocessor.h lib/settings.h lib/standards.h lib/suppressions.h lib/symboldatabase.h lib/templatesimplifier.h lib/timer.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/valueflow.h test/testsuite.h
|
test/testbufferoverrun.o: test/testbufferoverrun.cpp externals/simplecpp/simplecpp.h externals/tinyxml2/tinyxml2.h lib/check.h lib/checkbufferoverrun.h lib/color.h lib/config.h lib/ctu.h lib/errorlogger.h lib/errortypes.h lib/importproject.h lib/library.h lib/mathlib.h lib/platform.h lib/preprocessor.h lib/settings.h lib/standards.h lib/suppressions.h lib/symboldatabase.h lib/templatesimplifier.h lib/timer.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/valueflow.h test/testsuite.h
|
||||||
$(CXX) ${INCLUDE_FOR_TEST} $(CPPFLAGS) $(CPPFILESDIR) $(CXXFLAGS) $(UNDEF_STRICT_ANSI) -c -o test/testbufferoverrun.o test/testbufferoverrun.cpp
|
$(CXX) ${INCLUDE_FOR_TEST} $(CPPFLAGS) $(CPPFILESDIR) $(CXXFLAGS) $(UNDEF_STRICT_ANSI) -c -o test/testbufferoverrun.o test/testbufferoverrun.cpp
|
||||||
|
|
||||||
test/testbughuntingchecks.o: test/testbughuntingchecks.cpp lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/exprengine.h lib/importproject.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/standards.h lib/suppressions.h lib/templatesimplifier.h lib/timer.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/valueflow.h test/testsuite.h
|
|
||||||
$(CXX) ${INCLUDE_FOR_TEST} $(CPPFLAGS) $(CPPFILESDIR) $(CXXFLAGS) $(UNDEF_STRICT_ANSI) -c -o test/testbughuntingchecks.o test/testbughuntingchecks.cpp
|
|
||||||
|
|
||||||
test/testcharvar.o: test/testcharvar.cpp lib/check.h lib/checkother.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/importproject.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/standards.h lib/suppressions.h lib/templatesimplifier.h lib/timer.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/valueflow.h test/testsuite.h
|
test/testcharvar.o: test/testcharvar.cpp lib/check.h lib/checkother.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/importproject.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/standards.h lib/suppressions.h lib/templatesimplifier.h lib/timer.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/valueflow.h test/testsuite.h
|
||||||
$(CXX) ${INCLUDE_FOR_TEST} $(CPPFLAGS) $(CPPFILESDIR) $(CXXFLAGS) $(UNDEF_STRICT_ANSI) -c -o test/testcharvar.o test/testcharvar.cpp
|
$(CXX) ${INCLUDE_FOR_TEST} $(CPPFLAGS) $(CPPFILESDIR) $(CXXFLAGS) $(UNDEF_STRICT_ANSI) -c -o test/testcharvar.o test/testcharvar.cpp
|
||||||
|
|
||||||
|
@ -650,9 +629,6 @@ test/testerrorlogger.o: test/testerrorlogger.cpp externals/tinyxml2/tinyxml2.h l
|
||||||
test/testexceptionsafety.o: test/testexceptionsafety.cpp lib/check.h lib/checkexceptionsafety.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/importproject.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/standards.h lib/suppressions.h lib/templatesimplifier.h lib/timer.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/valueflow.h test/testsuite.h
|
test/testexceptionsafety.o: test/testexceptionsafety.cpp lib/check.h lib/checkexceptionsafety.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/importproject.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/standards.h lib/suppressions.h lib/templatesimplifier.h lib/timer.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/valueflow.h test/testsuite.h
|
||||||
$(CXX) ${INCLUDE_FOR_TEST} $(CPPFLAGS) $(CPPFILESDIR) $(CXXFLAGS) $(UNDEF_STRICT_ANSI) -c -o test/testexceptionsafety.o test/testexceptionsafety.cpp
|
$(CXX) ${INCLUDE_FOR_TEST} $(CPPFLAGS) $(CPPFILESDIR) $(CXXFLAGS) $(UNDEF_STRICT_ANSI) -c -o test/testexceptionsafety.o test/testexceptionsafety.cpp
|
||||||
|
|
||||||
test/testexprengine.o: test/testexprengine.cpp lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/exprengine.h lib/importproject.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/standards.h lib/suppressions.h lib/templatesimplifier.h lib/timer.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/valueflow.h test/testsuite.h
|
|
||||||
$(CXX) ${INCLUDE_FOR_TEST} $(CPPFLAGS) $(CPPFILESDIR) $(CXXFLAGS) $(UNDEF_STRICT_ANSI) -c -o test/testexprengine.o test/testexprengine.cpp
|
|
||||||
|
|
||||||
test/testfilelister.o: test/testfilelister.cpp cli/filelister.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/pathmatch.h lib/suppressions.h test/testsuite.h
|
test/testfilelister.o: test/testfilelister.cpp cli/filelister.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/pathmatch.h lib/suppressions.h test/testsuite.h
|
||||||
$(CXX) ${INCLUDE_FOR_TEST} $(CPPFLAGS) $(CPPFILESDIR) $(CXXFLAGS) $(UNDEF_STRICT_ANSI) -c -o test/testfilelister.o test/testfilelister.cpp
|
$(CXX) ${INCLUDE_FOR_TEST} $(CPPFLAGS) $(CPPFILESDIR) $(CXXFLAGS) $(UNDEF_STRICT_ANSI) -c -o test/testfilelister.o test/testfilelister.cpp
|
||||||
|
|
||||||
|
|
|
@ -29,9 +29,6 @@ target_include_directories(cppcheck PRIVATE ${PROJECT_SOURCE_DIR}/externals/simp
|
||||||
if (HAVE_RULES)
|
if (HAVE_RULES)
|
||||||
target_link_libraries(cppcheck ${PCRE_LIBRARY})
|
target_link_libraries(cppcheck ${PCRE_LIBRARY})
|
||||||
endif()
|
endif()
|
||||||
if (USE_Z3)
|
|
||||||
target_link_libraries(cppcheck ${Z3_LIBRARIES})
|
|
||||||
endif()
|
|
||||||
if (WIN32 AND NOT BORLAND)
|
if (WIN32 AND NOT BORLAND)
|
||||||
if(NOT MINGW)
|
if(NOT MINGW)
|
||||||
target_link_libraries(cppcheck Shlwapi.lib)
|
target_link_libraries(cppcheck Shlwapi.lib)
|
||||||
|
|
|
@ -229,13 +229,6 @@ bool CmdLineParser::parseFromArgs(int argc, const char* const argv[])
|
||||||
else if (std::strncmp(argv[i],"--addon-python=", 15) == 0)
|
else if (std::strncmp(argv[i],"--addon-python=", 15) == 0)
|
||||||
mSettings->addonPython.assign(argv[i]+15);
|
mSettings->addonPython.assign(argv[i]+15);
|
||||||
|
|
||||||
else if (std::strcmp(argv[i], "--bug-hunting") == 0)
|
|
||||||
mSettings->bugHunting = true;
|
|
||||||
|
|
||||||
// TODO: Rename or move this parameter?
|
|
||||||
else if (std::strncmp(argv[i], "--bug-hunting-check-function-max-time=", 38) == 0)
|
|
||||||
mSettings->bugHuntingCheckFunctionMaxTime = std::atoi(argv[i] + 38);
|
|
||||||
|
|
||||||
// Check configuration
|
// Check configuration
|
||||||
else if (std::strcmp(argv[i], "--check-config") == 0)
|
else if (std::strcmp(argv[i], "--check-config") == 0)
|
||||||
mSettings->checkConfiguration = true;
|
mSettings->checkConfiguration = true;
|
||||||
|
@ -278,10 +271,6 @@ bool CmdLineParser::parseFromArgs(int argc, const char* const argv[])
|
||||||
std::strcmp(argv[i], "--debug-normal") == 0)
|
std::strcmp(argv[i], "--debug-normal") == 0)
|
||||||
mSettings->debugnormal = true;
|
mSettings->debugnormal = true;
|
||||||
|
|
||||||
// show bug hunting debug output
|
|
||||||
else if (std::strcmp(argv[i], "--debug-bug-hunting") == 0)
|
|
||||||
mSettings->debugBugHunting = true;
|
|
||||||
|
|
||||||
// Flag used for various purposes during debugging
|
// Flag used for various purposes during debugging
|
||||||
else if (std::strcmp(argv[i], "--debug-simplified") == 0)
|
else if (std::strcmp(argv[i], "--debug-simplified") == 0)
|
||||||
mSettings->debugSimplified = true;
|
mSettings->debugSimplified = true;
|
||||||
|
@ -1289,6 +1278,5 @@ void CmdLineParser::printHelp()
|
||||||
" * tinyxml2 -- loading project/library/ctu files.\n"
|
" * tinyxml2 -- loading project/library/ctu files.\n"
|
||||||
" * picojson -- loading compile database.\n"
|
" * picojson -- loading compile database.\n"
|
||||||
" * pcre -- rules.\n"
|
" * pcre -- rules.\n"
|
||||||
" * qt -- used in GUI\n"
|
" * qt -- used in GUI\n";
|
||||||
" * z3 -- theorem prover from Microsoft Research used in bug hunting.\n";
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -92,13 +92,12 @@
|
||||||
/*static*/ FILE* CppCheckExecutor::mExceptionOutput = stdout;
|
/*static*/ FILE* CppCheckExecutor::mExceptionOutput = stdout;
|
||||||
|
|
||||||
CppCheckExecutor::CppCheckExecutor()
|
CppCheckExecutor::CppCheckExecutor()
|
||||||
: mSettings(nullptr), mLatestProgressOutputTime(0), mErrorOutput(nullptr), mBugHuntingReport(nullptr), mShowAllErrors(false)
|
: mSettings(nullptr), mLatestProgressOutputTime(0), mErrorOutput(nullptr), mShowAllErrors(false)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
CppCheckExecutor::~CppCheckExecutor()
|
CppCheckExecutor::~CppCheckExecutor()
|
||||||
{
|
{
|
||||||
delete mErrorOutput;
|
delete mErrorOutput;
|
||||||
delete mBugHuntingReport;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CppCheckExecutor::parseFromArgs(CppCheck *cppcheck, int argc, const char* const argv[])
|
bool CppCheckExecutor::parseFromArgs(CppCheck *cppcheck, int argc, const char* const argv[])
|
||||||
|
@ -1121,15 +1120,6 @@ void CppCheckExecutor::reportErr(const ErrorMessage &msg)
|
||||||
reportErr(msg.toString(mSettings->verbose, mSettings->templateFormat, mSettings->templateLocation));
|
reportErr(msg.toString(mSettings->verbose, mSettings->templateFormat, mSettings->templateLocation));
|
||||||
}
|
}
|
||||||
|
|
||||||
void CppCheckExecutor::bughuntingReport(const std::string &str)
|
|
||||||
{
|
|
||||||
if (!mSettings || str.empty())
|
|
||||||
return;
|
|
||||||
if (!mBugHuntingReport)
|
|
||||||
mBugHuntingReport = new std::ofstream(mSettings->bugHuntingReport);
|
|
||||||
(*mBugHuntingReport) << str << std::endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
void CppCheckExecutor::setExceptionOutput(FILE* exceptionOutput)
|
void CppCheckExecutor::setExceptionOutput(FILE* exceptionOutput)
|
||||||
{
|
{
|
||||||
mExceptionOutput = exceptionOutput;
|
mExceptionOutput = exceptionOutput;
|
||||||
|
|
|
@ -86,8 +86,6 @@ public:
|
||||||
*/
|
*/
|
||||||
void reportInfo(const ErrorMessage &msg) override;
|
void reportInfo(const ErrorMessage &msg) override;
|
||||||
|
|
||||||
void bughuntingReport(const std::string &str) override;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Information about how many files have been checked
|
* Information about how many files have been checked
|
||||||
*
|
*
|
||||||
|
@ -195,11 +193,6 @@ private:
|
||||||
*/
|
*/
|
||||||
std::ofstream *mErrorOutput;
|
std::ofstream *mErrorOutput;
|
||||||
|
|
||||||
/**
|
|
||||||
* Bug hunting report
|
|
||||||
*/
|
|
||||||
std::ostream *mBugHuntingReport;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Has --errorlist been given?
|
* Has --errorlist been given?
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -91,10 +91,6 @@ public:
|
||||||
report(msg, MessageType::REPORT_INFO);
|
report(msg, MessageType::REPORT_INFO);
|
||||||
}
|
}
|
||||||
|
|
||||||
void bughuntingReport(const std::string &str) override {
|
|
||||||
writeToPipe(REPORT_VERIFICATION, str);
|
|
||||||
}
|
|
||||||
|
|
||||||
void writeEnd(const std::string& str) {
|
void writeEnd(const std::string& str) {
|
||||||
writeToPipe(CHILD_END, str);
|
writeToPipe(CHILD_END, str);
|
||||||
}
|
}
|
||||||
|
@ -425,12 +421,6 @@ public:
|
||||||
report(msg, MessageType::REPORT_INFO);
|
report(msg, MessageType::REPORT_INFO);
|
||||||
}
|
}
|
||||||
|
|
||||||
void bughuntingReport(const std::string &str) override
|
|
||||||
{
|
|
||||||
std::lock_guard<std::mutex> lg(mReportSync);
|
|
||||||
mThreadExecutor.mErrorLogger.bughuntingReport(str);
|
|
||||||
}
|
|
||||||
|
|
||||||
ThreadExecutor &mThreadExecutor;
|
ThreadExecutor &mThreadExecutor;
|
||||||
|
|
||||||
std::map<std::string, std::size_t>::const_iterator mItNextFile;
|
std::map<std::string, std::size_t>::const_iterator mItNextFile;
|
||||||
|
|
|
@ -19,10 +19,6 @@ if (HAVE_RULES)
|
||||||
add_definitions(-DHAVE_RULES -DTIXML_USE_STL)
|
add_definitions(-DHAVE_RULES -DTIXML_USE_STL)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if (USE_Z3)
|
|
||||||
add_definitions(-DUSE_Z3)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if (Boost_FOUND)
|
if (Boost_FOUND)
|
||||||
add_definitions(-DHAVE_BOOST)
|
add_definitions(-DHAVE_BOOST)
|
||||||
endif()
|
endif()
|
||||||
|
|
|
@ -17,20 +17,6 @@ if (HAVE_RULES)
|
||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if (USE_Z3)
|
|
||||||
find_package(Z3 QUIET)
|
|
||||||
if (NOT Z3_FOUND)
|
|
||||||
find_library(Z3_LIBRARIES z3)
|
|
||||||
if (NOT Z3_LIBRARIES)
|
|
||||||
message(FATAL_ERROR "z3 dependency has not been found")
|
|
||||||
endif()
|
|
||||||
find_path(Z3_CXX_INCLUDE_DIRS z3++.h PATH_SUFFIXES "z3")
|
|
||||||
if (NOT Z3_CXX_INCLUDE_DIRS)
|
|
||||||
message(FATAL_ERROR "z3++.h has not been found")
|
|
||||||
endif()
|
|
||||||
endif()
|
|
||||||
endif()
|
|
||||||
|
|
||||||
set(CMAKE_INCLUDE_CURRENT_DIR ON)
|
set(CMAKE_INCLUDE_CURRENT_DIR ON)
|
||||||
|
|
||||||
if (NOT USE_MATCHCOMPILER_OPT MATCHES "Off")
|
if (NOT USE_MATCHCOMPILER_OPT MATCHES "Off")
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
#------------------------------------------------------
|
|
||||||
# Build type
|
# Build type
|
||||||
#------------------------------------------------------
|
#------------------------------------------------------
|
||||||
set(CMAKE_CONFIGURATION_TYPES "Debug;Release;RelWithDebInfo;MinSizeRel" CACHE STRING "Configs" FORCE)
|
set(CMAKE_CONFIGURATION_TYPES "Debug;Release;RelWithDebInfo;MinSizeRel" CACHE STRING "Configs" FORCE)
|
||||||
|
@ -40,7 +39,6 @@ option(BUILD_GUI "Build the qt application"
|
||||||
option(WITH_QCHART "When building GUI(need BUILD_GUI=ON), use Qt5 Charts" OFF)
|
option(WITH_QCHART "When building GUI(need BUILD_GUI=ON), use Qt5 Charts" OFF)
|
||||||
|
|
||||||
option(HAVE_RULES "Usage of rules (needs PCRE library and headers)" OFF)
|
option(HAVE_RULES "Usage of rules (needs PCRE library and headers)" OFF)
|
||||||
option(USE_Z3 "Usage of z3 library" OFF)
|
|
||||||
option(USE_BUNDLED_TINYXML2 "Usage of bundled tinyxml2 library" ON)
|
option(USE_BUNDLED_TINYXML2 "Usage of bundled tinyxml2 library" ON)
|
||||||
option(CPPCHK_GLIBCXX_DEBUG "Usage of _GLIBCXX_DEBUG in Debug build" ON)
|
option(CPPCHK_GLIBCXX_DEBUG "Usage of _GLIBCXX_DEBUG in Debug build" ON)
|
||||||
option(USE_THREADS "Usage of threads instead of fork() for -j" OFF)
|
option(USE_THREADS "Usage of threads instead of fork() for -j" OFF)
|
||||||
|
|
|
@ -58,12 +58,6 @@ if (NOT USE_MATCHCOMPILER_OPT MATCHES "Off")
|
||||||
message( STATUS "PYTHON_EXECUTABLE = ${PYTHON_EXECUTABLE}" )
|
message( STATUS "PYTHON_EXECUTABLE = ${PYTHON_EXECUTABLE}" )
|
||||||
endif()
|
endif()
|
||||||
message( STATUS )
|
message( STATUS )
|
||||||
message( STATUS "USE_Z3 = ${USE_Z3}" )
|
|
||||||
if (USE_Z3)
|
|
||||||
message( STATUS "Z3_LIBRARIES = ${Z3_LIBRARIES}" )
|
|
||||||
message( STATUS "Z3_CXX_INCLUDE_DIRS = ${Z3_CXX_INCLUDE_DIRS}" )
|
|
||||||
endif()
|
|
||||||
message( STATUS )
|
|
||||||
message( STATUS "USE_BUNDLED_TINYXML2 = ${USE_BUNDLED_TINYXML2}" )
|
message( STATUS "USE_BUNDLED_TINYXML2 = ${USE_BUNDLED_TINYXML2}" )
|
||||||
if (NOT USE_BUNDLED_TINYXML2)
|
if (NOT USE_BUNDLED_TINYXML2)
|
||||||
message(STATUS "tinyxml2_LIBRARIES = ${tinyxml2_LIBRARIES}")
|
message(STATUS "tinyxml2_LIBRARIES = ${tinyxml2_LIBRARIES}")
|
||||||
|
|
|
@ -13,9 +13,6 @@
|
||||||
# make clean && make CXXFLAGS=-O2 MATCHCOMPILER=yes -j4
|
# make clean && make CXXFLAGS=-O2 MATCHCOMPILER=yes -j4
|
||||||
# ./cppcheck -D__CPPCHECK__ --std=c++11 --library=cppcheck-lib --enable=style --inconclusive --inline-suppr --suppress=bitwiseOnBoolean --suppress=shadowFunction --suppress=useStlAlgorithm --suppress=*:externals/picojson.h --suppress=functionConst --suppress=functionStatic --xml cli gui/*.cpp lib 2> selfcheck.xml
|
# ./cppcheck -D__CPPCHECK__ --std=c++11 --library=cppcheck-lib --enable=style --inconclusive --inline-suppr --suppress=bitwiseOnBoolean --suppress=shadowFunction --suppress=useStlAlgorithm --suppress=*:externals/picojson.h --suppress=functionConst --suppress=functionStatic --xml cli gui/*.cpp lib 2> selfcheck.xml
|
||||||
#
|
#
|
||||||
# check --bug-hunting output:
|
|
||||||
# make clean && make -j4 USE_Z3=yes CXXFLAGS=-O2 MATCHCOMPILER=yes && ./cppcheck -D__CPPCHECK__ --bug-hunting --xml lib 2> bughunting.xml
|
|
||||||
#
|
|
||||||
# Update translations
|
# Update translations
|
||||||
# lupdate gui.pro
|
# lupdate gui.pro
|
||||||
#
|
#
|
||||||
|
@ -131,7 +128,7 @@ cp -R ~/cppcheck/cfg .
|
||||||
cp -R ~/cppcheck/addons .
|
cp -R ~/cppcheck/addons .
|
||||||
cp -R ~/cppcheck/platforms .
|
cp -R ~/cppcheck/platforms .
|
||||||
cd ~/cppcheck
|
cd ~/cppcheck
|
||||||
make clean ; make -j4 FILESDIR=~/.cppcheck/$tag MATCHCOMPILER=yes USE_Z3=yes
|
make clean ; make -j4 FILESDIR=~/.cppcheck/$tag MATCHCOMPILER=yes
|
||||||
mv cppcheck ~/.cppcheck/cppcheck-$tag
|
mv cppcheck ~/.cppcheck/cppcheck-$tag
|
||||||
|
|
||||||
git checkout main
|
git checkout main
|
||||||
|
|
|
@ -44,8 +44,6 @@ public:
|
||||||
cppcheck.check("test.cpp", code);
|
cppcheck.check("test.cpp", code);
|
||||||
}
|
}
|
||||||
|
|
||||||
void bughuntingReport(const std::string&) override {}
|
|
||||||
|
|
||||||
void reportOut(const std::string &outmsg, Color c) override {}
|
void reportOut(const std::string &outmsg, Color c) override {}
|
||||||
void reportErr(const ErrorMessage &msg) override {
|
void reportErr(const ErrorMessage &msg) override {
|
||||||
const std::string s = msg.toString(true);
|
const std::string s = msg.toString(true);
|
||||||
|
|
|
@ -1,10 +0,0 @@
|
||||||
Z3
|
|
||||||
Copyright (c) Microsoft Corporation
|
|
||||||
All rights reserved.
|
|
||||||
MIT License
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
|
@ -1,12 +0,0 @@
|
||||||
#ifndef Z3_MAJOR_VERSION
|
|
||||||
#define Z3_MAJOR_VERSION 0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef Z3_MINOR_VERSION
|
|
||||||
#define Z3_MINOR_VERSION 0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef Z3_BUILD_NUMBER
|
|
||||||
#define Z3_BUILD_NUMBER 0
|
|
||||||
#endif
|
|
||||||
|
|
|
@ -32,9 +32,6 @@ if (BUILD_GUI)
|
||||||
if (HAVE_RULES)
|
if (HAVE_RULES)
|
||||||
target_link_libraries(cppcheck-gui ${PCRE_LIBRARY})
|
target_link_libraries(cppcheck-gui ${PCRE_LIBRARY})
|
||||||
endif()
|
endif()
|
||||||
if (USE_Z3)
|
|
||||||
target_link_libraries(cppcheck-gui ${Z3_LIBRARIES})
|
|
||||||
endif()
|
|
||||||
if(tinyxml2_FOUND AND NOT USE_BUNDLED_TINYXML2)
|
if(tinyxml2_FOUND AND NOT USE_BUNDLED_TINYXML2)
|
||||||
target_link_libraries(cppcheck-gui ${tinyxml2_LIBRARIES})
|
target_link_libraries(cppcheck-gui ${tinyxml2_LIBRARIES})
|
||||||
endif()
|
endif()
|
||||||
|
|
|
@ -112,13 +112,7 @@ of the GNU General Public License version 3</string>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QLabel" name="mUsedLibs">
|
<widget class="QLabel" name="mUsedLibs">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string><html><head/><body>
|
<string><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></string>
|
||||||
<p>Many thanks to these libraries that we use:</p><ul>
|
|
||||||
<li>pcre</li>
|
|
||||||
<li>picojson</li>
|
|
||||||
<li>qt</li>
|
|
||||||
<li>tinyxml2</li>
|
|
||||||
<li>z3</li></ul></body></html></string>
|
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
|
|
@ -1,50 +0,0 @@
|
||||||
/*
|
|
||||||
* Cppcheck - A tool for static C/C++ code analysis
|
|
||||||
* Copyright (C) 2007-2022 Cppcheck team.
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "functioncontractdialog.h"
|
|
||||||
|
|
||||||
#include "ui_functioncontractdialog.h"
|
|
||||||
|
|
||||||
static QString formatFunctionName(QString f)
|
|
||||||
{
|
|
||||||
if (f.endsWith("()"))
|
|
||||||
return f;
|
|
||||||
f.replace("(", "(\n ");
|
|
||||||
f.replace(",", ",\n ");
|
|
||||||
return f;
|
|
||||||
}
|
|
||||||
|
|
||||||
FunctionContractDialog::FunctionContractDialog(QWidget *parent, const QString &name, const QString &expects) :
|
|
||||||
QDialog(parent),
|
|
||||||
mUi(new Ui::FunctionContractDialog)
|
|
||||||
{
|
|
||||||
mUi->setupUi(this);
|
|
||||||
mUi->functionName->setText(formatFunctionName(name));
|
|
||||||
mUi->expects->setPlainText(expects);
|
|
||||||
}
|
|
||||||
|
|
||||||
FunctionContractDialog::~FunctionContractDialog()
|
|
||||||
{
|
|
||||||
delete mUi;
|
|
||||||
}
|
|
||||||
|
|
||||||
QString FunctionContractDialog::getExpects() const
|
|
||||||
{
|
|
||||||
return mUi->expects->toPlainText();
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,39 +0,0 @@
|
||||||
/*
|
|
||||||
* Cppcheck - A tool for static C/C++ code analysis
|
|
||||||
* Copyright (C) 2007-2022 Cppcheck team.
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef FUNCTIONCONTRACTDIALOG_H
|
|
||||||
#define FUNCTIONCONTRACTDIALOG_H
|
|
||||||
|
|
||||||
#include <QDialog>
|
|
||||||
|
|
||||||
namespace Ui {
|
|
||||||
class FunctionContractDialog;
|
|
||||||
}
|
|
||||||
|
|
||||||
class FunctionContractDialog : public QDialog {
|
|
||||||
Q_OBJECT
|
|
||||||
|
|
||||||
public:
|
|
||||||
explicit FunctionContractDialog(QWidget *parent, const QString &name, const QString &expects);
|
|
||||||
~FunctionContractDialog() override;
|
|
||||||
QString getExpects() const;
|
|
||||||
private:
|
|
||||||
Ui::FunctionContractDialog *mUi;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // FUNCTIONCONTRACTDIALOG_H
|
|
|
@ -1,83 +0,0 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<ui version="4.0">
|
|
||||||
<class>FunctionContractDialog</class>
|
|
||||||
<widget class="QDialog" name="FunctionContractDialog">
|
|
||||||
<property name="geometry">
|
|
||||||
<rect>
|
|
||||||
<x>0</x>
|
|
||||||
<y>0</y>
|
|
||||||
<width>640</width>
|
|
||||||
<height>401</height>
|
|
||||||
</rect>
|
|
||||||
</property>
|
|
||||||
<property name="windowTitle">
|
|
||||||
<string>Function contract</string>
|
|
||||||
</property>
|
|
||||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
|
||||||
<item>
|
|
||||||
<widget class="QLabel" name="functionName">
|
|
||||||
<property name="text">
|
|
||||||
<string>Name</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QGroupBox" name="groupBox">
|
|
||||||
<property name="title">
|
|
||||||
<string>Requirements for parameters</string>
|
|
||||||
</property>
|
|
||||||
<layout class="QVBoxLayout" name="verticalLayout">
|
|
||||||
<item>
|
|
||||||
<widget class="QPlainTextEdit" name="expects"/>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QDialogButtonBox" name="buttonBox">
|
|
||||||
<property name="orientation">
|
|
||||||
<enum>Qt::Horizontal</enum>
|
|
||||||
</property>
|
|
||||||
<property name="standardButtons">
|
|
||||||
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</widget>
|
|
||||||
<resources/>
|
|
||||||
<connections>
|
|
||||||
<connection>
|
|
||||||
<sender>buttonBox</sender>
|
|
||||||
<signal>accepted()</signal>
|
|
||||||
<receiver>FunctionContractDialog</receiver>
|
|
||||||
<slot>accept()</slot>
|
|
||||||
<hints>
|
|
||||||
<hint type="sourcelabel">
|
|
||||||
<x>248</x>
|
|
||||||
<y>254</y>
|
|
||||||
</hint>
|
|
||||||
<hint type="destinationlabel">
|
|
||||||
<x>157</x>
|
|
||||||
<y>274</y>
|
|
||||||
</hint>
|
|
||||||
</hints>
|
|
||||||
</connection>
|
|
||||||
<connection>
|
|
||||||
<sender>buttonBox</sender>
|
|
||||||
<signal>rejected()</signal>
|
|
||||||
<receiver>FunctionContractDialog</receiver>
|
|
||||||
<slot>reject()</slot>
|
|
||||||
<hints>
|
|
||||||
<hint type="sourcelabel">
|
|
||||||
<x>316</x>
|
|
||||||
<y>260</y>
|
|
||||||
</hint>
|
|
||||||
<hint type="destinationlabel">
|
|
||||||
<x>286</x>
|
|
||||||
<y>274</y>
|
|
||||||
</hint>
|
|
||||||
</hints>
|
|
||||||
</connection>
|
|
||||||
</connections>
|
|
||||||
</ui>
|
|
21
gui/gui.pro
21
gui/gui.pro
|
@ -6,8 +6,7 @@ CONFIG += warn_on debug
|
||||||
DEPENDPATH += . \
|
DEPENDPATH += . \
|
||||||
../lib
|
../lib
|
||||||
INCLUDEPATH += . \
|
INCLUDEPATH += . \
|
||||||
../lib \
|
../lib
|
||||||
../externals/z3/include
|
|
||||||
QT += widgets
|
QT += widgets
|
||||||
QT += printsupport
|
QT += printsupport
|
||||||
QT += help
|
QT += help
|
||||||
|
@ -27,15 +26,7 @@ contains(LINKCORE, [yY][eE][sS]) {
|
||||||
LIBS += -l../bin/cppcheck-core
|
LIBS += -l../bin/cppcheck-core
|
||||||
DEFINES += CPPCHECKLIB_IMPORT
|
DEFINES += CPPCHECKLIB_IMPORT
|
||||||
}
|
}
|
||||||
LIBS += -L$$PWD/../externals -L$$PWD/../externals/z3/bin
|
LIBS += -L$$PWD/../externals
|
||||||
|
|
||||||
# z3
|
|
||||||
win32 {
|
|
||||||
LIBS += -llibz3
|
|
||||||
} else {
|
|
||||||
LIBS += -lz3
|
|
||||||
}
|
|
||||||
QMAKE_CXXFLAGS += -DUSE_Z3
|
|
||||||
|
|
||||||
DESTDIR = .
|
DESTDIR = .
|
||||||
RCC_DIR = temp
|
RCC_DIR = temp
|
||||||
|
@ -72,7 +63,6 @@ RESOURCES = gui.qrc
|
||||||
FORMS = about.ui \
|
FORMS = about.ui \
|
||||||
applicationdialog.ui \
|
applicationdialog.ui \
|
||||||
fileview.ui \
|
fileview.ui \
|
||||||
functioncontractdialog.ui \
|
|
||||||
helpdialog.ui \
|
helpdialog.ui \
|
||||||
mainwindow.ui \
|
mainwindow.ui \
|
||||||
projectfile.ui \
|
projectfile.ui \
|
||||||
|
@ -83,8 +73,7 @@ FORMS = about.ui \
|
||||||
librarydialog.ui \
|
librarydialog.ui \
|
||||||
libraryaddfunctiondialog.ui \
|
libraryaddfunctiondialog.ui \
|
||||||
libraryeditargdialog.ui \
|
libraryeditargdialog.ui \
|
||||||
newsuppressiondialog.ui \
|
newsuppressiondialog.ui
|
||||||
variablecontractsdialog.ui
|
|
||||||
|
|
||||||
TRANSLATIONS = cppcheck_de.ts \
|
TRANSLATIONS = cppcheck_de.ts \
|
||||||
cppcheck_es.ts \
|
cppcheck_es.ts \
|
||||||
|
@ -136,7 +125,6 @@ HEADERS += aboutdialog.h \
|
||||||
erroritem.h \
|
erroritem.h \
|
||||||
filelist.h \
|
filelist.h \
|
||||||
fileviewdialog.h \
|
fileviewdialog.h \
|
||||||
functioncontractdialog.h \
|
|
||||||
helpdialog.h \
|
helpdialog.h \
|
||||||
mainwindow.h \
|
mainwindow.h \
|
||||||
platforms.h \
|
platforms.h \
|
||||||
|
@ -154,7 +142,6 @@ HEADERS += aboutdialog.h \
|
||||||
threadresult.h \
|
threadresult.h \
|
||||||
translationhandler.h \
|
translationhandler.h \
|
||||||
txtreport.h \
|
txtreport.h \
|
||||||
variablecontractsdialog.h \
|
|
||||||
xmlreport.h \
|
xmlreport.h \
|
||||||
xmlreportv2.h \
|
xmlreportv2.h \
|
||||||
librarydialog.h \
|
librarydialog.h \
|
||||||
|
@ -178,7 +165,6 @@ SOURCES += aboutdialog.cpp \
|
||||||
erroritem.cpp \
|
erroritem.cpp \
|
||||||
filelist.cpp \
|
filelist.cpp \
|
||||||
fileviewdialog.cpp \
|
fileviewdialog.cpp \
|
||||||
functioncontractdialog.cpp \
|
|
||||||
helpdialog.cpp \
|
helpdialog.cpp \
|
||||||
main.cpp \
|
main.cpp \
|
||||||
mainwindow.cpp\
|
mainwindow.cpp\
|
||||||
|
@ -197,7 +183,6 @@ SOURCES += aboutdialog.cpp \
|
||||||
threadresult.cpp \
|
threadresult.cpp \
|
||||||
translationhandler.cpp \
|
translationhandler.cpp \
|
||||||
txtreport.cpp \
|
txtreport.cpp \
|
||||||
variablecontractsdialog.cpp \
|
|
||||||
xmlreport.cpp \
|
xmlreport.cpp \
|
||||||
xmlreportv2.cpp \
|
xmlreportv2.cpp \
|
||||||
librarydialog.cpp \
|
librarydialog.cpp \
|
||||||
|
|
|
@ -24,7 +24,6 @@
|
||||||
#include "cppcheck.h"
|
#include "cppcheck.h"
|
||||||
#include "filelist.h"
|
#include "filelist.h"
|
||||||
#include "fileviewdialog.h"
|
#include "fileviewdialog.h"
|
||||||
#include "functioncontractdialog.h"
|
|
||||||
#include "helpdialog.h"
|
#include "helpdialog.h"
|
||||||
#include "librarydialog.h"
|
#include "librarydialog.h"
|
||||||
#include "projectfile.h"
|
#include "projectfile.h"
|
||||||
|
@ -37,7 +36,6 @@
|
||||||
#include "threadhandler.h"
|
#include "threadhandler.h"
|
||||||
#include "threadresult.h"
|
#include "threadresult.h"
|
||||||
#include "translationhandler.h"
|
#include "translationhandler.h"
|
||||||
#include "variablecontractsdialog.h"
|
|
||||||
|
|
||||||
#include "ui_mainwindow.h"
|
#include "ui_mainwindow.h"
|
||||||
|
|
||||||
|
@ -143,15 +141,10 @@ MainWindow::MainWindow(TranslationHandler* th, QSettings* settings) :
|
||||||
connect(mThread, &ThreadHandler::done, this, &MainWindow::analysisDone);
|
connect(mThread, &ThreadHandler::done, this, &MainWindow::analysisDone);
|
||||||
connect(mThread, &ThreadHandler::log, mUI->mResults, &ResultsView::log);
|
connect(mThread, &ThreadHandler::log, mUI->mResults, &ResultsView::log);
|
||||||
connect(mThread, &ThreadHandler::debugError, mUI->mResults, &ResultsView::debugError);
|
connect(mThread, &ThreadHandler::debugError, mUI->mResults, &ResultsView::debugError);
|
||||||
connect(mThread, &ThreadHandler::bughuntingReportLine, mUI->mResults, &ResultsView::bughuntingReportLine);
|
|
||||||
connect(mUI->mResults, &ResultsView::gotResults, this, &MainWindow::resultsAdded);
|
connect(mUI->mResults, &ResultsView::gotResults, this, &MainWindow::resultsAdded);
|
||||||
connect(mUI->mResults, &ResultsView::resultsHidden, mUI->mActionShowHidden, &QAction::setEnabled);
|
connect(mUI->mResults, &ResultsView::resultsHidden, mUI->mActionShowHidden, &QAction::setEnabled);
|
||||||
connect(mUI->mResults, &ResultsView::checkSelected, this, &MainWindow::performSelectedFilesCheck);
|
connect(mUI->mResults, &ResultsView::checkSelected, this, &MainWindow::performSelectedFilesCheck);
|
||||||
connect(mUI->mResults, &ResultsView::suppressIds, this, &MainWindow::suppressIds);
|
connect(mUI->mResults, &ResultsView::suppressIds, this, &MainWindow::suppressIds);
|
||||||
connect(mUI->mResults, &ResultsView::editFunctionContract, this, &MainWindow::editFunctionContract);
|
|
||||||
connect(mUI->mResults, &ResultsView::editVariableContract, this, &MainWindow::editVariableContract);
|
|
||||||
connect(mUI->mResults, &ResultsView::deleteFunctionContract, this, &MainWindow::deleteFunctionContract);
|
|
||||||
connect(mUI->mResults, &ResultsView::deleteVariableContract, this, &MainWindow::deleteVariableContract);
|
|
||||||
connect(mUI->mMenuView, &QMenu::aboutToShow, this, &MainWindow::aboutToShowViewMenu);
|
connect(mUI->mMenuView, &QMenu::aboutToShow, this, &MainWindow::aboutToShowViewMenu);
|
||||||
|
|
||||||
// File menu
|
// File menu
|
||||||
|
@ -356,9 +349,6 @@ void MainWindow::loadSettings()
|
||||||
QDir::setCurrent(inf.absolutePath());
|
QDir::setCurrent(inf.absolutePath());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
updateFunctionContractsTab();
|
|
||||||
updateVariableContractsTab();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::saveSettings() const
|
void MainWindow::saveSettings() const
|
||||||
|
@ -620,33 +610,6 @@ QStringList MainWindow::selectFilesToAnalyze(QFileDialog::FileMode mode)
|
||||||
return selected;
|
return selected;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::updateFunctionContractsTab()
|
|
||||||
{
|
|
||||||
QStringList addedContracts;
|
|
||||||
if (mProjectFile) {
|
|
||||||
for (const auto& it: mProjectFile->getFunctionContracts()) {
|
|
||||||
addedContracts << QString::fromStdString(it.first);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
mUI->mResults->setAddedFunctionContracts(addedContracts);
|
|
||||||
}
|
|
||||||
|
|
||||||
void MainWindow::updateVariableContractsTab()
|
|
||||||
{
|
|
||||||
QStringList added;
|
|
||||||
if (mProjectFile) {
|
|
||||||
for (const auto &vc: mProjectFile->getVariableContracts()) {
|
|
||||||
QString line = vc.first;
|
|
||||||
if (!vc.second.minValue.empty())
|
|
||||||
line += " min:" + QString::fromStdString(vc.second.minValue);
|
|
||||||
if (!vc.second.maxValue.empty())
|
|
||||||
line += " max:" + QString::fromStdString(vc.second.maxValue);
|
|
||||||
added << line;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
mUI->mResults->setAddedVariableContracts(added);
|
|
||||||
}
|
|
||||||
|
|
||||||
void MainWindow::analyzeFiles()
|
void MainWindow::analyzeFiles()
|
||||||
{
|
{
|
||||||
Settings::terminate(false);
|
Settings::terminate(false);
|
||||||
|
@ -881,13 +844,6 @@ Settings MainWindow::getCppcheckSettings()
|
||||||
}
|
}
|
||||||
|
|
||||||
result.clang = mProjectFile->clangParser;
|
result.clang = mProjectFile->clangParser;
|
||||||
result.bugHunting = mProjectFile->bugHunting;
|
|
||||||
result.bugHuntingReport = " ";
|
|
||||||
|
|
||||||
result.functionContracts = mProjectFile->getFunctionContracts();
|
|
||||||
|
|
||||||
for (const auto& vc: mProjectFile->getVariableContracts())
|
|
||||||
result.variableContracts[vc.first.toStdString()] = vc.second;
|
|
||||||
|
|
||||||
const QStringList undefines = mProjectFile->getUndefines();
|
const QStringList undefines = mProjectFile->getUndefines();
|
||||||
for (const QString& undefine : undefines)
|
for (const QString& undefine : undefines)
|
||||||
|
@ -1557,9 +1513,6 @@ void MainWindow::loadProjectFile(const QString &filePath)
|
||||||
delete mProjectFile;
|
delete mProjectFile;
|
||||||
mProjectFile = new ProjectFile(filePath, this);
|
mProjectFile = new ProjectFile(filePath, this);
|
||||||
mProjectFile->setActiveProject();
|
mProjectFile->setActiveProject();
|
||||||
mUI->mResults->showContracts(mProjectFile->bugHunting);
|
|
||||||
updateFunctionContractsTab();
|
|
||||||
updateVariableContractsTab();
|
|
||||||
if (!loadLastResults())
|
if (!loadLastResults())
|
||||||
analyzeProject(mProjectFile);
|
analyzeProject(mProjectFile);
|
||||||
}
|
}
|
||||||
|
@ -1693,14 +1646,10 @@ void MainWindow::newProjectFile()
|
||||||
ProjectFileDialog dlg(mProjectFile, this);
|
ProjectFileDialog dlg(mProjectFile, this);
|
||||||
if (dlg.exec() == QDialog::Accepted) {
|
if (dlg.exec() == QDialog::Accepted) {
|
||||||
addProjectMRU(filepath);
|
addProjectMRU(filepath);
|
||||||
mUI->mResults->showContracts(mProjectFile->bugHunting);
|
|
||||||
analyzeProject(mProjectFile);
|
analyzeProject(mProjectFile);
|
||||||
} else {
|
} else {
|
||||||
closeProjectFile();
|
closeProjectFile();
|
||||||
}
|
}
|
||||||
|
|
||||||
updateFunctionContractsTab();
|
|
||||||
updateVariableContractsTab();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::closeProjectFile()
|
void MainWindow::closeProjectFile()
|
||||||
|
@ -1708,8 +1657,6 @@ void MainWindow::closeProjectFile()
|
||||||
delete mProjectFile;
|
delete mProjectFile;
|
||||||
mProjectFile = nullptr;
|
mProjectFile = nullptr;
|
||||||
mUI->mResults->clear(true);
|
mUI->mResults->clear(true);
|
||||||
mUI->mResults->clearContracts();
|
|
||||||
mUI->mResults->showContracts(false);
|
|
||||||
enableProjectActions(false);
|
enableProjectActions(false);
|
||||||
enableProjectOpenActions(true);
|
enableProjectOpenActions(true);
|
||||||
formatAndSetTitle();
|
formatAndSetTitle();
|
||||||
|
@ -1730,7 +1677,6 @@ void MainWindow::editProjectFile()
|
||||||
ProjectFileDialog dlg(mProjectFile, this);
|
ProjectFileDialog dlg(mProjectFile, this);
|
||||||
if (dlg.exec() == QDialog::Accepted) {
|
if (dlg.exec() == QDialog::Accepted) {
|
||||||
mProjectFile->write();
|
mProjectFile->write();
|
||||||
mUI->mResults->showContracts(mProjectFile->bugHunting);
|
|
||||||
analyzeProject(mProjectFile);
|
analyzeProject(mProjectFile);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1897,55 +1843,3 @@ void MainWindow::suppressIds(QStringList ids)
|
||||||
mProjectFile->setSuppressions(suppressions);
|
mProjectFile->setSuppressions(suppressions);
|
||||||
mProjectFile->write();
|
mProjectFile->write();
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::editFunctionContract(QString function)
|
|
||||||
{
|
|
||||||
if (!mProjectFile)
|
|
||||||
return;
|
|
||||||
|
|
||||||
QString expects;
|
|
||||||
const auto it = mProjectFile->getFunctionContracts().find(function.toStdString());
|
|
||||||
if (it != mProjectFile->getFunctionContracts().end())
|
|
||||||
expects = QString::fromStdString(it->second);
|
|
||||||
|
|
||||||
FunctionContractDialog dlg(nullptr,
|
|
||||||
function,
|
|
||||||
expects);
|
|
||||||
|
|
||||||
if (dlg.exec() == QDialog::Accepted) {
|
|
||||||
mProjectFile->setFunctionContract(function, dlg.getExpects());
|
|
||||||
mProjectFile->write();
|
|
||||||
}
|
|
||||||
|
|
||||||
updateFunctionContractsTab();
|
|
||||||
}
|
|
||||||
|
|
||||||
void MainWindow::editVariableContract(QString var)
|
|
||||||
{
|
|
||||||
if (!mProjectFile)
|
|
||||||
return;
|
|
||||||
|
|
||||||
VariableContractsDialog dlg(nullptr, var);
|
|
||||||
if (dlg.exec() == QDialog::Accepted) {
|
|
||||||
mProjectFile->setVariableContracts(dlg.getVarname(), dlg.getMin(), dlg.getMax());
|
|
||||||
mProjectFile->write();
|
|
||||||
}
|
|
||||||
|
|
||||||
updateVariableContractsTab();
|
|
||||||
}
|
|
||||||
|
|
||||||
void MainWindow::deleteFunctionContract(const QString& function)
|
|
||||||
{
|
|
||||||
if (mProjectFile) {
|
|
||||||
mProjectFile->deleteFunctionContract(function);
|
|
||||||
mProjectFile->write();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void MainWindow::deleteVariableContract(const QString& var)
|
|
||||||
{
|
|
||||||
if (mProjectFile) {
|
|
||||||
mProjectFile->deleteVariableContract(var);
|
|
||||||
mProjectFile->write();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -38,7 +38,7 @@ class QTimer;
|
||||||
class QLineEdit;
|
class QLineEdit;
|
||||||
namespace Ui {
|
namespace Ui {
|
||||||
class MainWindow;
|
class MainWindow;
|
||||||
};
|
}
|
||||||
|
|
||||||
/// @addtogroup GUI
|
/// @addtogroup GUI
|
||||||
/// @{
|
/// @{
|
||||||
|
@ -75,13 +75,6 @@ public:
|
||||||
void analyzeCode(const QString& code, const QString& filename);
|
void analyzeCode(const QString& code, const QString& filename);
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
|
|
||||||
/** Update "Functions" tab */
|
|
||||||
void updateFunctionContractsTab();
|
|
||||||
|
|
||||||
/** Update "Variables" tab */
|
|
||||||
void updateVariableContractsTab();
|
|
||||||
|
|
||||||
/** @brief Slot for analyze files menu item */
|
/** @brief Slot for analyze files menu item */
|
||||||
void analyzeFiles();
|
void analyzeFiles();
|
||||||
|
|
||||||
|
@ -231,18 +224,6 @@ protected slots:
|
||||||
/** Suppress error ids */
|
/** Suppress error ids */
|
||||||
void suppressIds(QStringList ids);
|
void suppressIds(QStringList ids);
|
||||||
|
|
||||||
/** Edit contract for function */
|
|
||||||
void editFunctionContract(QString function);
|
|
||||||
|
|
||||||
/** Edit constraints for variable */
|
|
||||||
void editVariableContract(QString var);
|
|
||||||
|
|
||||||
/** Delete contract for function */
|
|
||||||
void deleteFunctionContract(const QString& function);
|
|
||||||
|
|
||||||
/** Edit constraints for variable */
|
|
||||||
void deleteVariableContract(const QString& var);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
/** Get filename for last results */
|
/** Get filename for last results */
|
||||||
|
|
|
@ -37,7 +37,6 @@ NewSuppressionDialog::NewSuppressionDialog(QWidget *parent) :
|
||||||
void reportErr(const ErrorMessage &msg) override {
|
void reportErr(const ErrorMessage &msg) override {
|
||||||
errorIds << QString::fromStdString(msg.id);
|
errorIds << QString::fromStdString(msg.id);
|
||||||
}
|
}
|
||||||
void bughuntingReport(const std::string & /*str*/) override {}
|
|
||||||
QStringList errorIds;
|
QStringList errorIds;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -46,7 +46,6 @@ void ProjectFile::clear()
|
||||||
{
|
{
|
||||||
const Settings settings;
|
const Settings settings;
|
||||||
clangParser = false;
|
clangParser = false;
|
||||||
bugHunting = false;
|
|
||||||
mRootPath.clear();
|
mRootPath.clear();
|
||||||
mBuildDir.clear();
|
mBuildDir.clear();
|
||||||
mImportProject.clear();
|
mImportProject.clear();
|
||||||
|
@ -56,8 +55,6 @@ void ProjectFile::clear()
|
||||||
mUndefines.clear();
|
mUndefines.clear();
|
||||||
mPaths.clear();
|
mPaths.clear();
|
||||||
mExcludedPaths.clear();
|
mExcludedPaths.clear();
|
||||||
mFunctionContracts.clear();
|
|
||||||
mVariableContracts.clear();
|
|
||||||
mLibraries.clear();
|
mLibraries.clear();
|
||||||
mPlatform.clear();
|
mPlatform.clear();
|
||||||
mSuppressions.clear();
|
mSuppressions.clear();
|
||||||
|
@ -121,9 +118,6 @@ bool ProjectFile::read(const QString &filename)
|
||||||
if (xmlReader.name() == QString(CppcheckXml::Parser))
|
if (xmlReader.name() == QString(CppcheckXml::Parser))
|
||||||
clangParser = true;
|
clangParser = true;
|
||||||
|
|
||||||
if (xmlReader.name() == QString(CppcheckXml::BugHunting))
|
|
||||||
bugHunting = true;
|
|
||||||
|
|
||||||
if (xmlReader.name() == QString(CppcheckXml::CheckHeadersElementName))
|
if (xmlReader.name() == QString(CppcheckXml::CheckHeadersElementName))
|
||||||
mCheckHeaders = readBool(xmlReader);
|
mCheckHeaders = readBool(xmlReader);
|
||||||
|
|
||||||
|
@ -151,14 +145,6 @@ bool ProjectFile::read(const QString &filename)
|
||||||
if (xmlReader.name() == QString(CppcheckXml::IgnoreElementName))
|
if (xmlReader.name() == QString(CppcheckXml::IgnoreElementName))
|
||||||
readExcludes(xmlReader);
|
readExcludes(xmlReader);
|
||||||
|
|
||||||
// Function contracts
|
|
||||||
if (xmlReader.name() == QString(CppcheckXml::FunctionContracts))
|
|
||||||
readFunctionContracts(xmlReader);
|
|
||||||
|
|
||||||
// Variable constraints
|
|
||||||
if (xmlReader.name() == QString(CppcheckXml::VariableContractsElementName))
|
|
||||||
readVariableContracts(xmlReader);
|
|
||||||
|
|
||||||
// Find libraries list from inside project element
|
// Find libraries list from inside project element
|
||||||
if (xmlReader.name() == QString(CppcheckXml::LibrariesElementName))
|
if (xmlReader.name() == QString(CppcheckXml::LibrariesElementName))
|
||||||
readStringList(mLibraries, xmlReader, CppcheckXml::LibraryElementName);
|
readStringList(mLibraries, xmlReader, CppcheckXml::LibraryElementName);
|
||||||
|
@ -501,79 +487,6 @@ void ProjectFile::readExcludes(QXmlStreamReader &reader)
|
||||||
} while (!allRead);
|
} while (!allRead);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ProjectFile::readFunctionContracts(QXmlStreamReader &reader)
|
|
||||||
{
|
|
||||||
QXmlStreamReader::TokenType type;
|
|
||||||
bool allRead = false;
|
|
||||||
do {
|
|
||||||
type = reader.readNext();
|
|
||||||
switch (type) {
|
|
||||||
case QXmlStreamReader::StartElement:
|
|
||||||
if (reader.name().toString() == CppcheckXml::FunctionContract) {
|
|
||||||
QXmlStreamAttributes attribs = reader.attributes();
|
|
||||||
QString function = attribs.value(QString(), CppcheckXml::ContractFunction).toString();
|
|
||||||
QString expects = attribs.value(QString(), CppcheckXml::ContractExpects).toString();
|
|
||||||
if (!function.isEmpty() && !expects.isEmpty())
|
|
||||||
mFunctionContracts[function.toStdString()] = expects.toStdString();
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case QXmlStreamReader::EndElement:
|
|
||||||
if (reader.name().toString() == CppcheckXml::FunctionContracts)
|
|
||||||
allRead = true;
|
|
||||||
break;
|
|
||||||
|
|
||||||
// Not handled
|
|
||||||
case QXmlStreamReader::NoToken:
|
|
||||||
case QXmlStreamReader::Invalid:
|
|
||||||
case QXmlStreamReader::StartDocument:
|
|
||||||
case QXmlStreamReader::EndDocument:
|
|
||||||
case QXmlStreamReader::Characters:
|
|
||||||
case QXmlStreamReader::Comment:
|
|
||||||
case QXmlStreamReader::DTD:
|
|
||||||
case QXmlStreamReader::EntityReference:
|
|
||||||
case QXmlStreamReader::ProcessingInstruction:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
} while (!allRead);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ProjectFile::readVariableContracts(QXmlStreamReader &reader)
|
|
||||||
{
|
|
||||||
QXmlStreamReader::TokenType type;
|
|
||||||
while (true) {
|
|
||||||
type = reader.readNext();
|
|
||||||
switch (type) {
|
|
||||||
case QXmlStreamReader::StartElement:
|
|
||||||
if (reader.name().toString() == CppcheckXml::VariableContractItemElementName) {
|
|
||||||
QXmlStreamAttributes attribs = reader.attributes();
|
|
||||||
QString varname = attribs.value(QString(), CppcheckXml::VariableContractVarName).toString();
|
|
||||||
QString minValue = attribs.value(QString(), CppcheckXml::VariableContractMin).toString();
|
|
||||||
QString maxValue = attribs.value(QString(), CppcheckXml::VariableContractMax).toString();
|
|
||||||
setVariableContracts(varname, minValue, maxValue);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case QXmlStreamReader::EndElement:
|
|
||||||
if (reader.name().toString() == CppcheckXml::VariableContractsElementName)
|
|
||||||
return;
|
|
||||||
break;
|
|
||||||
|
|
||||||
// Not handled
|
|
||||||
case QXmlStreamReader::NoToken:
|
|
||||||
case QXmlStreamReader::Invalid:
|
|
||||||
case QXmlStreamReader::StartDocument:
|
|
||||||
case QXmlStreamReader::EndDocument:
|
|
||||||
case QXmlStreamReader::Characters:
|
|
||||||
case QXmlStreamReader::Comment:
|
|
||||||
case QXmlStreamReader::DTD:
|
|
||||||
case QXmlStreamReader::EntityReference:
|
|
||||||
case QXmlStreamReader::ProcessingInstruction:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ProjectFile::readVsConfigurations(QXmlStreamReader &reader)
|
void ProjectFile::readVsConfigurations(QXmlStreamReader &reader)
|
||||||
{
|
{
|
||||||
QXmlStreamReader::TokenType type;
|
QXmlStreamReader::TokenType type;
|
||||||
|
@ -788,11 +701,6 @@ void ProjectFile::setLibraries(const QStringList &libraries)
|
||||||
mLibraries = libraries;
|
mLibraries = libraries;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ProjectFile::setFunctionContract(const QString& function, const QString& expects)
|
|
||||||
{
|
|
||||||
mFunctionContracts[function.toStdString()] = expects.toStdString();
|
|
||||||
}
|
|
||||||
|
|
||||||
void ProjectFile::setPlatform(const QString &platform)
|
void ProjectFile::setPlatform(const QString &platform)
|
||||||
{
|
{
|
||||||
mPlatform = platform;
|
mPlatform = platform;
|
||||||
|
@ -881,11 +789,6 @@ bool ProjectFile::write(const QString &filename)
|
||||||
xmlWriter.writeEndElement();
|
xmlWriter.writeEndElement();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bugHunting) {
|
|
||||||
xmlWriter.writeStartElement(CppcheckXml::BugHunting);
|
|
||||||
xmlWriter.writeEndElement();
|
|
||||||
}
|
|
||||||
|
|
||||||
xmlWriter.writeStartElement(CppcheckXml::CheckHeadersElementName);
|
xmlWriter.writeStartElement(CppcheckXml::CheckHeadersElementName);
|
||||||
xmlWriter.writeCharacters(mCheckHeaders ? "true" : "false");
|
xmlWriter.writeCharacters(mCheckHeaders ? "true" : "false");
|
||||||
xmlWriter.writeEndElement();
|
xmlWriter.writeEndElement();
|
||||||
|
@ -959,31 +862,6 @@ bool ProjectFile::write(const QString &filename)
|
||||||
CppcheckXml::LibrariesElementName,
|
CppcheckXml::LibrariesElementName,
|
||||||
CppcheckXml::LibraryElementName);
|
CppcheckXml::LibraryElementName);
|
||||||
|
|
||||||
if (!mFunctionContracts.empty()) {
|
|
||||||
xmlWriter.writeStartElement(CppcheckXml::FunctionContracts);
|
|
||||||
for (const auto& contract: mFunctionContracts) {
|
|
||||||
xmlWriter.writeStartElement(CppcheckXml::FunctionContract);
|
|
||||||
xmlWriter.writeAttribute(CppcheckXml::ContractFunction, QString::fromStdString(contract.first));
|
|
||||||
xmlWriter.writeAttribute(CppcheckXml::ContractExpects, QString::fromStdString(contract.second));
|
|
||||||
xmlWriter.writeEndElement();
|
|
||||||
}
|
|
||||||
xmlWriter.writeEndElement();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!mVariableContracts.empty()) {
|
|
||||||
xmlWriter.writeStartElement(CppcheckXml::VariableContractsElementName);
|
|
||||||
|
|
||||||
for (const auto &vc: mVariableContracts) {
|
|
||||||
xmlWriter.writeStartElement(CppcheckXml::VariableContractItemElementName);
|
|
||||||
xmlWriter.writeAttribute(CppcheckXml::VariableContractVarName, vc.first);
|
|
||||||
xmlWriter.writeAttribute(CppcheckXml::VariableContractMin, QString::fromStdString(vc.second.minValue));
|
|
||||||
xmlWriter.writeAttribute(CppcheckXml::VariableContractMax, QString::fromStdString(vc.second.maxValue));
|
|
||||||
xmlWriter.writeEndElement();
|
|
||||||
}
|
|
||||||
|
|
||||||
xmlWriter.writeEndElement();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!mSuppressions.isEmpty()) {
|
if (!mSuppressions.isEmpty()) {
|
||||||
xmlWriter.writeStartElement(CppcheckXml::SuppressionsElementName);
|
xmlWriter.writeStartElement(CppcheckXml::SuppressionsElementName);
|
||||||
for (const Suppressions::Suppression &suppression : mSuppressions) {
|
for (const Suppressions::Suppression &suppression : mSuppressions) {
|
||||||
|
|
|
@ -228,26 +228,6 @@ public:
|
||||||
mMaxTemplateRecursion = maxTemplateRecursion;
|
mMaxTemplateRecursion = maxTemplateRecursion;
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::map<std::string,std::string>& getFunctionContracts() const {
|
|
||||||
return mFunctionContracts;
|
|
||||||
}
|
|
||||||
|
|
||||||
const std::map<QString, Settings::VariableContracts>& getVariableContracts() const {
|
|
||||||
return mVariableContracts;
|
|
||||||
}
|
|
||||||
|
|
||||||
void setVariableContracts(QString var, const QString& min, const QString& max) {
|
|
||||||
mVariableContracts[var] = Settings::VariableContracts{min.toStdString(), max.toStdString()};
|
|
||||||
}
|
|
||||||
|
|
||||||
void deleteFunctionContract(const QString& function) {
|
|
||||||
mFunctionContracts.erase(function.toStdString());
|
|
||||||
}
|
|
||||||
|
|
||||||
void deleteVariableContract(const QString& var) {
|
|
||||||
mVariableContracts.erase(var);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Get filename for the project file.
|
* @brief Get filename for the project file.
|
||||||
* @return file name.
|
* @return file name.
|
||||||
|
@ -312,9 +292,6 @@ public:
|
||||||
*/
|
*/
|
||||||
void setLibraries(const QStringList &libraries);
|
void setLibraries(const QStringList &libraries);
|
||||||
|
|
||||||
/** Set contract for a function */
|
|
||||||
void setFunctionContract(const QString& function, const QString& expects);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Set platform.
|
* @brief Set platform.
|
||||||
* @param platform platform.
|
* @param platform platform.
|
||||||
|
@ -391,8 +368,6 @@ public:
|
||||||
/** Use Clang parser */
|
/** Use Clang parser */
|
||||||
bool clangParser;
|
bool clangParser;
|
||||||
|
|
||||||
/** Bug hunting */
|
|
||||||
bool bugHunting;
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -437,18 +412,6 @@ protected:
|
||||||
*/
|
*/
|
||||||
void readExcludes(QXmlStreamReader &reader);
|
void readExcludes(QXmlStreamReader &reader);
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Read function contracts.
|
|
||||||
* @param reader XML stream reader.
|
|
||||||
*/
|
|
||||||
void readFunctionContracts(QXmlStreamReader &reader);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Read variable constraints.
|
|
||||||
* @param reader XML stream reader.
|
|
||||||
*/
|
|
||||||
void readVariableContracts(QXmlStreamReader &reader);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Read lists of Visual Studio configurations
|
* @brief Read lists of Visual Studio configurations
|
||||||
* @param reader XML stream reader.
|
* @param reader XML stream reader.
|
||||||
|
@ -564,10 +527,6 @@ private:
|
||||||
*/
|
*/
|
||||||
QStringList mLibraries;
|
QStringList mLibraries;
|
||||||
|
|
||||||
std::map<std::string, std::string> mFunctionContracts;
|
|
||||||
|
|
||||||
std::map<QString, Settings::VariableContracts> mVariableContracts;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Platform
|
* @brief Platform
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -458,23 +458,6 @@
|
||||||
<string>Analysis</string>
|
<string>Analysis</string>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QVBoxLayout" name="verticalLayout_19">
|
<layout class="QVBoxLayout" name="verticalLayout_19">
|
||||||
<item>
|
|
||||||
<widget class="QRadioButton" name="mBtnNormalAnalysis">
|
|
||||||
<property name="text">
|
|
||||||
<string>Normal analysis -- Avoid false positives.</string>
|
|
||||||
</property>
|
|
||||||
<property name="checked">
|
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QRadioButton" name="mBtnBugHunting">
|
|
||||||
<property name="text">
|
|
||||||
<string>Bug hunting -- Generates mostly noise. The goal is to be "soundy" and detect most bugs.</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
<item>
|
||||||
<widget class="QCheckBox" name="mBtnSafeClasses">
|
<widget class="QCheckBox" name="mBtnSafeClasses">
|
||||||
<property name="toolTip">
|
<property name="toolTip">
|
||||||
|
|
|
@ -210,7 +210,6 @@ ProjectFileDialog::ProjectFileDialog(ProjectFile *projectFile, QWidget *parent)
|
||||||
connect(mUI->mListSuppressions, &QListWidget::doubleClicked, this, &ProjectFileDialog::editSuppression);
|
connect(mUI->mListSuppressions, &QListWidget::doubleClicked, this, &ProjectFileDialog::editSuppression);
|
||||||
connect(mUI->mBtnBrowseMisraFile, &QPushButton::clicked, this, &ProjectFileDialog::browseMisraFile);
|
connect(mUI->mBtnBrowseMisraFile, &QPushButton::clicked, this, &ProjectFileDialog::browseMisraFile);
|
||||||
connect(mUI->mChkAllVsConfigs, &QCheckBox::clicked, this, &ProjectFileDialog::checkAllVSConfigs);
|
connect(mUI->mChkAllVsConfigs, &QCheckBox::clicked, this, &ProjectFileDialog::checkAllVSConfigs);
|
||||||
connect(mUI->mBtnNormalAnalysis, &QCheckBox::toggled, mUI->mBtnSafeClasses, &QCheckBox::setEnabled);
|
|
||||||
loadFromProjectFile(projectFile);
|
loadFromProjectFile(projectFile);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -282,7 +281,6 @@ void ProjectFileDialog::loadFromProjectFile(const ProjectFile *projectFile)
|
||||||
else
|
else
|
||||||
mUI->mBtnCppcheckParser->setChecked(true);
|
mUI->mBtnCppcheckParser->setChecked(true);
|
||||||
mUI->mBtnSafeClasses->setChecked(projectFile->safeChecks.classes);
|
mUI->mBtnSafeClasses->setChecked(projectFile->safeChecks.classes);
|
||||||
mUI->mBtnBugHunting->setChecked(projectFile->bugHunting);
|
|
||||||
setExcludedPaths(projectFile->getExcludedPaths());
|
setExcludedPaths(projectFile->getExcludedPaths());
|
||||||
setLibraries(projectFile->getLibraries());
|
setLibraries(projectFile->getLibraries());
|
||||||
const QString platform = projectFile->getPlatform();
|
const QString platform = projectFile->getPlatform();
|
||||||
|
@ -376,7 +374,6 @@ void ProjectFileDialog::saveToProjectFile(ProjectFile *projectFile) const
|
||||||
projectFile->setLibraries(getLibraries());
|
projectFile->setLibraries(getLibraries());
|
||||||
projectFile->clangParser = mUI->mBtnClangParser->isChecked();
|
projectFile->clangParser = mUI->mBtnClangParser->isChecked();
|
||||||
projectFile->safeChecks.classes = mUI->mBtnSafeClasses->isChecked();
|
projectFile->safeChecks.classes = mUI->mBtnSafeClasses->isChecked();
|
||||||
projectFile->bugHunting = mUI->mBtnBugHunting->isChecked();
|
|
||||||
if (mUI->mComboBoxPlatform->currentText().endsWith(".xml"))
|
if (mUI->mComboBoxPlatform->currentText().endsWith(".xml"))
|
||||||
projectFile->setPlatform(mUI->mComboBoxPlatform->currentText());
|
projectFile->setPlatform(mUI->mComboBoxPlatform->currentText());
|
||||||
else {
|
else {
|
||||||
|
|
|
@ -645,15 +645,6 @@ void ResultsTree::contextMenuEvent(QContextMenuEvent * e)
|
||||||
menu.addSeparator();
|
menu.addSeparator();
|
||||||
}
|
}
|
||||||
|
|
||||||
const bool bughunting = !multipleSelection && mContextItem->data().toMap().value("id").toString().startsWith("bughunting");
|
|
||||||
|
|
||||||
if (bughunting && !getFunction(mContextItem).isEmpty()) {
|
|
||||||
QAction *editContract = new QAction(tr("Edit contract.."), &menu);
|
|
||||||
connect(editContract, &QAction::triggered, this, &ResultsTree::editContract);
|
|
||||||
menu.addAction(editContract);
|
|
||||||
menu.addSeparator();
|
|
||||||
}
|
|
||||||
|
|
||||||
//Create an action for the application
|
//Create an action for the application
|
||||||
QAction *recheckSelectedFiles = new QAction(tr("Recheck"), &menu);
|
QAction *recheckSelectedFiles = new QAction(tr("Recheck"), &menu);
|
||||||
QAction *copy = new QAction(tr("Copy"), &menu);
|
QAction *copy = new QAction(tr("Copy"), &menu);
|
||||||
|
@ -677,15 +668,10 @@ void ResultsTree::contextMenuEvent(QContextMenuEvent * e)
|
||||||
menu.addAction(hide);
|
menu.addAction(hide);
|
||||||
menu.addAction(hideallid);
|
menu.addAction(hideallid);
|
||||||
|
|
||||||
if (!bughunting) {
|
QAction *suppress = new QAction(tr("Suppress selected id(s)"), &menu);
|
||||||
QAction *suppress = new QAction(tr("Suppress selected id(s)"), &menu);
|
menu.addAction(suppress);
|
||||||
menu.addAction(suppress);
|
connect(suppress, &QAction::triggered, this, &ResultsTree::suppressSelectedIds);
|
||||||
connect(suppress, &QAction::triggered, this, &ResultsTree::suppressSelectedIds);
|
|
||||||
} else {
|
|
||||||
QAction *suppress = new QAction(tr("Suppress"), &menu);
|
|
||||||
menu.addAction(suppress);
|
|
||||||
connect(suppress, &QAction::triggered, this, &ResultsTree::suppressHash);
|
|
||||||
}
|
|
||||||
menu.addSeparator();
|
menu.addSeparator();
|
||||||
menu.addAction(opencontainingfolder);
|
menu.addAction(opencontainingfolder);
|
||||||
|
|
||||||
|
@ -1107,11 +1093,6 @@ void ResultsTree::openContainingFolder()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ResultsTree::editContract()
|
|
||||||
{
|
|
||||||
emit editFunctionContract(getFunction(mContextItem));
|
|
||||||
}
|
|
||||||
|
|
||||||
void ResultsTree::tagSelectedItems(const QString &tag)
|
void ResultsTree::tagSelectedItems(const QString &tag)
|
||||||
{
|
{
|
||||||
if (!mSelectionModel)
|
if (!mSelectionModel)
|
||||||
|
|
|
@ -205,8 +205,6 @@ signals:
|
||||||
/** Suppress Ids */
|
/** Suppress Ids */
|
||||||
void suppressIds(QStringList ids);
|
void suppressIds(QStringList ids);
|
||||||
|
|
||||||
/** Edit contract for function */
|
|
||||||
void editFunctionContract(QString function);
|
|
||||||
public slots:
|
public slots:
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -284,11 +282,6 @@ protected slots:
|
||||||
*/
|
*/
|
||||||
void openContainingFolder();
|
void openContainingFolder();
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Allow user to edit contract to fix bughunting warning
|
|
||||||
*/
|
|
||||||
void editContract();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Slot for selection change in the results tree.
|
* @brief Slot for selection change in the results tree.
|
||||||
*
|
*
|
||||||
|
|
|
@ -55,7 +55,6 @@ ResultsView::ResultsView(QWidget * parent) :
|
||||||
connect(mUI->mTree, &ResultsTree::checkSelected, this, &ResultsView::checkSelected);
|
connect(mUI->mTree, &ResultsTree::checkSelected, this, &ResultsView::checkSelected);
|
||||||
connect(mUI->mTree, &ResultsTree::treeSelectionChanged, this, &ResultsView::updateDetails);
|
connect(mUI->mTree, &ResultsTree::treeSelectionChanged, this, &ResultsView::updateDetails);
|
||||||
connect(mUI->mTree, &ResultsTree::suppressIds, this, &ResultsView::suppressIds);
|
connect(mUI->mTree, &ResultsTree::suppressIds, this, &ResultsView::suppressIds);
|
||||||
connect(mUI->mTree, &ResultsTree::editFunctionContract, this, &ResultsView::editFunctionContract);
|
|
||||||
connect(this, &ResultsView::showResults, mUI->mTree, &ResultsTree::showResults);
|
connect(this, &ResultsView::showResults, mUI->mTree, &ResultsTree::showResults);
|
||||||
connect(this, &ResultsView::showCppcheckResults, mUI->mTree, &ResultsTree::showCppcheckResults);
|
connect(this, &ResultsView::showCppcheckResults, mUI->mTree, &ResultsTree::showCppcheckResults);
|
||||||
connect(this, &ResultsView::showClangResults, mUI->mTree, &ResultsTree::showClangResults);
|
connect(this, &ResultsView::showClangResults, mUI->mTree, &ResultsTree::showClangResults);
|
||||||
|
@ -63,21 +62,7 @@ ResultsView::ResultsView(QWidget * parent) :
|
||||||
connect(this, &ResultsView::expandAllResults, mUI->mTree, &ResultsTree::expandAll);
|
connect(this, &ResultsView::expandAllResults, mUI->mTree, &ResultsTree::expandAll);
|
||||||
connect(this, &ResultsView::showHiddenResults, mUI->mTree, &ResultsTree::showHiddenResults);
|
connect(this, &ResultsView::showHiddenResults, mUI->mTree, &ResultsTree::showHiddenResults);
|
||||||
|
|
||||||
// Function contracts
|
|
||||||
connect(mUI->mListAddedContracts, &QListWidget::itemDoubleClicked, this, &ResultsView::contractDoubleClicked);
|
|
||||||
connect(mUI->mListMissingContracts, &QListWidget::itemDoubleClicked, this, &ResultsView::contractDoubleClicked);
|
|
||||||
mUI->mListAddedContracts->installEventFilter(this);
|
|
||||||
|
|
||||||
// Variable contracts
|
|
||||||
connect(mUI->mListAddedVariables, &QListWidget::itemDoubleClicked, this, &ResultsView::variableDoubleClicked);
|
|
||||||
connect(mUI->mListMissingVariables, &QListWidget::itemDoubleClicked, this, &ResultsView::variableDoubleClicked);
|
|
||||||
connect(mUI->mEditVariablesFilter, &QLineEdit::textChanged, this, &ResultsView::editVariablesFilter);
|
|
||||||
mUI->mListAddedVariables->installEventFilter(this);
|
|
||||||
|
|
||||||
mUI->mListLog->setContextMenuPolicy(Qt::CustomContextMenu);
|
mUI->mListLog->setContextMenuPolicy(Qt::CustomContextMenu);
|
||||||
|
|
||||||
mUI->mListAddedContracts->setSortingEnabled(true);
|
|
||||||
mUI->mListMissingContracts->setSortingEnabled(true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ResultsView::initialize(QSettings *settings, ApplicationList *list, ThreadHandler *checkThreadHandler)
|
void ResultsView::initialize(QSettings *settings, ApplicationList *list, ThreadHandler *checkThreadHandler)
|
||||||
|
@ -100,28 +85,6 @@ ResultsView::~ResultsView()
|
||||||
delete mUI;
|
delete mUI;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ResultsView::setAddedFunctionContracts(const QStringList &addedContracts)
|
|
||||||
{
|
|
||||||
mUI->mListAddedContracts->clear();
|
|
||||||
mUI->mListAddedContracts->addItems(addedContracts);
|
|
||||||
for (const QString& f: addedContracts) {
|
|
||||||
auto res = mUI->mListMissingContracts->findItems(f, Qt::MatchExactly);
|
|
||||||
if (!res.empty())
|
|
||||||
delete res.front();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ResultsView::setAddedVariableContracts(const QStringList &added)
|
|
||||||
{
|
|
||||||
mUI->mListAddedVariables->clear();
|
|
||||||
mUI->mListAddedVariables->addItems(added);
|
|
||||||
for (const QString& var: added) {
|
|
||||||
for (auto *item: mUI->mListMissingVariables->findItems(var, Qt::MatchExactly))
|
|
||||||
delete item;
|
|
||||||
mVariableContracts.insert(var);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ResultsView::clear(bool results)
|
void ResultsView::clear(bool results)
|
||||||
{
|
{
|
||||||
if (results) {
|
if (results) {
|
||||||
|
@ -148,27 +111,11 @@ void ResultsView::clearRecheckFile(const QString &filename)
|
||||||
mUI->mTree->clearRecheckFile(filename);
|
mUI->mTree->clearRecheckFile(filename);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ResultsView::clearContracts()
|
|
||||||
{
|
|
||||||
mUI->mListAddedContracts->clear();
|
|
||||||
mUI->mListAddedVariables->clear();
|
|
||||||
mUI->mListMissingContracts->clear();
|
|
||||||
mUI->mListMissingVariables->clear();
|
|
||||||
mFunctionContracts.clear();
|
|
||||||
mVariableContracts.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
ShowTypes * ResultsView::getShowTypes() const
|
ShowTypes * ResultsView::getShowTypes() const
|
||||||
{
|
{
|
||||||
return &mUI->mTree->mShowSeverities;
|
return &mUI->mTree->mShowSeverities;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ResultsView::showContracts(bool visible)
|
|
||||||
{
|
|
||||||
mUI->mTabFunctionContracts->setVisible(visible);
|
|
||||||
mUI->mTabVariableContracts->setVisible(visible);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ResultsView::progress(int value, const QString& description)
|
void ResultsView::progress(int value, const QString& description)
|
||||||
{
|
{
|
||||||
mUI->mProgress->setValue(value);
|
mUI->mProgress->setValue(value);
|
||||||
|
@ -497,25 +444,6 @@ void ResultsView::debugError(const ErrorItem &item)
|
||||||
mUI->mListLog->addItem(item.toString());
|
mUI->mListLog->addItem(item.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
void ResultsView::bughuntingReportLine(const QString& line)
|
|
||||||
{
|
|
||||||
for (const QString& s: line.split("\n")) {
|
|
||||||
if (s.startsWith("[intvar] ")) {
|
|
||||||
const QString varname = s.mid(9);
|
|
||||||
if (!mVariableContracts.contains(varname)) {
|
|
||||||
mVariableContracts.insert(varname);
|
|
||||||
mUI->mListMissingVariables->addItem(varname);
|
|
||||||
}
|
|
||||||
} else if (s.startsWith("[missing contract] ")) {
|
|
||||||
const QString functionName = s.mid(19);
|
|
||||||
if (!mFunctionContracts.contains(functionName)) {
|
|
||||||
mFunctionContracts.insert(functionName);
|
|
||||||
mUI->mListMissingContracts->addItem(functionName);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ResultsView::logClear()
|
void ResultsView::logClear()
|
||||||
{
|
{
|
||||||
mUI->mListLog->clear();
|
mUI->mListLog->clear();
|
||||||
|
@ -543,34 +471,6 @@ void ResultsView::logCopyComplete()
|
||||||
clipboard->setText(logText);
|
clipboard->setText(logText);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ResultsView::contractDoubleClicked(QListWidgetItem* item)
|
|
||||||
{
|
|
||||||
emit editFunctionContract(item->text());
|
|
||||||
}
|
|
||||||
|
|
||||||
void ResultsView::variableDoubleClicked(QListWidgetItem* item)
|
|
||||||
{
|
|
||||||
emit editVariableContract(item->text());
|
|
||||||
}
|
|
||||||
|
|
||||||
void ResultsView::editVariablesFilter(const QString &text)
|
|
||||||
{
|
|
||||||
#if (QT_VERSION >= QT_VERSION_CHECK(5, 15, 0))
|
|
||||||
for (auto *item: mUI->mListAddedVariables->findItems(".*", Qt::MatchRegularExpression)) {
|
|
||||||
#else
|
|
||||||
for (auto *item: mUI->mListAddedVariables->findItems(".*", Qt::MatchRegExp)) {
|
|
||||||
#endif
|
|
||||||
QString varname = item->text().mid(0, item->text().indexOf(" "));
|
|
||||||
item->setHidden(!varname.contains(text));
|
|
||||||
}
|
|
||||||
#if (QT_VERSION >= QT_VERSION_CHECK(5, 15, 0))
|
|
||||||
for (auto *item: mUI->mListMissingVariables->findItems(".*", Qt::MatchRegularExpression))
|
|
||||||
#else
|
|
||||||
for (auto *item: mUI->mListMissingVariables->findItems(".*", Qt::MatchRegExp))
|
|
||||||
#endif
|
|
||||||
item->setHidden(!item->text().contains(text));
|
|
||||||
}
|
|
||||||
|
|
||||||
void ResultsView::on_mListLog_customContextMenuRequested(const QPoint &pos)
|
void ResultsView::on_mListLog_customContextMenuRequested(const QPoint &pos)
|
||||||
{
|
{
|
||||||
if (mUI->mListLog->count() <= 0)
|
if (mUI->mListLog->count() <= 0)
|
||||||
|
@ -585,32 +485,3 @@ void ResultsView::on_mListLog_customContextMenuRequested(const QPoint &pos)
|
||||||
|
|
||||||
contextMenu.exec(globalPos);
|
contextMenu.exec(globalPos);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ResultsView::eventFilter(QObject *target, QEvent *event)
|
|
||||||
{
|
|
||||||
if (event->type() == QEvent::KeyPress) {
|
|
||||||
if (target == mUI->mListAddedVariables) {
|
|
||||||
QKeyEvent *keyEvent = static_cast<QKeyEvent *>(event);
|
|
||||||
if (keyEvent->key() == Qt::Key_Delete) {
|
|
||||||
for (auto *i: mUI->mListAddedVariables->selectedItems()) {
|
|
||||||
emit deleteVariableContract(i->text().mid(0, i->text().indexOf(" ")));
|
|
||||||
delete i;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (target == mUI->mListAddedContracts) {
|
|
||||||
QKeyEvent *keyEvent = static_cast<QKeyEvent *>(event);
|
|
||||||
if (keyEvent->key() == Qt::Key_Delete) {
|
|
||||||
for (auto *i: mUI->mListAddedContracts->selectedItems()) {
|
|
||||||
emit deleteFunctionContract(i->text());
|
|
||||||
delete i;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return QObject::eventFilter(target, event);
|
|
||||||
}
|
|
||||||
|
|
|
@ -56,9 +56,6 @@ public:
|
||||||
~ResultsView() override;
|
~ResultsView() override;
|
||||||
ResultsView &operator=(const ResultsView &) = delete;
|
ResultsView &operator=(const ResultsView &) = delete;
|
||||||
|
|
||||||
void setAddedFunctionContracts(const QStringList &addedContracts);
|
|
||||||
void setAddedVariableContracts(const QStringList &added);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Clear results and statistics and reset progressinfo.
|
* @brief Clear results and statistics and reset progressinfo.
|
||||||
* @param results Remove all the results from view?
|
* @param results Remove all the results from view?
|
||||||
|
@ -75,9 +72,6 @@ public:
|
||||||
*/
|
*/
|
||||||
void clearRecheckFile(const QString &filename);
|
void clearRecheckFile(const QString &filename);
|
||||||
|
|
||||||
/** Clear the contracts */
|
|
||||||
void clearContracts();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Write statistics in file
|
* @brief Write statistics in file
|
||||||
*
|
*
|
||||||
|
@ -204,9 +198,6 @@ public:
|
||||||
*/
|
*/
|
||||||
ShowTypes * getShowTypes() const;
|
ShowTypes * getShowTypes() const;
|
||||||
|
|
||||||
/** Show/hide the contract tabs */
|
|
||||||
void showContracts(bool visible);
|
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -232,18 +223,6 @@ signals:
|
||||||
/** Suppress Ids */
|
/** Suppress Ids */
|
||||||
void suppressIds(QStringList ids);
|
void suppressIds(QStringList ids);
|
||||||
|
|
||||||
/** Edit contract for function */
|
|
||||||
void editFunctionContract(QString function);
|
|
||||||
|
|
||||||
/** Delete contract for function */
|
|
||||||
void deleteFunctionContract(QString function);
|
|
||||||
|
|
||||||
/** Edit contract for variable */
|
|
||||||
void editVariableContract(QString var);
|
|
||||||
|
|
||||||
/** Delete variable contract */
|
|
||||||
void deleteVariableContract(QString var);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Show/hide certain type of errors
|
* @brief Show/hide certain type of errors
|
||||||
* Refreshes the tree.
|
* Refreshes the tree.
|
||||||
|
@ -339,11 +318,6 @@ public slots:
|
||||||
*/
|
*/
|
||||||
void debugError(const ErrorItem &item);
|
void debugError(const ErrorItem &item);
|
||||||
|
|
||||||
/**
|
|
||||||
* \brief bughunting report line
|
|
||||||
*/
|
|
||||||
void bughuntingReportLine(const QString& line);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Clear log messages
|
* \brief Clear log messages
|
||||||
*/
|
*/
|
||||||
|
@ -359,14 +333,6 @@ public slots:
|
||||||
*/
|
*/
|
||||||
void logCopyComplete();
|
void logCopyComplete();
|
||||||
|
|
||||||
/** \brief Contract was double clicked => edit it */
|
|
||||||
void contractDoubleClicked(QListWidgetItem* item);
|
|
||||||
|
|
||||||
/** \brief Variable was double clicked => edit it */
|
|
||||||
void variableDoubleClicked(QListWidgetItem* item);
|
|
||||||
|
|
||||||
void editVariablesFilter(const QString &text);
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
/**
|
/**
|
||||||
* @brief Should we show a "No errors found dialog" every time no errors were found?
|
* @brief Should we show a "No errors found dialog" every time no errors were found?
|
||||||
|
@ -377,16 +343,12 @@ protected:
|
||||||
|
|
||||||
CheckStatistics *mStatistics;
|
CheckStatistics *mStatistics;
|
||||||
|
|
||||||
bool eventFilter(QObject *target, QEvent *event) override;
|
|
||||||
private slots:
|
private slots:
|
||||||
/**
|
/**
|
||||||
* @brief Custom context menu for Analysis Log
|
* @brief Custom context menu for Analysis Log
|
||||||
* @param pos Mouse click position
|
* @param pos Mouse click position
|
||||||
*/
|
*/
|
||||||
void on_mListLog_customContextMenuRequested(const QPoint &pos);
|
void on_mListLog_customContextMenuRequested(const QPoint &pos);
|
||||||
private:
|
|
||||||
QSet<QString> mFunctionContracts;
|
|
||||||
QSet<QString> mVariableContracts;
|
|
||||||
};
|
};
|
||||||
/// @}
|
/// @}
|
||||||
#endif // RESULTSVIEW_H
|
#endif // RESULTSVIEW_H
|
||||||
|
|
|
@ -153,109 +153,6 @@
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
<widget class="QWidget" name="mTabFunctionContracts">
|
|
||||||
<attribute name="title">
|
|
||||||
<string>Functions</string>
|
|
||||||
</attribute>
|
|
||||||
<layout class="QVBoxLayout" name="verticalLayout_6">
|
|
||||||
<item>
|
|
||||||
<widget class="QLabel" name="label_2">
|
|
||||||
<property name="text">
|
|
||||||
<string>Configured contracts:</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QListWidget" name="mListAddedContracts">
|
|
||||||
<property name="editTriggers">
|
|
||||||
<set>QAbstractItemView::NoEditTriggers</set>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QLabel" name="label">
|
|
||||||
<property name="text">
|
|
||||||
<string>Missing contracts:</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QListWidget" name="mListMissingContracts">
|
|
||||||
<property name="editTriggers">
|
|
||||||
<set>QAbstractItemView::NoEditTriggers</set>
|
|
||||||
</property>
|
|
||||||
<property name="sortingEnabled">
|
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</widget>
|
|
||||||
<widget class="QWidget" name="mTabVariableContracts">
|
|
||||||
<attribute name="title">
|
|
||||||
<string>Variables</string>
|
|
||||||
</attribute>
|
|
||||||
<layout class="QVBoxLayout" name="verticalLayout_4">
|
|
||||||
<item>
|
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
|
||||||
<item>
|
|
||||||
<spacer name="horizontalSpacer">
|
|
||||||
<property name="orientation">
|
|
||||||
<enum>Qt::Horizontal</enum>
|
|
||||||
</property>
|
|
||||||
<property name="sizeHint" stdset="0">
|
|
||||||
<size>
|
|
||||||
<width>40</width>
|
|
||||||
<height>20</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
</spacer>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QLabel" name="label_5">
|
|
||||||
<property name="text">
|
|
||||||
<string>Only show variable names that contain text:</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QLineEdit" name="mEditVariablesFilter"/>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QLabel" name="label_3">
|
|
||||||
<property name="text">
|
|
||||||
<string>Configured contracts:</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QListWidget" name="mListAddedVariables">
|
|
||||||
<property name="editTriggers">
|
|
||||||
<set>QAbstractItemView::NoEditTriggers</set>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QLabel" name="label_4">
|
|
||||||
<property name="text">
|
|
||||||
<string>Missing contracts:</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QListWidget" name="mListMissingVariables">
|
|
||||||
<property name="editTriggers">
|
|
||||||
<set>QAbstractItemView::NoEditTriggers</set>
|
|
||||||
</property>
|
|
||||||
<property name="sortingEnabled">
|
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</widget>
|
|
||||||
</widget>
|
</widget>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
|
|
@ -16,9 +16,6 @@ target_link_libraries(benchmark-simple ${QT_CORE_LIB} ${QT_TEST_LIB})
|
||||||
if (HAVE_RULES)
|
if (HAVE_RULES)
|
||||||
target_link_libraries(benchmark-simple ${PCRE_LIBRARY})
|
target_link_libraries(benchmark-simple ${PCRE_LIBRARY})
|
||||||
endif()
|
endif()
|
||||||
if (USE_Z3)
|
|
||||||
target_link_libraries(benchmark-simple ${Z3_LIBRARIES})
|
|
||||||
endif()
|
|
||||||
if(tinyxml2_FOUND AND NOT USE_BUNDLED_TINYXML2)
|
if(tinyxml2_FOUND AND NOT USE_BUNDLED_TINYXML2)
|
||||||
target_link_libraries(benchmark-simple ${tinyxml2_LIBRARIES})
|
target_link_libraries(benchmark-simple ${tinyxml2_LIBRARIES})
|
||||||
endif()
|
endif()
|
||||||
|
|
|
@ -33,5 +33,4 @@ private:
|
||||||
// We don't care about the output in the benchmark tests.
|
// We don't care about the output in the benchmark tests.
|
||||||
void reportOut(const std::string & /*outmsg*/, Color /*c*/ = Color::Reset) override {}
|
void reportOut(const std::string & /*outmsg*/, Color /*c*/ = Color::Reset) override {}
|
||||||
void reportErr(const ErrorMessage & /*msg*/) override {}
|
void reportErr(const ErrorMessage & /*msg*/) override {}
|
||||||
void bughuntingReport(const std::string & /*str*/) override {}
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -20,9 +20,6 @@ target_link_libraries(test-xmlreportv2 ${QT_CORE_LIB} ${QT_TEST_LIB})
|
||||||
if (HAVE_RULES)
|
if (HAVE_RULES)
|
||||||
target_link_libraries(test-xmlreportv2 ${PCRE_LIBRARY})
|
target_link_libraries(test-xmlreportv2 ${PCRE_LIBRARY})
|
||||||
endif()
|
endif()
|
||||||
if (USE_Z3)
|
|
||||||
target_link_libraries(test-xmlreportv2 ${Z3_LIBRARIES})
|
|
||||||
endif()
|
|
||||||
if(tinyxml2_FOUND AND NOT USE_BUNDLED_TINYXML2)
|
if(tinyxml2_FOUND AND NOT USE_BUNDLED_TINYXML2)
|
||||||
target_link_libraries(test-xmlreportv2 ${tinyxml2_LIBRARIES})
|
target_link_libraries(test-xmlreportv2 ${tinyxml2_LIBRARIES})
|
||||||
endif()
|
endif()
|
||||||
|
|
|
@ -200,9 +200,6 @@ void ThreadHandler::initialize(ResultsView *view)
|
||||||
|
|
||||||
connect(&mResults, &ThreadResult::debugError,
|
connect(&mResults, &ThreadResult::debugError,
|
||||||
this, &ThreadHandler::debugError);
|
this, &ThreadHandler::debugError);
|
||||||
|
|
||||||
connect(&mResults, &ThreadResult::bughuntingReportLine,
|
|
||||||
this, &ThreadHandler::bughuntingReportLine);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ThreadHandler::loadSettings(const QSettings &settings)
|
void ThreadHandler::loadSettings(const QSettings &settings)
|
||||||
|
|
|
@ -187,8 +187,6 @@ signals:
|
||||||
|
|
||||||
void debugError(const ErrorItem &item);
|
void debugError(const ErrorItem &item);
|
||||||
|
|
||||||
void bughuntingReportLine(QString line);
|
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -134,10 +134,3 @@ int ThreadResult::getFileCount() const
|
||||||
QMutexLocker locker(&mutex);
|
QMutexLocker locker(&mutex);
|
||||||
return mFiles.size() + mFileSettings.size();
|
return mFiles.size() + mFileSettings.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ThreadResult::bughuntingReport(const std::string &str)
|
|
||||||
{
|
|
||||||
if (str.empty())
|
|
||||||
return;
|
|
||||||
emit bughuntingReportLine(QString::fromStdString(str));
|
|
||||||
}
|
|
||||||
|
|
|
@ -76,7 +76,6 @@ public:
|
||||||
*/
|
*/
|
||||||
void reportOut(const std::string &outmsg, Color c = Color::Reset) override;
|
void reportOut(const std::string &outmsg, Color c = Color::Reset) override;
|
||||||
void reportErr(const ErrorMessage &msg) override;
|
void reportErr(const ErrorMessage &msg) override;
|
||||||
void bughuntingReport(const std::string &str) override;
|
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
|
|
||||||
|
@ -114,9 +113,6 @@ signals:
|
||||||
*/
|
*/
|
||||||
void debugError(const ErrorItem &item);
|
void debugError(const ErrorItem &item);
|
||||||
|
|
||||||
/** @brief bug hunting report */
|
|
||||||
void bughuntingReportLine(QString line);
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -1,69 +0,0 @@
|
||||||
/*
|
|
||||||
* Cppcheck - A tool for static C/C++ code analysis
|
|
||||||
* Copyright (C) 2007-2022 Cppcheck team.
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "variablecontractsdialog.h"
|
|
||||||
|
|
||||||
#include "ui_variablecontractsdialog.h"
|
|
||||||
|
|
||||||
#include <QRegularExpression>
|
|
||||||
#include <QRegularExpressionValidator>
|
|
||||||
|
|
||||||
VariableContractsDialog::VariableContractsDialog(QWidget *parent, QString var) :
|
|
||||||
QDialog(parent),
|
|
||||||
mUI(new Ui::VariableContractsDialog)
|
|
||||||
{
|
|
||||||
mUI->setupUi(this);
|
|
||||||
|
|
||||||
mVarName = var.indexOf(" ") < 0 ? var : var.mid(0, var.indexOf(" "));
|
|
||||||
|
|
||||||
this->setWindowTitle(mVarName);
|
|
||||||
|
|
||||||
auto getMinMax = [](const QString& var, const QString& minmax) {
|
|
||||||
if (var.indexOf(" " + minmax + ":") < 0)
|
|
||||||
return QString();
|
|
||||||
int pos1 = var.indexOf(" " + minmax + ":") + 2 + minmax.length();
|
|
||||||
int pos2 = var.indexOf(" ", pos1);
|
|
||||||
if (pos2 < 0)
|
|
||||||
return var.mid(pos1);
|
|
||||||
return var.mid(pos1, pos2-pos1);
|
|
||||||
};
|
|
||||||
|
|
||||||
mUI->mMinValue->setText(getMinMax(var, "min"));
|
|
||||||
mUI->mMaxValue->setText(getMinMax(var, "max"));
|
|
||||||
|
|
||||||
mUI->mMinValue->setValidator(new QRegularExpressionValidator(QRegularExpression("-?[0-9]*")));
|
|
||||||
mUI->mMaxValue->setValidator(new QRegularExpressionValidator(QRegularExpression("-?[0-9]*")));
|
|
||||||
}
|
|
||||||
|
|
||||||
VariableContractsDialog::~VariableContractsDialog()
|
|
||||||
{
|
|
||||||
delete mUI;
|
|
||||||
}
|
|
||||||
|
|
||||||
QString VariableContractsDialog::getVarname() const
|
|
||||||
{
|
|
||||||
return mVarName;
|
|
||||||
}
|
|
||||||
QString VariableContractsDialog::getMin() const
|
|
||||||
{
|
|
||||||
return mUI->mMinValue->text();
|
|
||||||
}
|
|
||||||
QString VariableContractsDialog::getMax() const
|
|
||||||
{
|
|
||||||
return mUI->mMaxValue->text();
|
|
||||||
}
|
|
|
@ -1,44 +0,0 @@
|
||||||
/*
|
|
||||||
* Cppcheck - A tool for static C/C++ code analysis
|
|
||||||
* Copyright (C) 2007-2022 Cppcheck team.
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef VARIABLECONSTRAINTSDIALOG_H
|
|
||||||
#define VARIABLECONSTRAINTSDIALOG_H
|
|
||||||
|
|
||||||
#include <QDialog>
|
|
||||||
|
|
||||||
namespace Ui {
|
|
||||||
class VariableContractsDialog;
|
|
||||||
}
|
|
||||||
|
|
||||||
class VariableContractsDialog : public QDialog {
|
|
||||||
Q_OBJECT
|
|
||||||
|
|
||||||
public:
|
|
||||||
explicit VariableContractsDialog(QWidget *parent, QString var);
|
|
||||||
~VariableContractsDialog() override;
|
|
||||||
|
|
||||||
QString getVarname() const;
|
|
||||||
QString getMin() const;
|
|
||||||
QString getMax() const;
|
|
||||||
|
|
||||||
private:
|
|
||||||
Ui::VariableContractsDialog *mUI;
|
|
||||||
QString mVarName;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // VARIABLECONSTRAINTSDIALOG_H
|
|
|
@ -1,108 +0,0 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<ui version="4.0">
|
|
||||||
<class>VariableContractsDialog</class>
|
|
||||||
<widget class="QDialog" name="VariableContractsDialog">
|
|
||||||
<property name="geometry">
|
|
||||||
<rect>
|
|
||||||
<x>0</x>
|
|
||||||
<y>0</y>
|
|
||||||
<width>400</width>
|
|
||||||
<height>172</height>
|
|
||||||
</rect>
|
|
||||||
</property>
|
|
||||||
<property name="windowTitle">
|
|
||||||
<string>Dialog</string>
|
|
||||||
</property>
|
|
||||||
<layout class="QVBoxLayout" name="verticalLayout">
|
|
||||||
<item>
|
|
||||||
<widget class="QLabel" name="label_3">
|
|
||||||
<property name="text">
|
|
||||||
<string>You can specify min and max value for the variable here</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<layout class="QGridLayout" name="gridLayout">
|
|
||||||
<item row="0" column="0">
|
|
||||||
<widget class="QLabel" name="label">
|
|
||||||
<property name="text">
|
|
||||||
<string>Min</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="0" column="1">
|
|
||||||
<widget class="QLineEdit" name="mMinValue"/>
|
|
||||||
</item>
|
|
||||||
<item row="1" column="0">
|
|
||||||
<widget class="QLabel" name="label_2">
|
|
||||||
<property name="text">
|
|
||||||
<string>Max</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="1" column="1">
|
|
||||||
<widget class="QLineEdit" name="mMaxValue"/>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<spacer name="verticalSpacer">
|
|
||||||
<property name="orientation">
|
|
||||||
<enum>Qt::Vertical</enum>
|
|
||||||
</property>
|
|
||||||
<property name="sizeHint" stdset="0">
|
|
||||||
<size>
|
|
||||||
<width>20</width>
|
|
||||||
<height>25</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
</spacer>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QDialogButtonBox" name="buttonBox">
|
|
||||||
<property name="orientation">
|
|
||||||
<enum>Qt::Horizontal</enum>
|
|
||||||
</property>
|
|
||||||
<property name="standardButtons">
|
|
||||||
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</widget>
|
|
||||||
<resources/>
|
|
||||||
<connections>
|
|
||||||
<connection>
|
|
||||||
<sender>buttonBox</sender>
|
|
||||||
<signal>accepted()</signal>
|
|
||||||
<receiver>VariableContractsDialog</receiver>
|
|
||||||
<slot>accept()</slot>
|
|
||||||
<hints>
|
|
||||||
<hint type="sourcelabel">
|
|
||||||
<x>248</x>
|
|
||||||
<y>254</y>
|
|
||||||
</hint>
|
|
||||||
<hint type="destinationlabel">
|
|
||||||
<x>157</x>
|
|
||||||
<y>274</y>
|
|
||||||
</hint>
|
|
||||||
</hints>
|
|
||||||
</connection>
|
|
||||||
<connection>
|
|
||||||
<sender>buttonBox</sender>
|
|
||||||
<signal>rejected()</signal>
|
|
||||||
<receiver>VariableContractsDialog</receiver>
|
|
||||||
<slot>reject()</slot>
|
|
||||||
<hints>
|
|
||||||
<hint type="sourcelabel">
|
|
||||||
<x>316</x>
|
|
||||||
<y>260</y>
|
|
||||||
</hint>
|
|
||||||
<hint type="destinationlabel">
|
|
||||||
<x>286</x>
|
|
||||||
<y>274</y>
|
|
||||||
</hint>
|
|
||||||
</hints>
|
|
||||||
</connection>
|
|
||||||
</connections>
|
|
||||||
</ui>
|
|
|
@ -42,9 +42,6 @@ target_include_directories(lib_objs SYSTEM PRIVATE ${PROJECT_SOURCE_DIR}/externa
|
||||||
if (HAVE_RULES)
|
if (HAVE_RULES)
|
||||||
target_include_directories(lib_objs SYSTEM PRIVATE ${PCRE_INCLUDE})
|
target_include_directories(lib_objs SYSTEM PRIVATE ${PCRE_INCLUDE})
|
||||||
endif()
|
endif()
|
||||||
if (USE_Z3)
|
|
||||||
target_include_directories(lib_objs SYSTEM PRIVATE ${Z3_CXX_INCLUDE_DIRS})
|
|
||||||
endif()
|
|
||||||
if (Boost_FOUND)
|
if (Boost_FOUND)
|
||||||
target_include_directories(lib_objs SYSTEM PRIVATE ${Boost_INCLUDE_DIRS})
|
target_include_directories(lib_objs SYSTEM PRIVATE ${Boost_INCLUDE_DIRS})
|
||||||
endif()
|
endif()
|
||||||
|
|
|
@ -1,719 +0,0 @@
|
||||||
/*
|
|
||||||
* Cppcheck - A tool for static C/C++ code analysis
|
|
||||||
* Copyright (C) 2007-2022 Cppcheck team.
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "bughuntingchecks.h"
|
|
||||||
|
|
||||||
#include "astutils.h"
|
|
||||||
#include "errorlogger.h"
|
|
||||||
#include "errortypes.h"
|
|
||||||
#include "library.h"
|
|
||||||
#include "mathlib.h"
|
|
||||||
#include "settings.h"
|
|
||||||
#include "symboldatabase.h"
|
|
||||||
#include "token.h"
|
|
||||||
#include "utils.h"
|
|
||||||
#include "valueflow.h"
|
|
||||||
|
|
||||||
#include <algorithm>
|
|
||||||
#include <cstring>
|
|
||||||
#include <list>
|
|
||||||
#include <map>
|
|
||||||
#include <memory>
|
|
||||||
#include <string>
|
|
||||||
#include <utility>
|
|
||||||
|
|
||||||
static const CWE CWE_BUFFER_UNDERRUN(786U); // Access of Memory Location Before Start of Buffer
|
|
||||||
static const CWE CWE_BUFFER_OVERRUN(788U); // Access of Memory Location After End of Buffer
|
|
||||||
|
|
||||||
|
|
||||||
static float getKnownFloatValue(const Token *tok, float def)
|
|
||||||
{
|
|
||||||
for (const auto &value: tok->values()) {
|
|
||||||
if (value.isKnown() && value.valueType == ValueFlow::Value::ValueType::FLOAT)
|
|
||||||
return value.floatValue;
|
|
||||||
}
|
|
||||||
return def;
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool isLessThan(ExprEngine::DataBase *dataBase, ExprEngine::ValuePtr lhs, ExprEngine::ValuePtr rhs)
|
|
||||||
{
|
|
||||||
return ExprEngine::BinOpResult("<", lhs, rhs).isTrue(dataBase);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void arrayIndex(const Token *tok, const ExprEngine::Value &value, ExprEngine::DataBase *dataBase)
|
|
||||||
{
|
|
||||||
if (!Token::simpleMatch(tok->astParent(), "["))
|
|
||||||
return;
|
|
||||||
int nr = 0;
|
|
||||||
const Token *buf = tok->astParent()->astOperand1();
|
|
||||||
while (Token::simpleMatch(buf, "[")) {
|
|
||||||
++nr;
|
|
||||||
buf = buf->astOperand1();
|
|
||||||
}
|
|
||||||
if (!buf || !buf->variable() || !buf->variable()->isArray() || buf == buf->variable()->nameToken())
|
|
||||||
// TODO
|
|
||||||
return;
|
|
||||||
const Token *index = tok->astParent()->astOperand2();
|
|
||||||
if (tok != index)
|
|
||||||
// TODO
|
|
||||||
return;
|
|
||||||
if (buf->variable()->dimensions().size() > nr && buf->variable()->dimensions()[nr].known) {
|
|
||||||
const MathLib::bigint bufSize = buf->variable()->dimensions()[nr].num;
|
|
||||||
if (value.isGreaterThan(dataBase, bufSize - 1)) {
|
|
||||||
const bool bailout = (value.type == ExprEngine::ValueType::BailoutValue);
|
|
||||||
dataBase->reportError(tok,
|
|
||||||
Severity::SeverityType::error,
|
|
||||||
"bughuntingArrayIndexOutOfBounds",
|
|
||||||
"Array index out of bounds, cannot determine that " + index->expressionString() + " is less than " + std::to_string(bufSize),
|
|
||||||
CWE_BUFFER_OVERRUN,
|
|
||||||
false,
|
|
||||||
bailout);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
bool isUnsigned = tok->valueType() && tok->valueType()->sign == ::ValueType::Sign::UNSIGNED;
|
|
||||||
if (!isUnsigned && value.isLessThan(dataBase, 0)) {
|
|
||||||
const bool bailout = (value.type == ExprEngine::ValueType::BailoutValue);
|
|
||||||
dataBase->reportError(tok,
|
|
||||||
Severity::SeverityType::error,
|
|
||||||
"bughuntingArrayIndexNegative",
|
|
||||||
"Array index out of bounds, cannot determine that " + index->expressionString() + " is not negative",
|
|
||||||
CWE_BUFFER_UNDERRUN,
|
|
||||||
false,
|
|
||||||
bailout);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void bufferOverflow(const Token *tok, const ExprEngine::Value &value, ExprEngine::DataBase *dataBase)
|
|
||||||
{
|
|
||||||
if (value.type != ExprEngine::ValueType::FunctionCallArgumentValues)
|
|
||||||
return;
|
|
||||||
if (!Token::simpleMatch(tok, "(") || !Token::Match(tok->previous(), "%name% ("))
|
|
||||||
return;
|
|
||||||
|
|
||||||
const Library::Function *func = dataBase->settings->library.getFunction(tok->previous());
|
|
||||||
if (!func)
|
|
||||||
return;
|
|
||||||
|
|
||||||
const ExprEngine::FunctionCallArgumentValues *functionCallArguments = dynamic_cast<const ExprEngine::FunctionCallArgumentValues *>(&value);
|
|
||||||
if (!functionCallArguments)
|
|
||||||
return;
|
|
||||||
|
|
||||||
const std::vector<const Token *> arguments = getArguments(tok);
|
|
||||||
if (functionCallArguments->argValues.size() != arguments.size())
|
|
||||||
// TODO investigate what to do
|
|
||||||
return;
|
|
||||||
|
|
||||||
int overflowArgument = 0;
|
|
||||||
bool bailout = false;
|
|
||||||
|
|
||||||
for (const auto &argNrChecks: func->argumentChecks) {
|
|
||||||
const int argnr = argNrChecks.first;
|
|
||||||
const Library::ArgumentChecks &checks = argNrChecks.second;
|
|
||||||
if (argnr <= 0 || argnr > arguments.size() || checks.minsizes.empty())
|
|
||||||
continue;
|
|
||||||
|
|
||||||
ExprEngine::ValuePtr argValue = functionCallArguments->argValues[argnr - 1];
|
|
||||||
if (!argValue || argValue->type == ExprEngine::ValueType::BailoutValue) {
|
|
||||||
overflowArgument = argnr;
|
|
||||||
bailout = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::shared_ptr<ExprEngine::ArrayValue> arrayValue = std::dynamic_pointer_cast<ExprEngine::ArrayValue>(argValue);
|
|
||||||
if (!arrayValue || arrayValue->size.size() != 1) {
|
|
||||||
// TODO: implement this properly.
|
|
||||||
overflowArgument = argnr;
|
|
||||||
bailout = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (const Library::ArgumentChecks::MinSize &minsize: checks.minsizes) {
|
|
||||||
if (minsize.type == Library::ArgumentChecks::MinSize::Type::ARGVALUE && minsize.arg > 0 && minsize.arg <= arguments.size()) {
|
|
||||||
ExprEngine::ValuePtr otherValue = functionCallArguments->argValues[minsize.arg - 1];
|
|
||||||
if (!otherValue || otherValue->type == ExprEngine::ValueType::BailoutValue) {
|
|
||||||
overflowArgument = argnr;
|
|
||||||
bailout = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (isLessThan(dataBase, arrayValue->size[0], otherValue)) {
|
|
||||||
overflowArgument = argnr;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
} else if (minsize.type == Library::ArgumentChecks::MinSize::Type::STRLEN && minsize.arg > 0 && minsize.arg <= arguments.size()) {
|
|
||||||
if (func->formatstr) {
|
|
||||||
// TODO: implement this properly. check if minsize refers to a format string and check max length of that..
|
|
||||||
overflowArgument = argnr;
|
|
||||||
bailout = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (Token::Match(arguments[minsize.arg - 1], "%str%")) {
|
|
||||||
const Token * const str = arguments[minsize.arg - 1];
|
|
||||||
if (arrayValue->size[0]->isLessThan(dataBase, Token::getStrLength(str))) {
|
|
||||||
overflowArgument = argnr;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
ExprEngine::ValuePtr otherValue = functionCallArguments->argValues[minsize.arg - 1];
|
|
||||||
if (!otherValue || otherValue->type == ExprEngine::ValueType::BailoutValue) {
|
|
||||||
overflowArgument = argnr;
|
|
||||||
bailout = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
std::shared_ptr<ExprEngine::ArrayValue> arrayValue2 = std::dynamic_pointer_cast<ExprEngine::ArrayValue>(otherValue);
|
|
||||||
if (!arrayValue2 || arrayValue2->size.size() != 1) {
|
|
||||||
overflowArgument = argnr;
|
|
||||||
bailout = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (isLessThan(dataBase, arrayValue->size[0], arrayValue2->size[0])) {
|
|
||||||
overflowArgument = argnr;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (overflowArgument > 0)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (overflowArgument == 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
dataBase->reportError(tok,
|
|
||||||
Severity::SeverityType::error,
|
|
||||||
"bughuntingBufferOverflow",
|
|
||||||
"Buffer read/write, when calling '" + tok->previous()->str() + "' it cannot be determined that " + std::to_string(overflowArgument) + getOrdinalText(overflowArgument) + " argument is not overflowed",
|
|
||||||
CWE(120),
|
|
||||||
false,
|
|
||||||
bailout);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void divByZero(const Token *tok, const ExprEngine::Value &value, ExprEngine::DataBase *dataBase)
|
|
||||||
{
|
|
||||||
if (!tok->astParent() || !std::strchr("/%", tok->astParent()->str()[0]))
|
|
||||||
return;
|
|
||||||
if (tok->hasKnownIntValue() && tok->getKnownIntValue() != 0)
|
|
||||||
return;
|
|
||||||
if (tok->isImpossibleIntValue(0))
|
|
||||||
return;
|
|
||||||
if (value.isUninit(dataBase) && value.type != ExprEngine::ValueType::BailoutValue)
|
|
||||||
return;
|
|
||||||
float f = getKnownFloatValue(tok, 0.0f);
|
|
||||||
if (f > 0.0f || f < 0.0f)
|
|
||||||
return;
|
|
||||||
if (value.type == ExprEngine::ValueType::BailoutValue) {
|
|
||||||
if (Token::simpleMatch(tok->previous(), "sizeof ("))
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (tok->astParent()->astOperand2() == tok && value.isEqual(dataBase, 0)) {
|
|
||||||
const char * const id = (tok->valueType() && tok->valueType()->isFloat()) ? "bughuntingDivByZeroFloat" : "bughuntingDivByZero";
|
|
||||||
const bool bailout = (value.type == ExprEngine::ValueType::BailoutValue);
|
|
||||||
dataBase->reportError(dataBase->settings->clang ? tok : tok->astParent(),
|
|
||||||
Severity::SeverityType::error,
|
|
||||||
id,
|
|
||||||
"There is division, cannot determine that there can't be a division by zero.",
|
|
||||||
CWE(369),
|
|
||||||
false,
|
|
||||||
bailout);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef BUG_HUNTING_INTEGEROVERFLOW
|
|
||||||
static void integerOverflow(const Token *tok, const ExprEngine::Value &value, ExprEngine::DataBase *dataBase)
|
|
||||||
{
|
|
||||||
if (!tok->isArithmeticalOp() || !tok->valueType() || !tok->valueType()->isIntegral() || tok->valueType()->pointer > 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
const ExprEngine::BinOpResult *b = dynamic_cast<const ExprEngine::BinOpResult *>(&value);
|
|
||||||
if (!b)
|
|
||||||
return;
|
|
||||||
|
|
||||||
int bits = getIntBitsFromValueType(tok->valueType(), *dataBase->settings);
|
|
||||||
if (bits == 0 || bits >= 60)
|
|
||||||
return;
|
|
||||||
|
|
||||||
std::string errorMessage;
|
|
||||||
if (tok->valueType()->sign == ::ValueType::Sign::SIGNED) {
|
|
||||||
MathLib::bigint v = 1LL << (bits - 1);
|
|
||||||
if (b->isGreaterThan(dataBase, v-1))
|
|
||||||
errorMessage = "greater than " + std::to_string(v - 1);
|
|
||||||
if (b->isLessThan(dataBase, -v)) {
|
|
||||||
if (!errorMessage.empty())
|
|
||||||
errorMessage += " or ";
|
|
||||||
errorMessage += "less than " + std::to_string(-v);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
MathLib::bigint maxValue = (1LL << bits) - 1;
|
|
||||||
if (b->isGreaterThan(dataBase, maxValue))
|
|
||||||
errorMessage = "greater than " + std::to_string(maxValue);
|
|
||||||
if (b->isLessThan(dataBase, 0)) {
|
|
||||||
if (!errorMessage.empty())
|
|
||||||
errorMessage += " or ";
|
|
||||||
errorMessage += "less than 0";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (errorMessage.empty())
|
|
||||||
return;
|
|
||||||
|
|
||||||
|
|
||||||
errorMessage = "There is integer arithmetic, cannot determine that there can't be overflow (if result is " + errorMessage + ").";
|
|
||||||
|
|
||||||
if (tok->valueType()->sign == ::ValueType::Sign::UNSIGNED)
|
|
||||||
errorMessage += " Note that unsigned integer overflow is defined and will wrap around.";
|
|
||||||
|
|
||||||
dataBase->reportError(tok, Severity::SeverityType::error, "bughuntingIntegerOverflow", errorMessage, false, value.type == ExprEngine::ValueType::BailoutValue);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/** check if variable is unconditionally assigned */
|
|
||||||
static bool isVariableAssigned(const Variable *var, const Token *tok, const Token *scopeStart=nullptr)
|
|
||||||
{
|
|
||||||
const Token * const start = scopeStart && precedes(var->nameToken(), scopeStart) ? scopeStart : var->nameToken();
|
|
||||||
|
|
||||||
for (const Token *prev = tok->previous(); prev; prev = prev->previous()) {
|
|
||||||
if (!precedes(start, prev))
|
|
||||||
break;
|
|
||||||
|
|
||||||
if (prev->str() == "}") {
|
|
||||||
if (Token::simpleMatch(prev->link()->tokAt(-2), "} else {")) {
|
|
||||||
const Token *elseEnd = prev;
|
|
||||||
const Token *elseStart = prev->link();
|
|
||||||
const Token *ifEnd = elseStart->tokAt(-2);
|
|
||||||
const Token *ifStart = ifEnd->link();
|
|
||||||
if (isVariableAssigned(var, ifEnd, ifStart) && isVariableAssigned(var, elseEnd, elseStart)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
prev = prev->link();
|
|
||||||
}
|
|
||||||
if (scopeStart && Token::Match(prev, "return|throw|continue|break"))
|
|
||||||
return true;
|
|
||||||
if (Token::Match(prev, "%varid% =", var->declarationId())) {
|
|
||||||
bool usedInRhs = false;
|
|
||||||
visitAstNodes(prev->next()->astOperand2(), [&usedInRhs, var](const Token *tok) {
|
|
||||||
if (tok->varId() == var->declarationId()) {
|
|
||||||
usedInRhs = true;
|
|
||||||
return ChildrenToVisit::done;
|
|
||||||
}
|
|
||||||
return ChildrenToVisit::op1_and_op2;
|
|
||||||
});
|
|
||||||
if (!usedInRhs)
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void uninit(const Token *tok, const ExprEngine::Value &value, ExprEngine::DataBase *dataBase)
|
|
||||||
{
|
|
||||||
if (!tok->astParent())
|
|
||||||
return;
|
|
||||||
|
|
||||||
std::string uninitStructMember;
|
|
||||||
if (const auto* structValue = dynamic_cast<const ExprEngine::StructValue*>(&value)) {
|
|
||||||
uninitStructMember = structValue->getUninitStructMember(dataBase);
|
|
||||||
|
|
||||||
// uninitialized struct member => is there data copy of struct..
|
|
||||||
if (!uninitStructMember.empty()) {
|
|
||||||
if (!Token::Match(tok->astParent(), "[=,(]"))
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool uninitData = false;
|
|
||||||
if (!value.isUninit(dataBase) && uninitStructMember.empty()) {
|
|
||||||
if (Token::Match(tok->astParent(), "[(,]")) {
|
|
||||||
if (const auto* arrayValue = dynamic_cast<const ExprEngine::ArrayValue*>(&value)) {
|
|
||||||
uninitData = arrayValue->data.size() >= 1 && arrayValue->data[0].value->isUninit(dataBase);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!uninitData)
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// container is not uninitialized
|
|
||||||
if (tok->valueType() && tok->valueType()->pointer==0 && tok->valueType()->container)
|
|
||||||
return;
|
|
||||||
|
|
||||||
// container element is not uninitialized
|
|
||||||
if (tok->str() == "[" &&
|
|
||||||
tok->astOperand1() &&
|
|
||||||
tok->astOperand1()->valueType() &&
|
|
||||||
tok->astOperand1()->valueType()->pointer==0 &&
|
|
||||||
tok->astOperand1()->valueType()->container) {
|
|
||||||
if (tok->astOperand1()->valueType()->container->stdStringLike)
|
|
||||||
return;
|
|
||||||
bool pointerType = false;
|
|
||||||
for (const Token *typeTok = tok->astOperand1()->valueType()->containerTypeToken; Token::Match(typeTok, "%name%|*|::|<"); typeTok = typeTok->next()) {
|
|
||||||
if (typeTok->str() == "<" && typeTok->link())
|
|
||||||
typeTok = typeTok->link();
|
|
||||||
if (typeTok->str() == "*")
|
|
||||||
pointerType = true;
|
|
||||||
}
|
|
||||||
if (!pointerType)
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// variable that is not uninitialized..
|
|
||||||
if (tok->variable() && !tok->variable()->isPointer() && !tok->variable()->isReference()) {
|
|
||||||
// smart pointer is not uninitialized
|
|
||||||
if (tok->variable()->isSmartPointer())
|
|
||||||
return;
|
|
||||||
|
|
||||||
// struct
|
|
||||||
if (tok->variable()->type() && tok->variable()->type()->needInitialization == Type::NeedInitialization::False)
|
|
||||||
return;
|
|
||||||
|
|
||||||
// template variable is not uninitialized
|
|
||||||
if (Token::findmatch(tok->variable()->typeStartToken(), "%name% <", tok->variable()->typeEndToken()))
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// lhs in assignment
|
|
||||||
if (tok->astParent()->str() == "=" && tok == tok->astParent()->astOperand1())
|
|
||||||
return;
|
|
||||||
|
|
||||||
// Avoid FP when there is bailout..
|
|
||||||
if (value.type == ExprEngine::ValueType::BailoutValue) {
|
|
||||||
if (tok->hasKnownValue())
|
|
||||||
return;
|
|
||||||
if (!tok->variable())
|
|
||||||
// FIXME
|
|
||||||
return;
|
|
||||||
|
|
||||||
// lhs for scope operator
|
|
||||||
if (Token::Match(tok, "%name% ::"))
|
|
||||||
return;
|
|
||||||
if (tok->astParent()->str() == "::" && tok == tok->astParent()->astOperand1())
|
|
||||||
return;
|
|
||||||
|
|
||||||
// Object allocated on the stack
|
|
||||||
if (Token::Match(tok, "%var% .") && tok->next()->originalName() != "->")
|
|
||||||
return;
|
|
||||||
|
|
||||||
// Assume that stream object is initialized
|
|
||||||
if (Token::Match(tok->previous(), "[;{}] %var% <<|>>") && !tok->next()->astParent())
|
|
||||||
return;
|
|
||||||
|
|
||||||
// Containers are not uninitialized
|
|
||||||
std::vector<const Token *> tokens{tok, tok->astOperand1(), tok->astOperand2()};
|
|
||||||
if (Token::Match(tok->previous(), ". %name%"))
|
|
||||||
tokens.push_back(tok->previous()->astOperand1());
|
|
||||||
for (const Token *t: tokens) {
|
|
||||||
if (t && t->valueType() && t->valueType()->pointer == 0 && t->valueType()->container)
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const Variable *var = tok->variable();
|
|
||||||
if (var && var->nameToken() == tok)
|
|
||||||
return;
|
|
||||||
if (var && !var->isLocal())
|
|
||||||
return; // FIXME
|
|
||||||
if (var && !var->isPointer()) {
|
|
||||||
if (!var->isLocal() || var->isStatic())
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (var && (Token::Match(var->nameToken(), "%name% [=:({)]") || var->isInit()))
|
|
||||||
return;
|
|
||||||
if (var && var->nameToken() == tok)
|
|
||||||
return;
|
|
||||||
|
|
||||||
// Are there unconditional assignment?
|
|
||||||
if (var && Token::Match(var->nameToken(), "%varid% ;| %varid%| =", tok->varId()))
|
|
||||||
return;
|
|
||||||
|
|
||||||
// Arrays are allocated on the stack
|
|
||||||
if (var && Token::Match(tok, "%var% [") && var->isArray())
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (tok->variable() && isVariableAssigned(tok->variable(), tok))
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Uninitialized function argument
|
|
||||||
bool inconclusive = false;
|
|
||||||
if (Token::Match(tok->astParent(), "[,(]")) {
|
|
||||||
const Token *parent = tok->astParent();
|
|
||||||
int count = 0;
|
|
||||||
if (Token::simpleMatch(parent, ",")) {
|
|
||||||
if (tok == parent->astOperand2())
|
|
||||||
count = 1;
|
|
||||||
parent = parent->astParent();
|
|
||||||
while (Token::simpleMatch(parent, ",")) {
|
|
||||||
count++;
|
|
||||||
parent = parent->astParent();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (Token::simpleMatch(parent, "(") && parent->astOperand1() != tok) {
|
|
||||||
if (parent->astOperand1()->function()) {
|
|
||||||
const Variable *argvar = parent->astOperand1()->function()->getArgumentVar(count);
|
|
||||||
if (argvar && argvar->isReference() && !argvar->isConst())
|
|
||||||
return;
|
|
||||||
if (uninitData && argvar && !argvar->isConst()) {
|
|
||||||
if (parent->astOperand1()->function()->hasBody())
|
|
||||||
return;
|
|
||||||
inconclusive = true;
|
|
||||||
}
|
|
||||||
if (!uninitStructMember.empty() && dataBase->isC() && argvar && !argvar->isConst()) {
|
|
||||||
if (parent->astOperand1()->function()->hasBody())
|
|
||||||
return;
|
|
||||||
inconclusive = true;
|
|
||||||
}
|
|
||||||
} else if (uninitData) {
|
|
||||||
if (dataBase->settings->library.getFunction(parent->astOperand1()))
|
|
||||||
return;
|
|
||||||
if (parent->astOperand1()->isKeyword())
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
} else if (uninitData)
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (inconclusive && !dataBase->settings->certainty.isEnabled(Certainty::inconclusive))
|
|
||||||
return;
|
|
||||||
|
|
||||||
// Avoid FP for array declaration
|
|
||||||
const Token *parent = tok->astParent();
|
|
||||||
while (parent && parent->str() == "[")
|
|
||||||
parent = parent->astParent();
|
|
||||||
if (!parent)
|
|
||||||
return;
|
|
||||||
|
|
||||||
const std::string inconclusiveMessage(inconclusive ? ". It is inconclusive if there would be a problem in the function call." : "");
|
|
||||||
|
|
||||||
if (!uninitStructMember.empty()) {
|
|
||||||
const std::string symbol = tok->expressionString() + "." + uninitStructMember;
|
|
||||||
dataBase->reportError(tok,
|
|
||||||
Severity::SeverityType::error,
|
|
||||||
"bughuntingUninitStructMember",
|
|
||||||
"$symbol:" + symbol + "\nCannot determine that '$symbol' is initialized" + inconclusiveMessage,
|
|
||||||
CWE_USE_OF_UNINITIALIZED_VARIABLE,
|
|
||||||
inconclusive,
|
|
||||||
value.type == ExprEngine::ValueType::BailoutValue);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string uninitexpr = tok->expressionString();
|
|
||||||
if (uninitData)
|
|
||||||
uninitexpr += "[0]";
|
|
||||||
|
|
||||||
const std::string symbol = (tok->varId() > 0) ? ("$symbol:" + tok->str() + "\n") : std::string();
|
|
||||||
|
|
||||||
std::string constMessage;
|
|
||||||
std::string errorId = "bughuntingUninit";
|
|
||||||
|
|
||||||
{
|
|
||||||
const Token *vartok = tok;
|
|
||||||
while (Token::Match(vartok, ".|["))
|
|
||||||
vartok = vartok->astOperand1();
|
|
||||||
const Variable *var = vartok ? vartok->variable() : nullptr;
|
|
||||||
if (var && var->isArgument()) {
|
|
||||||
errorId += "NonConstArg";
|
|
||||||
constMessage = " (you can use 'const' to say data must be initialized)";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
dataBase->reportError(tok,
|
|
||||||
Severity::SeverityType::error,
|
|
||||||
errorId.c_str(),
|
|
||||||
symbol + "Cannot determine that '" + uninitexpr + "' is initialized" + constMessage + inconclusiveMessage,
|
|
||||||
CWE_USE_OF_UNINITIALIZED_VARIABLE,
|
|
||||||
inconclusive,
|
|
||||||
value.type == ExprEngine::ValueType::BailoutValue);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void checkFunctionCall(const Token *tok, const ExprEngine::Value &value, ExprEngine::DataBase *dataBase)
|
|
||||||
{
|
|
||||||
if (!Token::Match(tok->astParent(), "[(,]"))
|
|
||||||
return;
|
|
||||||
const Token *parent = tok->astParent();
|
|
||||||
while (Token::simpleMatch(parent, ","))
|
|
||||||
parent = parent->astParent();
|
|
||||||
if (!parent || parent->str() != "(")
|
|
||||||
return;
|
|
||||||
|
|
||||||
int num = 0;
|
|
||||||
for (const Token *argTok: getArguments(parent->astOperand1())) {
|
|
||||||
--num;
|
|
||||||
if (argTok == tok) {
|
|
||||||
num = -num;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (num <= 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (parent->astOperand1()->function()) {
|
|
||||||
const Variable *arg = parent->astOperand1()->function()->getArgumentVar(num - 1);
|
|
||||||
if (arg && arg->nameToken()) {
|
|
||||||
std::string bad;
|
|
||||||
|
|
||||||
MathLib::bigint low;
|
|
||||||
if (arg->nameToken()->getCppcheckAttribute(TokenImpl::CppcheckAttributes::Type::LOW, &low)) {
|
|
||||||
if (!(tok->hasKnownIntValue() && tok->getKnownIntValue() >= low) && value.isLessThan(dataBase, low))
|
|
||||||
bad = "__cppcheck_low__(" + std::to_string(low) + ")";
|
|
||||||
}
|
|
||||||
|
|
||||||
MathLib::bigint high;
|
|
||||||
if (arg->nameToken()->getCppcheckAttribute(TokenImpl::CppcheckAttributes::Type::HIGH, &high)) {
|
|
||||||
if (!(tok->hasKnownIntValue() && tok->getKnownIntValue() <= high) && value.isGreaterThan(dataBase, high))
|
|
||||||
bad = "__cppcheck_high__(" + std::to_string(high) + ")";
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!bad.empty()) {
|
|
||||||
dataBase->reportError(tok,
|
|
||||||
Severity::SeverityType::error,
|
|
||||||
"bughuntingInvalidArgValue",
|
|
||||||
"There is function call, cannot determine that " + std::to_string(num) + getOrdinalText(num) + " argument value meets the attribute " + bad,
|
|
||||||
CWE(0),
|
|
||||||
false);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check invalid function argument values..
|
|
||||||
for (const Library::InvalidArgValue &invalidArgValue : Library::getInvalidArgValues(dataBase->settings->library.validarg(parent->astOperand1(), num))) {
|
|
||||||
bool err = false;
|
|
||||||
std::string bad;
|
|
||||||
switch (invalidArgValue.type) {
|
|
||||||
case Library::InvalidArgValue::Type::eq:
|
|
||||||
if (!tok->hasKnownIntValue() || tok->getKnownIntValue() == MathLib::toLongNumber(invalidArgValue.op1))
|
|
||||||
err = value.isEqual(dataBase, MathLib::toLongNumber(invalidArgValue.op1));
|
|
||||||
bad = "equals " + invalidArgValue.op1;
|
|
||||||
break;
|
|
||||||
case Library::InvalidArgValue::Type::le:
|
|
||||||
if (!tok->hasKnownIntValue() || tok->getKnownIntValue() <= MathLib::toLongNumber(invalidArgValue.op1))
|
|
||||||
err = value.isLessThan(dataBase, MathLib::toLongNumber(invalidArgValue.op1) + 1);
|
|
||||||
bad = "less equal " + invalidArgValue.op1;
|
|
||||||
break;
|
|
||||||
case Library::InvalidArgValue::Type::lt:
|
|
||||||
if (!tok->hasKnownIntValue() || tok->getKnownIntValue() < MathLib::toLongNumber(invalidArgValue.op1))
|
|
||||||
err = value.isLessThan(dataBase, MathLib::toLongNumber(invalidArgValue.op1));
|
|
||||||
bad = "less than " + invalidArgValue.op1;
|
|
||||||
break;
|
|
||||||
case Library::InvalidArgValue::Type::ge:
|
|
||||||
if (!tok->hasKnownIntValue() || tok->getKnownIntValue() >= MathLib::toLongNumber(invalidArgValue.op1))
|
|
||||||
err = value.isGreaterThan(dataBase, MathLib::toLongNumber(invalidArgValue.op1) - 1);
|
|
||||||
bad = "greater equal " + invalidArgValue.op1;
|
|
||||||
break;
|
|
||||||
case Library::InvalidArgValue::Type::gt:
|
|
||||||
if (!tok->hasKnownIntValue() || tok->getKnownIntValue() > MathLib::toLongNumber(invalidArgValue.op1))
|
|
||||||
err = value.isGreaterThan(dataBase, MathLib::toLongNumber(invalidArgValue.op1));
|
|
||||||
bad = "greater than " + invalidArgValue.op1;
|
|
||||||
break;
|
|
||||||
case Library::InvalidArgValue::Type::range:
|
|
||||||
// TODO
|
|
||||||
err = value.isEqual(dataBase, MathLib::toLongNumber(invalidArgValue.op1));
|
|
||||||
err |= value.isEqual(dataBase, MathLib::toLongNumber(invalidArgValue.op2));
|
|
||||||
bad = "range " + invalidArgValue.op1 + "-" + invalidArgValue.op2;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (err) {
|
|
||||||
dataBase->reportError(tok, Severity::SeverityType::error, "bughuntingInvalidArgValue", "There is function call, cannot determine that " + std::to_string(num) + getOrdinalText(num) + " argument value is valid. Bad value: " + bad, CWE(0), false);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Uninitialized function argument..
|
|
||||||
if (dataBase->settings->library.isuninitargbad(parent->astOperand1(), num) && dataBase->settings->library.isnullargbad(parent->astOperand1(), num) && value.type == ExprEngine::ValueType::ArrayValue) {
|
|
||||||
const ExprEngine::ArrayValue &arrayValue = static_cast<const ExprEngine::ArrayValue &>(value);
|
|
||||||
auto index0 = std::make_shared<ExprEngine::IntRange>("0", 0, 0);
|
|
||||||
for (const auto &v: arrayValue.read(index0)) {
|
|
||||||
if (v.second->isUninit(dataBase)) {
|
|
||||||
dataBase->reportError(tok, Severity::SeverityType::error, "bughuntingUninitArg", "There is function call, cannot determine that " + std::to_string(num) + getOrdinalText(num) + " argument is initialized.", CWE_USE_OF_UNINITIALIZED_VARIABLE, false);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void checkAssignment(const Token *tok, const ExprEngine::Value &value, ExprEngine::DataBase *dataBase)
|
|
||||||
{
|
|
||||||
if (!Token::simpleMatch(tok->astParent(), "="))
|
|
||||||
return;
|
|
||||||
const Token *lhs = tok->astParent()->astOperand1();
|
|
||||||
while (Token::simpleMatch(lhs, "."))
|
|
||||||
lhs = lhs->astOperand2();
|
|
||||||
if (!lhs || !lhs->variable() || !lhs->variable()->nameToken())
|
|
||||||
return;
|
|
||||||
|
|
||||||
const Token *vartok = lhs->variable()->nameToken();
|
|
||||||
|
|
||||||
bool executable = false;
|
|
||||||
std::string fullName = lhs->variable()->name();
|
|
||||||
for (const Scope *s = lhs->variable()->nameToken()->scope(); s->type != Scope::ScopeType::eGlobal; s = s->nestedIn) {
|
|
||||||
if (s->isExecutable()) {
|
|
||||||
executable = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
fullName = s->className + "::" + fullName;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto getMinMaxValue = [=](TokenImpl::CppcheckAttributes::Type type, MathLib::bigint *val) {
|
|
||||||
if (vartok->getCppcheckAttribute(type, val))
|
|
||||||
return true;
|
|
||||||
if (!executable) {
|
|
||||||
const auto it = dataBase->settings->variableContracts.find(fullName);
|
|
||||||
if (it != dataBase->settings->variableContracts.end()) {
|
|
||||||
const std::string *str;
|
|
||||||
if (type == TokenImpl::CppcheckAttributes::Type::LOW)
|
|
||||||
str = &it->second.minValue;
|
|
||||||
else if (type == TokenImpl::CppcheckAttributes::Type::HIGH)
|
|
||||||
str = &it->second.maxValue;
|
|
||||||
else
|
|
||||||
return false;
|
|
||||||
*val = MathLib::toLongNumber(*str);
|
|
||||||
return !str->empty();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
};
|
|
||||||
|
|
||||||
MathLib::bigint low;
|
|
||||||
if (getMinMaxValue(TokenImpl::CppcheckAttributes::Type::LOW, &low)) {
|
|
||||||
if (value.isLessThan(dataBase, low))
|
|
||||||
dataBase->reportError(tok, Severity::SeverityType::error, "bughuntingAssign", "There is assignment, cannot determine that value is greater or equal with " + std::to_string(low), CWE_INCORRECT_CALCULATION, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
MathLib::bigint high;
|
|
||||||
if (getMinMaxValue(TokenImpl::CppcheckAttributes::Type::HIGH, &high)) {
|
|
||||||
if (value.isGreaterThan(dataBase, high))
|
|
||||||
dataBase->reportError(tok, Severity::SeverityType::error, "bughuntingAssign", "There is assignment, cannot determine that value is lower or equal with " + std::to_string(high), CWE_INCORRECT_CALCULATION, false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void addBughuntingChecks(std::vector<ExprEngine::Callback> *callbacks)
|
|
||||||
{
|
|
||||||
callbacks->push_back(arrayIndex);
|
|
||||||
callbacks->push_back(bufferOverflow);
|
|
||||||
callbacks->push_back(divByZero);
|
|
||||||
callbacks->push_back(checkFunctionCall);
|
|
||||||
callbacks->push_back(checkAssignment);
|
|
||||||
#ifdef BUG_HUNTING_INTEGEROVERFLOW
|
|
||||||
callbacks->push_back(integerOverflow);
|
|
||||||
#endif
|
|
||||||
callbacks->push_back(uninit);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,31 +0,0 @@
|
||||||
/*
|
|
||||||
* Cppcheck - A tool for static C/C++ code analysis
|
|
||||||
* Copyright (C) 2007-2022 Cppcheck team.
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
//---------------------------------------------------------------------------
|
|
||||||
#ifndef bughuntingchecksH
|
|
||||||
#define bughuntingchecksH
|
|
||||||
//---------------------------------------------------------------------------
|
|
||||||
|
|
||||||
#include "exprengine.h"
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
void addBughuntingChecks(std::vector<ExprEngine::Callback> *callbacks);
|
|
||||||
|
|
||||||
//---------------------------------------------------------------------------
|
|
||||||
#endif // bughuntingchecksH
|
|
|
@ -51,7 +51,7 @@ void Check::reportError(const ErrorMessage &errmsg)
|
||||||
|
|
||||||
void Check::reportError(const std::list<const Token *> &callstack, Severity::SeverityType severity, const std::string &id, const std::string &msg, const CWE &cwe, Certainty::CertaintyLevel certainty)
|
void Check::reportError(const std::list<const Token *> &callstack, Severity::SeverityType severity, const std::string &id, const std::string &msg, const CWE &cwe, Certainty::CertaintyLevel certainty)
|
||||||
{
|
{
|
||||||
const ErrorMessage errmsg(callstack, mTokenizer ? &mTokenizer->list : nullptr, severity, id, msg, cwe, certainty, mSettings ? mSettings->bugHunting : false);
|
const ErrorMessage errmsg(callstack, mTokenizer ? &mTokenizer->list : nullptr, severity, id, msg, cwe, certainty);
|
||||||
if (mErrorLogger)
|
if (mErrorLogger)
|
||||||
mErrorLogger->reportErr(errmsg);
|
mErrorLogger->reportErr(errmsg);
|
||||||
else
|
else
|
||||||
|
@ -60,7 +60,7 @@ void Check::reportError(const std::list<const Token *> &callstack, Severity::Sev
|
||||||
|
|
||||||
void Check::reportError(const ErrorPath &errorPath, Severity::SeverityType severity, const char id[], const std::string &msg, const CWE &cwe, Certainty::CertaintyLevel certainty)
|
void Check::reportError(const ErrorPath &errorPath, Severity::SeverityType severity, const char id[], const std::string &msg, const CWE &cwe, Certainty::CertaintyLevel certainty)
|
||||||
{
|
{
|
||||||
const ErrorMessage errmsg(errorPath, mTokenizer ? &mTokenizer->list : nullptr, severity, id, msg, cwe, certainty, mSettings ? mSettings->bugHunting : false);
|
const ErrorMessage errmsg(errorPath, mTokenizer ? &mTokenizer->list : nullptr, severity, id, msg, cwe, certainty);
|
||||||
if (mErrorLogger)
|
if (mErrorLogger)
|
||||||
mErrorLogger->reportErr(errmsg);
|
mErrorLogger->reportErr(errmsg);
|
||||||
else
|
else
|
||||||
|
|
|
@ -302,7 +302,7 @@ void CheckMemoryLeak::reportErr(const Token *tok, Severity::SeverityType severit
|
||||||
|
|
||||||
void CheckMemoryLeak::reportErr(const std::list<const Token *> &callstack, Severity::SeverityType severity, const std::string &id, const std::string &msg, const CWE &cwe) const
|
void CheckMemoryLeak::reportErr(const std::list<const Token *> &callstack, Severity::SeverityType severity, const std::string &id, const std::string &msg, const CWE &cwe) const
|
||||||
{
|
{
|
||||||
const ErrorMessage errmsg(callstack, mTokenizer_ ? &mTokenizer_->list : nullptr, severity, id, msg, cwe, Certainty::normal, mSettings_->bugHunting);
|
const ErrorMessage errmsg(callstack, mTokenizer_ ? &mTokenizer_->list : nullptr, severity, id, msg, cwe, Certainty::normal);
|
||||||
if (mErrorLogger_)
|
if (mErrorLogger_)
|
||||||
mErrorLogger_->reportErr(errmsg);
|
mErrorLogger_->reportErr(errmsg);
|
||||||
else
|
else
|
||||||
|
|
|
@ -23,7 +23,6 @@
|
||||||
#include "color.h"
|
#include "color.h"
|
||||||
#include "ctu.h"
|
#include "ctu.h"
|
||||||
#include "errortypes.h"
|
#include "errortypes.h"
|
||||||
#include "exprengine.h"
|
|
||||||
#include "library.h"
|
#include "library.h"
|
||||||
#include "mathlib.h"
|
#include "mathlib.h"
|
||||||
#include "path.h"
|
#include "path.h"
|
||||||
|
@ -1016,44 +1015,39 @@ void CppCheck::checkRawTokens(const Tokenizer &tokenizer)
|
||||||
|
|
||||||
void CppCheck::checkNormalTokens(const Tokenizer &tokenizer)
|
void CppCheck::checkNormalTokens(const Tokenizer &tokenizer)
|
||||||
{
|
{
|
||||||
mSettings.library.bugHunting = mSettings.bugHunting;
|
// call all "runChecks" in all registered Check classes
|
||||||
if (mSettings.bugHunting)
|
for (Check *check : Check::instances()) {
|
||||||
ExprEngine::runChecks(this, &tokenizer, &mSettings);
|
if (Settings::terminated())
|
||||||
else {
|
|
||||||
// call all "runChecks" in all registered Check classes
|
|
||||||
for (Check *check : Check::instances()) {
|
|
||||||
if (Settings::terminated())
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (Tokenizer::isMaxTime())
|
|
||||||
return;
|
|
||||||
|
|
||||||
Timer timerRunChecks(check->name() + "::runChecks", mSettings.showtime, &s_timerResults);
|
|
||||||
check->runChecks(&tokenizer, &mSettings, this);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mSettings.clang)
|
|
||||||
// TODO: Use CTU for Clang analysis
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Analyse the tokens..
|
if (Tokenizer::isMaxTime())
|
||||||
|
return;
|
||||||
|
|
||||||
CTU::FileInfo *fi1 = CTU::getFileInfo(&tokenizer);
|
Timer timerRunChecks(check->name() + "::runChecks", mSettings.showtime, &s_timerResults);
|
||||||
if (fi1) {
|
check->runChecks(&tokenizer, &mSettings, this);
|
||||||
mFileInfo.push_back(fi1);
|
|
||||||
mAnalyzerInformation.setFileInfo("ctu", fi1->toString());
|
|
||||||
}
|
|
||||||
|
|
||||||
for (const Check *check : Check::instances()) {
|
|
||||||
Check::FileInfo *fi = check->getFileInfo(&tokenizer, &mSettings);
|
|
||||||
if (fi != nullptr) {
|
|
||||||
mFileInfo.push_back(fi);
|
|
||||||
mAnalyzerInformation.setFileInfo(check->name(), fi->toString());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
executeRules("normal", tokenizer);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (mSettings.clang)
|
||||||
|
// TODO: Use CTU for Clang analysis
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Analyse the tokens..
|
||||||
|
|
||||||
|
CTU::FileInfo *fi1 = CTU::getFileInfo(&tokenizer);
|
||||||
|
if (fi1) {
|
||||||
|
mFileInfo.push_back(fi1);
|
||||||
|
mAnalyzerInformation.setFileInfo("ctu", fi1->toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const Check *check : Check::instances()) {
|
||||||
|
Check::FileInfo *fi = check->getFileInfo(&tokenizer, &mSettings);
|
||||||
|
if (fi != nullptr) {
|
||||||
|
mFileInfo.push_back(fi);
|
||||||
|
mAnalyzerInformation.setFileInfo(check->name(), fi->toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
executeRules("normal", tokenizer);
|
||||||
}
|
}
|
||||||
|
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
@ -1573,11 +1567,6 @@ void CppCheck::reportInfo(const ErrorMessage &msg)
|
||||||
void CppCheck::reportStatus(unsigned int /*fileindex*/, unsigned int /*filecount*/, std::size_t /*sizedone*/, std::size_t /*sizetotal*/)
|
void CppCheck::reportStatus(unsigned int /*fileindex*/, unsigned int /*filecount*/, std::size_t /*sizedone*/, std::size_t /*sizetotal*/)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
void CppCheck::bughuntingReport(const std::string &str)
|
|
||||||
{
|
|
||||||
mErrorLogger.bughuntingReport(str);
|
|
||||||
}
|
|
||||||
|
|
||||||
void CppCheck::getErrorMessages()
|
void CppCheck::getErrorMessages()
|
||||||
{
|
{
|
||||||
Settings s(mSettings);
|
Settings s(mSettings);
|
||||||
|
|
|
@ -206,8 +206,6 @@ private:
|
||||||
*/
|
*/
|
||||||
void reportOut(const std::string &outmsg, Color c = Color::Reset) override;
|
void reportOut(const std::string &outmsg, Color c = Color::Reset) override;
|
||||||
|
|
||||||
void bughuntingReport(const std::string &str) override;
|
|
||||||
|
|
||||||
std::list<std::string> mErrorList;
|
std::list<std::string> mErrorList;
|
||||||
Settings mSettings;
|
Settings mSettings;
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
<ItemGroup Label="ProjectConfigurations">
|
<ItemGroup Label="ProjectConfigurations">
|
||||||
<ProjectConfiguration Include="Debug-PCRE|Win32">
|
<ProjectConfiguration Include="Debug-PCRE|Win32">
|
||||||
|
@ -39,7 +38,6 @@
|
||||||
<ClCompile Include="..\externals\tinyxml2\tinyxml2.cpp" />
|
<ClCompile Include="..\externals\tinyxml2\tinyxml2.cpp" />
|
||||||
<ClCompile Include="analyzerinfo.cpp" />
|
<ClCompile Include="analyzerinfo.cpp" />
|
||||||
<ClCompile Include="astutils.cpp" />
|
<ClCompile Include="astutils.cpp" />
|
||||||
<ClCompile Include="bughuntingchecks.cpp" />
|
|
||||||
<ClCompile Include="check.cpp">
|
<ClCompile Include="check.cpp">
|
||||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Create</PrecompiledHeader>
|
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Create</PrecompiledHeader>
|
||||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader>
|
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader>
|
||||||
|
@ -81,7 +79,6 @@
|
||||||
<ClCompile Include="ctu.cpp" />
|
<ClCompile Include="ctu.cpp" />
|
||||||
<ClCompile Include="errorlogger.cpp" />
|
<ClCompile Include="errorlogger.cpp" />
|
||||||
<ClCompile Include="errortypes.cpp" />
|
<ClCompile Include="errortypes.cpp" />
|
||||||
<ClCompile Include="exprengine.cpp" />
|
|
||||||
<ClCompile Include="infer.cpp" />
|
<ClCompile Include="infer.cpp" />
|
||||||
<ClCompile Include="library.cpp" />
|
<ClCompile Include="library.cpp" />
|
||||||
<ClCompile Include="mathlib.cpp" />
|
<ClCompile Include="mathlib.cpp" />
|
||||||
|
@ -111,7 +108,6 @@
|
||||||
<ClInclude Include="..\externals\tinyxml2\tinyxml2.h" />
|
<ClInclude Include="..\externals\tinyxml2\tinyxml2.h" />
|
||||||
<ClInclude Include="analyzerinfo.h" />
|
<ClInclude Include="analyzerinfo.h" />
|
||||||
<ClInclude Include="astutils.h" />
|
<ClInclude Include="astutils.h" />
|
||||||
<ClInclude Include="bughuntingchecks.h" />
|
|
||||||
<ClInclude Include="check.h" />
|
<ClInclude Include="check.h" />
|
||||||
<ClInclude Include="check64bit.h" />
|
<ClInclude Include="check64bit.h" />
|
||||||
<ClInclude Include="checkassert.h" />
|
<ClInclude Include="checkassert.h" />
|
||||||
|
|
|
@ -161,9 +161,6 @@
|
||||||
<ClCompile Include="ctu.cpp">
|
<ClCompile Include="ctu.cpp">
|
||||||
<Filter>Source Files</Filter>
|
<Filter>Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="exprengine.cpp">
|
|
||||||
<Filter>Source Files</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="pathanalysis.cpp">
|
<ClCompile Include="pathanalysis.cpp">
|
||||||
<Filter>Source Files</Filter>
|
<Filter>Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
@ -182,9 +179,6 @@
|
||||||
<ClCompile Include="summaries.cpp">
|
<ClCompile Include="summaries.cpp">
|
||||||
<Filter>Source Files</Filter>
|
<Filter>Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="bughuntingchecks.cpp">
|
|
||||||
<Filter>Source Files</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="reverseanalyzer.cpp">
|
<ClCompile Include="reverseanalyzer.cpp">
|
||||||
<Filter>Source Files</Filter>
|
<Filter>Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
@ -364,9 +358,6 @@
|
||||||
<ClInclude Include="summaries.h">
|
<ClInclude Include="summaries.h">
|
||||||
<Filter>Header Files</Filter>
|
<Filter>Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
<ClInclude Include="bughuntingchecks.h">
|
|
||||||
<Filter>Header Files</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="tokenrange.h">
|
<ClInclude Include="tokenrange.h">
|
||||||
<Filter>Header Files</Filter>
|
<Filter>Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
|
|
@ -61,14 +61,6 @@ InternalError::InternalError(const Token *tok, const std::string &errorMsg, Type
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::size_t calculateWarningHash(const TokenList *tokenList, const std::string &msg)
|
|
||||||
{
|
|
||||||
if (!tokenList)
|
|
||||||
return 0;
|
|
||||||
return std::hash<std::string> {}(msg + "\n" + tokenList->front()->stringifyList(false, true, false, false, false));
|
|
||||||
}
|
|
||||||
|
|
||||||
ErrorMessage::ErrorMessage()
|
ErrorMessage::ErrorMessage()
|
||||||
: incomplete(false), severity(Severity::none), cwe(0U), certainty(Certainty::normal), hash(0)
|
: incomplete(false), severity(Severity::none), cwe(0U), certainty(Certainty::normal), hash(0)
|
||||||
{}
|
{}
|
||||||
|
@ -122,7 +114,7 @@ ErrorMessage::ErrorMessage(const std::list<const Token*>& callstack, const Token
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
ErrorMessage::ErrorMessage(const std::list<const Token*>& callstack, const TokenList* list, Severity::SeverityType severity, const std::string& id, const std::string& msg, const CWE &cwe, Certainty::CertaintyLevel certainty, bool bugHunting)
|
ErrorMessage::ErrorMessage(const std::list<const Token*>& callstack, const TokenList* list, Severity::SeverityType severity, const std::string& id, const std::string& msg, const CWE &cwe, Certainty::CertaintyLevel certainty)
|
||||||
: id(id), incomplete(false), severity(severity), cwe(cwe.id), certainty(certainty)
|
: id(id), incomplete(false), severity(severity), cwe(cwe.id), certainty(certainty)
|
||||||
{
|
{
|
||||||
// Format callstack
|
// Format callstack
|
||||||
|
@ -139,15 +131,10 @@ ErrorMessage::ErrorMessage(const std::list<const Token*>& callstack, const Token
|
||||||
|
|
||||||
setmsg(msg);
|
setmsg(msg);
|
||||||
|
|
||||||
std::ostringstream hashWarning;
|
hash = 0; // calculateWarningHash(list, hashWarning.str());
|
||||||
for (const Token *tok: callstack)
|
|
||||||
hashWarning << std::hex << (tok ? tok->index() : 0) << " ";
|
|
||||||
hashWarning << mShortMessage;
|
|
||||||
|
|
||||||
hash = bugHunting ? calculateWarningHash(list, hashWarning.str()) : 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ErrorMessage::ErrorMessage(const ErrorPath &errorPath, const TokenList *tokenList, Severity::SeverityType severity, const char id[], const std::string &msg, const CWE &cwe, Certainty::CertaintyLevel certainty, bool bugHunting)
|
ErrorMessage::ErrorMessage(const ErrorPath &errorPath, const TokenList *tokenList, Severity::SeverityType severity, const char id[], const std::string &msg, const CWE &cwe, Certainty::CertaintyLevel certainty)
|
||||||
: id(id), incomplete(false), severity(severity), cwe(cwe.id), certainty(certainty)
|
: id(id), incomplete(false), severity(severity), cwe(cwe.id), certainty(certainty)
|
||||||
{
|
{
|
||||||
// Format callstack
|
// Format callstack
|
||||||
|
@ -171,12 +158,7 @@ ErrorMessage::ErrorMessage(const ErrorPath &errorPath, const TokenList *tokenLis
|
||||||
|
|
||||||
setmsg(msg);
|
setmsg(msg);
|
||||||
|
|
||||||
std::ostringstream hashWarning;
|
hash = 0; // calculateWarningHash(tokenList, hashWarning.str());
|
||||||
for (const ErrorPathItem &e: errorPath)
|
|
||||||
hashWarning << std::hex << (e.first ? e.first->index() : 0) << " ";
|
|
||||||
hashWarning << mShortMessage;
|
|
||||||
|
|
||||||
hash = bugHunting ? calculateWarningHash(tokenList, hashWarning.str()) : 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ErrorMessage::ErrorMessage(const tinyxml2::XMLElement * const errmsg)
|
ErrorMessage::ErrorMessage(const tinyxml2::XMLElement * const errmsg)
|
||||||
|
|
|
@ -144,16 +144,14 @@ public:
|
||||||
const std::string& id,
|
const std::string& id,
|
||||||
const std::string& msg,
|
const std::string& msg,
|
||||||
const CWE &cwe,
|
const CWE &cwe,
|
||||||
Certainty::CertaintyLevel certainty,
|
Certainty::CertaintyLevel certainty);
|
||||||
bool bugHunting);
|
|
||||||
ErrorMessage(const ErrorPath &errorPath,
|
ErrorMessage(const ErrorPath &errorPath,
|
||||||
const TokenList *tokenList,
|
const TokenList *tokenList,
|
||||||
Severity::SeverityType severity,
|
Severity::SeverityType severity,
|
||||||
const char id[],
|
const char id[],
|
||||||
const std::string &msg,
|
const std::string &msg,
|
||||||
const CWE &cwe,
|
const CWE &cwe,
|
||||||
Certainty::CertaintyLevel certainty,
|
Certainty::CertaintyLevel certainty);
|
||||||
bool bugHunting);
|
|
||||||
ErrorMessage();
|
ErrorMessage();
|
||||||
explicit ErrorMessage(const tinyxml2::XMLElement * const errmsg);
|
explicit ErrorMessage(const tinyxml2::XMLElement * const errmsg);
|
||||||
|
|
||||||
|
@ -283,8 +281,6 @@ public:
|
||||||
reportErr(msg);
|
reportErr(msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void bughuntingReport(const std::string &str) = 0;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Report unmatched suppressions
|
* Report unmatched suppressions
|
||||||
* @param unmatched list of unmatched suppressions (from Settings::Suppressions::getUnmatched(Local|Global)Suppressions)
|
* @param unmatched list of unmatched suppressions (from Settings::Suppressions::getUnmatched(Local|Global)Suppressions)
|
||||||
|
|
3174
lib/exprengine.cpp
3174
lib/exprengine.cpp
File diff suppressed because it is too large
Load Diff
348
lib/exprengine.h
348
lib/exprengine.h
|
@ -1,348 +0,0 @@
|
||||||
/*
|
|
||||||
* Cppcheck - A tool for static C/C++ code analysis
|
|
||||||
* Copyright (C) 2007-2022 Cppcheck team.
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
//---------------------------------------------------------------------------
|
|
||||||
#ifndef exprengineH
|
|
||||||
#define exprengineH
|
|
||||||
//---------------------------------------------------------------------------
|
|
||||||
|
|
||||||
#include "config.h"
|
|
||||||
#include "errortypes.h"
|
|
||||||
|
|
||||||
#include <algorithm>
|
|
||||||
#include <functional>
|
|
||||||
#include <iosfwd>
|
|
||||||
#include <map>
|
|
||||||
#include <memory>
|
|
||||||
#include <string>
|
|
||||||
#include <vector>
|
|
||||||
#include <utility>
|
|
||||||
|
|
||||||
class ErrorLogger;
|
|
||||||
class Tokenizer;
|
|
||||||
class Scope;
|
|
||||||
class Settings;
|
|
||||||
class Token;
|
|
||||||
class Variable;
|
|
||||||
|
|
||||||
#if defined(__GNUC__) && defined (__SIZEOF_INT128__)
|
|
||||||
typedef __int128_t int128_t;
|
|
||||||
#else
|
|
||||||
typedef long long int128_t;
|
|
||||||
#ifdef _MSC_VER
|
|
||||||
#pragma message(__FILE__ "(" _CRT_STRINGIZE(__LINE__) ")" ": warning: TODO No 128-bit integer type is available => Limited analysis of large integers...")
|
|
||||||
#else
|
|
||||||
#warning TODO No 128-bit integer type is available => Limited analysis of large integers
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
namespace ExprEngine {
|
|
||||||
std::string str(int128_t);
|
|
||||||
|
|
||||||
// TODO we need to handle floats, containers, pointers, aliases and structs and stuff
|
|
||||||
enum class ValueType {
|
|
||||||
UninitValue,
|
|
||||||
IntRange,
|
|
||||||
FloatRange,
|
|
||||||
ConditionalValue,
|
|
||||||
ArrayValue,
|
|
||||||
StringLiteralValue,
|
|
||||||
StructValue,
|
|
||||||
AddressOfValue,
|
|
||||||
BinOpResult,
|
|
||||||
IntegerTruncation,
|
|
||||||
FunctionCallArgumentValues,
|
|
||||||
BailoutValue
|
|
||||||
};
|
|
||||||
|
|
||||||
class Value;
|
|
||||||
typedef std::shared_ptr<Value> ValuePtr;
|
|
||||||
|
|
||||||
class DataBase {
|
|
||||||
public:
|
|
||||||
explicit DataBase(const std::string ¤tFunction, const Settings *settings)
|
|
||||||
: currentFunction(currentFunction)
|
|
||||||
, settings(settings) {}
|
|
||||||
virtual std::string getNewSymbolName() = 0;
|
|
||||||
const std::string currentFunction;
|
|
||||||
const Settings * const settings;
|
|
||||||
virtual bool isC() const = 0;
|
|
||||||
virtual bool isCPP() const = 0;
|
|
||||||
virtual void reportError(const Token *tok,
|
|
||||||
Severity::SeverityType severity,
|
|
||||||
const char id[],
|
|
||||||
const std::string &text,
|
|
||||||
CWE cwe,
|
|
||||||
bool inconclusive,
|
|
||||||
bool incomplete=false,
|
|
||||||
const std::string &functionName = std::string()) = 0;
|
|
||||||
ErrorPath errorPath;
|
|
||||||
};
|
|
||||||
|
|
||||||
class Value {
|
|
||||||
public:
|
|
||||||
Value(const std::string &name, const ValueType type) : name(name), type(type) {}
|
|
||||||
virtual ~Value() {}
|
|
||||||
virtual std::string getRange() const {
|
|
||||||
return name;
|
|
||||||
}
|
|
||||||
virtual std::string getSymbolicExpression() const {
|
|
||||||
return name;
|
|
||||||
}
|
|
||||||
virtual bool isEqual(const DataBase *dataBase, int value) const {
|
|
||||||
(void)dataBase;
|
|
||||||
(void)value;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
virtual bool isGreaterThan(const DataBase *dataBase, int value) const {
|
|
||||||
(void)dataBase;
|
|
||||||
(void)value;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
virtual bool isLessThan(const DataBase *dataBase, int value) const {
|
|
||||||
(void)dataBase;
|
|
||||||
(void)value;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
virtual bool isUninit(const DataBase *dataBase) const {
|
|
||||||
(void)dataBase;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
const std::string name;
|
|
||||||
ValueType type;
|
|
||||||
};
|
|
||||||
|
|
||||||
class UninitValue : public Value {
|
|
||||||
public:
|
|
||||||
UninitValue() : Value("?", ValueType::UninitValue) {}
|
|
||||||
bool isEqual(const DataBase *dataBase, int value) const override {
|
|
||||||
(void)dataBase;
|
|
||||||
(void)value;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
bool isUninit(const DataBase *dataBase) const override;
|
|
||||||
};
|
|
||||||
|
|
||||||
class IntRange : public Value {
|
|
||||||
public:
|
|
||||||
IntRange(const std::string &name, int128_t minValue, int128_t maxValue)
|
|
||||||
: Value(name, ValueType::IntRange)
|
|
||||||
, minValue(minValue)
|
|
||||||
, maxValue(maxValue)
|
|
||||||
, loopScope(nullptr) {}
|
|
||||||
std::string getRange() const override {
|
|
||||||
if (minValue == maxValue)
|
|
||||||
return str(minValue);
|
|
||||||
return str(minValue) + ":" + str(maxValue);
|
|
||||||
}
|
|
||||||
bool isEqual(const DataBase *dataBase, int value) const override;
|
|
||||||
bool isGreaterThan(const DataBase *dataBase, int value) const override;
|
|
||||||
bool isLessThan(const DataBase *dataBase, int value) const override;
|
|
||||||
|
|
||||||
int128_t minValue;
|
|
||||||
int128_t maxValue;
|
|
||||||
const Scope *loopScope;
|
|
||||||
};
|
|
||||||
|
|
||||||
class FloatRange : public Value {
|
|
||||||
public:
|
|
||||||
FloatRange(const std::string &name, long double minValue, long double maxValue)
|
|
||||||
: Value(name, ValueType::FloatRange)
|
|
||||||
, minValue(minValue)
|
|
||||||
, maxValue(maxValue) {}
|
|
||||||
|
|
||||||
std::string getRange() const override {
|
|
||||||
return std::to_string(minValue) + ":" + std::to_string(maxValue);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool isEqual(const DataBase *dataBase, int value) const override;
|
|
||||||
bool isGreaterThan(const DataBase *dataBase, int value) const override;
|
|
||||||
bool isLessThan(const DataBase *dataBase, int value) const override;
|
|
||||||
|
|
||||||
long double minValue;
|
|
||||||
long double maxValue;
|
|
||||||
};
|
|
||||||
|
|
||||||
class ConditionalValue : public Value {
|
|
||||||
public:
|
|
||||||
typedef std::vector<std::pair<ValuePtr,ValuePtr>> Vector;
|
|
||||||
|
|
||||||
ConditionalValue(const std::string &name, const Vector &values) : Value(name, ValueType::ConditionalValue), values(values) {}
|
|
||||||
|
|
||||||
std::string getSymbolicExpression() const override;
|
|
||||||
|
|
||||||
Vector values;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Array or pointer
|
|
||||||
class ArrayValue : public Value {
|
|
||||||
public:
|
|
||||||
enum { MAXSIZE = 0x7fffffff };
|
|
||||||
|
|
||||||
ArrayValue(const std::string &name, ValuePtr size, ValuePtr value, bool pointer, bool nullPointer, bool uninitPointer);
|
|
||||||
ArrayValue(DataBase *data, const Variable *var);
|
|
||||||
ArrayValue(const std::string &name, const ArrayValue &arrayValue);
|
|
||||||
|
|
||||||
std::string getRange() const override;
|
|
||||||
std::string getSymbolicExpression() const override;
|
|
||||||
|
|
||||||
void assign(ValuePtr index, ValuePtr value);
|
|
||||||
void clear();
|
|
||||||
ConditionalValue::Vector read(ValuePtr index) const;
|
|
||||||
|
|
||||||
bool pointer;
|
|
||||||
bool nullPointer;
|
|
||||||
bool uninitPointer;
|
|
||||||
|
|
||||||
struct IndexAndValue {
|
|
||||||
ValuePtr index;
|
|
||||||
ValuePtr value;
|
|
||||||
};
|
|
||||||
std::vector<IndexAndValue> data;
|
|
||||||
std::vector<ValuePtr> size;
|
|
||||||
};
|
|
||||||
|
|
||||||
class StringLiteralValue : public Value {
|
|
||||||
public:
|
|
||||||
StringLiteralValue(const std::string &name, const std::string &s) : Value(name, ValueType::StringLiteralValue), string(s) {}
|
|
||||||
|
|
||||||
std::string getRange() const override {
|
|
||||||
return "\"" + string + "\"";
|
|
||||||
}
|
|
||||||
|
|
||||||
int size() const {
|
|
||||||
return string.size();
|
|
||||||
}
|
|
||||||
const std::string string;
|
|
||||||
};
|
|
||||||
|
|
||||||
class StructValue : public Value {
|
|
||||||
public:
|
|
||||||
explicit StructValue(const std::string &name) : Value(name, ValueType::StructValue) {}
|
|
||||||
|
|
||||||
std::string getSymbolicExpression() const override;
|
|
||||||
|
|
||||||
std::string getRange() const override {
|
|
||||||
return getSymbolicExpression();
|
|
||||||
}
|
|
||||||
|
|
||||||
ValuePtr getValueOfMember(const std::string &n) const {
|
|
||||||
auto it = member.find(n);
|
|
||||||
return (it == member.end()) ? ValuePtr() : it->second;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string getUninitStructMember(const DataBase *dataBase) const {
|
|
||||||
for (auto memberNameValue: member) {
|
|
||||||
if (memberNameValue.second && memberNameValue.second->isUninit(dataBase))
|
|
||||||
return memberNameValue.first;
|
|
||||||
}
|
|
||||||
return std::string();
|
|
||||||
}
|
|
||||||
|
|
||||||
std::map<std::string, ValuePtr> member;
|
|
||||||
};
|
|
||||||
|
|
||||||
class AddressOfValue : public Value {
|
|
||||||
public:
|
|
||||||
AddressOfValue(const std::string &name, int varId)
|
|
||||||
: Value(name, ValueType::AddressOfValue)
|
|
||||||
, varId(varId)
|
|
||||||
{}
|
|
||||||
|
|
||||||
std::string getRange() const override {
|
|
||||||
return "&@" + std::to_string(varId);
|
|
||||||
}
|
|
||||||
|
|
||||||
int varId;
|
|
||||||
};
|
|
||||||
|
|
||||||
class BinOpResult : public Value {
|
|
||||||
public:
|
|
||||||
BinOpResult(const std::string &binop, ValuePtr op1, ValuePtr op2)
|
|
||||||
: Value(getName(binop, op1, op2), ValueType::BinOpResult)
|
|
||||||
, binop(binop)
|
|
||||||
, op1(op1)
|
|
||||||
, op2(op2) {}
|
|
||||||
|
|
||||||
bool isEqual(const DataBase *dataBase, int value) const override;
|
|
||||||
bool isGreaterThan(const DataBase *dataBase, int value) const override;
|
|
||||||
virtual bool isLessThan(const DataBase *dataBase, int value) const override;
|
|
||||||
bool isTrue(const DataBase *dataBase) const;
|
|
||||||
|
|
||||||
std::string getExpr(DataBase *dataBase) const;
|
|
||||||
|
|
||||||
std::string binop;
|
|
||||||
ValuePtr op1;
|
|
||||||
ValuePtr op2;
|
|
||||||
private:
|
|
||||||
static std::string getName(const std::string& binop, ValuePtr op1, ValuePtr op2) {
|
|
||||||
std::string name1 = op1 ? op1->name : std::string("null");
|
|
||||||
std::string name2 = op2 ? op2->name : std::string("null");
|
|
||||||
return "(" + name1 + ")" + binop + "(" + name2 + ")";
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
class IntegerTruncation : public Value {
|
|
||||||
public:
|
|
||||||
IntegerTruncation(const std::string &name, ValuePtr inputValue, int bits, char sign)
|
|
||||||
: Value(name, ValueType::IntegerTruncation)
|
|
||||||
, inputValue(inputValue)
|
|
||||||
, bits(bits)
|
|
||||||
, sign(sign) {}
|
|
||||||
|
|
||||||
std::string getSymbolicExpression() const override;
|
|
||||||
|
|
||||||
ExprEngine::ValuePtr inputValue;
|
|
||||||
int bits;
|
|
||||||
char sign;
|
|
||||||
};
|
|
||||||
|
|
||||||
class FunctionCallArgumentValues : public Value {
|
|
||||||
public:
|
|
||||||
explicit FunctionCallArgumentValues(const std::vector<ExprEngine::ValuePtr> &argValues)
|
|
||||||
: Value("argValues", ValueType::FunctionCallArgumentValues)
|
|
||||||
, argValues(argValues)
|
|
||||||
{}
|
|
||||||
|
|
||||||
const std::vector<ExprEngine::ValuePtr> argValues;
|
|
||||||
};
|
|
||||||
|
|
||||||
class BailoutValue : public Value {
|
|
||||||
public:
|
|
||||||
BailoutValue() : Value("bailout", ValueType::BailoutValue) {}
|
|
||||||
bool isEqual(const DataBase * /*dataBase*/, int /*value*/) const override {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
bool isUninit(const DataBase *dataBase) const override {
|
|
||||||
(void)dataBase;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef std::function<void (const Token *, const ExprEngine::Value &, ExprEngine::DataBase *)> Callback;
|
|
||||||
|
|
||||||
/** Execute all functions */
|
|
||||||
void CPPCHECKLIB executeAllFunctions(ErrorLogger *errorLogger, const Tokenizer *tokenizer, const Settings *settings, const std::vector<Callback> &callbacks, std::ostream &report);
|
|
||||||
void executeFunction(const Scope *functionScope, ErrorLogger *errorLogger, const Tokenizer *tokenizer, const Settings *settings, const std::vector<Callback> &callbacks, std::ostream &report);
|
|
||||||
|
|
||||||
void runChecks(ErrorLogger *errorLogger, const Tokenizer *tokenizer, const Settings *settings);
|
|
||||||
|
|
||||||
void dump(ExprEngine::ValuePtr val);
|
|
||||||
}
|
|
||||||
#endif // exprengineH
|
|
|
@ -1168,7 +1168,7 @@ bool ImportProject::importCppcheckGuiProject(std::istream &istr, Settings *setti
|
||||||
temp.basePaths.push_back(joinRelativePath(path, node->Attribute(CppcheckXml::RootPathNameAttrib)));
|
temp.basePaths.push_back(joinRelativePath(path, node->Attribute(CppcheckXml::RootPathNameAttrib)));
|
||||||
temp.relativePaths = true;
|
temp.relativePaths = true;
|
||||||
} else if (strcmp(node->Name(), CppcheckXml::BugHunting) == 0)
|
} else if (strcmp(node->Name(), CppcheckXml::BugHunting) == 0)
|
||||||
temp.bugHunting = true;
|
;
|
||||||
else if (strcmp(node->Name(), CppcheckXml::BuildDirElementName) == 0)
|
else if (strcmp(node->Name(), CppcheckXml::BuildDirElementName) == 0)
|
||||||
temp.buildDir = joinRelativePath(path, node->GetText() ? node->GetText() : "");
|
temp.buildDir = joinRelativePath(path, node->GetText() ? node->GetText() : "");
|
||||||
else if (strcmp(node->Name(), CppcheckXml::IncludeDirElementName) == 0)
|
else if (strcmp(node->Name(), CppcheckXml::IncludeDirElementName) == 0)
|
||||||
|
@ -1184,26 +1184,11 @@ bool ImportProject::importCppcheckGuiProject(std::istream &istr, Settings *setti
|
||||||
paths = readXmlStringList(node, path, CppcheckXml::PathName, CppcheckXml::PathNameAttrib);
|
paths = readXmlStringList(node, path, CppcheckXml::PathName, CppcheckXml::PathNameAttrib);
|
||||||
else if (strcmp(node->Name(), CppcheckXml::ExcludeElementName) == 0)
|
else if (strcmp(node->Name(), CppcheckXml::ExcludeElementName) == 0)
|
||||||
guiProject.excludedPaths = readXmlStringList(node, "", CppcheckXml::ExcludePathName, CppcheckXml::ExcludePathNameAttrib);
|
guiProject.excludedPaths = readXmlStringList(node, "", CppcheckXml::ExcludePathName, CppcheckXml::ExcludePathNameAttrib);
|
||||||
else if (strcmp(node->Name(), CppcheckXml::FunctionContracts) == 0) {
|
else if (strcmp(node->Name(), CppcheckXml::FunctionContracts) == 0)
|
||||||
for (const tinyxml2::XMLElement *child = node->FirstChildElement(); child; child = child->NextSiblingElement()) {
|
;
|
||||||
if (strcmp(child->Name(), CppcheckXml::FunctionContract) == 0) {
|
else if (strcmp(node->Name(), CppcheckXml::VariableContractsElementName) == 0)
|
||||||
const char *function = child->Attribute(CppcheckXml::ContractFunction);
|
;
|
||||||
const char *expects = child->Attribute(CppcheckXml::ContractExpects);
|
else if (strcmp(node->Name(), CppcheckXml::IgnoreElementName) == 0)
|
||||||
if (function && expects)
|
|
||||||
temp.functionContracts[function] = expects;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if (strcmp(node->Name(), CppcheckXml::VariableContractsElementName) == 0) {
|
|
||||||
for (const tinyxml2::XMLElement *child = node->FirstChildElement(); child; child = child->NextSiblingElement()) {
|
|
||||||
if (strcmp(child->Name(), CppcheckXml::VariableContractItemElementName) == 0) {
|
|
||||||
const char *name = child->Attribute(CppcheckXml::VariableContractVarName);
|
|
||||||
const char *min = child->Attribute(CppcheckXml::VariableContractMin);
|
|
||||||
const char *max = child->Attribute(CppcheckXml::VariableContractMax);
|
|
||||||
if (name)
|
|
||||||
temp.variableContracts[name] = Settings::VariableContracts{min?min:"", max?max:""};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if (strcmp(node->Name(), CppcheckXml::IgnoreElementName) == 0)
|
|
||||||
guiProject.excludedPaths = readXmlStringList(node, "", CppcheckXml::IgnorePathName, CppcheckXml::IgnorePathNameAttrib);
|
guiProject.excludedPaths = readXmlStringList(node, "", CppcheckXml::IgnorePathName, CppcheckXml::IgnorePathNameAttrib);
|
||||||
else if (strcmp(node->Name(), CppcheckXml::LibrariesElementName) == 0)
|
else if (strcmp(node->Name(), CppcheckXml::LibrariesElementName) == 0)
|
||||||
guiProject.libraries = readXmlStringList(node, "", CppcheckXml::LibraryElementName, nullptr);
|
guiProject.libraries = readXmlStringList(node, "", CppcheckXml::LibraryElementName, nullptr);
|
||||||
|
@ -1289,8 +1274,6 @@ bool ImportProject::importCppcheckGuiProject(std::istream &istr, Settings *setti
|
||||||
settings->maxCtuDepth = temp.maxCtuDepth;
|
settings->maxCtuDepth = temp.maxCtuDepth;
|
||||||
settings->maxTemplateRecursion = temp.maxTemplateRecursion;
|
settings->maxTemplateRecursion = temp.maxTemplateRecursion;
|
||||||
settings->safeChecks = temp.safeChecks;
|
settings->safeChecks = temp.safeChecks;
|
||||||
settings->bugHunting = temp.bugHunting;
|
|
||||||
settings->functionContracts = temp.functionContracts;
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -153,14 +153,7 @@ namespace CppcheckXml {
|
||||||
const char ExcludePathName[] = "path";
|
const char ExcludePathName[] = "path";
|
||||||
const char ExcludePathNameAttrib[] = "name";
|
const char ExcludePathNameAttrib[] = "name";
|
||||||
const char FunctionContracts[] = "function-contracts";
|
const char FunctionContracts[] = "function-contracts";
|
||||||
const char FunctionContract[] = "contract";
|
|
||||||
const char ContractFunction[] = "function";
|
|
||||||
const char ContractExpects[] = "expects";
|
|
||||||
const char VariableContractsElementName[] = "variable-contracts";
|
const char VariableContractsElementName[] = "variable-contracts";
|
||||||
const char VariableContractItemElementName[] = "var";
|
|
||||||
const char VariableContractVarName[] = "name";
|
|
||||||
const char VariableContractMin[] = "min";
|
|
||||||
const char VariableContractMax[] = "max";
|
|
||||||
const char LibrariesElementName[] = "libraries";
|
const char LibrariesElementName[] = "libraries";
|
||||||
const char LibraryElementName[] = "library";
|
const char LibraryElementName[] = "library";
|
||||||
const char PlatformElementName[] = "platform";
|
const char PlatformElementName[] = "platform";
|
||||||
|
|
|
@ -5,7 +5,6 @@ include($$PWD/../externals/externals.pri)
|
||||||
INCLUDEPATH += $$PWD
|
INCLUDEPATH += $$PWD
|
||||||
HEADERS += $${PWD}/analyzerinfo.h \
|
HEADERS += $${PWD}/analyzerinfo.h \
|
||||||
$${PWD}/astutils.h \
|
$${PWD}/astutils.h \
|
||||||
$${PWD}/bughuntingchecks.h \
|
|
||||||
$${PWD}/check.h \
|
$${PWD}/check.h \
|
||||||
$${PWD}/check64bit.h \
|
$${PWD}/check64bit.h \
|
||||||
$${PWD}/checkassert.h \
|
$${PWD}/checkassert.h \
|
||||||
|
@ -38,7 +37,6 @@ HEADERS += $${PWD}/analyzerinfo.h \
|
||||||
$${PWD}/ctu.h \
|
$${PWD}/ctu.h \
|
||||||
$${PWD}/errorlogger.h \
|
$${PWD}/errorlogger.h \
|
||||||
$${PWD}/errortypes.h \
|
$${PWD}/errortypes.h \
|
||||||
$${PWD}/exprengine.h \
|
|
||||||
$${PWD}/forwardanalyzer.h \
|
$${PWD}/forwardanalyzer.h \
|
||||||
$${PWD}/importproject.h \
|
$${PWD}/importproject.h \
|
||||||
$${PWD}/infer.h \
|
$${PWD}/infer.h \
|
||||||
|
@ -65,7 +63,6 @@ HEADERS += $${PWD}/analyzerinfo.h \
|
||||||
|
|
||||||
SOURCES += $${PWD}/analyzerinfo.cpp \
|
SOURCES += $${PWD}/analyzerinfo.cpp \
|
||||||
$${PWD}/astutils.cpp \
|
$${PWD}/astutils.cpp \
|
||||||
$${PWD}/bughuntingchecks.cpp \
|
|
||||||
$${PWD}/check.cpp \
|
$${PWD}/check.cpp \
|
||||||
$${PWD}/check64bit.cpp \
|
$${PWD}/check64bit.cpp \
|
||||||
$${PWD}/checkassert.cpp \
|
$${PWD}/checkassert.cpp \
|
||||||
|
@ -98,7 +95,6 @@ SOURCES += $${PWD}/analyzerinfo.cpp \
|
||||||
$${PWD}/ctu.cpp \
|
$${PWD}/ctu.cpp \
|
||||||
$${PWD}/errorlogger.cpp \
|
$${PWD}/errorlogger.cpp \
|
||||||
$${PWD}/errortypes.cpp \
|
$${PWD}/errortypes.cpp \
|
||||||
$${PWD}/exprengine.cpp \
|
|
||||||
$${PWD}/forwardanalyzer.cpp \
|
$${PWD}/forwardanalyzer.cpp \
|
||||||
$${PWD}/importproject.cpp \
|
$${PWD}/importproject.cpp \
|
||||||
$${PWD}/infer.cpp \
|
$${PWD}/infer.cpp \
|
||||||
|
|
|
@ -61,7 +61,7 @@ static void gettokenlistfromvalid(const std::string& valid, TokenList& tokenList
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Library::Library() : bugHunting(false), mAllocId(0)
|
Library::Library() : mAllocId(0)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
Library::Error Library::load(const char exename[], const char path[])
|
Library::Error Library::load(const char exename[], const char path[])
|
||||||
|
@ -892,56 +892,6 @@ Library::Error Library::loadFunction(const tinyxml2::XMLElement * const node, co
|
||||||
return Error(ErrorCode::OK);
|
return Error(ErrorCode::OK);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<Library::InvalidArgValue> Library::getInvalidArgValues(const std::string &validExpr)
|
|
||||||
{
|
|
||||||
std::vector<Library::InvalidArgValue> valid;
|
|
||||||
TokenList tokenList(nullptr);
|
|
||||||
gettokenlistfromvalid(validExpr, tokenList);
|
|
||||||
for (const Token *tok = tokenList.front(); tok; tok = tok ? tok->next() : nullptr) {
|
|
||||||
if (tok->str() == ",")
|
|
||||||
continue;
|
|
||||||
if (Token::Match(tok, ": %num%")) {
|
|
||||||
valid.push_back(InvalidArgValue{InvalidArgValue::Type::le, tok->next()->str(), std::string()});
|
|
||||||
tok = tok->tokAt(2);
|
|
||||||
} else if (Token::Match(tok, "%num% : %num%")) {
|
|
||||||
valid.push_back(InvalidArgValue{InvalidArgValue::Type::range, tok->str(), tok->strAt(2)});
|
|
||||||
tok = tok->tokAt(3);
|
|
||||||
} else if (Token::Match(tok, "%num% :")) {
|
|
||||||
valid.push_back(InvalidArgValue{InvalidArgValue::Type::ge, tok->str(), std::string()});
|
|
||||||
tok = tok->tokAt(2);
|
|
||||||
} else if (Token::Match(tok, "%num%")) {
|
|
||||||
valid.push_back(InvalidArgValue{InvalidArgValue::Type::eq, tok->str(), std::string()});
|
|
||||||
tok = tok->next();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<Library::InvalidArgValue> invalid;
|
|
||||||
if (valid.empty())
|
|
||||||
return invalid;
|
|
||||||
|
|
||||||
if (valid[0].type == InvalidArgValue::Type::ge || valid[0].type == InvalidArgValue::Type::eq)
|
|
||||||
invalid.push_back(InvalidArgValue{InvalidArgValue::Type::lt, valid[0].op1, std::string()});
|
|
||||||
if (valid.back().type == InvalidArgValue::Type::le || valid.back().type == InvalidArgValue::Type::eq)
|
|
||||||
invalid.push_back(InvalidArgValue{InvalidArgValue::Type::gt, valid[0].op1, std::string()});
|
|
||||||
for (int i = 0; i + 1 < valid.size(); i++) {
|
|
||||||
const InvalidArgValue &v1 = valid[i];
|
|
||||||
const InvalidArgValue &v2 = valid[i + 1];
|
|
||||||
if (v1.type == InvalidArgValue::Type::le && v2.type == InvalidArgValue::Type::ge) {
|
|
||||||
if (v1.isInt()) {
|
|
||||||
MathLib::bigint op1 = MathLib::toLongNumber(v1.op1);
|
|
||||||
MathLib::bigint op2 = MathLib::toLongNumber(v2.op1);
|
|
||||||
if (op1 + 1 == op2 - 1)
|
|
||||||
invalid.push_back(InvalidArgValue{InvalidArgValue::Type::eq, MathLib::toString(op1 + 1), std::string()});
|
|
||||||
else
|
|
||||||
invalid.push_back(InvalidArgValue{InvalidArgValue::Type::range, MathLib::toString(op1 + 1), MathLib::toString(op2 - 1)});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return invalid;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool Library::isIntArgValid(const Token *ftok, int argnr, const MathLib::bigint argvalue) const
|
bool Library::isIntArgValid(const Token *ftok, int argnr, const MathLib::bigint argvalue) const
|
||||||
{
|
{
|
||||||
const ArgumentChecks *ac = getarg(ftok, argnr);
|
const ArgumentChecks *ac = getarg(ftok, argnr);
|
||||||
|
@ -1484,7 +1434,7 @@ bool Library::isnoreturn(const Token *ftok) const
|
||||||
if (it == mNoReturn.end())
|
if (it == mNoReturn.end())
|
||||||
return false;
|
return false;
|
||||||
if (it->second == FalseTrueMaybe::Maybe)
|
if (it->second == FalseTrueMaybe::Maybe)
|
||||||
return !bugHunting; // in bugHunting "maybe" means function is not noreturn
|
return true;
|
||||||
return it->second == FalseTrueMaybe::True;
|
return it->second == FalseTrueMaybe::True;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1498,7 +1448,7 @@ bool Library::isnotnoreturn(const Token *ftok) const
|
||||||
if (it == mNoReturn.end())
|
if (it == mNoReturn.end())
|
||||||
return false;
|
return false;
|
||||||
if (it->second == FalseTrueMaybe::Maybe)
|
if (it->second == FalseTrueMaybe::Maybe)
|
||||||
return bugHunting; // in bugHunting "maybe" means function is not noreturn
|
return false;
|
||||||
return it->second == FalseTrueMaybe::False;
|
return it->second == FalseTrueMaybe::False;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -409,7 +409,6 @@ public:
|
||||||
return MathLib::isInt(op1);
|
return MathLib::isInt(op1);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
static std::vector<InvalidArgValue> getInvalidArgValues(const std::string &validExpr);
|
|
||||||
|
|
||||||
const ArgumentChecks::IteratorInfo *getArgIteratorInfo(const Token *ftok, int argnr) const {
|
const ArgumentChecks::IteratorInfo *getArgIteratorInfo(const Token *ftok, int argnr) const {
|
||||||
const ArgumentChecks *arg = getarg(ftok, argnr);
|
const ArgumentChecks *arg = getarg(ftok, argnr);
|
||||||
|
@ -557,8 +556,6 @@ public:
|
||||||
enum class TypeCheck { def, check, suppress };
|
enum class TypeCheck { def, check, suppress };
|
||||||
TypeCheck getTypeCheck(const std::string &check, const std::string &typeName) const;
|
TypeCheck getTypeCheck(const std::string &check, const std::string &typeName) const;
|
||||||
|
|
||||||
bool bugHunting;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// load a <function> xml node
|
// load a <function> xml node
|
||||||
Error loadFunction(const tinyxml2::XMLElement * const node, const std::string &name, std::set<std::string> &unknown_elements);
|
Error loadFunction(const tinyxml2::XMLElement * const node, const std::string &name, std::set<std::string> &unknown_elements);
|
||||||
|
|
|
@ -35,9 +35,7 @@ const char Settings::SafeChecks::XmlInternalFunctions[] = "internal-functions";
|
||||||
const char Settings::SafeChecks::XmlExternalVariables[] = "external-variables";
|
const char Settings::SafeChecks::XmlExternalVariables[] = "external-variables";
|
||||||
|
|
||||||
Settings::Settings()
|
Settings::Settings()
|
||||||
: bugHunting(false),
|
: checkAllConfigurations(true),
|
||||||
bugHuntingCheckFunctionMaxTime(60),
|
|
||||||
checkAllConfigurations(true),
|
|
||||||
checkConfiguration(false),
|
checkConfiguration(false),
|
||||||
checkHeaders(true),
|
checkHeaders(true),
|
||||||
checkLibrary(false),
|
checkLibrary(false),
|
||||||
|
@ -46,7 +44,6 @@ Settings::Settings()
|
||||||
clangExecutable("clang"),
|
clangExecutable("clang"),
|
||||||
clangTidy(false),
|
clangTidy(false),
|
||||||
daca(false),
|
daca(false),
|
||||||
debugBugHunting(false),
|
|
||||||
debugnormal(false),
|
debugnormal(false),
|
||||||
debugSimplified(false),
|
debugSimplified(false),
|
||||||
debugtemplate(false),
|
debugtemplate(false),
|
||||||
|
|
|
@ -108,16 +108,6 @@ public:
|
||||||
/** @brief Paths used as base for conversion to relative paths. */
|
/** @brief Paths used as base for conversion to relative paths. */
|
||||||
std::vector<std::string> basePaths;
|
std::vector<std::string> basePaths;
|
||||||
|
|
||||||
/** @brief Bug hunting */
|
|
||||||
bool bugHunting;
|
|
||||||
|
|
||||||
/** @brief Max time for bug hunting analysis in seconds, after
|
|
||||||
* timeout the analysis will just stop. */
|
|
||||||
int bugHuntingCheckFunctionMaxTime;
|
|
||||||
|
|
||||||
/** Filename for bug hunting report */
|
|
||||||
std::string bugHuntingReport;
|
|
||||||
|
|
||||||
/** @brief --cppcheck-build-dir. Always uses / as path separator. No trailing path separator. */
|
/** @brief --cppcheck-build-dir. Always uses / as path separator. No trailing path separator. */
|
||||||
std::string buildDir;
|
std::string buildDir;
|
||||||
|
|
||||||
|
@ -162,9 +152,6 @@ public:
|
||||||
/** @brief Are we running from DACA script? */
|
/** @brief Are we running from DACA script? */
|
||||||
bool daca;
|
bool daca;
|
||||||
|
|
||||||
/** @brief Debug bug hunting */
|
|
||||||
bool debugBugHunting;
|
|
||||||
|
|
||||||
/** @brief Is --debug-normal given? */
|
/** @brief Is --debug-normal given? */
|
||||||
bool debugnormal;
|
bool debugnormal;
|
||||||
|
|
||||||
|
@ -204,14 +191,6 @@ public:
|
||||||
/** @brief Force checking the files with "too many" configurations (--force). */
|
/** @brief Force checking the files with "too many" configurations (--force). */
|
||||||
bool force;
|
bool force;
|
||||||
|
|
||||||
std::map<std::string, std::string> functionContracts;
|
|
||||||
|
|
||||||
struct VariableContracts {
|
|
||||||
std::string minValue;
|
|
||||||
std::string maxValue;
|
|
||||||
};
|
|
||||||
std::map<std::string, VariableContracts> variableContracts;
|
|
||||||
|
|
||||||
/** @brief List of include paths, e.g. "my/includes/" which should be used
|
/** @brief List of include paths, e.g. "my/includes/" which should be used
|
||||||
for finding include files inside source files. (-I) */
|
for finding include files inside source files. (-I) */
|
||||||
std::list<std::string> includePaths;
|
std::list<std::string> includePaths;
|
||||||
|
|
|
@ -2409,21 +2409,6 @@ const ValueFlow::Value* Token::getKnownValue(ValueFlow::Value::ValueType t) cons
|
||||||
return it == mImpl->mValues->end() ? nullptr : &*it;
|
return it == mImpl->mValues->end() ? nullptr : &*it;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Token::isImpossibleIntValue(const MathLib::bigint val) const
|
|
||||||
{
|
|
||||||
if (!mImpl->mValues)
|
|
||||||
return false;
|
|
||||||
for (const auto& v : *mImpl->mValues) {
|
|
||||||
if (v.isIntValue() && v.isImpossible() && v.intvalue == val)
|
|
||||||
return true;
|
|
||||||
if (v.isIntValue() && v.bound == ValueFlow::Value::Bound::Lower && val > v.intvalue)
|
|
||||||
return true;
|
|
||||||
if (v.isIntValue() && v.bound == ValueFlow::Value::Bound::Upper && val < v.intvalue)
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
const ValueFlow::Value* Token::getValue(const MathLib::bigint val) const
|
const ValueFlow::Value* Token::getValue(const MathLib::bigint val) const
|
||||||
{
|
{
|
||||||
if (!mImpl->mValues)
|
if (!mImpl->mValues)
|
||||||
|
|
|
@ -1170,8 +1170,6 @@ public:
|
||||||
return mImpl->mValues->front().intvalue;
|
return mImpl->mValues->front().intvalue;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool isImpossibleIntValue(const MathLib::bigint val) const;
|
|
||||||
|
|
||||||
const ValueFlow::Value* getValue(const MathLib::bigint val) const;
|
const ValueFlow::Value* getValue(const MathLib::bigint val) const;
|
||||||
|
|
||||||
const ValueFlow::Value* getMaxValue(bool condition, MathLib::bigint path = 0) const;
|
const ValueFlow::Value* getMaxValue(bool condition, MathLib::bigint path = 0) const;
|
||||||
|
|
|
@ -21,9 +21,6 @@ if (ENABLE_OSS_FUZZ AND CMAKE_CXX_COMPILER_ID MATCHES "Clang")
|
||||||
if (HAVE_RULES)
|
if (HAVE_RULES)
|
||||||
target_link_libraries(fuzz-client PRIVATE ${PCRE_LIBRARY})
|
target_link_libraries(fuzz-client PRIVATE ${PCRE_LIBRARY})
|
||||||
endif()
|
endif()
|
||||||
if (USE_Z3)
|
|
||||||
target_link_libraries(fuzz-client PRIVATE ${Z3_LIBRARIES})
|
|
||||||
endif()
|
|
||||||
if(tinyxml2_FOUND AND NOT USE_BUNDLED_TINYXML2)
|
if(tinyxml2_FOUND AND NOT USE_BUNDLED_TINYXML2)
|
||||||
target_link_libraries(fuzz-client PRIVATE ${tinyxml2_LIBRARIES})
|
target_link_libraries(fuzz-client PRIVATE ${tinyxml2_LIBRARIES})
|
||||||
endif()
|
endif()
|
||||||
|
|
|
@ -50,9 +50,6 @@ public:
|
||||||
(void)stage;
|
(void)stage;
|
||||||
(void)value;
|
(void)value;
|
||||||
}
|
}
|
||||||
void bughuntingReport(const std::string &str) override {
|
|
||||||
(void)str;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -22,14 +22,6 @@ Compiling
|
||||||
|
|
||||||
While building the command line tool, PCRE is optional. It is used if you build with rules.
|
While building the command line tool, PCRE is optional. It is used if you build with rules.
|
||||||
|
|
||||||
For "bug hunting" you need Z3. Installing Z3:
|
|
||||||
* debian: "sudo apt-get install libz3-dev
|
|
||||||
* windows:
|
|
||||||
32-bit: https://github.com/Z3Prover/z3/releases/download/z3-4.8.7/z3-4.8.7-x86-win.zip
|
|
||||||
64-bit: https://github.com/Z3Prover/z3/releases/download/z3-4.8.7/z3-4.8.7-x64-win.zip
|
|
||||||
If you do not want to install z3 in some "system" include/lib paths you can put the files in
|
|
||||||
cppcheck/externals/z3/include and cppcheck/externals/z3/bin
|
|
||||||
|
|
||||||
There are multiple compilation choices:
|
There are multiple compilation choices:
|
||||||
* qmake - cross platform build tool
|
* qmake - cross platform build tool
|
||||||
* cmake - cross platform build tool
|
* cmake - cross platform build tool
|
||||||
|
|
|
@ -1,389 +0,0 @@
|
||||||
/*
|
|
||||||
* Cppcheck - A tool for static C/C++ code analysis
|
|
||||||
* Copyright (C) 2007-2022 Cppcheck team.
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "errortypes.h"
|
|
||||||
#include "exprengine.h"
|
|
||||||
#include "library.h"
|
|
||||||
#include "platform.h"
|
|
||||||
#include "settings.h"
|
|
||||||
#include "tokenize.h"
|
|
||||||
#include "testsuite.h"
|
|
||||||
|
|
||||||
#include <iosfwd>
|
|
||||||
|
|
||||||
class TestBughuntingChecks : public TestFixture {
|
|
||||||
public:
|
|
||||||
TestBughuntingChecks() : TestFixture("TestBughuntingChecks") {
|
|
||||||
settings.platform(cppcheck::Platform::Unix64);
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
Settings settings;
|
|
||||||
|
|
||||||
void run() override {
|
|
||||||
#ifdef USE_Z3
|
|
||||||
settings.certainty.setEnabled(Certainty::inconclusive, true);
|
|
||||||
LOAD_LIB_2(settings.library, "std.cfg");
|
|
||||||
TEST_CASE(checkAssignment);
|
|
||||||
TEST_CASE(arrayIndexOutOfBounds1);
|
|
||||||
TEST_CASE(arrayIndexOutOfBounds2);
|
|
||||||
TEST_CASE(arrayIndexOutOfBounds3);
|
|
||||||
TEST_CASE(arrayIndexOutOfBounds4);
|
|
||||||
TEST_CASE(arrayIndexOutOfBounds5);
|
|
||||||
TEST_CASE(arrayIndexOutOfBounds6);
|
|
||||||
TEST_CASE(arrayIndexOutOfBoundsDim1);
|
|
||||||
TEST_CASE(bufferOverflowMemCmp1);
|
|
||||||
TEST_CASE(bufferOverflowMemCmp2);
|
|
||||||
TEST_CASE(bufferOverflowStrcpy1);
|
|
||||||
TEST_CASE(bufferOverflowStrcpy2);
|
|
||||||
|
|
||||||
TEST_CASE(divisionByZeroNoReturn);
|
|
||||||
|
|
||||||
TEST_CASE(uninit);
|
|
||||||
TEST_CASE(uninit_array);
|
|
||||||
TEST_CASE(uninit_function_par);
|
|
||||||
TEST_CASE(uninit_malloc);
|
|
||||||
TEST_CASE(uninit_struct);
|
|
||||||
TEST_CASE(uninit_bailout);
|
|
||||||
TEST_CASE(uninit_fp_smartptr);
|
|
||||||
TEST_CASE(uninit_fp_struct);
|
|
||||||
TEST_CASE(uninit_fp_struct_member_init_2);
|
|
||||||
TEST_CASE(uninit_fp_template_var);
|
|
||||||
TEST_CASE(ctu);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
void check(const char code[]) {
|
|
||||||
settings.bugHunting = settings.library.bugHunting = true;
|
|
||||||
Tokenizer tokenizer(&settings, this);
|
|
||||||
std::istringstream istr(code);
|
|
||||||
tokenizer.tokenize(istr, "test.cpp");
|
|
||||||
errout.str("");
|
|
||||||
ExprEngine::runChecks(this, &tokenizer, &settings);
|
|
||||||
}
|
|
||||||
|
|
||||||
void checkAssignment() {
|
|
||||||
check("void foo(int any) { __cppcheck_low__(0) int x; x = any; }");
|
|
||||||
ASSERT_EQUALS("[test.cpp:1]: (error) There is assignment, cannot determine that value is greater or equal with 0\n", errout.str());
|
|
||||||
|
|
||||||
check("struct S { __cppcheck_low__(0) int x; };\n"
|
|
||||||
"void foo(S *s, int any) { s->x = any; }");
|
|
||||||
ASSERT_EQUALS("[test.cpp:2]: (error) There is assignment, cannot determine that value is greater or equal with 0\n", errout.str());
|
|
||||||
}
|
|
||||||
|
|
||||||
void arrayIndexOutOfBounds1() {
|
|
||||||
check("void foo(int x) {\n"
|
|
||||||
" int p[8];"
|
|
||||||
" p[x] = 0;\n"
|
|
||||||
"}");
|
|
||||||
ASSERT_EQUALS("[test.cpp:2]: (error) Array index out of bounds, cannot determine that x is less than 8\n"
|
|
||||||
"[test.cpp:2]: (error) Array index out of bounds, cannot determine that x is not negative\n",
|
|
||||||
errout.str());
|
|
||||||
}
|
|
||||||
|
|
||||||
void arrayIndexOutOfBounds2() { // loop
|
|
||||||
check("void foo(int n) {\n"
|
|
||||||
" int p[8];\n"
|
|
||||||
" for (int i = 0; i < n; i++)\n"
|
|
||||||
" p[i] = 0;\n"
|
|
||||||
"}");
|
|
||||||
ASSERT_EQUALS("[test.cpp:4]: (error) Array index out of bounds, cannot determine that i is less than 8\n"
|
|
||||||
"[test.cpp:4]: (error) Array index out of bounds, cannot determine that i is not negative\n",
|
|
||||||
errout.str());
|
|
||||||
|
|
||||||
// .. with unknown expression
|
|
||||||
check("void foo(int n) {\n"
|
|
||||||
" int p[8];\n"
|
|
||||||
" crx_data_header_t *d =\n"
|
|
||||||
" &libraw_internal_data.unpacker_data.crx_header[framei];\n"
|
|
||||||
" for (int i = 0; i < n; i++)\n"
|
|
||||||
" p[i] = 0;\n"
|
|
||||||
"}");
|
|
||||||
ASSERT_EQUALS("[test.cpp:6]: (error) Array index out of bounds, cannot determine that i is less than 8\n"
|
|
||||||
"[test.cpp:6]: (error) Array index out of bounds, cannot determine that i is not negative\n",
|
|
||||||
errout.str());
|
|
||||||
}
|
|
||||||
|
|
||||||
void arrayIndexOutOfBounds3() { // struct
|
|
||||||
check("struct S { int x; };\n"
|
|
||||||
"void foo(short i) {\n"
|
|
||||||
" S s[8];\n"
|
|
||||||
" if (s[i].x == 0) {}\n"
|
|
||||||
"}");
|
|
||||||
ASSERT_EQUALS("[test.cpp:4]: (error) Array index out of bounds, cannot determine that i is less than 8\n"
|
|
||||||
"[test.cpp:4]: (error) Array index out of bounds, cannot determine that i is not negative\n"
|
|
||||||
"[test.cpp:4]: (error) Cannot determine that 's[i]' is initialized\n",
|
|
||||||
errout.str());
|
|
||||||
}
|
|
||||||
|
|
||||||
void arrayIndexOutOfBounds4() { // ensure there are warnings for bailout value
|
|
||||||
check("void foo(short i) {\n"
|
|
||||||
" int buf[8];\n"
|
|
||||||
"\n"
|
|
||||||
" data *d = x;\n"
|
|
||||||
" switch (d->layout) { case 0: break; }\n"
|
|
||||||
"\n"
|
|
||||||
" if (buf[i] > 0) {}\n"
|
|
||||||
"}");
|
|
||||||
ASSERT_EQUALS("[test.cpp:7]: (error) Array index out of bounds, cannot determine that i is less than 8\n"
|
|
||||||
"[test.cpp:7]: (error) Array index out of bounds, cannot determine that i is not negative\n"
|
|
||||||
"[test.cpp:7]: (error) Cannot determine that 'buf[i]' is initialized\n",
|
|
||||||
errout.str());
|
|
||||||
}
|
|
||||||
|
|
||||||
void arrayIndexOutOfBounds5() {
|
|
||||||
check("struct {\n"
|
|
||||||
" struct { int z; } y;\n"
|
|
||||||
"} x;\n"
|
|
||||||
"\n"
|
|
||||||
"void foo(int i) {\n"
|
|
||||||
" for (int c = 0; c <= i; c++)\n"
|
|
||||||
" x.y.z = 13;\n"
|
|
||||||
" int buf[10];\n"
|
|
||||||
" if (buf[i] > 0) { }\n"
|
|
||||||
"}");
|
|
||||||
ASSERT_EQUALS("[test.cpp:9]: (error) Array index out of bounds, cannot determine that i is less than 10\n"
|
|
||||||
"[test.cpp:9]: (error) Array index out of bounds, cannot determine that i is not negative\n"
|
|
||||||
"[test.cpp:9]: (error) Cannot determine that 'buf[i]' is initialized\n",
|
|
||||||
errout.str());
|
|
||||||
}
|
|
||||||
|
|
||||||
void arrayIndexOutOfBounds6() {
|
|
||||||
check("int buf[5];\n"
|
|
||||||
"uint16_t foo(size_t offset) {\n"
|
|
||||||
" uint8_t c = (offset & 0xc0) >> 6;\n"
|
|
||||||
" return 2 * buf[c];\n"
|
|
||||||
"}");
|
|
||||||
ASSERT_EQUALS("[test.cpp:4]: (error) Array index out of bounds, cannot determine that c is less than 5\n", errout.str());
|
|
||||||
}
|
|
||||||
|
|
||||||
void arrayIndexOutOfBoundsDim1() { // itc test case
|
|
||||||
check("void overrun_st_008 () {\n"
|
|
||||||
" int buf[5][6];\n"
|
|
||||||
" buf[5][5] = 1;\n"
|
|
||||||
"}");
|
|
||||||
ASSERT_EQUALS("[test.cpp:3]: (error) Array index out of bounds, cannot determine that 5 is less than 5\n", errout.str());
|
|
||||||
}
|
|
||||||
|
|
||||||
void bufferOverflowMemCmp1() {
|
|
||||||
// CVE-2020-24265
|
|
||||||
check("void foo(const char *pktdata, int datalen) {\n"
|
|
||||||
" if (memcmp(pktdata, \"MGC\", 3)) {}\n"
|
|
||||||
"}");
|
|
||||||
ASSERT_EQUALS("[test.cpp:2]: (error) Buffer read/write, when calling 'memcmp' it cannot be determined that 1st argument is not overflowed\n", errout.str());
|
|
||||||
}
|
|
||||||
|
|
||||||
void bufferOverflowMemCmp2() {
|
|
||||||
check("void foo(const char *pktdata, unsigned int datalen) {\n"
|
|
||||||
" if (memcmp(pktdata, \"MGC\", datalen)) {}\n"
|
|
||||||
"}");
|
|
||||||
ASSERT_EQUALS("[test.cpp:2]: (error) Buffer read/write, when calling 'memcmp' it cannot be determined that 1st argument is not overflowed\n", errout.str());
|
|
||||||
}
|
|
||||||
|
|
||||||
void bufferOverflowStrcpy1() {
|
|
||||||
check("void foo(char *p) {\n"
|
|
||||||
" strcpy(p, \"hello\");\n"
|
|
||||||
"}");
|
|
||||||
ASSERT_EQUALS("[test.cpp:2]: (error) Buffer read/write, when calling 'strcpy' it cannot be determined that 1st argument is not overflowed\n", errout.str());
|
|
||||||
}
|
|
||||||
|
|
||||||
void bufferOverflowStrcpy2() {
|
|
||||||
check("void foo(char *p, const char *q) {\n"
|
|
||||||
" strcpy(p, q);\n"
|
|
||||||
"}");
|
|
||||||
ASSERT_EQUALS("[test.cpp:2]: (error) Buffer read/write, when calling 'strcpy' it cannot be determined that 1st argument is not overflowed\n", errout.str());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void divisionByZeroNoReturn() {
|
|
||||||
// Don't know if function is noreturn or not..
|
|
||||||
check("int f(int leftarg, int rightarg) {\n"
|
|
||||||
" if (rightarg == 0)\n"
|
|
||||||
" raise (SIGFPE);\n" // <- maybe noreturn
|
|
||||||
" return leftarg / rightarg;\n"
|
|
||||||
"}");
|
|
||||||
ASSERT_EQUALS("[test.cpp:4]: (error) There is division, cannot determine that there can't be a division by zero.\n", errout.str());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void uninit() {
|
|
||||||
check("void foo() { int x; x = x + 1; }");
|
|
||||||
ASSERT_EQUALS("[test.cpp:1]: (error) Cannot determine that 'x' is initialized\n", errout.str());
|
|
||||||
|
|
||||||
check("void foo() { int x; int y = x + 1; }");
|
|
||||||
ASSERT_EQUALS("[test.cpp:1]: (error) Cannot determine that 'x' is initialized\n", errout.str());
|
|
||||||
|
|
||||||
check("void foo() { int x; x++; }");
|
|
||||||
ASSERT_EQUALS("[test.cpp:1]: (error) Cannot determine that 'x' is initialized\n", errout.str());
|
|
||||||
}
|
|
||||||
|
|
||||||
void uninit_array() {
|
|
||||||
check("void foo(int x) {\n"
|
|
||||||
" int a[10];\n"
|
|
||||||
" if (x > 0) a[0] = 32;\n"
|
|
||||||
" return a[0];\n"
|
|
||||||
"}");
|
|
||||||
ASSERT_EQUALS("[test.cpp:4]: (error) Cannot determine that 'a[0]' is initialized\n", errout.str());
|
|
||||||
}
|
|
||||||
|
|
||||||
void uninit_function_par() {
|
|
||||||
// non constant parameters may point at uninitialized data
|
|
||||||
// constant parameters should point at initialized data
|
|
||||||
|
|
||||||
check("char foo(char id[]) { return id[0]; }");
|
|
||||||
ASSERT_EQUALS("[test.cpp:1]: (error) Cannot determine that 'id[0]' is initialized (you can use 'const' to say data must be initialized)\n", errout.str());
|
|
||||||
|
|
||||||
check("char foo(const char id[]) { return id[0]; }");
|
|
||||||
ASSERT_EQUALS("", errout.str());
|
|
||||||
|
|
||||||
check("char foo(const char id[]);\n"
|
|
||||||
"void bar() { char data[10]; foo(data); }");
|
|
||||||
ASSERT_EQUALS("[test.cpp:2]: (error) Cannot determine that 'data[0]' is initialized\n", errout.str());
|
|
||||||
|
|
||||||
check("char foo(char id[]);\n"
|
|
||||||
"void bar() { char data[10]; foo(data); }");
|
|
||||||
ASSERT_EQUALS("[test.cpp:2]: (error, inconclusive) Cannot determine that 'data[0]' is initialized. It is inconclusive if there would be a problem in the function call.\n", errout.str());
|
|
||||||
|
|
||||||
check("void foo(int *p) { if (p) *p=0; }");
|
|
||||||
ASSERT_EQUALS("", errout.str());
|
|
||||||
|
|
||||||
check("class C {\n"
|
|
||||||
"public:\n"
|
|
||||||
" C();\n"
|
|
||||||
" int x;\n"
|
|
||||||
"};\n"
|
|
||||||
"\n"
|
|
||||||
"void foo(const C &c) { int x = c.x; }");
|
|
||||||
ASSERT_EQUALS("", errout.str());
|
|
||||||
}
|
|
||||||
|
|
||||||
void uninit_malloc() {
|
|
||||||
check("void foo() { char *p = malloc(10); return *p; }");
|
|
||||||
ASSERT_EQUALS("[test.cpp:1]: (error) Cannot determine that '*p' is initialized\n", errout.str());
|
|
||||||
}
|
|
||||||
|
|
||||||
void uninit_struct() {
|
|
||||||
// Assume that constructors initialize all members
|
|
||||||
// TODO whole program analysis
|
|
||||||
check("struct Data { Data(); int x; }\n"
|
|
||||||
"void foo() {\n"
|
|
||||||
" Data data;\n"
|
|
||||||
" x = data.x;\n"
|
|
||||||
"}");
|
|
||||||
ASSERT_EQUALS("", errout.str());
|
|
||||||
}
|
|
||||||
|
|
||||||
void uninit_bailout() {
|
|
||||||
check("void foo() {\n"
|
|
||||||
" __CPPCHECK_BAILOUT__;\n"
|
|
||||||
" int values[5];\n"
|
|
||||||
" values[i] = 123;\n"
|
|
||||||
"}");
|
|
||||||
ASSERT_EQUALS("", errout.str());
|
|
||||||
|
|
||||||
check("void foo() {\n"
|
|
||||||
" __CPPCHECK_BAILOUT__;\n"
|
|
||||||
" std::ostringstream comm;\n"
|
|
||||||
" comm << 123;\n"
|
|
||||||
"}");
|
|
||||||
ASSERT_EQUALS("", errout.str());
|
|
||||||
}
|
|
||||||
|
|
||||||
void ctu() {
|
|
||||||
check("void init(int &x) {\n"
|
|
||||||
" x = 1;\n"
|
|
||||||
"}\n"
|
|
||||||
"\n"
|
|
||||||
"void foo() {\n"
|
|
||||||
" int x;\n"
|
|
||||||
" init(x);\n"
|
|
||||||
" x++;\n"
|
|
||||||
"}");
|
|
||||||
ASSERT_EQUALS("", errout.str());
|
|
||||||
|
|
||||||
check("void init(int a, int &x) {\n"
|
|
||||||
" if (a < 10)\n"
|
|
||||||
" x = 1;\n"
|
|
||||||
"}\n"
|
|
||||||
"\n"
|
|
||||||
"void foo(int a) {\n"
|
|
||||||
" int x;\n"
|
|
||||||
" init(a, x);\n"
|
|
||||||
" x++;\n"
|
|
||||||
"}");
|
|
||||||
ASSERT_EQUALS("[test.cpp:9]: (error) Cannot determine that 'x' is initialized\n", errout.str());
|
|
||||||
|
|
||||||
check("void init(int a, int &x) {\n"
|
|
||||||
" if (a < 10)\n"
|
|
||||||
" x = 1;\n"
|
|
||||||
" else\n"
|
|
||||||
" x = 3;\n"
|
|
||||||
"}\n"
|
|
||||||
"\n"
|
|
||||||
"void foo(int a) {\n"
|
|
||||||
" int x;\n"
|
|
||||||
" init(a, x);\n"
|
|
||||||
" x++;\n"
|
|
||||||
"}");
|
|
||||||
ASSERT_EQUALS("", errout.str());
|
|
||||||
}
|
|
||||||
|
|
||||||
void uninit_fp_smartptr() {
|
|
||||||
check("void foo() {\n"
|
|
||||||
" std::unique_ptr<std::string> buffer;\n"
|
|
||||||
" try { } catch (std::exception& e) { }\n"
|
|
||||||
" doneCallback(std::move(buffer));\n"
|
|
||||||
"}");
|
|
||||||
ASSERT_EQUALS("", errout.str());
|
|
||||||
}
|
|
||||||
|
|
||||||
void uninit_fp_struct() {
|
|
||||||
check("struct Pos {\n"
|
|
||||||
" int x {0};\n"
|
|
||||||
" int y {0};\n"
|
|
||||||
"};\n"
|
|
||||||
"\n"
|
|
||||||
"void dostuff() {\n"
|
|
||||||
" auto obj = C {};\n"
|
|
||||||
" Pos xy;\n"
|
|
||||||
" foo(xy);\n"
|
|
||||||
"}");
|
|
||||||
ASSERT_EQUALS("", errout.str());
|
|
||||||
}
|
|
||||||
|
|
||||||
void uninit_fp_struct_member_init_2() {
|
|
||||||
check("struct A {\n"
|
|
||||||
" int x {0}; int y {0};\n"
|
|
||||||
"};\n"
|
|
||||||
"void foo(const A& a) {\n"
|
|
||||||
" bar(a);\n"
|
|
||||||
"}");
|
|
||||||
ASSERT_EQUALS("", errout.str());
|
|
||||||
}
|
|
||||||
|
|
||||||
void uninit_fp_template_var() {
|
|
||||||
check("void foo() {\n"
|
|
||||||
" X*x = DYNAMIC_CAST(X, p);\n"
|
|
||||||
" C<int> c;\n"
|
|
||||||
" f(c);\n"
|
|
||||||
"}");
|
|
||||||
ASSERT_EQUALS("", errout.str());
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
REGISTER_TEST(TestBughuntingChecks)
|
|
|
@ -39,7 +39,6 @@ private:
|
||||||
std::list<std::string> id;
|
std::list<std::string> id;
|
||||||
|
|
||||||
void reportOut(const std::string & /*outmsg*/, Color = Color::Reset) override {}
|
void reportOut(const std::string & /*outmsg*/, Color = Color::Reset) override {}
|
||||||
void bughuntingReport(const std::string & /*str*/) override {}
|
|
||||||
|
|
||||||
void reportErr(const ErrorMessage &msg) override {
|
void reportErr(const ErrorMessage &msg) override {
|
||||||
id.push_back(msg.id);
|
id.push_back(msg.id);
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -45,7 +45,6 @@
|
||||||
<ClCompile Include="testcppcheck.cpp" />
|
<ClCompile Include="testcppcheck.cpp" />
|
||||||
<ClCompile Include="testerrorlogger.cpp" />
|
<ClCompile Include="testerrorlogger.cpp" />
|
||||||
<ClCompile Include="testexceptionsafety.cpp" />
|
<ClCompile Include="testexceptionsafety.cpp" />
|
||||||
<ClCompile Include="testexprengine.cpp" />
|
|
||||||
<ClCompile Include="testfilelister.cpp" />
|
<ClCompile Include="testfilelister.cpp" />
|
||||||
<ClCompile Include="testgarbage.cpp" />
|
<ClCompile Include="testgarbage.cpp" />
|
||||||
<ClCompile Include="testimportproject.cpp" />
|
<ClCompile Include="testimportproject.cpp" />
|
||||||
|
|
|
@ -211,9 +211,6 @@
|
||||||
<ClCompile Include="testsimplifyusing.cpp">
|
<ClCompile Include="testsimplifyusing.cpp">
|
||||||
<Filter>Source Files</Filter>
|
<Filter>Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="testexprengine.cpp">
|
|
||||||
<Filter>Source Files</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="testutils.cpp">
|
<ClCompile Include="testutils.cpp">
|
||||||
<Filter>Source Files</Filter>
|
<Filter>Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
|
|
@ -104,7 +104,6 @@ protected:
|
||||||
|
|
||||||
void processOptions(const options& args);
|
void processOptions(const options& args);
|
||||||
public:
|
public:
|
||||||
void bughuntingReport(const std::string & /*str*/) override {}
|
|
||||||
void reportOut(const std::string &outmsg, Color c = Color::Reset) override;
|
void reportOut(const std::string &outmsg, Color c = Color::Reset) override;
|
||||||
void reportErr(const ErrorMessage &msg) override;
|
void reportErr(const ErrorMessage &msg) override;
|
||||||
void run(const std::string &str);
|
void run(const std::string &str);
|
||||||
|
|
|
@ -55,9 +55,6 @@ static std::string objfiles(const std::vector<std::string> &files)
|
||||||
|
|
||||||
static void getDeps(const std::string &filename, std::vector<std::string> &depfiles)
|
static void getDeps(const std::string &filename, std::vector<std::string> &depfiles)
|
||||||
{
|
{
|
||||||
if (filename == "externals/z3_version.h")
|
|
||||||
return;
|
|
||||||
|
|
||||||
static const std::vector<std::string> externalfolders{"externals", "externals/picojson", "externals/simplecpp", "externals/tinyxml2" };
|
static const std::vector<std::string> externalfolders{"externals", "externals/picojson", "externals/simplecpp", "externals/tinyxml2" };
|
||||||
|
|
||||||
// Is the dependency already included?
|
// Is the dependency already included?
|
||||||
|
@ -239,13 +236,6 @@ int main(int argc, char **argv)
|
||||||
fout << "# To compile with rules, use 'make HAVE_RULES=yes'\n";
|
fout << "# To compile with rules, use 'make HAVE_RULES=yes'\n";
|
||||||
makeConditionalVariable(fout, "HAVE_RULES", "no");
|
makeConditionalVariable(fout, "HAVE_RULES", "no");
|
||||||
|
|
||||||
// Z3 is an optional dependency now..
|
|
||||||
makeConditionalVariable(fout, "USE_Z3", "no");
|
|
||||||
fout << "ifeq ($(USE_Z3),yes)\n"
|
|
||||||
<< " CPPFLAGS += -DUSE_Z3\n"
|
|
||||||
<< " LIBS += -lz3\n"
|
|
||||||
<< "endif\n";
|
|
||||||
|
|
||||||
// use match compiler..
|
// use match compiler..
|
||||||
fout << "# use match compiler\n";
|
fout << "# use match compiler\n";
|
||||||
fout << "ifeq ($(SRCDIR),build)\n"
|
fout << "ifeq ($(SRCDIR),build)\n"
|
||||||
|
|
|
@ -8,7 +8,6 @@
|
||||||
<?define PtfsDir = "files\platforms" ?>
|
<?define PtfsDir = "files\platforms" ?>
|
||||||
<?define AddonsDir = "files\addons" ?>
|
<?define AddonsDir = "files\addons" ?>
|
||||||
<?define QtDllDir = "files" ?>
|
<?define QtDllDir = "files" ?>
|
||||||
<?define Z3DllDir = "files" ?>
|
|
||||||
|
|
||||||
<?if $(var.Platform) = x64 ?>
|
<?if $(var.Platform) = x64 ?>
|
||||||
<?define CrtMergeModule = "$(env.VCToolsRedistDir)\MergeModules\Microsoft_VC142_CRT_x64.msm" ?>
|
<?define CrtMergeModule = "$(env.VCToolsRedistDir)\MergeModules\Microsoft_VC142_CRT_x64.msm" ?>
|
||||||
|
|
|
@ -20,9 +20,6 @@
|
||||||
<Component Id='cppcheckcore.dll' Guid='$(var.cppcheckcoreGUID)'>
|
<Component Id='cppcheckcore.dll' Guid='$(var.cppcheckcoreGUID)'>
|
||||||
<File Id='cppcheckcore.dll' Name='cppcheck-core.dll' DiskId='1' Source='$(var.CliBuildDir)\cppcheck-core.dll' KeyPath='yes' />
|
<File Id='cppcheckcore.dll' Name='cppcheck-core.dll' DiskId='1' Source='$(var.CliBuildDir)\cppcheck-core.dll' KeyPath='yes' />
|
||||||
</Component>
|
</Component>
|
||||||
<Component Id='libz3.dll' Guid='$(var.libz3GUID)'>
|
|
||||||
<File Id='libz3.dll' Name='libz3.dll' DiskId='1' Source='$(var.Z3DllDir)\libz3.dll' KeyPath='yes' />
|
|
||||||
</Component>
|
|
||||||
<Component Id='cppcheck.exe' Guid='$(var.cppcheckGUID)'>
|
<Component Id='cppcheck.exe' Guid='$(var.cppcheckGUID)'>
|
||||||
<File Id='cppcheck.exe' Name='cppcheck.exe' DiskId='1' Source='$(var.CliBuildDir)\cppcheck.exe' KeyPath='yes' />
|
<File Id='cppcheck.exe' Name='cppcheck.exe' DiskId='1' Source='$(var.CliBuildDir)\cppcheck.exe' KeyPath='yes' />
|
||||||
</Component>
|
</Component>
|
||||||
|
@ -167,7 +164,6 @@
|
||||||
<File Id='picojson_license.txt' Name='picojson-license.txt' DiskId='1' Source='../externals/picojson/LICENSE' />
|
<File Id='picojson_license.txt' Name='picojson-license.txt' DiskId='1' Source='../externals/picojson/LICENSE' />
|
||||||
<File Id='simplecpp_license.txt' Name='simplecpp-license.txt' DiskId='1' Source='../externals/simplecpp/LICENSE' />
|
<File Id='simplecpp_license.txt' Name='simplecpp-license.txt' DiskId='1' Source='../externals/simplecpp/LICENSE' />
|
||||||
<File Id='tinyxml2_license.txt' Name='tinyxml2-license.txt' DiskId='1' Source='../externals/tinyxml2/LICENSE' />
|
<File Id='tinyxml2_license.txt' Name='tinyxml2-license.txt' DiskId='1' Source='../externals/tinyxml2/LICENSE' />
|
||||||
<File Id='z3_license.txt' Name='z3-license.txt' DiskId='1' Source='../externals/z3-LICENSE' />
|
|
||||||
</Component>
|
</Component>
|
||||||
</Directory>
|
</Directory>
|
||||||
<Merge Id="CRT" Language="0" SourceFile="$(var.CrtMergeModule)" DiskId="1" />
|
<Merge Id="CRT" Language="0" SourceFile="$(var.CrtMergeModule)" DiskId="1" />
|
||||||
|
@ -188,7 +184,6 @@
|
||||||
Display='expand' Level='1' AllowAdvertise='no' ConfigurableDirectory='INSTALLDIR' >
|
Display='expand' Level='1' AllowAdvertise='no' ConfigurableDirectory='INSTALLDIR' >
|
||||||
<Feature Id='CppcheckCore' Display='hidden' AllowAdvertise='no' Title='Cppcheck-Core' Description='Cppcheck core components' Level='1'>
|
<Feature Id='CppcheckCore' Display='hidden' AllowAdvertise='no' Title='Cppcheck-Core' Description='Cppcheck core components' Level='1'>
|
||||||
<ComponentRef Id='cppcheckcore.dll' />
|
<ComponentRef Id='cppcheckcore.dll' />
|
||||||
<ComponentRef Id='libz3.dll' />
|
|
||||||
<ComponentRef Id='RegistryEntries' />
|
<ComponentRef Id='RegistryEntries' />
|
||||||
<ComponentRef Id='BaseDocs' />
|
<ComponentRef Id='BaseDocs' />
|
||||||
<ComponentRef Id='MandatoryCfgs' />
|
<ComponentRef Id='MandatoryCfgs' />
|
||||||
|
|
|
@ -10,7 +10,6 @@
|
||||||
<?define ProductUpgradeCode = "7E94124C-1CD1-433F-9423-4614E52300DD" ?>
|
<?define ProductUpgradeCode = "7E94124C-1CD1-433F-9423-4614E52300DD" ?>
|
||||||
<?define cppcheckGUID = "1c31dd76-07fa-4420-b9b5-5463742d6a48" ?>
|
<?define cppcheckGUID = "1c31dd76-07fa-4420-b9b5-5463742d6a48" ?>
|
||||||
<?define cppcheckcoreGUID = "1c31dd76-07fa-4420-b9b5-5463742d6a49" ?>
|
<?define cppcheckcoreGUID = "1c31dd76-07fa-4420-b9b5-5463742d6a49" ?>
|
||||||
<?define libz3GUID = "5d603179-e59a-4c47-b0aa-531ab1f6456b" ?>
|
|
||||||
<?define addonsGUID = "25DACF7E-4D29-890D-433F-6922A391C312" ?>
|
<?define addonsGUID = "25DACF7E-4D29-890D-433F-6922A391C312" ?>
|
||||||
<?define guiGUID = "D7D3FF8E-1D82-4215-B59B-4715A748C540" ?>
|
<?define guiGUID = "D7D3FF8E-1D82-4215-B59B-4715A748C540" ?>
|
||||||
<?define qtplatformsGUID = "E2C326DF-11F1-4C05-A955-2E2D2A3B0515" ?>
|
<?define qtplatformsGUID = "E2C326DF-11F1-4C05-A955-2E2D2A3B0515" ?>
|
||||||
|
|
Loading…
Reference in New Issue