diff --git a/.github/workflows/CI-windows.yml b/.github/workflows/CI-windows.yml index 5ed1648e770..19bcaf0047f 100644 --- a/.github/workflows/CI-windows.yml +++ b/.github/workflows/CI-windows.yml @@ -26,7 +26,7 @@ jobs: strategy: matrix: os: [windows-2019, windows-2022] - qt_ver: [5.15.2, 6.6.0] + qt_ver: [5.15.2, 6.7.0] fail-fast: false runs-on: ${{ matrix.os }} diff --git a/.github/workflows/asan.yml b/.github/workflows/asan.yml index bc0aa9468b0..e223952fc34 100644 --- a/.github/workflows/asan.yml +++ b/.github/workflows/asan.yml @@ -134,7 +134,7 @@ jobs: ec=0 ./cmake.output/bin/cppcheck $selfcheck_options externals/simplecpp || ec=1 ./cmake.output/bin/cppcheck $selfcheck_options $cppcheck_options --addon=naming.json cli lib || ec=1 - ./cmake.output/bin/cppcheck $selfcheck_options $cppcheck_options -DQT_VERSION=0x060000 -DQ_MOC_OUTPUT_REVISION=68 -DQT_CHARTS_LIB --library=qt --addon=naming.json -Icmake.output/gui -Igui gui/*.cpp cmake.output/gui/*.cpp || ec=1 + ./cmake.output/bin/cppcheck $selfcheck_options $cppcheck_options -DQT_VERSION=0x060000 -DQ_MOC_OUTPUT_REVISION=68 -DQT_CHARTS_LIB -DQT_MOC_HAS_STRINGDATA --library=qt --addon=naming.json -Icmake.output/gui -Igui gui/*.cpp cmake.output/gui/*.cpp || ec=1 ./cmake.output/bin/cppcheck $selfcheck_options $cppcheck_options -Icli test/*.cpp tools/*.cpp || ec=1 - ./cmake.output/bin/cppcheck $selfcheck_options $cppcheck_options -DQ_MOC_OUTPUT_REVISION=68 -DQT_CHARTS_LIB --library=qt -Icmake.output/tools/triage -Igui tools/triage/*.cpp cmake.output/tools/triage/*.cpp || ec=1 + ./cmake.output/bin/cppcheck $selfcheck_options $cppcheck_options -DQ_MOC_OUTPUT_REVISION=68 -DQT_CHARTS_LIB -DQT_MOC_HAS_STRINGDATA --library=qt -Icmake.output/tools/triage -Igui tools/triage/*.cpp cmake.output/tools/triage/*.cpp || ec=1 exit $ec diff --git a/.github/workflows/clang-tidy.yml b/.github/workflows/clang-tidy.yml index 90d04acd10f..29cf0ecbf67 100644 --- a/.github/workflows/clang-tidy.yml +++ b/.github/workflows/clang-tidy.yml @@ -20,7 +20,7 @@ jobs: runs-on: ubuntu-22.04 env: - QT_VERSION: 6.6.0 + QT_VERSION: 6.7.0 steps: - uses: actions/checkout@v3 diff --git a/.github/workflows/iwyu.yml b/.github/workflows/iwyu.yml index 1a8fcafdd5d..738d0d1489e 100644 --- a/.github/workflows/iwyu.yml +++ b/.github/workflows/iwyu.yml @@ -15,7 +15,7 @@ jobs: strategy: matrix: - image: ["opensuse/tumbleweed:latest"] # "fedora:latest" / "debian:unstable" / "archlinux:latest" + image: ["archlinux:latest"] # "opensuse/tumbleweed:latest" / "fedora:latest" / "debian:unstable" / "archlinux:latest" runs-on: ubuntu-22.04 if: ${{ github.repository_owner == 'danmar' }} @@ -23,25 +23,27 @@ jobs: container: image: ${{ matrix.image }} + env: + QT_VERSION: 6.7.0 + steps: - uses: actions/checkout@v3 - # TODO: the necessary packages are excessive - mostly because of Qt - use a pre-built image - name: Install missing software on debian/ubuntu if: contains(matrix.image, 'debian') run: | apt-get update - apt-get install -y cmake g++ make libpcre3-dev - apt-get install -y qtbase5-dev qttools5-dev libqt5charts5-dev - apt-get install -y wget iwyu - ln -s ../x86_64-linux-gnu/qt5 /usr/include/qt + apt-get install -y cmake clang make libpcre3-dev + apt-get install -y libgl-dev # fixes missing dependency for Qt in CMake + apt-get install -y iwyu - name: Install missing software on archlinux if: contains(matrix.image, 'archlinux') run: | set -x pacman -Sy - pacman -S cmake make gcc qt5-base qt5-tools qt5-charts pcre wget --noconfirm + pacman -S cmake make clang pcre --noconfirm + pacman -S libglvnd --noconfirm # fixes missing dependency for Qt in CMake pacman-key --init pacman-key --recv-key 3056513887B78AEB --keyserver keyserver.ubuntu.com pacman-key --lsign-key 3056513887B78AEB @@ -52,28 +54,45 @@ jobs: pacman -S include-what-you-use --noconfirm ln -s iwyu-tool /usr/sbin/iwyu_tool - # TODO: the necessary packages are excessive - mostly because of Qt - use a pre-built image - name: Install missing software on Fedora if: contains(matrix.image, 'fedora') run: | - dnf install -y cmake gcc-c++ qt5-qtbase-devel qt5-linguist qt5-qttools-devel qt5-qtcharts-devel pcre-devel - dnf install -y wget iwyu + dnf install -y cmake clang pcre-devel + dnf install -y libglvnd-devel # fixes missing dependency for Qt in CMake + dnf install -y iwyu ln -s iwyu_tool.py /usr/bin/iwyu_tool - ln -s qt5 /usr/include/qt - name: Install missing software on OpenSUSE if: contains(matrix.image, 'opensuse') run: | - zypper install -y cmake gcc-c++ pcre-devel libQt5Core-devel libQt5Gui-devel libQt5Widgets-devel libQt5PrintSupport-devel libqt5-linguist-devel libqt5-qttools-devel libQt5Network-devel libQt5Charts5-devel libQt5Test-devel - zypper install -y wget include-what-you-use-tools + zypper install -y cmake clang pcre-devel + zypper install -y include-what-you-use-tools + # fixes error during Qt installation + # /__w/cppcheck/Qt/6.7.0/gcc_64/bin/qmake: error while loading shared libraries: libgthread-2.0.so.0: cannot open shared object file: No such file or directory + zypper install -y libgthread-2_0-0 ln -s iwyu_tool.py /usr/bin/iwyu_tool - ln -s qt5 /usr/include/qt - # TODO: switch to Qt 6 after we enabled the Qt mappings again + # Fails on OpenSUSE: + # Warning: Failed to restore: Tar failed with error: Unable to locate executable file: tar. Please verify either the file path exists or the file can be found within a directory specified by the PATH environment variable. Also check the file mode to verify the file is executable. + # Also the shell is broken afterwards: + # OCI runtime exec failed: exec failed: unable to start container process: exec: "sh": executable file not found in $PATH: unknown + - name: Install Qt ${{ env.QT_VERSION }} + uses: jurplel/install-qt-action@v3 + with: + version: ${{ env.QT_VERSION }} + modules: 'qtcharts' + install-deps: false + cache: true + - name: Prepare CMake run: | - cmake -S . -B cmake.output -G "Unix Makefiles" -DCMAKE_BUILD_TYPE=Release -DHAVE_RULES=On -DBUILD_TESTS=On -DBUILD_GUI=On -DWITH_QCHART=On -DENABLE_CHECK_INTERNAL=On -DCMAKE_GLOBAL_AUTOGEN_TARGET=On -DCMAKE_DISABLE_PRECOMPILE_HEADERS=On -DCPPCHK_GLIBCXX_DEBUG=Off -DUSE_MATCHCOMPILER=Off -DEXTERNALS_AS_SYSTEM=On + cmake -S . -B cmake.output -G "Unix Makefiles" -DCMAKE_BUILD_TYPE=Release -DHAVE_RULES=On -DBUILD_TESTS=On -DBUILD_GUI=On -DUSE_QT6=On -DWITH_QCHART=On -DENABLE_CHECK_INTERNAL=On -DCMAKE_GLOBAL_AUTOGEN_TARGET=On -DCMAKE_DISABLE_PRECOMPILE_HEADERS=On -DCPPCHK_GLIBCXX_DEBUG=Off -DUSE_MATCHCOMPILER=Off -DEXTERNALS_AS_SYSTEM=On + env: + CC: clang + CXX: clang++ + # Fails on Debian: + # /__w/cppcheck/Qt/6.7.0/gcc_64/libexec/rcc: error while loading shared libraries: libglib-2.0.so.0: cannot open shared object file: No such file or directory - name: Prepare CMake dependencies run: | # make sure the precompiled headers exist @@ -87,16 +106,11 @@ jobs: make -C cmake.output gui-build-deps make -C cmake.output triage-build-ui-deps - - name: Build Qt mappings - run: | - wget https://raw.githubusercontent.com/include-what-you-use/include-what-you-use/master/mapgen/iwyu-mapgen-qt.py - python3 iwyu-mapgen-qt.py /usr/include/qt/ > qt5.imp - - name: iwyu_tool run: | PWD=$(pwd) # -isystem/usr/lib/clang/17/include - iwyu_tool -p cmake.output -j $(nproc) -- -w -Xiwyu --max_line_length=1024 -Xiwyu --comment_style=long -Xiwyu --quoted_includes_first -Xiwyu --update_comments -Xiwyu --mapping_file=$PWD/qt5.imp > iwyu.log + iwyu_tool -p cmake.output -j $(nproc) -- -w -Xiwyu --max_line_length=1024 -Xiwyu --comment_style=long -Xiwyu --quoted_includes_first -Xiwyu --update_comments > iwyu.log - uses: actions/upload-artifact@v3 if: success() || failure() @@ -104,12 +118,6 @@ jobs: name: Compilation Database path: ./cmake.output/compile_commands.json - - uses: actions/upload-artifact@v3 - if: success() || failure() - with: - name: Qt Mappings - path: ./qt5.imp - - uses: actions/upload-artifact@v3 if: success() || failure() with: @@ -122,7 +130,7 @@ jobs: if: ${{ github.repository_owner == 'danmar' }} env: - QT_VERSION: 5.15.2 + QT_VERSION: 6.7.0 steps: - uses: actions/checkout@v3 @@ -130,9 +138,8 @@ jobs: - name: Install missing software run: | sudo apt-get update - sudo apt-get install -y cmake make - sudo apt-get install -y libpcre3-dev - sudo apt-get install -y libffi7 # work around missing dependency for Qt install step + sudo apt-get install -y cmake make libpcre3-dev + sudo apt-get install -y libgl-dev # missing dependency for using Qt in CMake - name: Install clang run: | @@ -147,11 +154,12 @@ jobs: with: version: ${{ env.QT_VERSION }} modules: 'qtcharts' + install-deps: false cache: true - name: Prepare CMake run: | - cmake -S . -B cmake.output -G "Unix Makefiles" -DCMAKE_BUILD_TYPE=Release -DHAVE_RULES=On -DBUILD_TESTS=On -DBUILD_GUI=On -DBUILD_GUI=On -DWITH_QCHART=On -DENABLE_CHECK_INTERNAL=On -DCMAKE_GLOBAL_AUTOGEN_TARGET=On -DCMAKE_DISABLE_PRECOMPILE_HEADERS=On -DCPPCHK_GLIBCXX_DEBUG=Off -DUSE_MATCHCOMPILER=Off -DEXTERNALS_AS_SYSTEM=On + cmake -S . -B cmake.output -G "Unix Makefiles" -DCMAKE_BUILD_TYPE=Release -DHAVE_RULES=On -DBUILD_TESTS=On -DBUILD_GUI=On -DUSE_QT6=On -DWITH_QCHART=On -DENABLE_CHECK_INTERNAL=On -DCMAKE_GLOBAL_AUTOGEN_TARGET=On -DCMAKE_DISABLE_PRECOMPILE_HEADERS=On -DCPPCHK_GLIBCXX_DEBUG=Off -DUSE_MATCHCOMPILER=Off -DEXTERNALS_AS_SYSTEM=On env: CC: clang-18 CXX: clang++-18 @@ -171,7 +179,7 @@ jobs: - name: clang-include-cleaner run: | # TODO: run multi-threaded - find $PWD/cli $PWD/lib $PWD/test -maxdepth 1 -name "*.cpp" | xargs -t -n 1 clang-include-cleaner-18 --print=changes --extra-arg=-w -p cmake.output > clang-include-cleaner.log 2>&1 + find $PWD/cli $PWD/lib $PWD/test $PWD/gui -maxdepth 1 -name "*.cpp" | xargs -t -n 1 clang-include-cleaner-18 --print=changes --extra-arg=-w -p cmake.output > clang-include-cleaner.log 2>&1 - uses: actions/upload-artifact@v3 with: diff --git a/.github/workflows/selfcheck.yml b/.github/workflows/selfcheck.yml index ce7110c73f2..f76cb978cf0 100644 --- a/.github/workflows/selfcheck.yml +++ b/.github/workflows/selfcheck.yml @@ -20,7 +20,7 @@ jobs: runs-on: ubuntu-22.04 env: - QT_VERSION: 6.6.0 + QT_VERSION: 6.7.0 steps: - uses: actions/checkout@v3 @@ -75,7 +75,7 @@ jobs: - name: Self check (unusedFunction) if: false # TODO: fails with preprocessorErrorDirective - see #10667 run: | - ./cppcheck -q --template=selfcheck --error-exitcode=1 --library=cppcheck-lib --library=qt -D__CPPCHECK__ -D__GNUC__ -DQT_VERSION=0x060000 -DQ_MOC_OUTPUT_REVISION=68 -DQT_CHARTS_LIB --enable=unusedFunction --exception-handling -rp=. --project=cmake.output/compile_commands.json --suppressions-list=.selfcheck_unused_suppressions --inline-suppr + ./cppcheck -q --template=selfcheck --error-exitcode=1 --library=cppcheck-lib --library=qt -D__CPPCHECK__ -D__GNUC__ -DQT_VERSION=0x060000 -DQ_MOC_OUTPUT_REVISION=68 -DQT_CHARTS_LIB -DQT_MOC_HAS_STRINGDATA --enable=unusedFunction --exception-handling -rp=. --project=cmake.output/compile_commands.json --suppressions-list=.selfcheck_unused_suppressions --inline-suppr env: DISABLE_VALUEFLOW: 1 UNUSEDFUNCTION_ONLY: 1 @@ -96,7 +96,7 @@ jobs: # TODO: find a way to report unmatched suppressions without need to add information checks - name: Self check (unusedFunction / no test) run: | - ./cppcheck -q --template=selfcheck --error-exitcode=1 --library=cppcheck-lib --library=qt -D__CPPCHECK__ -D__GNUC__ -DQT_VERSION=0x060000 -DQ_MOC_OUTPUT_REVISION=68 -DQT_CHARTS_LIB --enable=unusedFunction --exception-handling -rp=. --project=cmake.output.notest/compile_commands.json --suppressions-list=.selfcheck_unused_suppressions --inline-suppr + ./cppcheck -q --template=selfcheck --error-exitcode=1 --library=cppcheck-lib --library=qt -D__CPPCHECK__ -D__GNUC__ -DQT_VERSION=0x060000 -DQ_MOC_OUTPUT_REVISION=68 -DQT_CHARTS_LIB -DQT_MOC_HAS_STRINGDATA --enable=unusedFunction --exception-handling -rp=. --project=cmake.output.notest/compile_commands.json --suppressions-list=.selfcheck_unused_suppressions --inline-suppr env: DISABLE_VALUEFLOW: 1 UNUSEDFUNCTION_ONLY: 1 @@ -122,7 +122,7 @@ jobs: - name: Self check (unusedFunction / corpus / no test / callgrind) run: | # TODO: fix -rp so the suppressions actually work - valgrind --tool=callgrind ./cppcheck --template=selfcheck --error-exitcode=0 --library=cppcheck-lib --library=qt -D__GNUC__ -DQT_VERSION=0x060000 -DQ_MOC_OUTPUT_REVISION=68 -DQT_CHARTS_LIB --enable=unusedFunction --exception-handling -rp=. --project=cmake.output.corpus/compile_commands.json --suppressions-list=.selfcheck_unused_suppressions --inline-suppr 2>callgrind.log || (cat callgrind.log && false) + valgrind --tool=callgrind ./cppcheck --template=selfcheck --error-exitcode=0 --library=cppcheck-lib --library=qt -D__GNUC__ -DQT_VERSION=0x060000 -DQ_MOC_OUTPUT_REVISION=68 -DQT_CHARTS_LIB -DQT_MOC_HAS_STRINGDATA --enable=unusedFunction --exception-handling -rp=. --project=cmake.output.corpus/compile_commands.json --suppressions-list=.selfcheck_unused_suppressions --inline-suppr 2>callgrind.log || (cat callgrind.log && false) cat callgrind.log callgrind_annotate --auto=no > callgrind.annotated.log head -50 callgrind.annotated.log diff --git a/.github/workflows/tsan.yml b/.github/workflows/tsan.yml index 0cabb7b2271..28f508fdbd0 100644 --- a/.github/workflows/tsan.yml +++ b/.github/workflows/tsan.yml @@ -136,7 +136,7 @@ jobs: ec=0 ./cmake.output/bin/cppcheck $selfcheck_options externals/simplecpp || ec=1 ./cmake.output/bin/cppcheck $selfcheck_options $cppcheck_options --addon=naming.json -DCHECK_INTERNAL cli lib || ec=1 - ./cmake.output/bin/cppcheck $selfcheck_options $cppcheck_options -DQT_VERSION=0x060000 -DQ_MOC_OUTPUT_REVISION=68 -DQT_CHARTS_LIB --library=qt --addon=naming.json -Icmake.output/gui -Igui gui/*.cpp cmake.output/gui/*.cpp || ec=1 + ./cmake.output/bin/cppcheck $selfcheck_options $cppcheck_options -DQT_VERSION=0x060000 -DQ_MOC_OUTPUT_REVISION=68 -DQT_CHARTS_LIB -DQT_MOC_HAS_STRINGDATA --library=qt --addon=naming.json -Icmake.output/gui -Igui gui/*.cpp cmake.output/gui/*.cpp || ec=1 ./cmake.output/bin/cppcheck $selfcheck_options $cppcheck_options -Icli test/*.cpp tools/*.cpp || ec=1 - ./cmake.output/bin/cppcheck $selfcheck_options $cppcheck_options -DQ_MOC_OUTPUT_REVISION=68 -DQT_CHARTS_LIB --library=qt -Icmake.output/tools/triage -Igui tools/triage/*.cpp cmake.output/tools/triage/*.cpp || ec=1 + ./cmake.output/bin/cppcheck $selfcheck_options $cppcheck_options -DQ_MOC_OUTPUT_REVISION=68 -DQT_CHARTS_LIB -DQT_MOC_HAS_STRINGDATA --library=qt -Icmake.output/tools/triage -Igui tools/triage/*.cpp cmake.output/tools/triage/*.cpp || ec=1 exit $ec diff --git a/.github/workflows/ubsan.yml b/.github/workflows/ubsan.yml index a1951adc406..31701b1bbd4 100644 --- a/.github/workflows/ubsan.yml +++ b/.github/workflows/ubsan.yml @@ -130,7 +130,7 @@ jobs: ec=0 ./cmake.output/bin/cppcheck $selfcheck_options externals/simplecpp || ec=1 ./cmake.output/bin/cppcheck $selfcheck_options $cppcheck_options --addon=naming.json cli lib || ec=1 - ./cmake.output/bin/cppcheck $selfcheck_options $cppcheck_options -DQT_VERSION=0x060000 -DQ_MOC_OUTPUT_REVISION=68 -DQT_CHARTS_LIB --library=qt --addon=naming.json -Icmake.output/gui -Igui gui/*.cpp cmake.output/gui/*.cpp || ec=1 + ./cmake.output/bin/cppcheck $selfcheck_options $cppcheck_options -DQT_VERSION=0x060000 -DQ_MOC_OUTPUT_REVISION=68 -DQT_CHARTS_LIB -DQT_MOC_HAS_STRINGDATA --library=qt --addon=naming.json -Icmake.output/gui -Igui gui/*.cpp cmake.output/gui/*.cpp || ec=1 ./cmake.output/bin/cppcheck $selfcheck_options $cppcheck_options -Icli test/*.cpp tools/*.cpp || ec=1 - ./cmake.output/bin/cppcheck $selfcheck_options $cppcheck_options -DQ_MOC_OUTPUT_REVISION=68 -DQT_CHARTS_LIB --library=qt -Icmake.output/tools/triage -Igui tools/triage/*.cpp cmake.output/tools/triage/*.cpp || ec=1 + ./cmake.output/bin/cppcheck $selfcheck_options $cppcheck_options -DQ_MOC_OUTPUT_REVISION=68 -DQT_CHARTS_LIB -DQT_MOC_HAS_STRINGDATA --library=qt -Icmake.output/tools/triage -Igui tools/triage/*.cpp cmake.output/tools/triage/*.cpp || ec=1 exit $ec diff --git a/gui/mainwindow.cpp b/gui/mainwindow.cpp index 5d79794784c..eb2905d3475 100644 --- a/gui/mainwindow.cpp +++ b/gui/mainwindow.cpp @@ -823,24 +823,24 @@ void MainWindow::addIncludeDirs(const QStringList &includeDirs, Settings &result } } -Library::Error MainWindow::loadLibrary(Library *library, const QString &filename) +Library::Error MainWindow::loadLibrary(Library &library, const QString &filename) { Library::Error ret; // Try to load the library from the project folder.. if (mProjectFile) { QString path = QFileInfo(mProjectFile->getFilename()).canonicalPath(); - ret = library->load(nullptr, (path+"/"+filename).toLatin1()); + ret = library.load(nullptr, (path+"/"+filename).toLatin1()); if (ret.errorcode != Library::ErrorCode::FILE_NOT_FOUND) return ret; } // Try to load the library from the application folder.. const QString appPath = QFileInfo(QCoreApplication::applicationFilePath()).canonicalPath(); - ret = library->load(nullptr, (appPath+"/"+filename).toLatin1()); + ret = library.load(nullptr, (appPath+"/"+filename).toLatin1()); if (ret.errorcode != Library::ErrorCode::FILE_NOT_FOUND) return ret; - ret = library->load(nullptr, (appPath+"/cfg/"+filename).toLatin1()); + ret = library.load(nullptr, (appPath+"/cfg/"+filename).toLatin1()); if (ret.errorcode != Library::ErrorCode::FILE_NOT_FOUND) return ret; @@ -848,10 +848,10 @@ Library::Error MainWindow::loadLibrary(Library *library, const QString &filename // Try to load the library from FILESDIR/cfg.. const QString filesdir = FILESDIR; if (!filesdir.isEmpty()) { - ret = library->load(nullptr, (filesdir+"/cfg/"+filename).toLatin1()); + ret = library.load(nullptr, (filesdir+"/cfg/"+filename).toLatin1()); if (ret.errorcode != Library::ErrorCode::FILE_NOT_FOUND) return ret; - ret = library->load(nullptr, (filesdir+filename).toLatin1()); + ret = library.load(nullptr, (filesdir+filename).toLatin1()); if (ret.errorcode != Library::ErrorCode::FILE_NOT_FOUND) return ret; } @@ -860,10 +860,10 @@ Library::Error MainWindow::loadLibrary(Library *library, const QString &filename // Try to load the library from the cfg subfolder.. const QString datadir = getDataDir(); if (!datadir.isEmpty()) { - ret = library->load(nullptr, (datadir+"/"+filename).toLatin1()); + ret = library.load(nullptr, (datadir+"/"+filename).toLatin1()); if (ret.errorcode != Library::ErrorCode::FILE_NOT_FOUND) return ret; - ret = library->load(nullptr, (datadir+"/cfg/"+filename).toLatin1()); + ret = library.load(nullptr, (datadir+"/cfg/"+filename).toLatin1()); if (ret.errorcode != Library::ErrorCode::FILE_NOT_FOUND) return ret; } @@ -871,7 +871,7 @@ Library::Error MainWindow::loadLibrary(Library *library, const QString &filename return ret; } -bool MainWindow::tryLoadLibrary(Library *library, const QString& filename) +bool MainWindow::tryLoadLibrary(Library &library, const QString& filename) { const Library::Error error = loadLibrary(library, filename); if (error.errorcode != Library::ErrorCode::OK) { @@ -972,7 +972,7 @@ QPair MainWindow::getCppcheckSettings() // default to --check-level=normal for GUI for now result.setCheckLevel(Settings::CheckLevel::normal); - const bool std = tryLoadLibrary(&result.library, "std.cfg"); + const bool std = tryLoadLibrary(result.library, "std.cfg"); if (!std) { QMessageBox::critical(this, tr("Error"), tr("Failed to load %1. Your Cppcheck installation is broken. You can use --data-dir= at the command line to specify where this file is located. Please note that --data-dir is supposed to be used by installation scripts and therefore the GUI does not start when it is used, all that happens is that the setting is configured.\n\nAnalysis is aborted.").arg("std.cfg")); return {false, {}}; @@ -1022,7 +1022,7 @@ QPair MainWindow::getCppcheckSettings() for (const QString& library : libraries) { result.libraries.emplace_back(library.toStdString()); const QString filename = library + ".cfg"; - tryLoadLibrary(&result.library, filename); + tryLoadLibrary(result.library, filename); } for (const SuppressionList::Suppression &suppression : mProjectFile->getCheckingSuppressions()) { diff --git a/gui/mainwindow.h b/gui/mainwindow.h index 5214b690ddc..b0721213545 100644 --- a/gui/mainwindow.h +++ b/gui/mainwindow.h @@ -392,7 +392,7 @@ private slots: * @param filename filename (no path) * @return error code */ - Library::Error loadLibrary(Library *library, const QString &filename); + Library::Error loadLibrary(Library &library, const QString &filename); /** * @brief Tries to load library file, prints message on error @@ -400,7 +400,7 @@ private slots: * @param filename filename (no path) * @return True if no error */ - bool tryLoadLibrary(Library *library, const QString& filename); + bool tryLoadLibrary(Library &library, const QString& filename); QString loadAddon(Settings &settings, const QString &filesDir, const QString &pythonCmd, const QString& addon); diff --git a/lib/astutils.cpp b/lib/astutils.cpp index 65180150852..105d780fd88 100644 --- a/lib/astutils.cpp +++ b/lib/astutils.cpp @@ -304,15 +304,12 @@ Library::Container::Yield astContainerYield(const Token* tok, const Token** ftok return tok->valueType()->container->getYield(ftok2->str()); } -Library::Container::Yield astFunctionYield(const Token* tok, const Settings* settings, const Token** ftok) +Library::Container::Yield astFunctionYield(const Token* tok, const Settings& settings, const Token** ftok) { if (!tok) return Library::Container::Yield::NO_YIELD; - if (!settings) - return Library::Container::Yield::NO_YIELD; - - const auto* function = settings->library.getFunction(tok); + const auto* function = settings.library.getFunction(tok); if (!function) return Library::Container::Yield::NO_YIELD; @@ -635,7 +632,7 @@ static std::vector getParentMembers(const Token* tok) return result; } -const Token* getParentLifetime(const Token* tok, const Library* library) +const Token* getParentLifetime(const Token* tok, const Library& library) { std::vector members = getParentMembers(tok); if (members.size() < 2) @@ -647,7 +644,7 @@ const Token* getParentLifetime(const Token* tok, const Library* library) return var->isLocal() || var->isArgument(); if (Token::simpleMatch(tok2, "[")) return true; - return isTemporary(tok2, library); + return isTemporary(tok2, &library); }); if (it == members.rend()) return tok; @@ -771,7 +768,7 @@ std::vector getParentValueTypes(const Token* tok, const Settings* set if (Token::simpleMatch(tok->astParent(), "(") && ftok && !tok->astParent()->isCast() && ftok->tokType() != Token::eType) return {}; - if (Token::Match(tok->astParent(), "return|(|{|%assign%") && parent) { + if (parent && Token::Match(tok->astParent(), "return|(|{|%assign%")) { *parent = tok->astParent(); } if (tok->astParent()->valueType()) @@ -2127,18 +2124,18 @@ bool isUniqueExpression(const Token* tok) return isUniqueExpression(tok->astOperand2()); } -static bool isEscaped(const Token* tok, bool functionsScope, const Library* library) +static bool isEscaped(const Token* tok, bool functionsScope, const Library& library) { - if (library && library->isnoreturn(tok)) + if (library.isnoreturn(tok)) return true; if (functionsScope) return Token::simpleMatch(tok, "throw"); return Token::Match(tok, "return|throw"); } -static bool isEscapedOrJump(const Token* tok, bool functionsScope, const Library* library) +static bool isEscapedOrJump(const Token* tok, bool functionsScope, const Library& library) { - if (library && library->isnoreturn(tok)) + if (library.isnoreturn(tok)) return true; if (functionsScope) return Token::simpleMatch(tok, "throw"); @@ -2162,7 +2159,7 @@ bool isEscapeFunction(const Token* ftok, const Library* library) return false; } -static bool hasNoreturnFunction(const Token* tok, const Library* library, const Token** unknownFunc) +static bool hasNoreturnFunction(const Token* tok, const Library& library, const Token** unknownFunc) { if (!tok) return false; @@ -2176,12 +2173,12 @@ static bool hasNoreturnFunction(const Token* tok, const Library* library, const return true; if (function->isAttributeNoreturn()) return true; - } else if (library && library->isnoreturn(ftok)) { + } else if (library.isnoreturn(ftok)) { return true; } else if (Token::Match(ftok, "exit|abort")) { return true; } - if (unknownFunc && !function && library && library->functions.count(library->getFunctionName(ftok)) == 0) + if (unknownFunc && !function && library.functions.count(library.getFunctionName(ftok)) == 0) *unknownFunc = ftok; return false; } @@ -2192,7 +2189,7 @@ static bool hasNoreturnFunction(const Token* tok, const Library* library, const return false; } -bool isReturnScope(const Token* const endToken, const Library* library, const Token** unknownFunc, bool functionScope) +bool isReturnScope(const Token* const endToken, const Library& library, const Token** unknownFunc, bool functionScope) { if (!endToken || endToken->str() != "}") return false; @@ -3005,9 +3002,9 @@ namespace { }; struct ExpressionChangedSkipDeadCode { - const Library* library; + const Library& library; const std::function(const Token* tok)>* evaluate; - ExpressionChangedSkipDeadCode(const Library* library, + ExpressionChangedSkipDeadCode(const Library& library, const std::function(const Token* tok)>& evaluate) : library(library), evaluate(&evaluate) {} @@ -3036,7 +3033,7 @@ const Token* findExpressionChangedSkipDeadCode(const Token* expr, int depth) { return findExpressionChangedImpl( - expr, start, end, settings, depth, ExpressionChangedSkipDeadCode{&settings->library, evaluate}); + expr, start, end, settings, depth, ExpressionChangedSkipDeadCode{settings->library, evaluate}); } const Token* getArgumentStart(const Token* ftok) @@ -3286,7 +3283,7 @@ bool isConstVarExpression(const Token *tok, const std::functionastParent() && tok->astParent()->isUnaryOp("&"); @@ -3326,11 +3323,11 @@ static ExprUsage getFunctionUsage(const Token* tok, int indirect, const Settings if (ftok->variable()->isStlType() || (ftok->variable()->valueType() && ftok->variable()->valueType()->container)) // STL types or containers don't initialize external variables return ExprUsage::Used; } else { - const bool isnullbad = settings->library.isnullargbad(ftok, argnr + 1); + const bool isnullbad = settings.library.isnullargbad(ftok, argnr + 1); if (indirect == 0 && astIsPointer(tok) && !addressOf && isnullbad) return ExprUsage::Used; bool hasIndirect = false; - const bool isuninitbad = settings->library.isuninitargbad(ftok, argnr + 1, indirect, &hasIndirect); + const bool isuninitbad = settings.library.isuninitargbad(ftok, argnr + 1, indirect, &hasIndirect); if (isuninitbad && (!addressOf || isnullbad)) return ExprUsage::Used; } @@ -3349,7 +3346,7 @@ bool isLeafDot(const Token* tok) return isLeafDot(parent); } -ExprUsage getExprUsage(const Token* tok, int indirect, const Settings* settings) +ExprUsage getExprUsage(const Token* tok, int indirect, const Settings& settings) { const Token* parent = tok->astParent(); if (indirect > 0 && parent) { @@ -3365,7 +3362,7 @@ ExprUsage getExprUsage(const Token* tok, int indirect, const Settings* settings) return ExprUsage::NotUsed; if (Token::simpleMatch(parent, ":") && Token::simpleMatch(parent->astParent(), "?")) return getExprUsage(parent->astParent(), indirect, settings); - if (isUsedAsBool(tok, settings)) + if (isUsedAsBool(tok, &settings)) return ExprUsage::NotUsed; } if (indirect == 0) { diff --git a/lib/astutils.h b/lib/astutils.h index 1526d00a7d7..6426225253e 100644 --- a/lib/astutils.h +++ b/lib/astutils.h @@ -173,7 +173,7 @@ bool astIsContainerString(const Token* tok); Library::Container::Action astContainerAction(const Token* tok, const Token** ftok = nullptr); Library::Container::Yield astContainerYield(const Token* tok, const Token** ftok = nullptr); -Library::Container::Yield astFunctionYield(const Token* tok, const Settings* settings, const Token** ftok = nullptr); +Library::Container::Yield astFunctionYield(const Token* tok, const Settings& settings, const Token** ftok = nullptr); /** Is given token a range-declaration in a range-based for loop */ bool astIsRangeBasedForDecl(const Token* tok); @@ -209,7 +209,7 @@ const Token* astParentSkipParens(const Token* tok); const Token* getParentMember(const Token * tok); const Token* getParentLifetime(const Token* tok); -const Token* getParentLifetime(const Token* tok, const Library* library); +const Token* getParentLifetime(const Token* tok, const Library& library); std::vector getParentValueTypes(const Token* tok, const Settings* settings = nullptr, @@ -304,7 +304,7 @@ bool isEscapeFunction(const Token* ftok, const Library* library); /** Is scope a return scope (scope will unconditionally return) */ CPPCHECKLIB bool isReturnScope(const Token* const endToken, - const Library* library = nullptr, + const Library& library, const Token** unknownFunc = nullptr, bool functionScope = false); @@ -439,7 +439,7 @@ bool isLeafDot(const Token* tok); enum class ExprUsage { None, NotUsed, PassedByReference, Used, Inconclusive }; -ExprUsage getExprUsage(const Token* tok, int indirect, const Settings* settings); +ExprUsage getExprUsage(const Token* tok, int indirect, const Settings& settings); const Variable *getLHSVariable(const Token *tok); diff --git a/lib/check.h b/lib/check.h index 91930a37450..ab7f3ccad13 100644 --- a/lib/check.h +++ b/lib/check.h @@ -109,9 +109,7 @@ class CPPCHECKLIB Check { } }; - virtual FileInfo * getFileInfo(const Tokenizer *tokenizer, const Settings *settings) const { - (void)tokenizer; - (void)settings; + virtual FileInfo * getFileInfo(const Tokenizer& /*tokenizer*/, const Settings& /*settings*/) const { return nullptr; } diff --git a/lib/checkautovariables.cpp b/lib/checkautovariables.cpp index 7434fb3be3a..17242326490 100644 --- a/lib/checkautovariables.cpp +++ b/lib/checkautovariables.cpp @@ -598,7 +598,7 @@ void CheckAutoVariables::checkVarLifetimeScope(const Token * start, const Token continue; if (!printInconclusive && val.isInconclusive()) continue; - const Token* parent = getParentLifetime(val.tokvalue, &mSettings->library); + const Token* parent = getParentLifetime(val.tokvalue, mSettings->library); if (!exprs.insert(parent).second) continue; for (const ValueFlow::LifetimeToken& lt : ValueFlow::getLifetimeTokens(parent, escape || isAssignedToNonLocal(tok))) { diff --git a/lib/checkbufferoverrun.cpp b/lib/checkbufferoverrun.cpp index 5c5cc5e0c81..884ca51f2f3 100644 --- a/lib/checkbufferoverrun.cpp +++ b/lib/checkbufferoverrun.cpp @@ -915,11 +915,11 @@ namespace }; } -bool CheckBufferOverrun::isCtuUnsafeBufferUsage(const Settings *settings, const Token *argtok, MathLib::bigint *offset, int type) +bool CheckBufferOverrun::isCtuUnsafeBufferUsage(const Settings &settings, const Token *argtok, MathLib::bigint *offset, int type) { if (!offset) return false; - if (!argtok->valueType() || argtok->valueType()->typeSize(settings->platform) == 0) + if (!argtok->valueType() || argtok->valueType()->typeSize(settings.platform) == 0) return false; const Token *indexTok = nullptr; if (type == 1 && Token::Match(argtok, "%name% [") && argtok->astParent() == argtok->next() && !Token::simpleMatch(argtok->linkAt(1), "] [")) @@ -932,22 +932,22 @@ bool CheckBufferOverrun::isCtuUnsafeBufferUsage(const Settings *settings, const return false; if (!indexTok->hasKnownIntValue()) return false; - *offset = indexTok->getKnownIntValue() * argtok->valueType()->typeSize(settings->platform); + *offset = indexTok->getKnownIntValue() * argtok->valueType()->typeSize(settings.platform); return true; } -bool CheckBufferOverrun::isCtuUnsafeArrayIndex(const Settings *settings, const Token *argtok, MathLib::bigint *offset) +bool CheckBufferOverrun::isCtuUnsafeArrayIndex(const Settings &settings, const Token *argtok, MathLib::bigint *offset) { return isCtuUnsafeBufferUsage(settings, argtok, offset, 1); } -bool CheckBufferOverrun::isCtuUnsafePointerArith(const Settings *settings, const Token *argtok, MathLib::bigint *offset) +bool CheckBufferOverrun::isCtuUnsafePointerArith(const Settings &settings, const Token *argtok, MathLib::bigint *offset) { return isCtuUnsafeBufferUsage(settings, argtok, offset, 2); } /** @brief Parse current TU and extract file info */ -Check::FileInfo *CheckBufferOverrun::getFileInfo(const Tokenizer *tokenizer, const Settings *settings) const +Check::FileInfo *CheckBufferOverrun::getFileInfo(const Tokenizer &tokenizer, const Settings &settings) const { const std::list &unsafeArrayIndex = CTU::getUnsafeUsage(tokenizer, settings, isCtuUnsafeArrayIndex); const std::list &unsafePointerArith = CTU::getUnsafeUsage(tokenizer, settings, isCtuUnsafePointerArith); diff --git a/lib/checkbufferoverrun.h b/lib/checkbufferoverrun.h index e97cf518848..b993dafdfbb 100644 --- a/lib/checkbufferoverrun.h +++ b/lib/checkbufferoverrun.h @@ -92,7 +92,7 @@ class CPPCHECKLIB CheckBufferOverrun : public Check { } /** @brief Parse current TU and extract file info */ - Check::FileInfo *getFileInfo(const Tokenizer *tokenizer, const Settings *settings) const override; + Check::FileInfo *getFileInfo(const Tokenizer &tokenizer, const Settings &settings) const override; /** @brief Analyse all file infos for all TU */ bool analyseWholeProgram(const CTU::FileInfo *ctu, const std::list &fileInfo, const Settings& settings, ErrorLogger &errorLogger) override; @@ -130,9 +130,9 @@ class CPPCHECKLIB CheckBufferOverrun : public Check { ValueFlow::Value getBufferSize(const Token *bufTok) const; // CTU - static bool isCtuUnsafeBufferUsage(const Settings *settings, const Token *argtok, MathLib::bigint *offset, int type); - static bool isCtuUnsafeArrayIndex(const Settings *settings, const Token *argtok, MathLib::bigint *offset); - static bool isCtuUnsafePointerArith(const Settings *settings, const Token *argtok, MathLib::bigint *offset); + static bool isCtuUnsafeBufferUsage(const Settings &settings, const Token *argtok, MathLib::bigint *offset, int type); + static bool isCtuUnsafeArrayIndex(const Settings &settings, const Token *argtok, MathLib::bigint *offset); + static bool isCtuUnsafePointerArith(const Settings &settings, const Token *argtok, MathLib::bigint *offset); Check::FileInfo * loadFileInfoFromXml(const tinyxml2::XMLElement *xmlElement) const override; static bool analyseWholeProgram1(const std::map> &callsMap, const CTU::FileInfo::UnsafeUsage &unsafeUsage, int type, ErrorLogger &errorLogger); diff --git a/lib/checkclass.cpp b/lib/checkclass.cpp index 8fadb87e2a2..7dc6c3f1468 100644 --- a/lib/checkclass.cpp +++ b/lib/checkclass.cpp @@ -1740,7 +1740,7 @@ void CheckClass::operatorEqToSelf() // find the parameter name const Token *rhs = func.argumentList.cbegin()->nameToken(); const Token* out_ifStatementScopeStart = nullptr; - if (!hasAssignSelf(&func, rhs, &out_ifStatementScopeStart)) { + if (!hasAssignSelf(&func, rhs, out_ifStatementScopeStart)) { if (hasAllocation(&func, scope)) operatorEqToSelfError(func.token); } else if (out_ifStatementScopeStart != nullptr) { @@ -1859,7 +1859,7 @@ const Token * CheckClass::getIfStmtBodyStart(const Token *tok, const Token *rhs) return nullptr; } -bool CheckClass::hasAssignSelf(const Function *func, const Token *rhs, const Token **out_ifStatementScopeStart) +bool CheckClass::hasAssignSelf(const Function *func, const Token *rhs, const Token *&out_ifStatementScopeStart) { if (!rhs) return false; @@ -1882,7 +1882,7 @@ bool CheckClass::hasAssignSelf(const Function *func, const Token *rhs, const Tok if (tok2 && tok2->isUnaryOp("&") && tok2->astOperand1()->str() == rhs->str()) ret = true; if (ret) { - *out_ifStatementScopeStart = getIfStmtBodyStart(tok2, rhs); + out_ifStatementScopeStart = getIfStmtBodyStart(tok2, rhs); } return ret ? ChildrenToVisit::done : ChildrenToVisit::op1_and_op2; }); @@ -3400,13 +3400,13 @@ void CheckClass::checkThisUseAfterFree() const Token * freeToken = nullptr; std::set callstack; - checkThisUseAfterFreeRecursive(classScope, &func, &var, std::move(callstack), &freeToken); + checkThisUseAfterFreeRecursive(classScope, &func, &var, std::move(callstack), freeToken); } } } } -bool CheckClass::checkThisUseAfterFreeRecursive(const Scope *classScope, const Function *func, const Variable *selfPointer, std::set callstack, const Token **freeToken) +bool CheckClass::checkThisUseAfterFreeRecursive(const Scope *classScope, const Function *func, const Variable *selfPointer, std::set callstack, const Token *&freeToken) { if (!func || !func->functionScope) return false; @@ -3419,23 +3419,23 @@ bool CheckClass::checkThisUseAfterFreeRecursive(const Scope *classScope, const F const Token * const bodyStart = func->functionScope->bodyStart; const Token * const bodyEnd = func->functionScope->bodyEnd; for (const Token *tok = bodyStart; tok != bodyEnd; tok = tok->next()) { - const bool isDestroyed = *freeToken != nullptr && !func->isStatic(); + const bool isDestroyed = freeToken != nullptr && !func->isStatic(); if (Token::Match(tok, "delete %var% ;") && selfPointer == tok->next()->variable()) { - *freeToken = tok; + freeToken = tok; tok = tok->tokAt(2); } else if (Token::Match(tok, "%var% . reset ( )") && selfPointer == tok->variable()) - *freeToken = tok; + freeToken = tok; else if (Token::Match(tok->previous(), "!!. %name% (") && tok->function() && tok->function()->nestedIn == classScope) { if (isDestroyed) { - thisUseAfterFree(selfPointer->nameToken(), *freeToken, tok); + thisUseAfterFree(selfPointer->nameToken(), freeToken, tok); return true; } if (checkThisUseAfterFreeRecursive(classScope, tok->function(), selfPointer, callstack, freeToken)) return true; } else if (isDestroyed && Token::Match(tok->previous(), "!!. %name%") && tok->variable() && tok->variable()->scope() == classScope && !tok->variable()->isStatic() && !tok->variable()->isArgument()) { - thisUseAfterFree(selfPointer->nameToken(), *freeToken, tok); + thisUseAfterFree(selfPointer->nameToken(), freeToken, tok); return true; - } else if (*freeToken && Token::Match(tok, "return|throw")) { + } else if (freeToken && Token::Match(tok, "return|throw")) { // TODO return tok->str() == "throw"; } else if (tok->str() == "{" && tok->scope()->type == Scope::ScopeType::eLambda) { @@ -3533,14 +3533,14 @@ namespace }; } -Check::FileInfo *CheckClass::getFileInfo(const Tokenizer *tokenizer, const Settings *settings) const +Check::FileInfo *CheckClass::getFileInfo(const Tokenizer &tokenizer, const Settings& /*settings*/) const { - if (!tokenizer->isCPP()) + if (!tokenizer.isCPP()) return nullptr; - (void)settings; + // One definition rule std::vector classDefinitions; - for (const Scope * classScope : tokenizer->getSymbolDatabase()->classAndStructScopes) { + for (const Scope * classScope : tokenizer.getSymbolDatabase()->classAndStructScopes) { if (classScope->isAnonymous()) continue; @@ -3575,7 +3575,7 @@ Check::FileInfo *CheckClass::getFileInfo(const Tokenizer *tokenizer, const Setti MyFileInfo::NameLoc nameLoc; nameLoc.className = std::move(name); - nameLoc.fileName = tokenizer->list.file(classScope->classDef); + nameLoc.fileName = tokenizer.list.file(classScope->classDef); nameLoc.lineNumber = classScope->classDef->linenr(); nameLoc.column = classScope->classDef->column(); diff --git a/lib/checkclass.h b/lib/checkclass.h index bc2a9d5116d..820b14ab858 100644 --- a/lib/checkclass.h +++ b/lib/checkclass.h @@ -168,7 +168,7 @@ class CPPCHECKLIB CheckClass : public Check { void checkUnsafeClassRefMember(); /** @brief Parse current TU and extract file info */ - Check::FileInfo *getFileInfo(const Tokenizer *tokenizer, const Settings *settings) const override; + Check::FileInfo *getFileInfo(const Tokenizer &tokenizer, const Settings &settings) const override; Check::FileInfo * loadFileInfoFromXml(const tinyxml2::XMLElement *xmlElement) const override; @@ -298,7 +298,7 @@ class CPPCHECKLIB CheckClass : public Check { bool hasAllocation(const Function *func, const Scope* scope) const; bool hasAllocation(const Function *func, const Scope* scope, const Token *start, const Token *end) const; bool hasAllocationInIfScope(const Function *func, const Scope* scope, const Token *ifStatementScopeStart) const; - static bool hasAssignSelf(const Function *func, const Token *rhs, const Token **out_ifStatementScopeStart); + static bool hasAssignSelf(const Function *func, const Token *rhs, const Token *&out_ifStatementScopeStart); enum class Bool { TRUE, FALSE, BAILOUT }; static Bool isInverted(const Token *tok, const Token *rhs); static const Token * getIfStmtBodyStart(const Token *tok, const Token *rhs); @@ -411,7 +411,7 @@ class CPPCHECKLIB CheckClass : public Check { /** * @brief Helper for checkThisUseAfterFree */ - bool checkThisUseAfterFreeRecursive(const Scope *classScope, const Function *func, const Variable *selfPointer, std::set callstack, const Token **freeToken); + bool checkThisUseAfterFreeRecursive(const Scope *classScope, const Function *func, const Variable *selfPointer, std::set callstack, const Token *&freeToken); }; /// @} //--------------------------------------------------------------------------- diff --git a/lib/checkcondition.cpp b/lib/checkcondition.cpp index f5e250a0cd8..3203bef3986 100644 --- a/lib/checkcondition.cpp +++ b/lib/checkcondition.cpp @@ -1573,8 +1573,8 @@ void CheckCondition::alwaysTrueFalse() { const ValueFlow::Value *zeroValue = nullptr; const Token *nonZeroExpr = nullptr; - if (CheckOther::comparisonNonZeroExpressionLessThanZero(tok, &zeroValue, &nonZeroExpr, /*suppress*/ true) || - CheckOther::testIfNonZeroExpressionIsPositive(tok, &zeroValue, &nonZeroExpr)) + if (CheckOther::comparisonNonZeroExpressionLessThanZero(tok, zeroValue, nonZeroExpr, /*suppress*/ true) || + CheckOther::testIfNonZeroExpressionIsPositive(tok, zeroValue, nonZeroExpr)) continue; } diff --git a/lib/checkio.cpp b/lib/checkio.cpp index b4fc0a4abb6..cd919537b75 100644 --- a/lib/checkio.cpp +++ b/lib/checkio.cpp @@ -487,7 +487,7 @@ void CheckIO::invalidScanfError(const Token *tok) //--------------------------------------------------------------------------- static bool findFormat(nonneg int arg, const Token *firstArg, - const Token **formatStringTok, const Token **formatArgTok) + const Token *&formatStringTok, const Token *&formatArgTok) { const Token* argTok = firstArg; @@ -495,8 +495,8 @@ static bool findFormat(nonneg int arg, const Token *firstArg, argTok = argTok->nextArgument(); if (Token::Match(argTok, "%str% [,)]")) { - *formatArgTok = argTok->nextArgument(); - *formatStringTok = argTok; + formatArgTok = argTok->nextArgument(); + formatStringTok = argTok; return true; } if (Token::Match(argTok, "%var% [,)]") && @@ -506,13 +506,13 @@ static bool findFormat(nonneg int arg, const Token *firstArg, (argTok->variable()->dimensions().size() == 1 && argTok->variable()->dimensionKnown(0) && argTok->variable()->dimension(0) != 0))) { - *formatArgTok = argTok->nextArgument(); + formatArgTok = argTok->nextArgument(); if (!argTok->values().empty()) { const std::list::const_iterator value = std::find_if( argTok->values().cbegin(), argTok->values().cend(), std::mem_fn(&ValueFlow::Value::isTokValue)); if (value != argTok->values().cend() && value->isTokValue() && value->tokvalue && value->tokvalue->tokType() == Token::eString) { - *formatStringTok = value->tokvalue; + formatStringTok = value->tokvalue; } } return true; @@ -552,37 +552,37 @@ void CheckIO::checkWrongPrintfScanfArguments() if (formatStringArgNo >= 0) { // formatstring found in library. Find format string and first argument belonging to format string. - if (!findFormat(formatStringArgNo, tok->tokAt(2), &formatStringTok, &argListTok)) + if (!findFormat(formatStringArgNo, tok->tokAt(2), formatStringTok, argListTok)) continue; } else if (Token::simpleMatch(tok, "swprintf (")) { if (Token::Match(tok->tokAt(2)->nextArgument(), "%str%")) { // Find third parameter and format string - if (!findFormat(1, tok->tokAt(2), &formatStringTok, &argListTok)) + if (!findFormat(1, tok->tokAt(2), formatStringTok, argListTok)) continue; } else { // Find fourth parameter and format string - if (!findFormat(2, tok->tokAt(2), &formatStringTok, &argListTok)) + if (!findFormat(2, tok->tokAt(2), formatStringTok, argListTok)) continue; } } else if (isWindows && Token::Match(tok, "sprintf_s|swprintf_s (")) { // template int sprintf_s(char (&buffer)[size], const char *format, ...); - if (findFormat(1, tok->tokAt(2), &formatStringTok, &argListTok)) { + if (findFormat(1, tok->tokAt(2), formatStringTok, argListTok)) { if (!formatStringTok) continue; } // int sprintf_s(char *buffer, size_t sizeOfBuffer, const char *format, ...); - else if (findFormat(2, tok->tokAt(2), &formatStringTok, &argListTok)) { + else if (findFormat(2, tok->tokAt(2), formatStringTok, argListTok)) { if (!formatStringTok) continue; } } else if (isWindows && Token::Match(tok, "_snprintf_s|_snwprintf_s (")) { // template int _snprintf_s(char (&buffer)[size], size_t count, const char *format, ...); - if (findFormat(2, tok->tokAt(2), &formatStringTok, &argListTok)) { + if (findFormat(2, tok->tokAt(2), formatStringTok, argListTok)) { if (!formatStringTok) continue; } // int _snprintf_s(char *buffer, size_t sizeOfBuffer, size_t count, const char *format, ...); - else if (findFormat(3, tok->tokAt(2), &formatStringTok, &argListTok)) { + else if (findFormat(3, tok->tokAt(2), formatStringTok, argListTok)) { if (!formatStringTok) continue; } diff --git a/lib/checkleakautovar.cpp b/lib/checkleakautovar.cpp index 266da5c50b7..de06c9f28aa 100644 --- a/lib/checkleakautovar.cpp +++ b/lib/checkleakautovar.cpp @@ -834,7 +834,7 @@ const Token * CheckLeakAutoVar::checkTokenInsideExpression(const Token * const t const std::map::const_iterator var = varInfo.alloctype.find(tok->varId()); if (var != varInfo.alloctype.end()) { bool unknown = false; - if (var->second.status == VarInfo::DEALLOC && CheckNullPointer::isPointerDeRef(tok, unknown, mSettings) && !unknown) { + if (var->second.status == VarInfo::DEALLOC && CheckNullPointer::isPointerDeRef(tok, unknown, *mSettings) && !unknown) { deallocUseError(tok, tok->str()); } else if (Token::simpleMatch(tok->tokAt(-2), "= &")) { varInfo.erase(tok->varId()); diff --git a/lib/checknullpointer.cpp b/lib/checknullpointer.cpp index cec36ee06dd..12c8b5ea4b1 100644 --- a/lib/checknullpointer.cpp +++ b/lib/checknullpointer.cpp @@ -62,28 +62,26 @@ static bool checkNullpointerFunctionCallPlausibility(const Function* func, unsig * @param var variables that the function read / write. * @param library --library files data */ -void CheckNullPointer::parseFunctionCall(const Token &tok, std::list &var, const Library *library) +void CheckNullPointer::parseFunctionCall(const Token &tok, std::list &var, const Library &library) { if (Token::Match(&tok, "%name% ( )") || !tok.tokAt(2)) return; const std::vector args = getArguments(&tok); - if (library || tok.function() != nullptr) { - for (int argnr = 1; argnr <= args.size(); ++argnr) { - const Token *param = args[argnr - 1]; - if (library && library->isnullargbad(&tok, argnr) && checkNullpointerFunctionCallPlausibility(tok.function(), argnr)) + for (int argnr = 1; argnr <= args.size(); ++argnr) { + const Token *param = args[argnr - 1]; + if (library.isnullargbad(&tok, argnr) && checkNullpointerFunctionCallPlausibility(tok.function(), argnr)) + var.push_back(param); + else if (tok.function()) { + const Variable* argVar = tok.function()->getArgumentVar(argnr-1); + if (argVar && argVar->isStlStringType() && !argVar->isArrayOrPointer()) var.push_back(param); - else if (tok.function()) { - const Variable* argVar = tok.function()->getArgumentVar(argnr-1); - if (argVar && argVar->isStlStringType() && !argVar->isArrayOrPointer()) - var.push_back(param); - } } } - if (library && library->formatstr_function(&tok)) { - const int formatStringArgNr = library->formatstr_argno(&tok); + if (library.formatstr_function(&tok)) { + const int formatStringArgNr = library.formatstr_argno(&tok); if (formatStringArgNr < 0 || formatStringArgNr >= args.size()) return; @@ -95,7 +93,7 @@ void CheckNullPointer::parseFunctionCall(const Token &tok, std::liststrValue(); int argnr = formatStringArgNr + 1; - const bool scan = library->formatstr_scan(&tok); + const bool scan = library.formatstr_scan(&tok); bool percent = false; for (std::string::const_iterator i = formatString.cbegin(); i != formatString.cend(); ++i) { @@ -148,15 +146,15 @@ namespace { */ bool CheckNullPointer::isPointerDeRef(const Token *tok, bool &unknown) const { - return isPointerDeRef(tok, unknown, mSettings); + return isPointerDeRef(tok, unknown, *mSettings); } -bool CheckNullPointer::isPointerDeRef(const Token *tok, bool &unknown, const Settings *settings) +bool CheckNullPointer::isPointerDeRef(const Token *tok, bool &unknown, const Settings &settings) { unknown = false; // Is pointer used as function parameter? - if (Token::Match(tok->previous(), "[(,] %name% [,)]") && settings) { + if (Token::Match(tok->previous(), "[(,] %name% [,)]")) { const Token *ftok = tok->previous(); while (ftok && ftok->str() != "(") { if (ftok->str() == ")") @@ -165,7 +163,7 @@ bool CheckNullPointer::isPointerDeRef(const Token *tok, bool &unknown, const Set } if (ftok && ftok->previous()) { std::list varlist; - parseFunctionCall(*ftok->previous(), varlist, &settings->library); + parseFunctionCall(*ftok->previous(), varlist, settings.library); if (std::find(varlist.cbegin(), varlist.cend(), tok) != varlist.cend()) { return true; } @@ -263,7 +261,7 @@ bool CheckNullPointer::isPointerDeRef(const Token *tok, bool &unknown, const Set } -static bool isNullablePointer(const Token* tok, const Settings* settings) +static bool isNullablePointer(const Token* tok) { if (!tok) return false; @@ -274,7 +272,7 @@ static bool isNullablePointer(const Token* tok, const Settings* settings) if (astIsSmartPointer(tok)) return true; if (Token::simpleMatch(tok, ".")) - return isNullablePointer(tok->astOperand2(), settings); + return isNullablePointer(tok->astOperand2()); if (const Variable* var = tok->variable()) { return (var->isPointer() || var->isSmartPointer()); } @@ -294,8 +292,8 @@ void CheckNullPointer::nullPointerByDeRefAndChec() if (Token::Match(tok, "%num%|%char%|%str%")) continue; - if (!isNullablePointer(tok, mSettings) || - (tok->str() == "." && isNullablePointer(tok->astOperand2(), mSettings) && tok->astOperand2()->getValue(0))) // avoid duplicate warning + if (!isNullablePointer(tok) || + (tok->str() == "." && isNullablePointer(tok->astOperand2()) && tok->astOperand2()->getValue(0))) // avoid duplicate warning continue; // Can pointer be NULL? @@ -367,7 +365,7 @@ void CheckNullPointer::nullConstantDereference() nullPointerError(tok); } else { // function call std::list var; - parseFunctionCall(*tok, var, &mSettings->library); + parseFunctionCall(*tok, var, mSettings->library); // is one of the var items a NULL pointer? for (const Token *vartok : var) { @@ -551,7 +549,7 @@ void CheckNullPointer::redundantConditionWarning(const Token* tok, const ValueFl } // NOLINTNEXTLINE(readability-non-const-parameter) - used as callback so we need to preserve the signature -static bool isUnsafeUsage(const Settings *settings, const Token *vartok, MathLib::bigint *value) +static bool isUnsafeUsage(const Settings &settings, const Token *vartok, MathLib::bigint *value) { (void)value; bool unknown = false; @@ -580,7 +578,7 @@ namespace }; } -Check::FileInfo *CheckNullPointer::getFileInfo(const Tokenizer *tokenizer, const Settings *settings) const +Check::FileInfo *CheckNullPointer::getFileInfo(const Tokenizer &tokenizer, const Settings &settings) const { const std::list &unsafeUsage = CTU::getUnsafeUsage(tokenizer, settings, isUnsafeUsage); if (unsafeUsage.empty()) diff --git a/lib/checknullpointer.h b/lib/checknullpointer.h index 19171e337eb..53e3c98f26a 100644 --- a/lib/checknullpointer.h +++ b/lib/checknullpointer.h @@ -67,7 +67,7 @@ class CPPCHECKLIB CheckNullPointer : public Check { */ bool isPointerDeRef(const Token *tok, bool &unknown) const; - static bool isPointerDeRef(const Token *tok, bool &unknown, const Settings *settings); + static bool isPointerDeRef(const Token *tok, bool &unknown, const Settings &settings); private: /** @@ -78,7 +78,7 @@ class CPPCHECKLIB CheckNullPointer : public Check { */ static void parseFunctionCall(const Token &tok, std::list &var, - const Library *library); + const Library &library); /** @brief This constructor is used when running checks. */ CheckNullPointer(const Tokenizer *tokenizer, const Settings *settings, ErrorLogger *errorLogger) @@ -106,7 +106,7 @@ class CPPCHECKLIB CheckNullPointer : public Check { void nullPointerError(const Token *tok, const std::string &varname, const ValueFlow::Value* value, bool inconclusive); /** @brief Parse current TU and extract file info */ - Check::FileInfo *getFileInfo(const Tokenizer *tokenizer, const Settings *settings) const override; + Check::FileInfo *getFileInfo(const Tokenizer &tokenizer, const Settings &settings) const override; Check::FileInfo * loadFileInfoFromXml(const tinyxml2::XMLElement *xmlElement) const override; diff --git a/lib/checkother.cpp b/lib/checkother.cpp index 0f9f90415d4..171437a20db 100644 --- a/lib/checkother.cpp +++ b/lib/checkother.cpp @@ -915,6 +915,10 @@ static bool isSimpleExpr(const Token* tok, const Variable* var, const Settings* if (Token::Match(ftok, "%name% (") && ((ftok->function() && ftok->function()->isConst()) || settings->library.isFunctionConst(ftok->str(), /*pure*/ true))) needsCheck = true; + if (tok->isArithmeticalOp() && + (!tok->astOperand1() || isSimpleExpr(tok->astOperand1(), var, settings)) && + (!tok->astOperand2() || isSimpleExpr(tok->astOperand2(), var, settings))) + return true; } return (needsCheck && !findExpressionChanged(tok, tok->astParent(), var->scope()->bodyEnd, settings)); } @@ -2713,13 +2717,13 @@ void CheckOther::checkSignOfUnsignedVariable() for (const Token *tok = scope->bodyStart->next(); tok != scope->bodyEnd; tok = tok->next()) { const ValueFlow::Value *zeroValue = nullptr; const Token *nonZeroExpr = nullptr; - if (comparisonNonZeroExpressionLessThanZero(tok, &zeroValue, &nonZeroExpr)) { + if (comparisonNonZeroExpressionLessThanZero(tok, zeroValue, nonZeroExpr)) { const ValueType* vt = nonZeroExpr->valueType(); if (vt->pointer) pointerLessThanZeroError(tok, zeroValue); else unsignedLessThanZeroError(tok, zeroValue, nonZeroExpr->expressionString()); - } else if (testIfNonZeroExpressionIsPositive(tok, &zeroValue, &nonZeroExpr)) { + } else if (testIfNonZeroExpressionIsPositive(tok, zeroValue, nonZeroExpr)) { const ValueType* vt = nonZeroExpr->valueType(); if (vt->pointer) pointerPositiveError(tok, zeroValue); @@ -2730,7 +2734,7 @@ void CheckOther::checkSignOfUnsignedVariable() } } -bool CheckOther::comparisonNonZeroExpressionLessThanZero(const Token *tok, const ValueFlow::Value **zeroValue, const Token **nonZeroExpr, bool suppress) +bool CheckOther::comparisonNonZeroExpressionLessThanZero(const Token *tok, const ValueFlow::Value *&zeroValue, const Token *&nonZeroExpr, bool suppress) { if (!tok->isComparisonOp() || !tok->astOperand1() || !tok->astOperand2()) return false; @@ -2739,24 +2743,24 @@ bool CheckOther::comparisonNonZeroExpressionLessThanZero(const Token *tok, const const ValueFlow::Value *v2 = tok->astOperand2()->getValue(0); if (Token::Match(tok, "<|<=") && v2 && v2->isKnown()) { - *zeroValue = v2; - *nonZeroExpr = tok->astOperand1(); + zeroValue = v2; + nonZeroExpr = tok->astOperand1(); } else if (Token::Match(tok, ">|>=") && v1 && v1->isKnown()) { - *zeroValue = v1; - *nonZeroExpr = tok->astOperand2(); + zeroValue = v1; + nonZeroExpr = tok->astOperand2(); } else { return false; } - if (const Variable* var = (*nonZeroExpr)->variable()) + if (const Variable* var = nonZeroExpr->variable()) if (var->typeStartToken()->isTemplateArg()) return suppress; - const ValueType* vt = (*nonZeroExpr)->valueType(); + const ValueType* vt = nonZeroExpr->valueType(); return vt && (vt->pointer || vt->sign == ValueType::UNSIGNED); } -bool CheckOther::testIfNonZeroExpressionIsPositive(const Token *tok, const ValueFlow::Value **zeroValue, const Token **nonZeroExpr) +bool CheckOther::testIfNonZeroExpressionIsPositive(const Token *tok, const ValueFlow::Value *&zeroValue, const Token *&nonZeroExpr) { if (!tok->isComparisonOp() || !tok->astOperand1() || !tok->astOperand2()) return false; @@ -2765,16 +2769,16 @@ bool CheckOther::testIfNonZeroExpressionIsPositive(const Token *tok, const Value const ValueFlow::Value *v2 = tok->astOperand2()->getValue(0); if (Token::simpleMatch(tok, ">=") && v2 && v2->isKnown()) { - *zeroValue = v2; - *nonZeroExpr = tok->astOperand1(); + zeroValue = v2; + nonZeroExpr = tok->astOperand1(); } else if (Token::simpleMatch(tok, "<=") && v1 && v1->isKnown()) { - *zeroValue = v1; - *nonZeroExpr = tok->astOperand2(); + zeroValue = v1; + nonZeroExpr = tok->astOperand2(); } else { return false; } - const ValueType* vt = (*nonZeroExpr)->valueType(); + const ValueType* vt = nonZeroExpr->valueType(); return vt && (vt->pointer || vt->sign == ValueType::UNSIGNED); } @@ -3363,7 +3367,7 @@ void CheckOther::checkAccessOfMovedVariable() else inconclusive = true; } else { - const ExprUsage usage = getExprUsage(tok, 0, mSettings); + const ExprUsage usage = getExprUsage(tok, 0, *mSettings); if (usage == ExprUsage::Used) accessOfMoved = true; if (usage == ExprUsage::PassedByReference) @@ -3802,10 +3806,10 @@ void CheckOther::checkComparePointers() continue; if (var1->isRValueReference() || var2->isRValueReference()) continue; - if (const Token* parent2 = getParentLifetime(v2.tokvalue, &mSettings->library)) + if (const Token* parent2 = getParentLifetime(v2.tokvalue, mSettings->library)) if (var1 == parent2->variable()) continue; - if (const Token* parent1 = getParentLifetime(v1.tokvalue, &mSettings->library)) + if (const Token* parent1 = getParentLifetime(v1.tokvalue, mSettings->library)) if (var2 == parent1->variable()) continue; comparePointersError(tok, &v1, &v2); @@ -3863,7 +3867,7 @@ void CheckOther::checkModuloOfOneError(const Token *tok) //----------------------------------------------------------------------------- // Overlapping write (undefined behavior) //----------------------------------------------------------------------------- -static bool getBufAndOffset(const Token *expr, const Token **buf, MathLib::bigint *offset) +static bool getBufAndOffset(const Token *expr, const Token *&buf, MathLib::bigint *offset) { if (!expr) return false; @@ -3884,7 +3888,7 @@ static bool getBufAndOffset(const Token *expr, const Token **buf, MathLib::bigin return false; } } else if (expr->valueType() && expr->valueType()->pointer > 0) { - *buf = expr; + buf = expr; *offset = 0; return true; } else { @@ -3894,7 +3898,7 @@ static bool getBufAndOffset(const Token *expr, const Token **buf, MathLib::bigin return false; if (!offsetToken->hasKnownIntValue()) return false; - *buf = bufToken; + buf = bufToken; *offset = offsetToken->getKnownIntValue(); return true; } @@ -3973,9 +3977,9 @@ void CheckOther::checkOverlappingWrite() const MathLib::bigint sizeValue = args[nonOverlappingData->sizeArg-1]->getKnownIntValue(); const Token *buf1, *buf2; MathLib::bigint offset1, offset2; - if (!getBufAndOffset(ptr1, &buf1, &offset1)) + if (!getBufAndOffset(ptr1, buf1, &offset1)) continue; - if (!getBufAndOffset(ptr2, &buf2, &offset2)) + if (!getBufAndOffset(ptr2, buf2, &offset2)) continue; if (offset1 < offset2 && offset1 + sizeValue <= offset2) diff --git a/lib/checkother.h b/lib/checkother.h index 1b7d080e7e5..b64281d46de 100644 --- a/lib/checkother.h +++ b/lib/checkother.h @@ -56,10 +56,10 @@ class CPPCHECKLIB CheckOther : public Check { CheckOther() : Check(myName()) {} /** Is expression a comparison that checks if a nonzero (unsigned/pointer) expression is less than zero? */ - static bool comparisonNonZeroExpressionLessThanZero(const Token *tok, const ValueFlow::Value **zeroValue, const Token **nonZeroExpr, bool suppress = false); + static bool comparisonNonZeroExpressionLessThanZero(const Token *tok, const ValueFlow::Value *&zeroValue, const Token *&nonZeroExpr, bool suppress = false); /** Is expression a comparison that checks if a nonzero (unsigned/pointer) expression is positive? */ - static bool testIfNonZeroExpressionIsPositive(const Token *tok, const ValueFlow::Value **zeroValue, const Token **nonZeroExpr); + static bool testIfNonZeroExpressionIsPositive(const Token *tok, const ValueFlow::Value *&zeroValue, const Token *&nonZeroExpr); private: /** @brief This constructor is used when running checks. */ diff --git a/lib/checkstl.cpp b/lib/checkstl.cpp index 5eca694028f..e581a36fc47 100644 --- a/lib/checkstl.cpp +++ b/lib/checkstl.cpp @@ -1121,7 +1121,7 @@ void CheckStl::invalidContainer() const Scope* s = tok2->scope(); if (!s) continue; - if (isReturnScope(s->bodyEnd, &mSettings->library)) + if (isReturnScope(s->bodyEnd, mSettings->library)) continue; invalidContainerLoopError(r.ftok, tok, r.errorPath); bail = true; @@ -2479,7 +2479,7 @@ void CheckStl::checkDereferenceInvalidIterator2() emptyAdvance = tok->astParent(); } } - if (!CheckNullPointer::isPointerDeRef(tok, unknown, mSettings) && !isInvalidIterator && !emptyAdvance) { + if (!CheckNullPointer::isPointerDeRef(tok, unknown, *mSettings) && !isInvalidIterator && !emptyAdvance) { if (!unknown) continue; inconclusive = true; diff --git a/lib/checkuninitvar.cpp b/lib/checkuninitvar.cpp index 6e58f0acd54..2b8e566305b 100644 --- a/lib/checkuninitvar.cpp +++ b/lib/checkuninitvar.cpp @@ -1641,13 +1641,13 @@ void CheckUninitVar::valueFlowUninit() const bool isarray = tok->variable()->isArray(); if (isarray && tok->variable()->isMember()) continue; // Todo: this is a bailout - const bool deref = CheckNullPointer::isPointerDeRef(tok, unknown, mSettings); + const bool deref = CheckNullPointer::isPointerDeRef(tok, unknown, *mSettings); uninitderef = deref && v->indirect == 0; const bool isleaf = isLeafDot(tok) || uninitderef; if (!isleaf && Token::Match(tok->astParent(), ". %name%") && (tok->astParent()->next()->varId() || tok->astParent()->next()->isEnumerator())) continue; } - const ExprUsage usage = getExprUsage(tok, v->indirect, mSettings); + const ExprUsage usage = getExprUsage(tok, v->indirect, *mSettings); if (usage == ExprUsage::NotUsed || usage == ExprUsage::Inconclusive) continue; if (!v->subexpressions.empty() && usage == ExprUsage::PassedByReference) @@ -1670,10 +1670,10 @@ void CheckUninitVar::valueFlowUninit() } // NOLINTNEXTLINE(readability-non-const-parameter) - used as callback so we need to preserve the signature -static bool isVariableUsage(const Settings *settings, const Token *vartok, MathLib::bigint *value) +static bool isVariableUsage(const Settings &settings, const Token *vartok, MathLib::bigint *value) { (void)value; - return CheckUninitVar::isVariableUsage(vartok, settings->library, true, CheckUninitVar::Alloc::ARRAY); + return CheckUninitVar::isVariableUsage(vartok, settings.library, true, CheckUninitVar::Alloc::ARRAY); } // a Clang-built executable will crash when using the anonymous MyFileInfo later on - so put it in a unique namespace for now @@ -1698,7 +1698,7 @@ namespace }; } -Check::FileInfo *CheckUninitVar::getFileInfo(const Tokenizer *tokenizer, const Settings *settings) const +Check::FileInfo *CheckUninitVar::getFileInfo(const Tokenizer &tokenizer, const Settings &settings) const { const std::list &unsafeUsage = CTU::getUnsafeUsage(tokenizer, settings, ::isVariableUsage); if (unsafeUsage.empty()) diff --git a/lib/checkuninitvar.h b/lib/checkuninitvar.h index 025cc9f119f..d715b5352a7 100644 --- a/lib/checkuninitvar.h +++ b/lib/checkuninitvar.h @@ -106,7 +106,7 @@ class CPPCHECKLIB CheckUninitVar : public Check { void valueFlowUninit(); /** @brief Parse current TU and extract file info */ - Check::FileInfo *getFileInfo(const Tokenizer *tokenizer, const Settings *settings) const override; + Check::FileInfo *getFileInfo(const Tokenizer &tokenizer, const Settings &settings) const override; Check::FileInfo * loadFileInfoFromXml(const tinyxml2::XMLElement *xmlElement) const override; diff --git a/lib/cppcheck.cpp b/lib/cppcheck.cpp index db1df11cd54..cfe7b624fbe 100644 --- a/lib/cppcheck.cpp +++ b/lib/cppcheck.cpp @@ -1090,7 +1090,7 @@ void CppCheck::checkNormalTokens(const Tokenizer &tokenizer) if (mSettings.useSingleJob() || !mSettings.buildDir.empty()) { // Analyse the tokens.. - if (CTU::FileInfo * const fi1 = CTU::getFileInfo(&tokenizer)) { + if (CTU::FileInfo * const fi1 = CTU::getFileInfo(tokenizer)) { if (!mSettings.buildDir.empty()) mAnalyzerInformation.setFileInfo("ctu", fi1->toString()); if (mSettings.useSingleJob()) @@ -1102,7 +1102,7 @@ void CppCheck::checkNormalTokens(const Tokenizer &tokenizer) if (!doUnusedFunctionOnly) { // cppcheck-suppress shadowFunction - TODO: fix this for (const Check *check : Check::instances()) { - if (Check::FileInfo * const fi = check->getFileInfo(&tokenizer, &mSettings)) { + if (Check::FileInfo * const fi = check->getFileInfo(tokenizer, mSettings)) { if (!mSettings.buildDir.empty()) mAnalyzerInformation.setFileInfo(check->name(), fi->toString()); if (mSettings.useSingleJob()) diff --git a/lib/ctu.cpp b/lib/ctu.cpp index 19a0e834136..41e8a5aa0ed 100644 --- a/lib/ctu.cpp +++ b/lib/ctu.cpp @@ -57,13 +57,13 @@ static constexpr char ATTR_VALUE[] = "value"; int CTU::maxCtuDepth = 2; -std::string CTU::getFunctionId(const Tokenizer *tokenizer, const Function *function) +std::string CTU::getFunctionId(const Tokenizer &tokenizer, const Function *function) { - return tokenizer->list.file(function->tokenDef) + ':' + std::to_string(function->tokenDef->linenr()) + ':' + std::to_string(function->tokenDef->column()); + return tokenizer.list.file(function->tokenDef) + ':' + std::to_string(function->tokenDef->linenr()) + ':' + std::to_string(function->tokenDef->column()); } -CTU::FileInfo::Location::Location(const Tokenizer *tokenizer, const Token *tok) - : fileName(tokenizer->list.file(tok)) +CTU::FileInfo::Location::Location(const Tokenizer &tokenizer, const Token *tok) + : fileName(tokenizer.list.file(tok)) , lineNumber(tok->linenr()) , column(tok->column()) {} @@ -156,13 +156,13 @@ std::string CTU::toString(const std::list &unsafeUsa return ret.str(); } -CTU::FileInfo::CallBase::CallBase(const Tokenizer *tokenizer, const Token *callToken) +CTU::FileInfo::CallBase::CallBase(const Tokenizer &tokenizer, const Token *callToken) : callId(getFunctionId(tokenizer, callToken->function())) , callFunctionName(callToken->next()->astOperand1()->expressionString()) , location(CTU::FileInfo::Location(tokenizer, callToken)) {} -CTU::FileInfo::NestedCall::NestedCall(const Tokenizer *tokenizer, const Function *myFunction, const Token *callToken) +CTU::FileInfo::NestedCall::NestedCall(const Tokenizer &tokenizer, const Function *myFunction, const Token *callToken) : CallBase(tokenizer, callToken) , myId(getFunctionId(tokenizer, myFunction)) {} @@ -276,7 +276,7 @@ std::list CTU::loadUnsafeUsageListFromXml(const tiny return ret; } -static int isCallFunction(const Scope *scope, int argnr, const Token **tok) +static int isCallFunction(const Scope *scope, int argnr, const Token *&tok) { const Variable * const argvar = scope->function->getArgumentVar(argnr); if (!argvar->isPointer()) @@ -299,16 +299,16 @@ static int isCallFunction(const Scope *scope, int argnr, const Token **tok) break; if (!prev->astOperand1() || !prev->astOperand1()->function()) break; - *tok = prev->previous(); + tok = prev->previous(); return argnr2; } return -1; } -CTU::FileInfo *CTU::getFileInfo(const Tokenizer *tokenizer) +CTU::FileInfo *CTU::getFileInfo(const Tokenizer &tokenizer) { - const SymbolDatabase * const symbolDatabase = tokenizer->getSymbolDatabase(); + const SymbolDatabase * const symbolDatabase = tokenizer.getSymbolDatabase(); auto *fileInfo = new FileInfo; @@ -346,7 +346,7 @@ CTU::FileInfo *CTU::getFileInfo(const Tokenizer *tokenizer) functionCall.callArgValue = value.intvalue; functionCall.warning = !value.errorSeverity(); for (const ErrorPathItem &i : value.errorPath) { - const std::string& file = tokenizer->list.file(i.first); + const std::string& file = tokenizer.list.file(i.first); const std::string& info = i.second; const int line = i.first->linenr(); const int column = i.first->column(); @@ -364,7 +364,7 @@ CTU::FileInfo *CTU::getFileInfo(const Tokenizer *tokenizer) functionCall.location = FileInfo::Location(tokenizer, tok); functionCall.callArgNr = argnr + 1; functionCall.callArgumentExpression = argtok->expressionString(); - const auto typeSize = argtok->valueType()->typeSize(tokenizer->getSettings().platform); + const auto typeSize = argtok->valueType()->typeSize(tokenizer.getSettings().platform); functionCall.callArgValue = typeSize > 0 ? argtok->variable()->dimension(0) * typeSize : -1; functionCall.warning = false; fileInfo->functionCalls.push_back(std::move(functionCall)); @@ -378,7 +378,7 @@ CTU::FileInfo *CTU::getFileInfo(const Tokenizer *tokenizer) functionCall.location = FileInfo::Location(tokenizer, tok); functionCall.callArgNr = argnr + 1; functionCall.callArgumentExpression = argtok->expressionString(); - functionCall.callArgValue = argtok->astOperand1()->valueType()->typeSize(tokenizer->getSettings().platform); + functionCall.callArgValue = argtok->astOperand1()->valueType()->typeSize(tokenizer.getSettings().platform); functionCall.warning = false; fileInfo->functionCalls.push_back(std::move(functionCall)); } @@ -424,7 +424,7 @@ CTU::FileInfo *CTU::getFileInfo(const Tokenizer *tokenizer) // Nested function calls for (int argnr = 0; argnr < scopeFunction->argCount(); ++argnr) { const Token *tok; - const int argnr2 = isCallFunction(&scope, argnr, &tok); + const int argnr2 = isCallFunction(&scope, argnr, tok); if (argnr2 > 0) { FileInfo::NestedCall nestedCall(tokenizer, scopeFunction, tok); nestedCall.myArgNr = argnr + 1; @@ -437,7 +437,7 @@ CTU::FileInfo *CTU::getFileInfo(const Tokenizer *tokenizer) return fileInfo; } -static std::list> getUnsafeFunction(const Settings *settings, const Scope *scope, int argnr, bool (*isUnsafeUsage)(const Settings *settings, const Token *argtok, MathLib::bigint *value)) +static std::list> getUnsafeFunction(const Settings &settings, const Scope *scope, int argnr, bool (*isUnsafeUsage)(const Settings &settings, const Token *argtok, MathLib::bigint *value)) { std::list> ret; const Variable * const argvar = scope->function->getArgumentVar(argnr); @@ -451,7 +451,7 @@ static std::list> getUnsafeFunction(co int indirect = 0; if (argvar->valueType()) indirect = argvar->valueType()->pointer; - if (isVariableChanged(tok2->link(), tok2, indirect, argvar->declarationId(), false, settings)) + if (isVariableChanged(tok2->link(), tok2, indirect, argvar->declarationId(), false, &settings)) return ret; } if (Token::Match(tok2, "%oror%|&&|?")) { @@ -469,12 +469,12 @@ static std::list> getUnsafeFunction(co return ret; } -std::list CTU::getUnsafeUsage(const Tokenizer *tokenizer, const Settings *settings, bool (*isUnsafeUsage)(const Settings *settings, const Token *argtok, MathLib::bigint *value)) +std::list CTU::getUnsafeUsage(const Tokenizer &tokenizer, const Settings &settings, bool (*isUnsafeUsage)(const Settings &settings, const Token *argtok, MathLib::bigint *value)) { std::list unsafeUsage; // Parse all functions in TU - const SymbolDatabase * const symbolDatabase = tokenizer->getSymbolDatabase(); + const SymbolDatabase * const symbolDatabase = tokenizer.getSymbolDatabase(); for (const Scope &scope : symbolDatabase->scopeList) { if (!scope.isExecutable() || scope.type != Scope::eFunction || !scope.function) diff --git a/lib/ctu.h b/lib/ctu.h index 28e4421871c..af2cd6b07f0 100644 --- a/lib/ctu.h +++ b/lib/ctu.h @@ -57,7 +57,7 @@ namespace CTU { struct Location { Location() = default; - Location(const Tokenizer *tokenizer, const Token *tok); + Location(const Tokenizer &tokenizer, const Token *tok); Location(std::string fileName, nonneg int lineNumber, nonneg int column) : fileName(std::move(fileName)), lineNumber(lineNumber), column(column) {} std::string fileName; nonneg int lineNumber{}; @@ -81,7 +81,7 @@ namespace CTU { CallBase(std::string callId, int callArgNr, std::string callFunctionName, Location loc) : callId(std::move(callId)), callArgNr(callArgNr), callFunctionName(std::move(callFunctionName)), location(std::move(loc)) {} - CallBase(const Tokenizer *tokenizer, const Token *callToken); + CallBase(const Tokenizer &tokenizer, const Token *callToken); virtual ~CallBase() = default; CallBase(const CallBase&) = default; std::string callId; @@ -114,7 +114,7 @@ namespace CTU { myId(std::move(myId)), myArgNr(myArgNr) {} - NestedCall(const Tokenizer *tokenizer, const Function *myFunction, const Token *callToken); + NestedCall(const Tokenizer &tokenizer, const Function *myFunction, const Token *callToken); std::string toXmlString() const; bool loadFromXml(const tinyxml2::XMLElement *xmlElement); @@ -141,12 +141,12 @@ namespace CTU { CPPCHECKLIB std::string toString(const std::list &unsafeUsage); - CPPCHECKLIB std::string getFunctionId(const Tokenizer *tokenizer, const Function *function); + CPPCHECKLIB std::string getFunctionId(const Tokenizer &tokenizer, const Function *function); /** @brief Parse current TU and extract file info */ - CPPCHECKLIB FileInfo *getFileInfo(const Tokenizer *tokenizer); + CPPCHECKLIB FileInfo *getFileInfo(const Tokenizer &tokenizer); - CPPCHECKLIB std::list getUnsafeUsage(const Tokenizer *tokenizer, const Settings *settings, bool (*isUnsafeUsage)(const Settings *settings, const Token *argtok, MathLib::bigint *value)); + CPPCHECKLIB std::list getUnsafeUsage(const Tokenizer &tokenizer, const Settings &settings, bool (*isUnsafeUsage)(const Settings &settings, const Token *argtok, MathLib::bigint *value)); CPPCHECKLIB std::list loadUnsafeUsageListFromXml(const tinyxml2::XMLElement *xmlElement); } diff --git a/lib/findtoken.h b/lib/findtoken.h index d3404758b16..f75845fd813 100644 --- a/lib/findtoken.h +++ b/lib/findtoken.h @@ -79,7 +79,7 @@ template )> -bool findTokensSkipDeadCodeImpl(const Library* library, +bool findTokensSkipDeadCodeImpl(const Library& library, T* start, const Token* end, const Predicate& pred, @@ -169,7 +169,7 @@ bool findTokensSkipDeadCodeImpl(const Library* library, } template )> -std::vector findTokensSkipDeadCode(const Library* library, +std::vector findTokensSkipDeadCode(const Library& library, T* start, const Token* end, const Predicate& pred, @@ -190,13 +190,13 @@ std::vector findTokensSkipDeadCode(const Library* library, } template )> -std::vector findTokensSkipDeadCode(const Library* library, T* start, const Token* end, const Predicate& pred) +std::vector findTokensSkipDeadCode(const Library& library, T* start, const Token* end, const Predicate& pred) { return findTokensSkipDeadCode(library, start, end, pred, &evaluateKnownValues); } template )> -T* findTokenSkipDeadCode(const Library* library, T* start, const Token* end, const Predicate& pred, const Evaluate& evaluate) +T* findTokenSkipDeadCode(const Library& library, T* start, const Token* end, const Predicate& pred, const Evaluate& evaluate) { T* result = nullptr; (void)findTokensSkipDeadCodeImpl( @@ -213,7 +213,7 @@ T* findTokenSkipDeadCode(const Library* library, T* start, const Token* end, con } template )> -T* findTokenSkipDeadCode(const Library* library, T* start, const Token* end, const Predicate& pred) +T* findTokenSkipDeadCode(const Library& library, T* start, const Token* end, const Predicate& pred) { return findTokenSkipDeadCode(library, start, end, pred, &evaluateKnownValues); } diff --git a/lib/forwardanalyzer.cpp b/lib/forwardanalyzer.cpp index c5cb8eaf3ee..2572ccc0613 100644 --- a/lib/forwardanalyzer.cpp +++ b/lib/forwardanalyzer.cpp @@ -311,7 +311,7 @@ namespace { for (const Token* tok=start; tok != end; tok = tok->previous()) { if (Token::simpleMatch(tok, "}")) { const Token* ftok = nullptr; - const bool r = isReturnScope(tok, &settings.library, &ftok); + const bool r = isReturnScope(tok, settings.library, &ftok); if (r) return true; } @@ -321,7 +321,7 @@ namespace { bool isEscapeScope(const Token* endBlock, bool& unknown) const { const Token* ftok = nullptr; - const bool r = isReturnScope(endBlock, &settings.library, &ftok); + const bool r = isReturnScope(endBlock, settings.library, &ftok); if (!r && ftok) unknown = true; return r; diff --git a/lib/fwdanalysis.cpp b/lib/fwdanalysis.cpp index 264153d1fd0..c261b39ea96 100644 --- a/lib/fwdanalysis.cpp +++ b/lib/fwdanalysis.cpp @@ -236,7 +236,7 @@ FwdAnalysis::Result FwdAnalysis::checkRecursive(const Token *expr, const Token * } } tok = bodyStart->link(); - if (isReturnScope(tok, &mLibrary)) + if (isReturnScope(tok, mLibrary)) return Result(Result::Type::BAILOUT); if (Token::simpleMatch(tok, "} else {")) tok = tok->linkAt(2); diff --git a/lib/programmemory.cpp b/lib/programmemory.cpp index 532da5ed879..49b11310104 100644 --- a/lib/programmemory.cpp +++ b/lib/programmemory.cpp @@ -97,11 +97,11 @@ void ProgramMemory::setIntValue(const Token* expr, MathLib::bigint value, bool i setValue(expr, v); } -bool ProgramMemory::getTokValue(nonneg int exprid, const Token** result) const +bool ProgramMemory::getTokValue(nonneg int exprid, const Token*& result) const { const ValueFlow::Value* value = getValue(exprid); if (value && value->isTokValue()) { - *result = value->tokvalue; + result = value->tokvalue; return true; } return false; @@ -271,7 +271,7 @@ static bool isBasicForLoop(const Token* tok) return true; } -void programMemoryParseCondition(ProgramMemory& pm, const Token* tok, const Token* endTok, const Settings* settings, bool then) +static void programMemoryParseCondition(ProgramMemory& pm, const Token* tok, const Token* endTok, const Settings* settings, bool then) { auto eval = [&](const Token* t) -> std::vector { if (!t) @@ -427,14 +427,14 @@ static void removeModifiedVars(ProgramMemory& pm, const Token* tok, const Token* static ProgramMemory getInitialProgramState(const Token* tok, const Token* origin, - const Settings* settings, + const Settings& settings, const ProgramMemory::Map& vars = ProgramMemory::Map {}) { ProgramMemory pm; if (origin) { fillProgramMemoryFromConditions(pm, origin, nullptr); const ProgramMemory state = pm; - fillProgramMemoryFromAssignments(pm, tok, settings, state, vars); + fillProgramMemoryFromAssignments(pm, tok, &settings, state, vars); removeModifiedVars(pm, tok, origin); } return pm; @@ -534,15 +534,15 @@ ProgramMemory ProgramMemoryState::get(const Token* tok, const Token* ctx, const return local.state; } -ProgramMemory getProgramMemory(const Token* tok, const Token* expr, const ValueFlow::Value& value, const Settings* settings) +ProgramMemory getProgramMemory(const Token* tok, const Token* expr, const ValueFlow::Value& value, const Settings& settings) { ProgramMemory programMemory; programMemory.replace(getInitialProgramState(tok, value.tokvalue, settings)); programMemory.replace(getInitialProgramState(tok, value.condition, settings)); - fillProgramMemoryFromConditions(programMemory, tok, settings); + fillProgramMemoryFromConditions(programMemory, tok, &settings); programMemory.setValue(expr, value); const ProgramMemory state = programMemory; - fillProgramMemoryFromAssignments(programMemory, tok, settings, state, {{expr, value}}); + fillProgramMemoryFromAssignments(programMemory, tok, &settings, state, {{expr, value}}); return programMemory; } @@ -1257,7 +1257,7 @@ namespace { int fdepth = 4; int depth = 10; - explicit Executor(ProgramMemory* pm = nullptr, const Settings* settings = nullptr) : pm(pm), settings(settings) {} + Executor(ProgramMemory* pm, const Settings* settings) : pm(pm), settings(settings) {} static ValueFlow::Value unknown() { return ValueFlow::Value::unknown(); @@ -1469,7 +1469,7 @@ namespace { return lhs; } else if (expr->str() == "[" && expr->astOperand1() && expr->astOperand2()) { const Token* tokvalue = nullptr; - if (!pm->getTokValue(expr->astOperand1()->exprId(), &tokvalue)) { + if (!pm->getTokValue(expr->astOperand1()->exprId(), tokvalue)) { auto tokvalue_it = std::find_if(expr->astOperand1()->values().cbegin(), expr->astOperand1()->values().cend(), std::mem_fn(&ValueFlow::Value::isTokValue)); @@ -1748,9 +1748,9 @@ static ValueFlow::Value execute(const Token* expr, ProgramMemory& pm, const Sett return ex.execute(expr); } -std::vector execute(const Scope* scope, ProgramMemory& pm, const Settings* settings) +std::vector execute(const Scope* scope, ProgramMemory& pm, const Settings& settings) { - Executor ex{&pm, settings}; + Executor ex{&pm, &settings}; return ex.execute(scope); } diff --git a/lib/programmemory.h b/lib/programmemory.h index 717284efb24..85703455b5f 100644 --- a/lib/programmemory.h +++ b/lib/programmemory.h @@ -115,7 +115,7 @@ struct ProgramMemory { void setUnknown(const Token* expr); - bool getTokValue(nonneg int exprid, const Token** result) const; + bool getTokValue(nonneg int exprid, const Token*& result) const; bool hasValue(nonneg int exprid); const ValueFlow::Value& at(nonneg int exprid) const; @@ -161,8 +161,6 @@ struct ProgramMemory { Map mValues; }; -void programMemoryParseCondition(ProgramMemory& pm, const Token* tok, const Token* endTok, const Settings* settings, bool then); - struct ProgramMemoryState { ProgramMemory state; std::map origins; @@ -182,13 +180,13 @@ struct ProgramMemoryState { ProgramMemory get(const Token* tok, const Token* ctx, const ProgramMemory::Map& vars) const; }; -std::vector execute(const Scope* scope, ProgramMemory& pm, const Settings* settings); +std::vector execute(const Scope* scope, ProgramMemory& pm, const Settings& settings); void execute(const Token* expr, ProgramMemory& programMemory, MathLib::bigint* result, bool* error, - const Settings* settings = nullptr); + const Settings* settings); /** * Is condition always false when variable has given value? @@ -207,7 +205,7 @@ bool conditionIsTrue(const Token* condition, ProgramMemory pm, const Settings* s /** * Get program memory by looking backwards from given token. */ -ProgramMemory getProgramMemory(const Token* tok, const Token* expr, const ValueFlow::Value& value, const Settings* settings); +ProgramMemory getProgramMemory(const Token* tok, const Token* expr, const ValueFlow::Value& value, const Settings& settings); ValueFlow::Value evaluateLibraryFunction(const std::unordered_map& args, const std::string& returnValue, diff --git a/lib/summaries.cpp b/lib/summaries.cpp index c35f66f8f49..e4dddc1e365 100644 --- a/lib/summaries.cpp +++ b/lib/summaries.cpp @@ -34,10 +34,10 @@ -std::string Summaries::create(const Tokenizer *tokenizer, const std::string &cfg) +std::string Summaries::create(const Tokenizer &tokenizer, const std::string &cfg) { - const SymbolDatabase *symbolDatabase = tokenizer->getSymbolDatabase(); - const Settings &settings = tokenizer->getSettings(); + const SymbolDatabase *symbolDatabase = tokenizer.getSymbolDatabase(); + const Settings &settings = tokenizer.getSettings(); std::ostringstream ostr; for (const Scope *scope : symbolDatabase->functionScopes) { @@ -82,7 +82,7 @@ std::string Summaries::create(const Tokenizer *tokenizer, const std::string &cfg } if (!settings.buildDir.empty()) { - std::string filename = AnalyzerInformation::getAnalyzerInfoFile(settings.buildDir, tokenizer->list.getSourceFilePath(), cfg); + std::string filename = AnalyzerInformation::getAnalyzerInfoFile(settings.buildDir, tokenizer.list.getSourceFilePath(), cfg); const std::string::size_type pos = filename.rfind(".a"); if (pos != std::string::npos) { filename[pos+1] = 's'; diff --git a/lib/summaries.h b/lib/summaries.h index 0d9bd1da8b7..11a370c0f5f 100644 --- a/lib/summaries.h +++ b/lib/summaries.h @@ -29,7 +29,7 @@ class Tokenizer; namespace Summaries { - CPPCHECKLIB std::string create(const Tokenizer *tokenizer, const std::string &cfg); + CPPCHECKLIB std::string create(const Tokenizer &tokenizer, const std::string &cfg); CPPCHECKLIB void loadReturn(const std::string &buildDir, std::set &summaryReturn); } diff --git a/lib/symboldatabase.cpp b/lib/symboldatabase.cpp index 4f86497551c..b2d3605f409 100644 --- a/lib/symboldatabase.cpp +++ b/lib/symboldatabase.cpp @@ -542,7 +542,7 @@ void SymbolDatabase::createSymbolDatabaseFindAllScopes() } // class function? - else if (isFunction(tok, scope, &funcStart, &argStart, &declEnd)) { + else if (isFunction(tok, scope, funcStart, argStart, declEnd)) { if (tok->previous()->str() != "::" || tok->strAt(-2) == scope->className) { Function function(tok, scope, funcStart, argStart); @@ -591,7 +591,7 @@ void SymbolDatabase::createSymbolDatabaseFindAllScopes() Function* funcptr = &scope->functionList.back(); const Token *tok2 = funcStart; - addNewFunction(&scope, &tok2); + addNewFunction(scope, tok2); if (scope) { scope->functionOf = function.nestedIn; scope->function = funcptr; @@ -608,7 +608,7 @@ void SymbolDatabase::createSymbolDatabaseFindAllScopes() const Scope * const nested = scope->findInNestedListRecursive(tok->strAt(-2)); if (nested) - addClassFunction(&scope, &tok, argStart); + addClassFunction(scope, tok, argStart); else { /** @todo handle friend functions */ } @@ -645,20 +645,20 @@ void SymbolDatabase::createSymbolDatabaseFindAllScopes() const Token *declEnd = nullptr; // function? - if (isFunction(tok, scope, &funcStart, &argStart, &declEnd)) { + if (isFunction(tok, scope, funcStart, argStart, declEnd)) { // has body? if (declEnd && declEnd->str() == "{") { tok = funcStart; // class function if (tok->previous() && tok->previous()->str() == "::") - addClassFunction(&scope, &tok, argStart); + addClassFunction(scope, tok, argStart); // class destructor else if (tok->previous() && tok->previous()->str() == "~" && tok->strAt(-2) == "::") - addClassFunction(&scope, &tok, argStart); + addClassFunction(scope, tok, argStart); // regular function else { @@ -676,7 +676,7 @@ void SymbolDatabase::createSymbolDatabaseFindAllScopes() else if (declEnd && declEnd->str() == ";") { if (tok->astParent() && tok->astParent()->str() == "::" && Token::Match(declEnd->previous(), "default|delete")) { - addClassFunction(&scope, &tok, argStart); + addClassFunction(scope, tok, argStart); continue; } @@ -761,7 +761,7 @@ void SymbolDatabase::createSymbolDatabaseFindAllScopes() const Token *funcStart = nullptr; const Token *argStart = nullptr; const Token *declEnd = nullptr; - if (isFunction(ftok, scope, &funcStart, &argStart, &declEnd)) { + if (isFunction(ftok, scope, funcStart, argStart, declEnd)) { if (declEnd && declEnd->str() == ";") { bool newFunc = true; // Is this function already in the database? auto range = scope->functionMap.equal_range(ftok->str()); @@ -1522,7 +1522,7 @@ void SymbolDatabase::createSymbolDatabaseEscapeFunctions() continue; if (Token::findsimplematch(scope.bodyStart, "return", scope.bodyEnd)) continue; - function->isEscapeFunction(isReturnScope(scope.bodyEnd, &mSettings.library, nullptr, true)); + function->isEscapeFunction(isReturnScope(scope.bodyEnd, mSettings.library, nullptr, true)); } } @@ -1886,7 +1886,7 @@ SymbolDatabase::~SymbolDatabase() } } -bool SymbolDatabase::isFunction(const Token *tok, const Scope* outerScope, const Token **funcStart, const Token **argStart, const Token** declEnd) const +bool SymbolDatabase::isFunction(const Token *tok, const Scope* outerScope, const Token *&funcStart, const Token *&argStart, const Token*& declEnd) const { if (tok->varId()) return false; @@ -1903,9 +1903,9 @@ bool SymbolDatabase::isFunction(const Token *tok, const Scope* outerScope, const argStartTok = tok->link()->linkAt(-2); else argStartTok = tok->link()->linkAt(-1); - *funcStart = argStartTok->previous(); - *argStart = argStartTok; - *declEnd = Token::findmatch(tok2->link()->next(), "{|;"); + funcStart = argStartTok->previous(); + argStart = argStartTok; + declEnd = Token::findmatch(tok2->link()->next(), "{|;"); return true; } if (tok2 && tok2->str() == "[") { @@ -1917,9 +1917,9 @@ bool SymbolDatabase::isFunction(const Token *tok, const Scope* outerScope, const argStartTok = tok->link()->linkAt(-2); else argStartTok = tok->link()->linkAt(-1); - *funcStart = argStartTok->previous(); - *argStart = argStartTok; - *declEnd = Token::findmatch(tok2, "{|;"); + funcStart = argStartTok->previous(); + argStart = argStartTok; + declEnd = Token::findmatch(tok2, "{|;"); return true; } } @@ -2031,9 +2031,9 @@ bool SymbolDatabase::isFunction(const Token *tok, const Scope* outerScope, const Token::Match(tok2, ": ::| %name% (|::|<|{") || Token::Match(tok2, "&|&&| ;|{") || Token::Match(tok2, "= delete|default ;"))) { - *funcStart = tok; - *argStart = tok->next(); - *declEnd = Token::findmatch(tok2, "{|;"); + funcStart = tok; + argStart = tok->next(); + declEnd = Token::findmatch(tok2, "{|;"); return true; } } @@ -2044,9 +2044,9 @@ bool SymbolDatabase::isFunction(const Token *tok, const Scope* outerScope, const tok->isUpperCaseName() && Token::simpleMatch(tok->linkAt(1), ") {") && (!tok->previous() || Token::Match(tok->previous(), "[;{}]"))) { - *funcStart = tok; - *argStart = tok->next(); - *declEnd = tok->linkAt(1)->next(); + funcStart = tok; + argStart = tok->next(); + declEnd = tok->linkAt(1)->next(); return true; } @@ -2056,9 +2056,9 @@ bool SymbolDatabase::isFunction(const Token *tok, const Scope* outerScope, const if (Token::Match(tok2, ") const| ;|{|=") || Token::Match(tok2, ") : ::| %name% (|::|<|{") || Token::Match(tok2, ") const| noexcept {|;|(")) { - *funcStart = tok; - *argStart = tok2->link(); - *declEnd = Token::findmatch(tok2->next(), "{|;"); + funcStart = tok; + argStart = tok2->link(); + declEnd = Token::findmatch(tok2->next(), "{|;"); return true; } } @@ -2069,9 +2069,9 @@ bool SymbolDatabase::isFunction(const Token *tok, const Scope* outerScope, const (!tok->previous() || Token::Match(tok->previous(), ";|}"))) { if (tok->isC()) { returnImplicitIntError(tok); - *funcStart = tok; - *argStart = tok->next(); - *declEnd = tok->linkAt(1)->next(); + funcStart = tok; + argStart = tok->next(); + declEnd = tok->linkAt(1)->next(); return true; } mTokenizer.syntaxError(tok); @@ -2306,7 +2306,7 @@ void Variable::evaluate(const Settings* settings) if (!settings) return; - const Library * const lib = &settings->library; + const Library & lib = settings->library; // TODO: ValueType::parseDecl() is also performing a container lookup bool isContainer = false; @@ -2367,10 +2367,10 @@ void Variable::evaluate(const Settings* settings) std::string strtype = mTypeStartToken->str(); for (const Token *typeToken = mTypeStartToken; Token::Match(typeToken, "%type% :: %type%"); typeToken = typeToken->tokAt(2)) strtype += "::" + typeToken->strAt(2); - setFlag(fIsClass, !lib->podtype(strtype) && !mTypeStartToken->isStandardType() && !isEnumType() && !isPointer() && strtype != "..."); + setFlag(fIsClass, !lib.podtype(strtype) && !mTypeStartToken->isStandardType() && !isEnumType() && !isPointer() && strtype != "..."); setFlag(fIsStlType, Token::simpleMatch(mTypeStartToken, "std ::")); setFlag(fIsStlString, ::isStlStringType(mTypeStartToken)); - setFlag(fIsSmartPointer, mTypeStartToken->isCpp() && lib->isSmartPointer(mTypeStartToken)); + setFlag(fIsSmartPointer, mTypeStartToken->isCpp() && lib.isSmartPointer(mTypeStartToken)); } if (mAccess == AccessControl::Argument) { tok = mNameToken; @@ -2763,8 +2763,8 @@ static bool typesMatch( const Token *first_token, const Scope *second_scope, const Token *second_token, - const Token **new_first, - const Token **new_second) + const Token *&new_first, + const Token *&new_second) { // get first type const Type* first_type = first_scope->check->findType(first_token, first_scope, /*lookOutside*/ true); @@ -2781,8 +2781,8 @@ static bool typesMatch( tok2 = tok2->next(); // update parser token positions if (tok1 && tok2) { - *new_first = tok1->previous(); - *new_second = tok2->previous(); + new_first = tok1->previous(); + new_second = tok2->previous(); return true; } } @@ -2958,7 +2958,7 @@ bool Function::argsMatch(const Scope *scope, const Token *first, const Token *se first = first->tokAt(offset); // same type with different qualification - else if (typesMatch(scope, first->next(), nestedIn, second->next(), &first, &second)) + else if (typesMatch(scope, first->next(), nestedIn, second->next(), first, second)) ; // variable with class path @@ -3225,7 +3225,7 @@ Function* SymbolDatabase::addGlobalFunction(Scope*& scope, const Token*& tok, co function->token = funcStart; function->hasBody(true); - addNewFunction(&scope, &tok); + addNewFunction(scope, tok); if (scope) { scope->function = function; @@ -3242,16 +3242,16 @@ Function* SymbolDatabase::addGlobalFunctionDecl(Scope*& scope, const Token *tok, return &scope->functionList.back(); } -void SymbolDatabase::addClassFunction(Scope **scope, const Token **tok, const Token *argStart) +void SymbolDatabase::addClassFunction(Scope *&scope, const Token *&tok, const Token *argStart) { - const bool destructor((*tok)->previous()->str() == "~"); + const bool destructor(tok->previous()->str() == "~"); const bool has_const(argStart->link()->strAt(1) == "const"); const bool lval(argStart->link()->strAt(has_const ? 2 : 1) == "&"); const bool rval(argStart->link()->strAt(has_const ? 2 : 1) == "&&"); int count = 0; std::string path; unsigned int path_length = 0; - const Token *tok1 = (*tok); + const Token *tok1 = tok; if (destructor) tok1 = tok1->previous(); @@ -3292,14 +3292,14 @@ void SymbolDatabase::addClassFunction(Scope **scope, const Token **tok, const To bool match = false; // check in namespace if using found - if (*scope == scope1 && !scope1->usingList.empty()) { + if (scope == scope1 && !scope1->usingList.empty()) { std::vector::const_iterator it2; for (it2 = scope1->usingList.cbegin(); it2 != scope1->usingList.cend(); ++it2) { if (it2->scope) { Function * func = findFunctionInScope(tok1, it2->scope, path, path_length); if (func) { if (!func->hasBody()) { - const Token *closeParen = (*tok)->next()->link(); + const Token *closeParen = tok->next()->link(); if (closeParen) { const Token *eq = Tokenizer::isFunctionHead(closeParen, ";"); if (eq && Token::simpleMatch(eq->tokAt(-2), "= default ;")) { @@ -3308,13 +3308,13 @@ void SymbolDatabase::addClassFunction(Scope **scope, const Token **tok, const To } } func->hasBody(true); - func->token = *tok; + func->token = tok; func->arg = argStart; addNewFunction(scope, tok); - if (*scope) { - (*scope)->functionOf = func->nestedIn; - (*scope)->function = func; - (*scope)->function->functionScope = *scope; + if (scope) { + scope->functionOf = func->nestedIn; + scope->function = func; + scope->function->functionScope = scope; } return; } @@ -3326,14 +3326,14 @@ void SymbolDatabase::addClassFunction(Scope **scope, const Token **tok, const To const bool isAnonymousNamespace = (scope1->type == Scope::eNamespace && scope1->className.empty()); if ((scope1->className == tok1->str() && (scope1->type != Scope::eFunction)) || isAnonymousNamespace) { // do the scopes match (same scope) or do their names match (multiple namespaces) - if ((*scope == scope1->nestedIn) || (*scope && - (*scope)->className == scope1->nestedIn->className && - !(*scope)->className.empty() && - (*scope)->type == scope1->nestedIn->type)) { + if ((scope == scope1->nestedIn) || (scope && + scope->className == scope1->nestedIn->className && + !scope->className.empty() && + scope->type == scope1->nestedIn->type)) { // nested scopes => check that they match { - const Scope *s1 = *scope; + const Scope *s1 = scope; const Scope *s2 = scope1->nestedIn; while (s1 && s2) { if (s1->className != s2->className) @@ -3367,12 +3367,12 @@ void SymbolDatabase::addClassFunction(Scope **scope, const Token **tok, const To } if (match) { - auto range = scope1->functionMap.equal_range((*tok)->str()); + auto range = scope1->functionMap.equal_range(tok->str()); for (std::multimap::const_iterator it = range.first; it != range.second; ++it) { auto * func = const_cast(it->second); if (!func->hasBody()) { - if (func->argsMatch(scope1, func->argDef, (*tok)->next(), path, path_length)) { - const Token *closeParen = (*tok)->next()->link(); + if (func->argsMatch(scope1, func->argDef, tok->next(), path, path_length)) { + const Token *closeParen = tok->next()->link(); if (closeParen) { const Token *eq = Tokenizer::isFunctionHead(closeParen, ";"); if (eq && Token::simpleMatch(eq->tokAt(-2), "= default ;")) { @@ -3393,13 +3393,13 @@ void SymbolDatabase::addClassFunction(Scope **scope, const Token **tok, const To } if (func->hasBody()) { - func->token = *tok; + func->token = tok; func->arg = argStart; addNewFunction(scope, tok); - if (*scope) { - (*scope)->functionOf = scope1; - (*scope)->function = func; - (*scope)->function->functionScope = *scope; + if (scope) { + scope->functionOf = scope1; + scope->function = func; + scope->function->functionScope = scope; } return; } @@ -3413,10 +3413,10 @@ void SymbolDatabase::addClassFunction(Scope **scope, const Token **tok, const To addNewFunction(scope, tok); } -void SymbolDatabase::addNewFunction(Scope **scope, const Token **tok) +void SymbolDatabase::addNewFunction(Scope *&scope, const Token *&tok) { - const Token *tok1 = *tok; - scopeList.emplace_back(this, tok1, *scope); + const Token *tok1 = tok; + scopeList.emplace_back(this, tok1, scope); Scope *newScope = &scopeList.back(); // find start of function '{' @@ -3440,15 +3440,15 @@ void SymbolDatabase::addNewFunction(Scope **scope, const Token **tok) if (!newScope->bodyEnd) { mTokenizer.unmatchedToken(tok1); } else { - (*scope)->nestedList.push_back(newScope); - *scope = newScope; + scope->nestedList.push_back(newScope); + scope = newScope; } } else if (tok1 && Token::Match(tok1->tokAt(-2), "= default|delete ;")) { scopeList.pop_back(); } else { - throw InternalError(*tok, "Analysis failed (function not recognized). If the code is valid then please report this failure."); + throw InternalError(tok, "Analysis failed (function not recognized). If the code is valid then please report this failure."); } - *tok = tok1; + tok = tok1; } bool Type::isClassType() const @@ -7599,7 +7599,7 @@ void SymbolDatabase::setValueTypeInTokenList(bool reportDebugWarnings, Token *to continue; } - const auto yield = astFunctionYield(tok->previous(), &mSettings); + const auto yield = astFunctionYield(tok->previous(), mSettings); if (yield == Library::Container::Yield::START_ITERATOR || yield == Library::Container::Yield::END_ITERATOR || yield == Library::Container::Yield::ITERATOR) { diff --git a/lib/symboldatabase.h b/lib/symboldatabase.h index 901991313d4..0dfebdbedb6 100644 --- a/lib/symboldatabase.h +++ b/lib/symboldatabase.h @@ -1435,11 +1435,11 @@ class CPPCHECKLIB SymbolDatabase { void debugSymbolDatabase() const; - void addClassFunction(Scope **scope, const Token **tok, const Token *argStart); + void addClassFunction(Scope *&scope, const Token *&tok, const Token *argStart); static Function *addGlobalFunctionDecl(Scope*& scope, const Token* tok, const Token *argStart, const Token* funcStart); Function *addGlobalFunction(Scope*& scope, const Token*& tok, const Token *argStart, const Token* funcStart); - void addNewFunction(Scope **scope, const Token **tok); - bool isFunction(const Token *tok, const Scope* outerScope, const Token **funcStart, const Token **argStart, const Token** declEnd) const; + void addNewFunction(Scope *&scope, const Token *&tok); + bool isFunction(const Token *tok, const Scope* outerScope, const Token *&funcStart, const Token *&argStart, const Token*& declEnd) const; const Type *findTypeInNested(const Token *startTok, const Scope *startScope) const; const Scope *findNamespace(const Token * tok, const Scope * scope) const; static Function *findFunctionInScope(const Token *func, const Scope *ns, const std::string & path, nonneg int path_length); diff --git a/lib/tokenize.h b/lib/tokenize.h index a7bbbe32a25..556eb18f253 100644 --- a/lib/tokenize.h +++ b/lib/tokenize.h @@ -538,7 +538,7 @@ class CPPCHECKLIB Tokenizer { void reportError(const Token* tok, const Severity severity, const std::string& id, const std::string& msg, bool inconclusive = false) const; void reportError(const std::list& callstack, Severity severity, const std::string& id, const std::string& msg, bool inconclusive = false) const; - bool duplicateTypedef(Token **tokPtr, const Token *name, const Token *typeDef) const; + bool duplicateTypedef(Token *&tokPtr, const Token *name, const Token *typeDef) const; void unsupportedTypedef(const Token *tok) const; diff --git a/lib/valueflow.cpp b/lib/valueflow.cpp index dcb0eb710bc..6e7e79c4c1b 100644 --- a/lib/valueflow.cpp +++ b/lib/valueflow.cpp @@ -4040,7 +4040,7 @@ static void valueFlowForwardLifetime(Token * tok, TokenList &tokenlist, ErrorLog // TODO: handle `[` if (Token::simpleMatch(parent->astOperand1(), ".")) { const Token* parentLifetime = - getParentLifetime(parent->astOperand1()->astOperand2(), &settings.library); + getParentLifetime(parent->astOperand1()->astOperand2(), settings.library); if (parentLifetime && parentLifetime->exprId() > 0) { valueFlowForward(nextExpression, endOfVarScope, parentLifetime, std::move(values), tokenlist, errorLogger, settings); } @@ -5049,7 +5049,7 @@ static void valueFlowLifetime(TokenList &tokenlist, ErrorLogger &errorLogger, co // Skip if its a free function that doesnt yield an iterator to the container if (Token::Match(parent->previous(), "%name% (") && !contains({Library::Container::Yield::START_ITERATOR, Library::Container::Yield::END_ITERATOR}, - astFunctionYield(parent->previous(), &settings))) + astFunctionYield(parent->previous(), settings))) continue; ValueFlow::Value master; @@ -5061,7 +5061,7 @@ static void valueFlowLifetime(TokenList &tokenlist, ErrorLogger &errorLogger, co master.lifetimeKind = ValueFlow::Value::LifetimeKind::Iterator; } else if (astIsIterator(parent) && Token::Match(parent->previous(), "%name% (") && contains({Library::Container::Yield::START_ITERATOR, Library::Container::Yield::END_ITERATOR}, - astFunctionYield(parent->previous(), &settings))) { + astFunctionYield(parent->previous(), settings))) { master.errorPath.emplace_back(parent, "Iterator to container is created here."); master.lifetimeKind = ValueFlow::Value::LifetimeKind::Iterator; } else if ((astIsPointer(parent->tokAt(2)) && @@ -5820,12 +5820,12 @@ static void valueFlowForwardConst(Token* start, static ValueFlow::Value::Bound findVarBound(const Variable* var, const Token* start, const Token* end, - const Settings* settings) + const Settings& settings) { ValueFlow::Value::Bound result = ValueFlow::Value::Bound::Point; const Token* next = start; while ((next = findExpressionChangedSkipDeadCode( - var->nameToken(), next->next(), end, settings, &evaluateKnownValues))) { + var->nameToken(), next->next(), end, &settings, &evaluateKnownValues))) { ValueFlow::Value::Bound b = ValueFlow::Value::Bound::Point; if (next->varId() != var->declarationId()) return ValueFlow::Value::Bound::Point; @@ -5948,7 +5948,7 @@ static void valueFlowForwardAssign(Token* const tok, } if (isInitialVarAssign(expr)) { // Check if variable is only incremented or decremented - ValueFlow::Value::Bound b = findVarBound(expr->variable(), nextExpression, endOfVarScope, &settings); + ValueFlow::Value::Bound b = findVarBound(expr->variable(), nextExpression, endOfVarScope, settings); if (b != ValueFlow::Value::Bound::Point) { auto knownValueIt = std::find_if(values.begin(), values.end(), [](const ValueFlow::Value& value) { if (!value.isKnown()) @@ -6713,9 +6713,9 @@ struct ConditionHandler { ProgramMemory pm; fillFromPath(pm, initTok, path); fillFromPath(pm, condTok, path); - execute(initTok, pm, nullptr, nullptr); + execute(initTok, pm, nullptr, nullptr, nullptr); MathLib::bigint result = 1; - execute(condTok, pm, &result, nullptr); + execute(condTok, pm, &result, nullptr, nullptr); if (result == 0) return; // Remove condition since for condition is not redundant @@ -6783,7 +6783,7 @@ struct ConditionHandler { if (condTok->astParent() && Token::Match(top->previous(), "while|for (")) dead_if = !isBreakScope(after); else if (!dead_if) - dead_if = isReturnScope(after, &settings.library, &unknownFunction); + dead_if = isReturnScope(after, settings.library, &unknownFunction); if (!dead_if && unknownFunction) { if (settings.debugwarnings) @@ -6795,7 +6795,7 @@ struct ConditionHandler { after = after->linkAt(2); unknownFunction = nullptr; if (!dead_else) - dead_else = isReturnScope(after, &settings.library, &unknownFunction); + dead_else = isReturnScope(after, settings.library, &unknownFunction); if (!dead_else && unknownFunction) { if (settings.debugwarnings) bailout(tokenlist, errorLogger, unknownFunction, "possible noreturn scope"); @@ -7132,10 +7132,10 @@ static bool valueFlowForLoop2(const Token *tok, ProgramMemory programMemory; MathLib::bigint result(0); bool error = false; - execute(firstExpression, programMemory, &result, &error); + execute(firstExpression, programMemory, &result, &error, nullptr); if (error) return false; - execute(secondExpression, programMemory, &result, &error); + execute(secondExpression, programMemory, &result, &error, nullptr); if (result == 0) // 2nd expression is false => no looping return false; if (error) { @@ -7158,9 +7158,9 @@ static bool valueFlowForLoop2(const Token *tok, int maxcount = 10000; while (result != 0 && !error && --maxcount > 0) { endMemory = programMemory; - execute(thirdExpression, programMemory, &result, &error); + execute(thirdExpression, programMemory, &result, &error, nullptr); if (!error) - execute(secondExpression, programMemory, &result, &error); + execute(secondExpression, programMemory, &result, &error, nullptr); } if (memory1) @@ -7217,7 +7217,7 @@ static void valueFlowForLoopSimplify(Token* const bodyStart, } if (Token::Match(tok2, "%oror%|&&")) { - const ProgramMemory programMemory(getProgramMemory(tok2->astTop(), expr, ValueFlow::Value(value), &settings)); + const ProgramMemory programMemory(getProgramMemory(tok2->astTop(), expr, ValueFlow::Value(value), settings)); if ((tok2->str() == "&&" && !conditionIsTrue(tok2->astOperand1(), programMemory, &settings)) || (tok2->str() == "||" && !conditionIsFalse(tok2->astOperand1(), programMemory, &settings))) { // Skip second expression.. @@ -7242,11 +7242,11 @@ static void valueFlowForLoopSimplify(Token* const bodyStart, if ((tok2->str() == "&&" && conditionIsFalse(tok2->astOperand1(), - getProgramMemory(tok2->astTop(), expr, ValueFlow::Value(value), &settings), + getProgramMemory(tok2->astTop(), expr, ValueFlow::Value(value), settings), &settings)) || (tok2->str() == "||" && conditionIsTrue(tok2->astOperand1(), - getProgramMemory(tok2->astTop(), expr, ValueFlow::Value(value), &settings), + getProgramMemory(tok2->astTop(), expr, ValueFlow::Value(value), settings), &settings))) break; @@ -7965,7 +7965,7 @@ static void valueFlowFunctionReturn(TokenList &tokenlist, ErrorLogger &errorLogg } if (programMemory.empty() && !arguments.empty()) continue; - std::vector values = execute(function->functionScope, programMemory, &settings); + std::vector values = execute(function->functionScope, programMemory, settings); for (const ValueFlow::Value& v : values) { if (v.isUninitValue()) continue; @@ -8020,7 +8020,7 @@ static void addToErrorPath(ValueFlow::Value& value, const ValueFlow::Value& from static std::vector findAllUsages(const Variable* var, Token* start, // cppcheck-suppress constParameterPointer // FP - const Library* library) + const Library& library) { // std::vector result; const Scope* scope = var->scope(); @@ -8031,7 +8031,7 @@ static std::vector findAllUsages(const Variable* var, }); } -static Token* findStartToken(const Variable* var, Token* start, const Library* library) +static Token* findStartToken(const Variable* var, Token* start, const Library& library) { std::vector uses = findAllUsages(var, start, library); if (uses.empty()) @@ -8111,7 +8111,7 @@ static void valueFlowUninit(TokenList& tokenlist, ErrorLogger& errorLogger, cons bool partial = false; - Token* start = findStartToken(var, tok->next(), &settings.library); + Token* start = findStartToken(var, tok->next(), settings.library); std::map partialReads; if (const Scope* scope = var->typeScope()) { @@ -8561,14 +8561,14 @@ static void valueFlowSmartPointer(TokenList &tokenlist, ErrorLogger & errorLogge static Library::Container::Yield findIteratorYield(Token* tok, const Token** ftok, const Settings &settings) { auto yield = astContainerYield(tok, ftok); - if (*ftok) + if (ftok && *ftok) return yield; if (!tok->astParent()) return yield; //begin/end free functions - return astFunctionYield(tok->astParent()->previous(), &settings, ftok); + return astFunctionYield(tok->astParent()->previous(), settings, ftok); } static void valueFlowIterators(TokenList &tokenlist, const Settings &settings) diff --git a/test/testastutils.cpp b/test/testastutils.cpp index baa8357d09c..869e991ed54 100644 --- a/test/testastutils.cpp +++ b/test/testastutils.cpp @@ -145,7 +145,7 @@ class TestAstUtils : public TestFixture { const Token * const tok = (offset < 0) ? tokenizer.list.back()->tokAt(1+offset) : tokenizer.tokens()->tokAt(offset); - return (isReturnScope)(tok); + return (isReturnScope)(tok, settingsDefault.library); } void isReturnScopeTest() { diff --git a/test/testbufferoverrun.cpp b/test/testbufferoverrun.cpp index 7c845c82722..82471879321 100644 --- a/test/testbufferoverrun.cpp +++ b/test/testbufferoverrun.cpp @@ -5163,12 +5163,12 @@ class TestBufferOverrun : public TestFixture { SimpleTokenizer tokenizer(settings0, *this); ASSERT_LOC(tokenizer.tokenize(code), file, line); - CTU::FileInfo *ctu = CTU::getFileInfo(&tokenizer); + CTU::FileInfo *ctu = CTU::getFileInfo(tokenizer); // Check code.. std::list fileInfo; Check& c = getCheck(); - fileInfo.push_back(c.getFileInfo(&tokenizer, &settings0)); + fileInfo.push_back(c.getFileInfo(tokenizer, settings0)); c.analyseWholeProgram(ctu, fileInfo, settings0, *this); while (!fileInfo.empty()) { delete fileInfo.back(); diff --git a/test/testclass.cpp b/test/testclass.cpp index a6ba8a202b1..c9dde77fae5 100644 --- a/test/testclass.cpp +++ b/test/testclass.cpp @@ -8854,7 +8854,7 @@ class TestClass : public TestFixture { const std::string filename = std::to_string(fileInfo.size()) + ".cpp"; ASSERT(tokenizer.list.createTokens(istr, filename)); ASSERT(tokenizer.simplifyTokens1("")); - fileInfo.push_back(check.getFileInfo(&tokenizer, &settingsDefault)); + fileInfo.push_back(check.getFileInfo(tokenizer, settingsDefault)); } // Check code.. @@ -8898,7 +8898,7 @@ class TestClass : public TestFixture { // Check.. const Check& c = getCheck(); - Check::FileInfo * fileInfo = (c.getFileInfo)(&tokenizer, &settings1); + Check::FileInfo * fileInfo = (c.getFileInfo)(tokenizer, settings1); delete fileInfo; } diff --git a/test/testgarbage.cpp b/test/testgarbage.cpp index 3726a3d2602..86e7c6c58e5 100644 --- a/test/testgarbage.cpp +++ b/test/testgarbage.cpp @@ -252,6 +252,7 @@ class TestGarbage : public TestFixture { TEST_CASE(garbageCode224); TEST_CASE(garbageCode225); TEST_CASE(garbageCode226); + TEST_CASE(garbageCode227); TEST_CASE(garbageCodeFuzzerClientMode1); // test cases created with the fuzzer client, mode 1 @@ -1753,6 +1754,9 @@ class TestGarbage : public TestFixture { ASSERT_THROW_INTERNAL(checkCode("int a() { (b((c)\\)) } {}"), SYNTAX); ASSERT_THROW_INTERNAL(checkCode("int a() { (b((c)@)) } {}"), SYNTAX); } + void garbageCode227() { // #12615 + ASSERT_NO_THROW(checkCode("f(&S::operator=);")); + } void syntaxErrorFirstToken() { ASSERT_THROW_INTERNAL(checkCode("&operator(){[]};"), SYNTAX); // #7818 diff --git a/test/testnullpointer.cpp b/test/testnullpointer.cpp index 3dfaefb06c5..fadc729caf6 100644 --- a/test/testnullpointer.cpp +++ b/test/testnullpointer.cpp @@ -4153,7 +4153,7 @@ class TestNullPointer : public TestFixture { library.functions["x"].argumentChecks[3] = arg; std::list null; - CheckNullPointer::parseFunctionCall(*xtok, null, &library); + CheckNullPointer::parseFunctionCall(*xtok, null, library); ASSERT_EQUALS(0U, null.size()); } @@ -4167,7 +4167,7 @@ class TestNullPointer : public TestFixture { library.functions["x"].argumentChecks[1].notnull = true; std::list null; - CheckNullPointer::parseFunctionCall(*xtok, null, &library); + CheckNullPointer::parseFunctionCall(*xtok, null, library); ASSERT_EQUALS(1U, null.size()); ASSERT_EQUALS("a", null.front()->str()); } @@ -4483,12 +4483,12 @@ class TestNullPointer : public TestFixture { SimpleTokenizer tokenizer(settings, *this); ASSERT_LOC(tokenizer.tokenize(code), file, line); - CTU::FileInfo *ctu = CTU::getFileInfo(&tokenizer); + CTU::FileInfo *ctu = CTU::getFileInfo(tokenizer); // Check code.. std::list fileInfo; Check& c = getCheck(); - fileInfo.push_back(c.getFileInfo(&tokenizer, &settings)); + fileInfo.push_back(c.getFileInfo(tokenizer, settings)); c.analyseWholeProgram(ctu, fileInfo, settings, *this); while (!fileInfo.empty()) { delete fileInfo.back(); diff --git a/test/testother.cpp b/test/testother.cpp index 4d4286ce1d5..85ee90f7ff6 100644 --- a/test/testother.cpp +++ b/test/testother.cpp @@ -100,6 +100,7 @@ class TestOther : public TestFixture { TEST_CASE(varScope37); // #12158 TEST_CASE(varScope38); TEST_CASE(varScope39); + TEST_CASE(varScope40); TEST_CASE(oldStylePointerCast); TEST_CASE(invalidPointerCast); @@ -1710,6 +1711,28 @@ class TestOther : public TestFixture { ASSERT_EQUALS("", errout_str()); } + void varScope40() { + checkP("#define NUM (-999.9)\n" + "double f(int i) {\n" + " double a = NUM;\n" + " double b = -NUM;\n" + " double c = -1.0 * NUM;\n" + " if (i == 1) {\n" + " return a;\n" + " }\n" + " if (i == 2) {\n" + " return b;\n" + " }\n" + " if (i == 3) {\n" + " return c;\n" + " }\n" + " return 0.0;\n" + "}\n"); + ASSERT_EQUALS("[test.cpp:3]: (style) The scope of the variable 'a' can be reduced.\n" + "[test.cpp:4]: (style) The scope of the variable 'b' can be reduced.\n" + "[test.cpp:5]: (style) The scope of the variable 'c' can be reduced.\n", + errout_str()); + } #define checkOldStylePointerCast(code) checkOldStylePointerCast_(code, __FILE__, __LINE__) void checkOldStylePointerCast_(const char code[], const char* file, int line) { diff --git a/test/testsummaries.cpp b/test/testsummaries.cpp index a133d3eab38..6f5b198e255 100644 --- a/test/testsummaries.cpp +++ b/test/testsummaries.cpp @@ -39,7 +39,7 @@ class TestSummaries : public TestFixture { // tokenize.. SimpleTokenizer tokenizer(settingsDefault, *this); ASSERT_LOC(tokenizer.tokenize(code, cpp), file, line); - return Summaries::create(&tokenizer, ""); + return Summaries::create(tokenizer, ""); } void createSummaries1() { diff --git a/test/testsymboldatabase.cpp b/test/testsymboldatabase.cpp index d56db42fef9..7e44bf56a21 100644 --- a/test/testsymboldatabase.cpp +++ b/test/testsymboldatabase.cpp @@ -6568,7 +6568,8 @@ class TestSymbolDatabase : public TestFixture { " *PTRRELOC(&x) = &y;\n" "}"); ASSERT(db != nullptr); - ASSERT(db && !db->isFunction(Token::findsimplematch(tokenizer.tokens(), "PTRRELOC ( &"), &db->scopeList.back(), nullptr, nullptr, nullptr)); + const Token *funcStart, *argStart, *declEnd; + ASSERT(db && !db->isFunction(Token::findsimplematch(tokenizer.tokens(), "PTRRELOC ( &"), &db->scopeList.back(), funcStart, argStart, declEnd)); ASSERT(db->findScopeByName("set_cur_cpu_spec") != nullptr); ASSERT(db->findScopeByName("setup_cpu_spec") != nullptr); ASSERT(db->findScopeByName("PTRRELOC") == nullptr); diff --git a/test/testuninitvar.cpp b/test/testuninitvar.cpp index 08b1a0908d3..f86f0acc0ce 100644 --- a/test/testuninitvar.cpp +++ b/test/testuninitvar.cpp @@ -7502,6 +7502,16 @@ class TestUninitVar : public TestFixture { " int len = strlen(arr);\n" "}\n"); ASSERT_EQUALS("[test.cpp:8]: (error) Uninitialized variable: arr\n", errout_str()); + + valueFlowUninit("struct S1 { int x; };\n" // #12401 + "struct S2 { struct S1 s1; };\n" + "struct S2 f() {\n" + " struct S2 s2;\n" + " struct S1* s1 = &s2.s1;\n" + " s1->x = 0;\n" + " return s2;\n" + "}\n"); + ASSERT_EQUALS("", errout_str()); } void uninitvar_memberfunction() { @@ -7753,12 +7763,12 @@ class TestUninitVar : public TestFixture { SimpleTokenizer tokenizer(settings, *this); ASSERT_LOC(tokenizer.tokenize(code), file, line); - CTU::FileInfo *ctu = CTU::getFileInfo(&tokenizer); + CTU::FileInfo *ctu = CTU::getFileInfo(tokenizer); // Check code.. std::list fileInfo; Check& c = getCheck(); - fileInfo.push_back(c.getFileInfo(&tokenizer, &settings)); + fileInfo.push_back(c.getFileInfo(tokenizer, settings)); c.analyseWholeProgram(ctu, fileInfo, settings, *this); while (!fileInfo.empty()) { delete fileInfo.back();