Remove bug hunting. This feature will be provided in Cppcheck premium.

This commit is contained in:
Daniel Marjamäki 2022-04-11 07:30:55 +02:00
parent 98f84e34c6
commit 8f386e15fd
90 changed files with 87 additions and 7309 deletions

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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: |

View File

@ -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

View File

@ -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

View File

@ -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: |

View File

@ -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

View File

@ -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: |

View File

@ -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.

View File

@ -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

View File

@ -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)

View File

@ -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";
} }

View File

@ -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;

View File

@ -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?
*/ */

View File

@ -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;

View File

@ -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()

View File

@ -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")

View File

@ -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)

View File

@ -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}")

View File

@ -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

View File

@ -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);

10
externals/z3-LICENSE vendored
View File

@ -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.

View File

@ -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

View File

@ -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()

View File

@ -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>&lt;html&gt;&lt;head/&gt;&lt;body&gt; <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Many thanks to these libraries that we use:&lt;/p&gt;&lt;ul style=&quot;margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; -qt-list-indent: 1;&quot;&gt;&lt;li style=&quot; margin-top:12px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;pcre&lt;/li&gt;&lt;li style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;picojson&lt;/li&gt;&lt;li style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;qt&lt;/li&gt;&lt;li style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;tinyxml2&lt;/li&gt;&lt;/ul&gt;&lt;/body&gt;&lt;/html&gt;</string>
&lt;p&gt;Many thanks to these libraries that we use:&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;pcre&lt;/li&gt;
&lt;li&gt;picojson&lt;/li&gt;
&lt;li&gt;qt&lt;/li&gt;
&lt;li&gt;tinyxml2&lt;/li&gt;
&lt;li&gt;z3&lt;/li&gt;&lt;/ul&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property> </property>
</widget> </widget>
</item> </item>

View File

@ -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();
}

View File

@ -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

View File

@ -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>

View File

@ -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 \

View File

@ -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();
}
}

View File

@ -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 */

View File

@ -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;
}; };

View File

@ -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) {

View File

@ -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
*/ */

View File

@ -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 &quot;soundy&quot; 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">

View File

@ -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 {

View File

@ -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)

View File

@ -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.
* *

View File

@ -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);
}

View File

@ -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

View File

@ -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>

View File

@ -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()

View File

@ -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 {}
}; };

View File

@ -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()

View File

@ -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)

View File

@ -187,8 +187,6 @@ signals:
void debugError(const ErrorItem &item); void debugError(const ErrorItem &item);
void bughuntingReportLine(QString line);
public slots: public slots:
/** /**

View File

@ -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));
}

View File

@ -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:
/** /**

View File

@ -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();
}

View File

@ -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

View File

@ -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>

View File

@ -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()

View File

@ -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);
}

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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);

View File

@ -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;

View File

@ -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" />

View File

@ -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>

View File

@ -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)

View File

@ -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)

File diff suppressed because it is too large Load Diff

View File

@ -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 &currentFunction, 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

View File

@ -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;
} }

View File

@ -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";

View File

@ -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 \

View File

@ -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;
} }

View File

@ -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);

View File

@ -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),

View File

@ -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;

View File

@ -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)

View File

@ -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;

View File

@ -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()

View File

@ -50,9 +50,6 @@ public:
(void)stage; (void)stage;
(void)value; (void)value;
} }
void bughuntingReport(const std::string &str) override {
(void)str;
}
}; };

View File

@ -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

View File

@ -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)

View File

@ -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

View File

@ -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" />

View File

@ -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>

View File

@ -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);

View File

@ -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"

View File

@ -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" ?>

View File

@ -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' />

View File

@ -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" ?>