diff --git a/.clang-tidy b/.clang-tidy
index 95710ddfbe0..e1bae2cd255 100644
--- a/.clang-tidy
+++ b/.clang-tidy
@@ -1,5 +1,75 @@
---
-Checks: '*,-abseil-*,-altera-*,-android-*,-boost-*,-cert-*,-cppcoreguidelines-*,-darwin-*,-fuchsia-*,-google-*,-hicpp-*,-linuxkernel-*,-llvm-*,-llvmlibc-*,-mpi-*,-objc-*,-openmp-*,-zircon-*,google-explicit-constructor,-readability-braces-around-statements,-readability-magic-numbers,-bugprone-macro-parentheses,-readability-isolate-declaration,-readability-function-size,-modernize-use-trailing-return-type,-readability-implicit-bool-conversion,-readability-uppercase-literal-suffix,-modernize-use-auto,-modernize-use-default-member-init,-readability-redundant-member-init,-modernize-avoid-c-arrays,-modernize-use-equals-default,-readability-container-size-empty,-bugprone-branch-clone,-bugprone-narrowing-conversions,-modernize-raw-string-literal,-readability-convert-member-functions-to-static,-modernize-loop-convert,-readability-const-return-type,-modernize-return-braced-init-list,-performance-inefficient-string-concatenation,-misc-throw-by-value-catch-by-reference,-readability-avoid-const-params-in-decls,-misc-non-private-member-variables-in-classes,-clang-analyzer-*,-bugprone-signed-char-misuse,-misc-no-recursion,-readability-use-anyofallof,-performance-no-automatic-move,-readability-function-cognitive-complexity,-readability-redundant-access-specifiers,-concurrency-mt-unsafe,-bugprone-easily-swappable-parameters,-readability-suspicious-call-argument,-readability-identifier-length,-readability-container-data-pointer,-bugprone-assignment-in-if-condition,-misc-const-correctness,-portability-std-allocator-const,-modernize-deprecated-ios-base-aliases,-bugprone-unchecked-optional-access,-modernize-replace-auto-ptr,-readability-identifier-naming,-portability-simd-intrinsics,-misc-use-anonymous-namespace,cert-err34-c'
+Checks: >
+ *,
+ -abseil-*,
+ -altera-*,
+ -android-*,
+ -boost-*,
+ -cert-*,
+ -cppcoreguidelines-*,
+ -darwin-*,
+ -fuchsia-*,
+ -google-*,
+ -hicpp-*,
+ -linuxkernel-*,
+ -llvm-*,
+ -llvmlibc-*,
+ -mpi-*,
+ -objc-*,
+ -openmp-*,
+ -zircon-*,
+ cert-err34-c,
+ google-explicit-constructor,
+ cppcoreguidelines-rvalue-reference-param-not-moved,
+ -bugprone-assignment-in-if-condition,
+ -bugprone-branch-clone,
+ -bugprone-easily-swappable-parameters,
+ -bugprone-empty-catch,
+ -bugprone-macro-parentheses,
+ -bugprone-narrowing-conversions,
+ -bugprone-signed-char-misuse,
+ -bugprone-switch-missing-default-case,
+ -bugprone-unchecked-optional-access,
+ -clang-analyzer-*,
+ -concurrency-mt-unsafe,
+ -misc-const-correctness,
+ -misc-no-recursion,
+ -misc-non-private-member-variables-in-classes,
+ -misc-throw-by-value-catch-by-reference,
+ -misc-use-anonymous-namespace,
+ -modernize-avoid-c-arrays,
+ -modernize-deprecated-ios-base-aliases,
+ -misc-include-cleaner,
+ -modernize-loop-convert,
+ -modernize-raw-string-literal,
+ -modernize-replace-auto-ptr,
+ -modernize-return-braced-init-list,
+ -modernize-use-auto,
+ -modernize-use-equals-default,
+ -modernize-use-trailing-return-type,
+ -performance-avoid-endl,
+ -performance-inefficient-string-concatenation,
+ -performance-no-automatic-move,
+ -performance-noexcept-swap,
+ -portability-simd-intrinsics,
+ -portability-std-allocator-const,
+ -readability-avoid-const-params-in-decls,
+ -readability-braces-around-statements,
+ -readability-const-return-type,
+ -readability-container-data-pointer,
+ -readability-container-size-empty,
+ -readability-convert-member-functions-to-static,
+ -readability-function-cognitive-complexity,
+ -readability-function-size,
+ -readability-identifier-length,
+ -readability-identifier-naming,
+ -readability-implicit-bool-conversion,
+ -readability-isolate-declaration,
+ -readability-magic-numbers,
+ -readability-redundant-access-specifiers,
+ -readability-suspicious-call-argument,
+ -readability-uppercase-literal-suffix,
+ -readability-use-anyofallof
WarningsAsErrors: '*'
HeaderFilterRegex: '(cli|gui|lib|oss-fuzz|test|triage)\/[a-z]+\.h'
CheckOptions:
diff --git a/.github/workflows/asan.yml b/.github/workflows/asan.yml
index fdc029ad9f8..fe7c5a95a77 100644
--- a/.github/workflows/asan.yml
+++ b/.github/workflows/asan.yml
@@ -42,7 +42,7 @@ jobs:
sudo apt-get purge --auto-remove llvm python3-lldb-14 llvm-14
wget https://apt.llvm.org/llvm.sh
chmod +x llvm.sh
- sudo ./llvm.sh 16
+ sudo ./llvm.sh 17
- name: Install Qt ${{ env.QT_VERSION }}
if: false
@@ -56,8 +56,8 @@ jobs:
run: |
cmake -S . -B cmake.output -DCMAKE_BUILD_TYPE=RelWithDebInfo -DHAVE_RULES=On -DBUILD_TESTS=On -DBUILD_GUI=Off -DWITH_QCHART=Off -DUSE_MATCHCOMPILER=Verify -DANALYZE_ADDRESS=On -DENABLE_CHECK_INTERNAL=On -DUSE_BOOST=On -DCPPCHK_GLIBCXX_DEBUG=Off -DCMAKE_DISABLE_PRECOMPILE_HEADERS=On -DCMAKE_GLOBAL_AUTOGEN_TARGET=Off -DDISABLE_DMAKE=On -DCMAKE_C_COMPILER_LAUNCHER=ccache -DCMAKE_CXX_COMPILER_LAUNCHER=ccache
env:
- CC: clang-16
- CXX: clang++-16
+ CC: clang-17
+ CXX: clang++-17
- name: Build cppcheck
run: |
diff --git a/.github/workflows/clang-tidy.yml b/.github/workflows/clang-tidy.yml
index c8546db9ab2..7bcd8bd8e31 100644
--- a/.github/workflows/clang-tidy.yml
+++ b/.github/workflows/clang-tidy.yml
@@ -30,8 +30,8 @@ jobs:
sudo apt-get purge --auto-remove llvm python3-lldb-14 llvm-14
wget https://apt.llvm.org/llvm.sh
chmod +x llvm.sh
- sudo ./llvm.sh 16
- sudo apt-get install -y clang-tidy-16
+ sudo ./llvm.sh 17
+ sudo apt-get install -y clang-tidy-17
- name: Install Qt ${{ env.QT_VERSION }}
uses: jurplel/install-qt-action@v3
@@ -42,14 +42,14 @@ jobs:
- name: Verify clang-tidy configuration
run: |
- clang-tidy-16 --verify-config
+ clang-tidy-17 --verify-config
- name: Prepare CMake
run: |
cmake -S . -B cmake.output -G "Unix Makefiles" -DHAVE_RULES=On -DBUILD_TESTS=On -DBUILD_GUI=On -DWITH_QCHART=On -DENABLE_CHECK_INTERNAL=On -DCMAKE_GLOBAL_AUTOGEN_TARGET=On -DCPPCHK_GLIBCXX_DEBUG=Off
env:
- CC: clang-16
- CXX: clang++-16
+ CC: clang-17
+ CXX: clang++-17
- name: Prepare CMake dependencies
run: |
diff --git a/.github/workflows/tsan.yml b/.github/workflows/tsan.yml
index 5a5aaa2c900..6114817c194 100644
--- a/.github/workflows/tsan.yml
+++ b/.github/workflows/tsan.yml
@@ -42,7 +42,7 @@ jobs:
sudo apt-get purge --auto-remove llvm python3-lldb-14 llvm-14
wget https://apt.llvm.org/llvm.sh
chmod +x llvm.sh
- sudo ./llvm.sh 16
+ sudo ./llvm.sh 17
- name: Install Qt ${{ env.QT_VERSION }}
if: false
@@ -56,8 +56,8 @@ jobs:
run: |
cmake -S . -B cmake.output -DCMAKE_BUILD_TYPE=RelWithDebInfo -DHAVE_RULES=On -DBUILD_TESTS=On -DBUILD_GUI=Off -DWITH_QCHART=Off -DUSE_MATCHCOMPILER=Verify -DANALYZE_THREAD=On -DUSE_THREADS=On -DENABLE_CHECK_INTERNAL=On -DUSE_BOOST=On -DCPPCHK_GLIBCXX_DEBUG=Off -DCMAKE_DISABLE_PRECOMPILE_HEADERS=On -DCMAKE_GLOBAL_AUTOGEN_TARGET=Off -DDISABLE_DMAKE=On -DCMAKE_C_COMPILER_LAUNCHER=ccache -DCMAKE_CXX_COMPILER_LAUNCHER=ccache
env:
- CC: clang-16
- CXX: clang++-16
+ CC: clang-17
+ CXX: clang++-17
- name: Build cppcheck
run: |
diff --git a/.github/workflows/ubsan.yml b/.github/workflows/ubsan.yml
index ed6d4e61f6c..3076801002e 100644
--- a/.github/workflows/ubsan.yml
+++ b/.github/workflows/ubsan.yml
@@ -42,7 +42,7 @@ jobs:
sudo apt-get purge --auto-remove llvm python3-lldb-14 llvm-14
wget https://apt.llvm.org/llvm.sh
chmod +x llvm.sh
- sudo ./llvm.sh 16
+ sudo ./llvm.sh 17
- name: Install Qt ${{ env.QT_VERSION }}
uses: jurplel/install-qt-action@v3
@@ -55,8 +55,8 @@ jobs:
run: |
cmake -S . -B cmake.output -DCMAKE_BUILD_TYPE=RelWithDebInfo -DHAVE_RULES=On -DBUILD_TESTS=On -DBUILD_GUI=ON -DWITH_QCHART=ON -DUSE_MATCHCOMPILER=Verify -DANALYZE_UNDEFINED=On -DENABLE_CHECK_INTERNAL=On -DUSE_BOOST=On -DCPPCHK_GLIBCXX_DEBUG=Off -DCMAKE_DISABLE_PRECOMPILE_HEADERS=On -DCMAKE_GLOBAL_AUTOGEN_TARGET=On -DDISABLE_DMAKE=On -DCMAKE_C_COMPILER_LAUNCHER=ccache -DCMAKE_CXX_COMPILER_LAUNCHER=ccache
env:
- CC: clang-16
- CXX: clang++-16
+ CC: clang-17
+ CXX: clang++-17
- name: Build cppcheck
run: |
diff --git a/Makefile b/Makefile
index fe2665a7726..946755da0cb 100644
--- a/Makefile
+++ b/Makefile
@@ -278,6 +278,7 @@ TESTOBJ = test/fixture.o \
test/testboost.o \
test/testbufferoverrun.o \
test/testcharvar.o \
+ test/testcheck.o \
test/testclangimport.o \
test/testclass.o \
test/testcmdlineparser.o \
@@ -706,6 +707,9 @@ test/testbufferoverrun.o: test/testbufferoverrun.cpp externals/simplecpp/simplec
test/testcharvar.o: test/testcharvar.cpp lib/check.h lib/checkother.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/importproject.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/standards.h lib/suppressions.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h
$(CXX) ${INCLUDE_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testcharvar.cpp
+test/testcheck.o: test/testcheck.cpp lib/check.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/importproject.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/standards.h lib/suppressions.h lib/utils.h test/fixture.h
+ $(CXX) ${INCLUDE_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testcheck.cpp
+
test/testclangimport.o: test/testclangimport.cpp lib/check.h lib/clangimport.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/importproject.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/sourcelocation.h lib/standards.h lib/suppressions.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h
$(CXX) ${INCLUDE_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testclangimport.cpp
diff --git a/clang-tidy.md b/clang-tidy.md
index 8e6625081a6..2311d2d3a97 100644
--- a/clang-tidy.md
+++ b/clang-tidy.md
@@ -8,158 +8,169 @@ We do not perform static analysis of the source of the external libraries. `simp
## Disabled Checks
-`abseil-*`
-`altera-*`
-`android-*`
-`boost-*`
-`darwin-*`
-`fuchsia-*`
-`linuxkernel-*`
-`llvm-*`
-`llvmlibc-*`
-`mpi-*`
-`objc-*`
-`openmp-*`
-`zircon-*`
+`abseil-*`
+`altera-*`
+`android-*`
+`boost-*`
+`darwin-*`
+`fuchsia-*`
+`linuxkernel-*`
+`llvm-*`
+`llvmlibc-*`
+`mpi-*`
+`objc-*`
+`openmp-*`
+`zircon-*`
These are disabled since the platforms/libraries in question are not targeted by us.
-`cert-*`
-`cppcoreguidelines-*`
-`google-*`
-`hicpp-*`
+`cert-*`
+`cppcoreguidelines-*`
+`google-*`
+`hicpp-*`
These are coding guidelines we do not follow. Some of the checks might be explicitly enabled though.
-`readability-braces-around-statements`
-`readability-isolate-declaration`
-`modernize-use-trailing-return-type`
-`modernize-use-auto`
-`readability-uppercase-literal-suffix`
-`readability-else-after-return`
-`modernize-use-default-member-init`
-`readability-identifier-length`
+`readability-braces-around-statements`
+`readability-isolate-declaration`
+`modernize-use-trailing-return-type`
+`modernize-use-auto`
+`readability-uppercase-literal-suffix`
+`readability-else-after-return`
+`readability-identifier-length`
-These do not relect the style we are (currently) enforcing.
+These do not reflect the style we are (currently) enforcing.
-`readability-function-size`
-`readability-function-cognitive-complexity`
+`readability-function-size`
+`readability-function-cognitive-complexity`
-We are not interesting in the size/complexity of a function.
+We are not interested in the size/complexity of a function.
-`readability-magic-numbers`
-`readability-redundant-member-init`
+`readability-magic-numbers`
These do not (always) increase readability.
-`bugprone-macro-parentheses`
+`bugprone-macro-parentheses`
To be documented.
-`readability-implicit-bool-conversion`
+`readability-implicit-bool-conversion`
-This does not appear not to be useful as it is reported on very common code.
+This does not appear to be useful as it is reported on very common code.
-`bugprone-narrowing-conversions`
-`performance-no-automatic-move`
+`bugprone-narrowing-conversions`
+`performance-no-automatic-move`
It was decided not to apply these.
-`modernize-use-equals-default`
-`modernize-loop-convert`
+`modernize-use-equals-default`
+`modernize-loop-convert`
These might change the behavior of code which might not be intended (need to file an upstream issue)
-`modernize-raw-string-literal`
+`modernize-raw-string-literal`
This leads to a mismatch of raw string literals and regular ones and does reduce the readability.
-`readability-convert-member-functions-to-static`
+`readability-convert-member-functions-to-static`
Disabled because of false positives with Qt `slot` methods (see https://github.com/llvm/llvm-project/issues/57520).
-`-clang-analyzer-*`
+`-clang-analyzer-*`
Disabled because of false positives (needs to file an upstream bug report).
-`misc-non-private-member-variables-in-classes`
+`misc-non-private-member-variables-in-classes`
We intentionally use this.
-`misc-no-recursion`
+`misc-no-recursion`
Leads to lots of "false positives". This seem to enforce a coding guidelines of certain codebases.
-`readability-use-anyofallof`
+`readability-use-anyofallof`
We currently don't even apply our own `useStlAlgorithm` findings.
-`bugprone-easily-swappable-parameters`
+`bugprone-easily-swappable-parameters`
This produces a lot of noise and they are not fixable that easily.
-`readability-container-data-pointer`
+`readability-container-data-pointer`
Disable because of false positives and inconsistent warnings (need to file an upstream bug report).
-`misc-const-correctness`
+`misc-const-correctness`
Work in progress.
-`bugprone-assignment-in-if-condition`
+`bugprone-assignment-in-if-condition`
Is reported for valid patterns we are using.
-`readability-suspicious-call-argument`
+`readability-suspicious-call-argument`
Produces a lot of false positives since it is too vague in its analysis.
-`performance-inefficient-string-concatenation`
+`performance-inefficient-string-concatenation`
Produces warnings which might be considered false positives starting with C++11 - see https://github.com/llvm/llvm-project/issues/54526.
-`readability-redundant-access-specifiers`
+`readability-redundant-access-specifiers`
Reports warning with the Qt ` slots:` syntax in class declarations - see https://github.com/llvm/llvm-project/issues/60055.
-`modernize-avoid-c-arrays`
+`modernize-avoid-c-arrays`
Produces warnings when `const char[]` is being used which is quite common in our code. Does not make sense to enable before C++17 when `std::string_view` becomes available.
Also reports a false positive about templates which deduce the array length: https://github.com/llvm/llvm-project/issues/60053.
-`readability-container-size-empty`
-`bugprone-branch-clone`
-`readability-const-return-type`
-`modernize-return-braced-init-list`
-`misc-throw-by-value-catch-by-reference`
-`readability-avoid-const-params-in-decls`
-`bugprone-signed-char-misuse`
-`readability-redundant-access-specifiers`
-`concurrency-mt-unsafe`
-`misc-use-anonymous-namespace`
+`misc-include-cleaner`
-To be evaluated.
+We run this separately via `clang-include-cleaner` in the `iwyu.yml` workflow as the findings of the include checkers still need to be reviewed manually before applying them.
-`portability-std-allocator-const`
+`readability-container-size-empty`
+`bugprone-branch-clone`
+`readability-const-return-type`
+`modernize-return-braced-init-list`
+`misc-throw-by-value-catch-by-reference`
+`readability-avoid-const-params-in-decls`
+`bugprone-signed-char-misuse`
+`readability-redundant-access-specifiers`
+`concurrency-mt-unsafe`
+`misc-use-anonymous-namespace`
+`performance-avoid-endl`
+`performance-noexcept-swap`
+`bugprone-switch-missing-default-case`
+`bugprone-empty-catch`
+
+To be evaluated (need to remove exclusion).
+
+`cppcoreguidelines-missing-std-forward`
+`cppcoreguidelines-avoid-const-or-ref-data-members`
+
+To be evaluated (need to enable explicitly).
+
+`portability-std-allocator-const`
Only necessary for code which is exclusively compiled with `libc++`. Also disabled for performance reasons - see https://github.com/llvm/llvm-project/issues/57527#issuecomment-1237935132.
-`modernize-deprecated-ios-base-aliases`
+`modernize-deprecated-ios-base-aliases`
Warns about aliases which are removed in C++20. Also disabled for performance reasons - see https://github.com/llvm/llvm-project/issues/57527#issuecomment-1237935132.
-`bugprone-unchecked-optional-access`
+`bugprone-unchecked-optional-access`
We are not using any `optional` implementation. Also disabled for performance reasons - see https://github.com/llvm/llvm-project/issues/57527#issuecomment-1237935132.
-`modernize-replace-auto-ptr`
+`modernize-replace-auto-ptr`
Still available until C++17. It is unlikely such code will ever be introduced. Also disabled for performance reasons - see https://github.com/llvm/llvm-project/issues/57527#issuecomment-1237935132.
-`readability-identifier-naming`
+`readability-identifier-naming`
We are currently using our own `naming.json` to enforce naming schemes. Also disabled for performance reasons - see https://github.com/llvm/llvm-project/issues/57527#issuecomment-1237935132.
-`portability-simd-intrinsics`
+`portability-simd-intrinsics`
We are not using SIMD instructions and it suggests to use `std::experiemental::` features which might not be commonly available. Also disabled for performance reasons - see https://github.com/llvm/llvm-project/issues/57527#issuecomment-1237935132.
diff --git a/cli/cmdlineparser.cpp b/cli/cmdlineparser.cpp
index a77fc33690b..92b5c6a0a78 100644
--- a/cli/cmdlineparser.cpp
+++ b/cli/cmdlineparser.cpp
@@ -113,10 +113,6 @@ CmdLineParser::CmdLineParser(Settings &settings, Suppressions &suppressions, Sup
: mSettings(settings)
, mSuppressions(suppressions)
, mSuppressionsNoFail(suppressionsNoFail)
- , mShowHelp(false)
- , mShowVersion(false)
- , mShowErrorMessages(false)
- , mExitAfterPrint(false)
{}
void CmdLineParser::printMessage(const std::string &message)
diff --git a/cli/cmdlineparser.h b/cli/cmdlineparser.h
index e84e6835270..2cd5df1cd56 100644
--- a/cli/cmdlineparser.h
+++ b/cli/cmdlineparser.h
@@ -146,10 +146,10 @@ class CmdLineParser {
Settings &mSettings;
Suppressions &mSuppressions;
Suppressions &mSuppressionsNoFail;
- bool mShowHelp;
- bool mShowVersion;
- bool mShowErrorMessages;
- bool mExitAfterPrint;
+ bool mShowHelp{};
+ bool mShowVersion{};
+ bool mShowErrorMessages{};
+ bool mExitAfterPrint{};
std::string mVSConfig;
};
diff --git a/cli/cppcheckexecutor.cpp b/cli/cppcheckexecutor.cpp
index cb07f3f356e..eabf0582022 100644
--- a/cli/cppcheckexecutor.cpp
+++ b/cli/cppcheckexecutor.cpp
@@ -43,6 +43,7 @@
#endif
#include
+#include
#include
#include // EXIT_SUCCESS and EXIT_FAILURE
#include
@@ -66,12 +67,25 @@
#include
#endif
+class XMLErrorMessagesLogger : public ErrorLogger
+{
+ void reportOut(const std::string & outmsg, Color /*c*/ = Color::Reset) override
+ {
+ std::cout << outmsg << std::endl;
+ }
-/*static*/ FILE* CppCheckExecutor::mExceptionOutput = stdout;
+ void reportErr(const ErrorMessage &msg) override
+ {
+ reportOut(msg.toXML());
+ }
+
+ void reportProgress(const std::string & /*filename*/, const char /*stage*/[], const std::size_t /*value*/) override
+ {}
+};
-CppCheckExecutor::CppCheckExecutor()
- : mSettings(nullptr), mLatestProgressOutputTime(0), mErrorOutput(nullptr), mShowAllErrors(false)
-{}
+// TODO: do not directly write to stdout
+
+/*static*/ FILE* CppCheckExecutor::mExceptionOutput = stdout;
CppCheckExecutor::~CppCheckExecutor()
{
@@ -98,9 +112,9 @@ bool CppCheckExecutor::parseFromArgs(Settings &settings, int argc, const char* c
}
if (parser.getShowErrorMessages()) {
- mShowAllErrors = true;
+ XMLErrorMessagesLogger xmlLogger;
std::cout << ErrorMessage::getXMLHeader(settings.cppcheckCfgProductName);
- CppCheck::getErrorMessages(*this);
+ CppCheck::getErrorMessages(xmlLogger);
std::cout << ErrorMessage::getXMLFooter() << std::endl;
}
@@ -285,13 +299,13 @@ int CppCheckExecutor::check_internal(CppCheck& cppcheck)
unsigned int returnValue = 0;
if (settings.useSingleJob()) {
// Single process
- SingleExecutor executor(cppcheck, mFiles, settings, *this);
+ SingleExecutor executor(cppcheck, mFiles, settings, settings.nomsg, *this);
returnValue = executor.check();
} else {
#if defined(THREADING_MODEL_THREAD)
- ThreadExecutor executor(mFiles, settings, *this);
+ ThreadExecutor executor(mFiles, settings, settings.nomsg, *this);
#elif defined(THREADING_MODEL_FORK)
- ProcessExecutor executor(mFiles, settings, *this);
+ ProcessExecutor executor(mFiles, settings, settings.nomsg, *this);
#endif
returnValue = executor.check();
}
@@ -319,21 +333,7 @@ int CppCheckExecutor::check_internal(CppCheck& cppcheck)
bool CppCheckExecutor::loadLibraries(Settings& settings)
{
- const bool std = tryLoadLibrary(settings.library, settings.exename, "std.cfg");
-
- const auto failed_lib = std::find_if(settings.libraries.begin(), settings.libraries.end(), [&](const std::string& lib) {
- return !tryLoadLibrary(settings.library, settings.exename, lib.c_str());
- });
- if (failed_lib != settings.libraries.end()) {
- const std::string msg("Failed to load the library " + *failed_lib);
- const std::list callstack;
- ErrorMessage errmsg(callstack, emptyString, Severity::information, msg, "failedToLoadCfg", Certainty::normal);
- reportErr(errmsg);
- return false;
- }
-
- if (!std) {
- const std::list callstack;
+ if (!tryLoadLibrary(settings.library, settings.exename, "std.cfg")) {
const std::string msg("Failed to load std.cfg. Your Cppcheck installation is broken, please re-install.");
#ifdef FILESDIR
const std::string details("The Cppcheck binary was compiled with FILESDIR set to \""
@@ -345,12 +345,17 @@ bool CppCheckExecutor::loadLibraries(Settings& settings)
"std.cfg should be available in " + cfgfolder + " or the FILESDIR "
"should be configured.");
#endif
- ErrorMessage errmsg(callstack, emptyString, Severity::information, msg+" "+details, "failedToLoadCfg", Certainty::normal);
- reportErr(errmsg);
+ std::cout << msg << " " << details << std::endl;
return false;
}
- return true;
+ bool result = true;
+ for (const auto& lib : settings.libraries) {
+ if (!tryLoadLibrary(settings.library, settings.exename, lib.c_str())) {
+ result = false;
+ }
+ }
+ return result;
}
#ifdef _WIN32
@@ -419,10 +424,7 @@ void CppCheckExecutor::reportProgress(const std::string &filename, const char st
void CppCheckExecutor::reportErr(const ErrorMessage &msg)
{
- if (mShowAllErrors) {
- reportOut(msg.toXML());
- return;
- }
+ assert(mSettings != nullptr);
// Alert only about unique errors
if (!mShownErrors.insert(msg.toString(mSettings->verbose)).second)
diff --git a/cli/cppcheckexecutor.h b/cli/cppcheckexecutor.h
index 1e94aa58d22..23e845e0e6f 100644
--- a/cli/cppcheckexecutor.h
+++ b/cli/cppcheckexecutor.h
@@ -46,7 +46,7 @@ class CppCheckExecutor : public ErrorLogger {
/**
* Constructor
*/
- CppCheckExecutor();
+ CppCheckExecutor() = default;
CppCheckExecutor(const CppCheckExecutor &) = delete;
void operator=(const CppCheckExecutor&) = delete;
@@ -154,7 +154,7 @@ class CppCheckExecutor : public ErrorLogger {
/**
* Pointer to current settings; set while check() is running for reportError().
*/
- const Settings* mSettings;
+ const Settings* mSettings{};
/**
* Used to filter out duplicate error messages.
@@ -169,7 +169,7 @@ class CppCheckExecutor : public ErrorLogger {
/**
* Report progress time
*/
- std::time_t mLatestProgressOutputTime;
+ std::time_t mLatestProgressOutputTime{};
/**
* Output file name for exception handler
@@ -179,12 +179,7 @@ class CppCheckExecutor : public ErrorLogger {
/**
* Error output
*/
- std::ofstream *mErrorOutput;
-
- /**
- * Has --errorlist been given?
- */
- bool mShowAllErrors;
+ std::ofstream* mErrorOutput{};
};
#endif // CPPCHECKEXECUTOR_H
diff --git a/cli/executor.cpp b/cli/executor.cpp
index 7185db07b73..489d9f8951b 100644
--- a/cli/executor.cpp
+++ b/cli/executor.cpp
@@ -27,8 +27,8 @@
#include // IWYU pragma: keep
#include
-Executor::Executor(const std::map &files, Settings &settings, ErrorLogger &errorLogger)
- : mFiles(files), mSettings(settings), mErrorLogger(errorLogger)
+Executor::Executor(const std::map &files, const Settings &settings, Suppressions &suppressions, ErrorLogger &errorLogger)
+ : mFiles(files), mSettings(settings), mSuppressions(suppressions), mErrorLogger(errorLogger)
{}
Executor::~Executor()
@@ -36,7 +36,7 @@ Executor::~Executor()
bool Executor::hasToLog(const ErrorMessage &msg)
{
- if (!mSettings.nomsg.isSuppressed(msg))
+ if (!mSuppressions.isSuppressed(msg))
{
std::string errmsg = msg.toString(mSettings.verbose);
diff --git a/cli/executor.h b/cli/executor.h
index f8f010c2d83..1b7db25e71e 100644
--- a/cli/executor.h
+++ b/cli/executor.h
@@ -28,6 +28,7 @@
class Settings;
class ErrorLogger;
class ErrorMessage;
+class Suppressions;
/// @addtogroup CLI
/// @{
@@ -38,7 +39,7 @@ class ErrorMessage;
*/
class Executor {
public:
- Executor(const std::map &files, Settings &settings, ErrorLogger &errorLogger);
+ Executor(const std::map &files, const Settings &settings, Suppressions &suppressions, ErrorLogger &errorLogger);
virtual ~Executor();
Executor(const Executor &) = delete;
@@ -65,7 +66,8 @@ class Executor {
bool hasToLog(const ErrorMessage &msg);
const std::map &mFiles;
- Settings &mSettings;
+ const Settings &mSettings;
+ Suppressions &mSuppressions;
ErrorLogger &mErrorLogger;
private:
diff --git a/cli/processexecutor.cpp b/cli/processexecutor.cpp
index e6aca40ee3a..be9c61d1548 100644
--- a/cli/processexecutor.cpp
+++ b/cli/processexecutor.cpp
@@ -61,8 +61,8 @@ enum class Color;
using std::memset;
-ProcessExecutor::ProcessExecutor(const std::map &files, Settings &settings, ErrorLogger &errorLogger)
- : Executor(files, settings, errorLogger)
+ProcessExecutor::ProcessExecutor(const std::map &files, const Settings &settings, Suppressions &suppressions, ErrorLogger &errorLogger)
+ : Executor(files, settings, suppressions, errorLogger)
{
assert(mSettings.jobs > 1);
}
@@ -280,9 +280,11 @@ unsigned int ProcessExecutor::check()
if (iFileSettings != mSettings.project.fileSettings.end()) {
resultOfCheck = fileChecker.check(*iFileSettings);
+ // TODO: call analyseClangTidy()
} else {
// Read file from a file
resultOfCheck = fileChecker.check(iFile->first);
+ // TODO: call analyseClangTidy()?
}
pipewriter.writeEnd(std::to_string(resultOfCheck));
@@ -391,7 +393,7 @@ void ProcessExecutor::reportInternalChildErr(const std::string &childname, const
"cppcheckError",
Certainty::normal);
- if (!mSettings.nomsg.isSuppressed(errmsg))
+ if (!mSuppressions.isSuppressed(errmsg))
mErrorLogger.reportErr(errmsg);
}
diff --git a/cli/processexecutor.h b/cli/processexecutor.h
index c472fe89500..4b51d596acc 100644
--- a/cli/processexecutor.h
+++ b/cli/processexecutor.h
@@ -27,6 +27,7 @@
class Settings;
class ErrorLogger;
+class Suppressions;
/// @addtogroup CLI
/// @{
@@ -37,7 +38,7 @@ class ErrorLogger;
*/
class ProcessExecutor : public Executor {
public:
- ProcessExecutor(const std::map &files, Settings &settings, ErrorLogger &errorLogger);
+ ProcessExecutor(const std::map &files, const Settings &settings, Suppressions &suppressions, ErrorLogger &errorLogger);
ProcessExecutor(const ProcessExecutor &) = delete;
~ProcessExecutor() override;
void operator=(const ProcessExecutor &) = delete;
diff --git a/cli/singleexecutor.cpp b/cli/singleexecutor.cpp
index ce7476f3d4c..c3fea886b24 100644
--- a/cli/singleexecutor.cpp
+++ b/cli/singleexecutor.cpp
@@ -30,8 +30,8 @@
class ErrorLogger;
-SingleExecutor::SingleExecutor(CppCheck &cppcheck, const std::map &files, Settings &settings, ErrorLogger &errorLogger)
- : Executor(files, settings, errorLogger)
+SingleExecutor::SingleExecutor(CppCheck &cppcheck, const std::map &files, const Settings &settings, Suppressions &suppressions, ErrorLogger &errorLogger)
+ : Executor(files, settings, suppressions, errorLogger)
, mCppcheck(cppcheck)
{
assert(mSettings.jobs == 1);
@@ -61,7 +61,7 @@ unsigned int SingleExecutor::check()
processedsize += i->second;
if (!mSettings.quiet)
reportStatus(c + 1, mFiles.size(), processedsize, totalfilesize);
- // TODO: call analyseClangTidy()
+ // TODO: call analyseClangTidy()?
c++;
}
}
@@ -92,7 +92,7 @@ unsigned int SingleExecutor::check()
processedsize += i->second;
if (!mSettings.quiet)
reportStatus(c + 1, mFiles.size(), processedsize, totalfilesize);
- // TODO: call analyseClangTidy()
+ // TODO: call analyseClangTidy()?
c++;
}
}
diff --git a/cli/singleexecutor.h b/cli/singleexecutor.h
index 74143be7c00..4ca53768b43 100644
--- a/cli/singleexecutor.h
+++ b/cli/singleexecutor.h
@@ -28,11 +28,12 @@
class ErrorLogger;
class Settings;
class CppCheck;
+class Suppressions;
class SingleExecutor : public Executor
{
public:
- SingleExecutor(CppCheck &cppcheck, const std::map &files, Settings &settings, ErrorLogger &errorLogger);
+ SingleExecutor(CppCheck &cppcheck, const std::map &files, const Settings &settings, Suppressions &suppressions, ErrorLogger &errorLogger);
SingleExecutor(const SingleExecutor &) = delete;
~SingleExecutor() override;
void operator=(const SingleExecutor &) = delete;
diff --git a/cli/threadexecutor.cpp b/cli/threadexecutor.cpp
index 8efdfeea76f..a6a9e671bd0 100644
--- a/cli/threadexecutor.cpp
+++ b/cli/threadexecutor.cpp
@@ -40,8 +40,8 @@
enum class Color;
-ThreadExecutor::ThreadExecutor(const std::map &files, Settings &settings, ErrorLogger &errorLogger)
- : Executor(files, settings, errorLogger)
+ThreadExecutor::ThreadExecutor(const std::map &files, const Settings &settings, Suppressions &suppressions, ErrorLogger &errorLogger)
+ : Executor(files, settings, suppressions, errorLogger)
{
assert(mSettings.jobs > 1);
}
@@ -85,7 +85,7 @@ class ThreadData
{
public:
ThreadData(ThreadExecutor &threadExecutor, ErrorLogger &errorLogger, const Settings &settings, const std::map &files, const std::list &fileSettings)
- : mFiles(files), mFileSettings(fileSettings), mProcessedFiles(0), mProcessedSize(0), mSettings(settings), logForwarder(threadExecutor, errorLogger)
+ : mFiles(files), mFileSettings(fileSettings), mSettings(settings), logForwarder(threadExecutor, errorLogger)
{
mItNextFile = mFiles.begin();
mItNextFileSettings = mFileSettings.begin();
@@ -129,6 +129,7 @@ class ThreadData
} else {
// Read file from a file
result = fileChecker.check(*file);
+ // TODO: call analyseClangTidy()?
}
return result;
}
@@ -147,10 +148,10 @@ class ThreadData
const std::list &mFileSettings;
std::list::const_iterator mItNextFileSettings;
- std::size_t mProcessedFiles;
- std::size_t mTotalFiles;
- std::size_t mProcessedSize;
- std::size_t mTotalFileSize;
+ std::size_t mProcessedFiles{};
+ std::size_t mTotalFiles{};
+ std::size_t mProcessedSize{};
+ std::size_t mTotalFileSize{};
std::mutex mFileSync;
const Settings &mSettings;
diff --git a/cli/threadexecutor.h b/cli/threadexecutor.h
index 5c24dfe0c13..62ad8e0a860 100644
--- a/cli/threadexecutor.h
+++ b/cli/threadexecutor.h
@@ -27,6 +27,7 @@
class Settings;
class ErrorLogger;
+class Suppressions;
/// @addtogroup CLI
/// @{
@@ -37,7 +38,7 @@ class ErrorLogger;
*/
class ThreadExecutor : public Executor {
public:
- ThreadExecutor(const std::map &files, Settings &settings, ErrorLogger &errorLogger);
+ ThreadExecutor(const std::map &files, const Settings &settings, Suppressions &suppressions, ErrorLogger &errorLogger);
ThreadExecutor(const ThreadExecutor &) = delete;
~ThreadExecutor() override;
void operator=(const ThreadExecutor &) = delete;
diff --git a/cmake/clang_tidy.cmake b/cmake/clang_tidy.cmake
index 07134ddaa9d..679c14cdb1b 100644
--- a/cmake/clang_tidy.cmake
+++ b/cmake/clang_tidy.cmake
@@ -9,7 +9,7 @@ if (NOT CMAKE_DISABLE_PRECOMPILE_HEADERS)
message(STATUS "Cannot use non-Clang compiler with clang-tidy when precompiled headers are enabled - skipping 'run-clang-tidy' target generation")
endif()
else()
- set(RUN_CLANG_TIDY_NAMES run-clang-tidy run-clang-tidy-16 run-clang-tidy-15 run-clang-tidy-14 run-clang-tidy-13 run-clang-tidy-12 run-clang-tidy-11 run-clang-tidy-10 run-clang-tidy-9 run-clang-tidy-8)
+ set(RUN_CLANG_TIDY_NAMES run-clang-tidy run-clang-tidy-17 run-clang-tidy-16 run-clang-tidy-15 run-clang-tidy-14 run-clang-tidy-13 run-clang-tidy-12 run-clang-tidy-11 run-clang-tidy-10 run-clang-tidy-9 run-clang-tidy-8)
endif()
if (RUN_CLANG_TIDY_NAMES)
diff --git a/cmake/compileroptions.cmake b/cmake/compileroptions.cmake
index 74256f5abde..e7d0a3bf787 100644
--- a/cmake/compileroptions.cmake
+++ b/cmake/compileroptions.cmake
@@ -73,14 +73,11 @@ elseif (CMAKE_CXX_COMPILER_ID MATCHES "Clang")
add_link_options(-lc++)
endif()
- add_compile_options_safe(-Wno-documentation-unknown-command)
-
# TODO: fix and enable these warnings - or move to suppression list below
+ add_compile_options_safe(-Wno-documentation-unknown-command) # TODO: Clang currently does not support all commands
add_compile_options_safe(-Wno-inconsistent-missing-destructor-override) # caused by Qt moc code
add_compile_options_safe(-Wno-unused-exception-parameter)
add_compile_options_safe(-Wno-old-style-cast)
- add_compile_options_safe(-Wno-global-constructors)
- add_compile_options_safe(-Wno-exit-time-destructors)
add_compile_options_safe(-Wno-sign-conversion)
add_compile_options_safe(-Wno-shadow-field-in-constructor)
add_compile_options_safe(-Wno-covered-switch-default)
@@ -102,16 +99,26 @@ elseif (CMAKE_CXX_COMPILER_ID MATCHES "Clang")
add_compile_options_safe(-Wno-tautological-type-limit-compare)
add_compile_options(-Wno-disabled-macro-expansion)
add_compile_options_safe(-Wno-bitwise-instead-of-logical)
+
+ # these cannot be fixed properly without adopting later C++ standards
add_compile_options_safe(-Wno-unsafe-buffer-usage)
+ add_compile_options_safe(-Wno-global-constructors)
+ add_compile_options_safe(-Wno-exit-time-destructors)
- # warnings we are not interested in
- add_compile_options(-Wno-four-char-constants)
- add_compile_options(-Wno-c++98-compat)
- add_compile_options(-Wno-weak-vtables)
+ # can only be partially addressed
add_compile_options(-Wno-padded)
+
+ # no need for C++98 compatibility
+ add_compile_options(-Wno-c++98-compat)
add_compile_options(-Wno-c++98-compat-pedantic)
+
+ # only need to be addressed to work around issues in older compilers
add_compile_options_safe(-Wno-return-std-move-in-c++11)
+ # warnings we are currently not interested in
+ add_compile_options(-Wno-four-char-constants)
+ add_compile_options(-Wno-weak-vtables)
+
if(ENABLE_COVERAGE OR ENABLE_COVERAGE_XML)
message(FATAL_ERROR "Do not use clang to generate code coverage. Use GCC instead.")
endif()
diff --git a/externals/tinyxml2/CMakeLists.txt b/externals/tinyxml2/CMakeLists.txt
index 6ec93e526f2..6ad63ecf0f0 100644
--- a/externals/tinyxml2/CMakeLists.txt
+++ b/externals/tinyxml2/CMakeLists.txt
@@ -17,5 +17,6 @@ if (CMAKE_CXX_COMPILER_ID MATCHES "Clang")
target_compile_options_safe(tinyxml2_objs -Wno-suggest-destructor-override)
target_compile_options_safe(tinyxml2_objs -Wno-zero-as-null-pointer-constant)
target_compile_options_safe(tinyxml2_objs -Wno-format-nonliteral)
+ target_compile_options_safe(tinyxml2_objs -Wno-old-style-cast)
endif()
diff --git a/gui/applicationlist.cpp b/gui/applicationlist.cpp
index 03079b1d7ed..dde03718fea 100644
--- a/gui/applicationlist.cpp
+++ b/gui/applicationlist.cpp
@@ -27,8 +27,7 @@
#include
ApplicationList::ApplicationList(QObject *parent) :
- QObject(parent),
- mDefaultApplicationIndex(-1)
+ QObject(parent)
{
//ctor
}
diff --git a/gui/applicationlist.h b/gui/applicationlist.h
index d7885a8bc2b..537ca51af35 100644
--- a/gui/applicationlist.h
+++ b/gui/applicationlist.h
@@ -133,7 +133,7 @@ class ApplicationList : public QObject {
* @brief Index of the default application.
*
*/
- int mDefaultApplicationIndex;
+ int mDefaultApplicationIndex = -1;
};
/// @}
#endif // APPLICATIONLIST_H
diff --git a/gui/checkthread.cpp b/gui/checkthread.cpp
index 480907a599f..b45f30c6eb0 100644
--- a/gui/checkthread.cpp
+++ b/gui/checkthread.cpp
@@ -84,10 +84,8 @@ static bool executeCommand(std::string exe, std::vector args, std::
CheckThread::CheckThread(ThreadResult &result) :
- mState(Ready),
mResult(result),
- mCppcheck(result, true, executeCommand),
- mAnalyseWholeProgram(false)
+ mCppcheck(result, true, executeCommand)
{
//ctor
}
diff --git a/gui/checkthread.h b/gui/checkthread.h
index 519d74923e0..d74ec2514a9 100644
--- a/gui/checkthread.h
+++ b/gui/checkthread.h
@@ -24,6 +24,8 @@
#include "importproject.h"
#include "suppressions.h"
+#include
+
#include
#include
#include
@@ -118,9 +120,9 @@ class CheckThread : public QThread {
};
/**
- * @brief Thread's current execution state.
+ * @brief Thread's current execution state. Can be changed from outside
*/
- State mState;
+ std::atomic mState{Ready};
ThreadResult &mResult;
/**
@@ -136,7 +138,7 @@ class CheckThread : public QThread {
bool isSuppressed(const Suppressions::ErrorMessage &errorMessage) const;
QStringList mFiles;
- bool mAnalyseWholeProgram;
+ bool mAnalyseWholeProgram{};
QStringList mAddonsAndTools;
QStringList mClangIncludePaths;
QList mSuppressions;
diff --git a/gui/codeeditorstyle.cpp b/gui/codeeditorstyle.cpp
index 85900d033df..fc981ad40ba 100644
--- a/gui/codeeditorstyle.cpp
+++ b/gui/codeeditorstyle.cpp
@@ -42,7 +42,6 @@ CodeEditorStyle::CodeEditorStyle(
// cppcheck-suppress naming-varname - TODO: fix this
QColor SymbFGColor, QColor SymbBGColor,
const QFont::Weight& SymbWeight) :
- mSystemTheme(false),
widgetFGColor(std::move(CtrlFGColor)),
widgetBGColor(std::move(CtrlBGColor)),
highlightBGColor(std::move(HiLiBGColor)),
diff --git a/gui/codeeditorstyle.h b/gui/codeeditorstyle.h
index aee3d028cfe..392602b9a07 100644
--- a/gui/codeeditorstyle.h
+++ b/gui/codeeditorstyle.h
@@ -81,7 +81,7 @@ class CodeEditorStyle {
static void saveSettings(QSettings *settings, const CodeEditorStyle& theStyle);
public:
- bool mSystemTheme;
+ bool mSystemTheme{};
QColor widgetFGColor;
QColor widgetBGColor;
QColor highlightBGColor;
diff --git a/gui/codeeditstylecontrols.cpp b/gui/codeeditstylecontrols.cpp
index 186d76c1e42..8cd4465c568 100644
--- a/gui/codeeditstylecontrols.cpp
+++ b/gui/codeeditstylecontrols.cpp
@@ -69,8 +69,7 @@ const QColor& SelectColorButton::getColor()
}
SelectFontWeightCombo::SelectFontWeightCombo(QWidget* parent) :
- QComboBox(parent),
- mWeight(QFont::Normal)
+ QComboBox(parent)
{
addItem(QObject::tr("Thin"),
QVariant(static_cast(QFont::Thin)));
diff --git a/gui/codeeditstylecontrols.h b/gui/codeeditstylecontrols.h
index b624d0e8d41..7e87c7b5fc0 100644
--- a/gui/codeeditstylecontrols.h
+++ b/gui/codeeditstylecontrols.h
@@ -71,7 +71,7 @@ public slots:
void changeWeight(int index);
private:
- QFont::Weight mWeight;
+ QFont::Weight mWeight = QFont::Normal;
};
#endif //CODEEDITORSTYLECONTROLS_H
diff --git a/gui/cppchecklibrarydata.h b/gui/cppchecklibrarydata.h
index e0360534e34..252d66920ba 100644
--- a/gui/cppchecklibrarydata.h
+++ b/gui/cppchecklibrarydata.h
@@ -33,8 +33,6 @@ class CppcheckLibraryData {
CppcheckLibraryData();
struct Container {
- Container() : access_arrayLike(false), size_templateParameter(-1) {}
-
QString id;
QString inherits;
QString startPattern;
@@ -42,8 +40,8 @@ class CppcheckLibraryData {
QString opLessAllowed;
QString itEndPattern;
- bool access_arrayLike;
- int size_templateParameter;
+ bool access_arrayLike{};
+ int size_templateParameter = -1;
struct {
QString templateParameter;
@@ -72,21 +70,17 @@ class CppcheckLibraryData {
};
struct Function {
- Function() : noreturn(Unknown), gccPure(false), gccConst(false),
- leakignore(false), useretval(false) {}
-
QString comments;
QString name;
- enum TrueFalseUnknown { False, True, Unknown } noreturn;
- bool gccPure;
- bool gccConst;
- bool leakignore;
- bool useretval;
+ enum TrueFalseUnknown { False, True, Unknown } noreturn = Unknown;
+ bool gccPure{};
+ bool gccConst{};
+ bool leakignore{};
+ bool useretval{};
struct ReturnValue {
- ReturnValue() : container(-1) {}
QString type;
QString value;
- int container;
+ int container = -1;
bool empty() const {
return type.isNull() && value.isNull() && container < 0;
}
@@ -96,19 +90,16 @@ class CppcheckLibraryData {
QString secure;
} formatstr;
struct Arg {
- Arg() : nr(0), notbool(false), notnull(false), notuninit(false),
- formatstr(false), strz(false) {}
-
QString name;
- unsigned int nr;
+ unsigned int nr{};
static const unsigned int ANY;
static const unsigned int VARIADIC;
QString defaultValue;
- bool notbool;
- bool notnull;
- bool notuninit;
- bool formatstr;
- bool strz;
+ bool notbool{};
+ bool notnull{};
+ bool notuninit{};
+ bool formatstr{};
+ bool strz{};
QString valid;
struct MinSize {
QString type;
@@ -117,8 +108,7 @@ class CppcheckLibraryData {
};
QList minsizes;
struct Iterator {
- Iterator() : container(-1) {}
- int container;
+ int container = -1;
QString type;
} iterator;
};
@@ -147,26 +137,15 @@ class CppcheckLibraryData {
struct MemoryResource {
QString type; // "memory" or "resource"
struct Alloc {
- Alloc() :
- isRealloc(false),
- init(false),
- arg(-1), // -1: Has no optional "arg" attribute
- reallocArg(-1) // -1: Has no optional "realloc-arg" attribute
- {}
-
- bool isRealloc;
- bool init;
- int arg;
- int reallocArg;
+ bool isRealloc{};
+ bool init{};
+ int arg = -1; // -1: Has no optional "realloc-arg" attribute
+ int reallocArg = -1; // -1: Has no optional "arg" attribute
QString bufferSize;
QString name;
};
struct Dealloc {
- Dealloc() :
- arg(-1) // -1: Has no optional "arg" attribute
- {}
-
- int arg;
+ int arg = -1; // -1: Has no optional "arg" attribute
QString name;
};
@@ -193,11 +172,7 @@ class CppcheckLibraryData {
struct Reflection {
struct Call {
- Call() :
- arg {-1} // -1: Mandatory "arg" attribute not available
- {}
-
- int arg;
+ int arg = -1; // -1: Mandatory "arg" attribute not available
QString name;
};
@@ -206,12 +181,8 @@ class CppcheckLibraryData {
struct Markup {
struct CodeBlocks {
- CodeBlocks() :
- offset {-1}
- {}
-
QStringList blocks;
- int offset;
+ int offset = -1;
QString start;
QString end;
};
@@ -223,8 +194,8 @@ class CppcheckLibraryData {
};
QString ext;
- bool afterCode;
- bool reportErrors;
+ bool afterCode{};
+ bool reportErrors{};
QStringList keywords;
QStringList importer;
QList codeBlocks;
@@ -232,12 +203,8 @@ class CppcheckLibraryData {
};
struct SmartPointer {
- SmartPointer() :
- unique {false}
- {}
-
QString name;
- bool unique;
+ bool unique{};
};
struct Entrypoint {
diff --git a/gui/helpdialog.h b/gui/helpdialog.h
index a5dc0b43039..075005fd8f2 100644
--- a/gui/helpdialog.h
+++ b/gui/helpdialog.h
@@ -34,7 +34,7 @@ namespace Ui {
class HelpBrowser : public QTextBrowser {
public:
- explicit HelpBrowser(QWidget* parent = nullptr) : QTextBrowser(parent), mHelpEngine(nullptr) {}
+ explicit HelpBrowser(QWidget* parent = nullptr) : QTextBrowser(parent) {}
HelpBrowser(const HelpBrowser&) = delete;
HelpBrowser(HelpBrowser&&) = delete;
HelpBrowser& operator=(const HelpBrowser&) = delete;
@@ -42,7 +42,7 @@ class HelpBrowser : public QTextBrowser {
void setHelpEngine(QHelpEngine *helpEngine);
QVariant loadResource(int type, const QUrl& name) override;
private:
- QHelpEngine* mHelpEngine;
+ QHelpEngine* mHelpEngine{};
};
class HelpDialog : public QDialog {
diff --git a/gui/librarydialog.cpp b/gui/librarydialog.cpp
index e077a6b7677..47545679922 100644
--- a/gui/librarydialog.cpp
+++ b/gui/librarydialog.cpp
@@ -61,8 +61,7 @@ class FunctionListItem : public QListWidgetItem {
LibraryDialog::LibraryDialog(QWidget *parent) :
QDialog(parent),
- mUi(new Ui::LibraryDialog),
- mIgnoreChanges(false)
+ mUi(new Ui::LibraryDialog)
{
mUi->setupUi(this);
mUi->buttonSave->setEnabled(false);
diff --git a/gui/librarydialog.h b/gui/librarydialog.h
index d8dd3c247c1..ac27d42756c 100644
--- a/gui/librarydialog.h
+++ b/gui/librarydialog.h
@@ -56,7 +56,7 @@ private slots:
Ui::LibraryDialog *mUi;
CppcheckLibraryData mData;
QString mFileName;
- bool mIgnoreChanges;
+ bool mIgnoreChanges{};
static QString getArgText(const CppcheckLibraryData::Function::Arg &arg);
CppcheckLibraryData::Function *currentFunction();
diff --git a/gui/mainwindow.cpp b/gui/mainwindow.cpp
index 814ec585d8a..2840c48330d 100644
--- a/gui/mainwindow.cpp
+++ b/gui/mainwindow.cpp
@@ -109,14 +109,10 @@ MainWindow::MainWindow(TranslationHandler* th, QSettings* settings) :
mApplications(new ApplicationList(this)),
mTranslation(th),
mUI(new Ui::MainWindow),
- mScratchPad(nullptr),
- mProjectFile(nullptr),
mPlatformActions(new QActionGroup(this)),
mCStandardActions(new QActionGroup(this)),
mCppStandardActions(new QActionGroup(this)),
- mSelectLanguageActions(new QActionGroup(this)),
- mExiting(false),
- mIsLogfileLoaded(false)
+ mSelectLanguageActions(new QActionGroup(this))
{
{
Settings tempSettings;
diff --git a/gui/mainwindow.h b/gui/mainwindow.h
index ab7d45d6428..78782b22bdd 100644
--- a/gui/mainwindow.h
+++ b/gui/mainwindow.h
@@ -437,10 +437,10 @@ private slots:
QString mCurrentDirectory;
/** @brief Scratchpad. */
- ScratchPad* mScratchPad;
+ ScratchPad* mScratchPad{};
/** @brief Project (file). */
- ProjectFile *mProjectFile;
+ ProjectFile* mProjectFile{};
/** @brief Filter field in the Filter toolbar. */
QLineEdit* mLineEditFilter;
@@ -462,10 +462,10 @@ private slots:
* If this is true then the cppcheck is waiting for check threads to exit
* so that the application can be closed.
*/
- bool mExiting;
+ bool mExiting{};
/** @brief Set to true in case of loading log file. */
- bool mIsLogfileLoaded;
+ bool mIsLogfileLoaded{};
/**
* @brief Project MRU menu actions.
diff --git a/gui/report.cpp b/gui/report.cpp
index 9a4c391fd0b..e7b7e06edf9 100644
--- a/gui/report.cpp
+++ b/gui/report.cpp
@@ -23,7 +23,6 @@
#include
Report::Report(QString filename) :
- QObject(),
mFilename(std::move(filename))
{}
diff --git a/gui/resultstree.cpp b/gui/resultstree.cpp
index 241322c18ae..61f995e6bf4 100644
--- a/gui/resultstree.cpp
+++ b/gui/resultstree.cpp
@@ -81,19 +81,7 @@ static const int COLUMN_SINCE_DATE = 6;
static const int COLUMN_TAGS = 7;
ResultsTree::ResultsTree(QWidget * parent) :
- QTreeView(parent),
- mSettings(nullptr),
- mApplications(nullptr),
- mContextItem(nullptr),
- mShowFullPath(false),
- mSaveFullPath(false),
- mSaveAllErrors(true),
- mShowErrorId(false),
- mVisibleErrors(false),
- mSelectionModel(nullptr),
- mThread(nullptr),
- mShowCppcheck(true),
- mShowClang(true)
+ QTreeView(parent)
{
setModel(&mModel);
translate(); // Adds columns to grid
diff --git a/gui/resultstree.h b/gui/resultstree.h
index 1e67dca9710..5828c0e383b 100644
--- a/gui/resultstree.h
+++ b/gui/resultstree.h
@@ -453,7 +453,7 @@ protected slots:
* @brief Program settings
*
*/
- QSettings *mSettings;
+ QSettings* mSettings{};
/**
* @brief A string used to filter the results for display.
@@ -465,37 +465,37 @@ protected slots:
* @brief List of applications to open errors with
*
*/
- ApplicationList *mApplications;
+ ApplicationList* mApplications{};
/**
* @brief Right clicked item (used by context menu slots)
*
*/
- QStandardItem *mContextItem;
+ QStandardItem* mContextItem{};
/**
* @brief Should full path of files be shown (true) or relative (false)
*
*/
- bool mShowFullPath;
+ bool mShowFullPath{};
/**
* @brief Should full path of files be saved
*
*/
- bool mSaveFullPath;
+ bool mSaveFullPath{};
/**
* @brief Save all errors (true) or only visible (false)
*
*/
- bool mSaveAllErrors;
+ bool mSaveAllErrors = true;
/**
* @brief true if optional column "Id" is shown
*
*/
- bool mShowErrorId;
+ bool mShowErrorId{};
/**
* @brief Path we are currently checking
@@ -507,7 +507,7 @@ protected slots:
* @brief Are there any visible errors
*
*/
- bool mVisibleErrors;
+ bool mVisibleErrors{};
private:
/** tag selected items */
@@ -518,11 +518,11 @@ protected slots:
QStringList mHiddenMessageId;
- QItemSelectionModel *mSelectionModel;
- ThreadHandler *mThread;
+ QItemSelectionModel* mSelectionModel{};
+ ThreadHandler *mThread{};
- bool mShowCppcheck;
- bool mShowClang;
+ bool mShowCppcheck = true;
+ bool mShowClang = true;
};
/// @}
#endif // RESULTSTREE_H
diff --git a/gui/resultsview.cpp b/gui/resultsview.cpp
index 2ee37ae9493..6c57e8c159a 100644
--- a/gui/resultsview.cpp
+++ b/gui/resultsview.cpp
@@ -67,7 +67,6 @@
ResultsView::ResultsView(QWidget * parent) :
QWidget(parent),
- mShowNoErrorsMessage(true),
mUI(new Ui::ResultsView),
mStatistics(new CheckStatistics(this))
{
diff --git a/gui/resultsview.h b/gui/resultsview.h
index f07c588732a..b44adfd0782 100644
--- a/gui/resultsview.h
+++ b/gui/resultsview.h
@@ -344,7 +344,7 @@ public slots:
/**
* @brief Should we show a "No errors found dialog" every time no errors were found?
*/
- bool mShowNoErrorsMessage;
+ bool mShowNoErrorsMessage = true;
Ui::ResultsView *mUI;
diff --git a/gui/statsdialog.cpp b/gui/statsdialog.cpp
index 7b8db7ca66d..4f5ce9a85bf 100644
--- a/gui/statsdialog.cpp
+++ b/gui/statsdialog.cpp
@@ -71,8 +71,7 @@ static const QString CPPCHECK("cppcheck");
StatsDialog::StatsDialog(QWidget *parent)
: QDialog(parent),
- mUI(new Ui::StatsDialog),
- mStatistics(nullptr)
+ mUI(new Ui::StatsDialog)
{
mUI->setupUi(this);
diff --git a/gui/statsdialog.h b/gui/statsdialog.h
index 1b7f41d0e06..62c93fcab58 100644
--- a/gui/statsdialog.h
+++ b/gui/statsdialog.h
@@ -73,7 +73,7 @@ private slots:
void pdfExport();
private:
Ui::StatsDialog *mUI;
- const CheckStatistics *mStatistics;
+ const CheckStatistics* mStatistics{};
};
/// @}
diff --git a/gui/test/projectfile/testprojectfile.cpp b/gui/test/projectfile/testprojectfile.cpp
index 95cbe9404bd..cbd98dc86ca 100644
--- a/gui/test/projectfile/testprojectfile.cpp
+++ b/gui/test/projectfile/testprojectfile.cpp
@@ -39,9 +39,8 @@ const char Settings::SafeChecks::XmlClasses[] = "class-public";
const char Settings::SafeChecks::XmlExternalFunctions[] = "external-functions";
const char Settings::SafeChecks::XmlInternalFunctions[] = "internal-functions";
const char Settings::SafeChecks::XmlExternalVariables[] = "external-variables";
-Settings::Settings() : maxCtuDepth(10), maxTemplateRecursion(100) {}
+Settings::Settings() : maxCtuDepth(10) {}
cppcheck::Platform::Platform() {}
-Library::Library() {}
ImportProject::ImportProject() {}
bool ImportProject::sourceFileExists(const std::string & /*file*/) {
return true;
diff --git a/gui/threadhandler.cpp b/gui/threadhandler.cpp
index fddb3348022..6e99afe0488 100644
--- a/gui/threadhandler.cpp
+++ b/gui/threadhandler.cpp
@@ -36,11 +36,7 @@
#include
ThreadHandler::ThreadHandler(QObject *parent) :
- QObject(parent),
- mScanDuration(0),
- mRunningThreadCount(0),
- mAnalyseWholeProgram(false)
-
+ QObject(parent)
{
setThreadCount(1);
}
@@ -152,7 +148,10 @@ void ThreadHandler::setThreadCount(const int count)
void ThreadHandler::removeThreads()
{
for (CheckThread* thread : mThreads) {
- thread->terminate();
+ if (thread->isRunning()) {
+ thread->terminate();
+ thread->wait();
+ }
disconnect(thread, &CheckThread::done,
this, &ThreadHandler::threadDone);
disconnect(thread, &CheckThread::fileChecked,
diff --git a/gui/threadhandler.h b/gui/threadhandler.h
index 93d30893d2a..cdf2a6f0261 100644
--- a/gui/threadhandler.h
+++ b/gui/threadhandler.h
@@ -230,7 +230,7 @@ protected slots:
* @brief The previous scan duration in milliseconds.
*
*/
- int mScanDuration;
+ int mScanDuration{};
/**
* @brief Function to delete all threads
@@ -254,9 +254,9 @@ protected slots:
* @brief The amount of threads currently running
*
*/
- int mRunningThreadCount;
+ int mRunningThreadCount{};
- bool mAnalyseWholeProgram;
+ bool mAnalyseWholeProgram{};
QStringList mAddonsAndTools;
QList mSuppressions;
diff --git a/gui/threadresult.cpp b/gui/threadresult.cpp
index f32da9b1c74..5e1aed89b78 100644
--- a/gui/threadresult.cpp
+++ b/gui/threadresult.cpp
@@ -28,11 +28,6 @@
#include
#include
-ThreadResult::ThreadResult() : QObject(), ErrorLogger(), mMaxProgress(0), mProgress(0), mFilesChecked(0), mTotalFiles(0)
-{
- //ctor
-}
-
ThreadResult::~ThreadResult()
{
//dtor
diff --git a/gui/threadresult.h b/gui/threadresult.h
index 9a3c5895375..f08bb945230 100644
--- a/gui/threadresult.h
+++ b/gui/threadresult.h
@@ -45,7 +45,7 @@ class ErrorItem;
class ThreadResult : public QObject, public ErrorLogger {
Q_OBJECT
public:
- ThreadResult();
+ ThreadResult() = default;
~ThreadResult() override;
/**
@@ -142,25 +142,25 @@ public slots:
* @brief Max progress
*
*/
- quint64 mMaxProgress;
+ quint64 mMaxProgress{};
/**
* @brief Current progress
*
*/
- quint64 mProgress;
+ quint64 mProgress{};
/**
* @brief Current number of files checked
*
*/
- unsigned long mFilesChecked;
+ unsigned long mFilesChecked{};
/**
* @brief Total number of files
*
*/
- unsigned long mTotalFiles;
+ unsigned long mTotalFiles{};
};
/// @}
#endif // THREADRESULT_H
diff --git a/gui/translationhandler.cpp b/gui/translationhandler.cpp
index 0a0aefd0763..6b14b6241fb 100644
--- a/gui/translationhandler.cpp
+++ b/gui/translationhandler.cpp
@@ -42,8 +42,7 @@ static UNUSED void unused()
TranslationHandler::TranslationHandler(QObject *parent) :
QObject(parent),
- mCurrentLanguage("en"),
- mTranslator(nullptr)
+ mCurrentLanguage("en")
{
// Add our available languages
// Keep this list sorted
diff --git a/gui/translationhandler.h b/gui/translationhandler.h
index 66effc5ed40..e9ff8722058 100644
--- a/gui/translationhandler.h
+++ b/gui/translationhandler.h
@@ -135,7 +135,7 @@ class TranslationHandler : QObject {
* @brief Translator class instance.
*
*/
- QTranslator *mTranslator;
+ QTranslator* mTranslator{};
};
/// @}
diff --git a/lib/analyzer.h b/lib/analyzer.h
index 51da0281f69..3c65e0e68de 100644
--- a/lib/analyzer.h
+++ b/lib/analyzer.h
@@ -32,7 +32,7 @@ class ValuePtr;
struct Analyzer {
struct Action {
- Action() : mFlag(0) {}
+ Action() = default;
template ),
@@ -125,7 +125,7 @@ struct Analyzer {
}
private:
- unsigned int mFlag;
+ unsigned int mFlag{};
};
enum class Terminate { None, Bail, Escape, Modified, Inconclusive, Conditional };
diff --git a/lib/astutils.cpp b/lib/astutils.cpp
index 94307ab276f..ca7c08af30a 100644
--- a/lib/astutils.cpp
+++ b/lib/astutils.cpp
@@ -2188,7 +2188,7 @@ T* getTokenArgumentFunctionImpl(T* tok, int& argn)
argn = -1;
{
T* parent = tok->astParent();
- if (parent && parent->isUnaryOp("&"))
+ if (parent && (parent->isUnaryOp("&") || parent->isIncDecOp()))
parent = parent->astParent();
while (parent && parent->isCast())
parent = parent->astParent();
@@ -2196,7 +2196,7 @@ T* getTokenArgumentFunctionImpl(T* tok, int& argn)
parent = parent->astParent();
// passing variable to subfunction?
- if (Token::Match(parent, "[[(,{]"))
+ if (Token::Match(parent, "[*[(,{]"))
;
else if (Token::simpleMatch(parent, ":")) {
while (Token::Match(parent, "[?:]"))
@@ -2347,6 +2347,10 @@ bool isVariableChangedByFunctionCall(const Token *tok, int indirect, const Setti
if (addressOf)
indirect++;
+ const bool deref = tok->astParent() && tok->astParent()->isUnaryOp("*");
+ if (deref && indirect > 0)
+ indirect--;
+
int argnr;
tok = getTokenArgumentFunction(tok, argnr);
if (!tok)
@@ -2455,7 +2459,7 @@ bool isVariableChanged(const Token *tok, int indirect, const Settings *settings,
(Token::simpleMatch(tok2->astParent(), ":") && Token::simpleMatch(tok2->astParent()->astParent(), "?")))
tok2 = tok2->astParent();
- if (tok2->astParent() && tok2->astParent()->tokType() == Token::eIncDecOp)
+ if (indirect == 0 && tok2->astParent() && tok2->astParent()->tokType() == Token::eIncDecOp)
return true;
auto skipRedundantPtrOp = [](const Token* tok, const Token* parent) {
@@ -2578,7 +2582,7 @@ bool isVariableChanged(const Token *tok, int indirect, const Settings *settings,
const Token *parent = tok2->astParent();
while (Token::Match(parent, ".|::"))
parent = parent->astParent();
- if (parent && parent->tokType() == Token::eIncDecOp)
+ if (parent && parent->tokType() == Token::eIncDecOp && (indirect == 0 || tok2 != tok))
return true;
// structured binding, nonconst reference variable in lhs
@@ -2615,7 +2619,7 @@ bool isVariableChanged(const Token *tok, int indirect, const Settings *settings,
if (indirect > 0) {
// check for `*(ptr + 1) = new_value` case
parent = tok2->astParent();
- while (parent && parent->isArithmeticalOp() && parent->isBinaryOp()) {
+ while (parent && ((parent->isArithmeticalOp() && parent->isBinaryOp()) || parent->isIncDecOp())) {
parent = parent->astParent();
}
if (Token::simpleMatch(parent, "*")) {
@@ -2839,8 +2843,9 @@ bool isExpressionChanged(const Token* expr, const Token* start, const Token* end
if (vt->type == ValueType::ITERATOR)
++indirect;
}
- if (isExpressionChangedAt(tok, tok2, indirect, global, settings, cpp, depth))
- return true;
+ for (int i = 0; i <= indirect; ++i)
+ if (isExpressionChangedAt(tok, tok2, i, global, settings, cpp, depth))
+ return true;
}
}
return false;
diff --git a/lib/calculate.h b/lib/calculate.h
index 3e62e212b21..96520cc629f 100644
--- a/lib/calculate.h
+++ b/lib/calculate.h
@@ -36,7 +36,7 @@ inline bool isEqual(double x, double y)
}
inline bool isEqual(float x, float y)
{
- return isEqual(double{x}, double{y});
+ return isEqual(double(x), double(y));
}
template
diff --git a/lib/check.cpp b/lib/check.cpp
index f01d938a699..bc67e683dfc 100644
--- a/lib/check.cpp
+++ b/lib/check.cpp
@@ -35,7 +35,7 @@
//---------------------------------------------------------------------------
Check::Check(const std::string &aname)
- : mTokenizer(nullptr), mSettings(nullptr), mErrorLogger(nullptr), mName(aname)
+ : mName(aname)
{
{
const auto it = std::find_if(instances().begin(), instances().end(), [&](const Check *i) {
diff --git a/lib/check.h b/lib/check.h
index 2f29d9b1db5..39e34781505 100644
--- a/lib/check.h
+++ b/lib/check.h
@@ -130,9 +130,9 @@ class CPPCHECKLIB Check {
static std::string getMessageId(const ValueFlow::Value &value, const char id[]);
protected:
- const Tokenizer * const mTokenizer;
- const Settings * const mSettings;
- ErrorLogger * const mErrorLogger;
+ const Tokenizer* const mTokenizer{};
+ const Settings* const mSettings{};
+ ErrorLogger* const mErrorLogger{};
/** report an error */
void reportError(const Token *tok, const Severity::SeverityType severity, const std::string &id, const std::string &msg) {
diff --git a/lib/checkclass.cpp b/lib/checkclass.cpp
index 781b04e2cea..662a6707619 100644
--- a/lib/checkclass.cpp
+++ b/lib/checkclass.cpp
@@ -1055,12 +1055,9 @@ void CheckClass::initializeVarList(const Function &func, std::list stl_containers_not_const;
private:
- const SymbolDatabase *mSymbolDatabase;
+ const SymbolDatabase* mSymbolDatabase{};
// Reporting errors..
void noConstructorError(const Token *tok, const std::string &classname, bool isStruct);
@@ -330,16 +330,16 @@ class CPPCHECKLIB CheckClass : public Check {
// constructors helper function
/** @brief Information about a member variable. Used when checking for uninitialized variables */
struct Usage {
- explicit Usage(const Variable *var) : var(var), assign(false), init(false) {}
+ explicit Usage(const Variable *var) : var(var) {}
/** Variable that this usage is for */
const Variable *var;
/** @brief has this variable been assigned? */
- bool assign;
+ bool assign{};
/** @brief has this variable been initialized? */
- bool init;
+ bool init{};
};
static bool isBaseClassMutableMemberFunc(const Token *tok, const Scope *scope);
diff --git a/lib/checkcondition.cpp b/lib/checkcondition.cpp
index a0799b4b41c..477719d3e6d 100644
--- a/lib/checkcondition.cpp
+++ b/lib/checkcondition.cpp
@@ -981,7 +981,7 @@ T getvalue3(const T value1, const T value2)
template<>
double getvalue3(const double value1, const double value2)
{
- return (value1 + value2) / 2.0f;
+ return (value1 + value2) / 2.0;
}
diff --git a/lib/checkio.cpp b/lib/checkio.cpp
index 2a0fdc4d483..dc14c0832a7 100644
--- a/lib/checkio.cpp
+++ b/lib/checkio.cpp
@@ -106,14 +106,14 @@ static OpenMode getMode(const std::string& str)
struct Filepointer {
OpenMode mode;
- nonneg int mode_indent;
- enum class Operation {NONE, UNIMPORTANT, READ, WRITE, POSITIONING, OPEN, CLOSE, UNKNOWN_OP} lastOperation;
- nonneg int op_indent;
+ nonneg int mode_indent{};
+ enum class Operation {NONE, UNIMPORTANT, READ, WRITE, POSITIONING, OPEN, CLOSE, UNKNOWN_OP} lastOperation = Operation::NONE;
+ nonneg int op_indent{};
enum class AppendMode { UNKNOWN_AM, APPEND, APPEND_EX };
- AppendMode append_mode;
+ AppendMode append_mode = AppendMode::UNKNOWN_AM;
std::string filename;
explicit Filepointer(OpenMode mode_ = OpenMode::UNKNOWN_OM)
- : mode(mode_), mode_indent(0), lastOperation(Operation::NONE), op_indent(0), append_mode(AppendMode::UNKNOWN_AM) {}
+ : mode(mode_) {}
};
namespace {
@@ -1331,14 +1331,7 @@ void CheckIO::checkFormatString(const Token * const tok,
/// @todo add non-string literals, and generic expressions
CheckIO::ArgumentInfo::ArgumentInfo(const Token * arg, const Settings *settings, bool _isCPP)
- : variableInfo(nullptr)
- , typeToken(nullptr)
- , functionInfo(nullptr)
- , tempToken(nullptr)
- , element(false)
- , _template(false)
- , address(false)
- , isCPP(_isCPP)
+ : isCPP(_isCPP)
{
if (!arg)
return;
diff --git a/lib/checkio.h b/lib/checkio.h
index 9e9b07a2581..29c3344d5c1 100644
--- a/lib/checkio.h
+++ b/lib/checkio.h
@@ -86,14 +86,14 @@ class CPPCHECKLIB CheckIO : public Check {
bool isStdContainer(const Token *tok);
bool isLibraryType(const Settings *settings) const;
- const Variable *variableInfo;
- const Token *typeToken;
- const Function *functionInfo;
- Token *tempToken;
- bool element;
- bool _template;
- bool address;
- bool isCPP;
+ const Variable* variableInfo{};
+ const Token* typeToken{};
+ const Function* functionInfo{};
+ Token* tempToken{};
+ bool element{};
+ bool _template{};
+ bool address{};
+ bool isCPP{};
};
void checkFormatString(const Token * const tok,
diff --git a/lib/checkother.cpp b/lib/checkother.cpp
index cf421268bca..f11a523a940 100644
--- a/lib/checkother.cpp
+++ b/lib/checkother.cpp
@@ -1587,9 +1587,10 @@ void CheckOther::checkConstPointer()
if (std::find(nonConstPointers.cbegin(), nonConstPointers.cend(), var) != nonConstPointers.cend())
continue;
pointers.emplace_back(var);
- const Token* const parent = tok->astParent();
+ const Token* parent = tok->astParent();
enum Deref { NONE, DEREF, MEMBER } deref = NONE;
- if (parent && parent->isUnaryOp("*"))
+ bool hasIncDec = false;
+ if (parent && (parent->isUnaryOp("*") || (hasIncDec = parent->isIncDecOp() && parent->astParent() && parent->astParent()->isUnaryOp("*"))))
deref = DEREF;
else if (Token::simpleMatch(parent, "[") && parent->astOperand1() == tok && tok != nameTok)
deref = DEREF;
@@ -1600,7 +1601,7 @@ void CheckOther::checkConstPointer()
else if (astIsRangeBasedForDecl(tok))
continue;
if (deref != NONE) {
- const Token* const gparent = parent->astParent();
+ const Token* gparent = parent->astParent();
if (deref == MEMBER) {
if (!gparent)
continue;
@@ -1613,6 +1614,10 @@ void CheckOther::checkConstPointer()
}
if (Token::Match(gparent, "%cop%") && !gparent->isUnaryOp("&") && !gparent->isUnaryOp("*"))
continue;
+ if (hasIncDec) {
+ parent = gparent;
+ gparent = gparent ? gparent->astParent() : nullptr;
+ }
int argn = -1;
if (Token::simpleMatch(gparent, "return")) {
const Function* function = gparent->scope()->function;
@@ -1633,7 +1638,7 @@ void CheckOther::checkConstPointer()
continue;
else if (const Token* ftok = getTokenArgumentFunction(parent, argn)) {
bool inconclusive{};
- if (!isVariableChangedByFunctionCall(ftok, vt->pointer, var->declarationId(), mSettings, &inconclusive) && !inconclusive)
+ if (!isVariableChangedByFunctionCall(ftok->next(), vt->pointer, var->declarationId(), mSettings, &inconclusive) && !inconclusive)
continue;
}
} else {
diff --git a/lib/checkuninitvar.h b/lib/checkuninitvar.h
index 8c4ccbccba0..fbb645e07ca 100644
--- a/lib/checkuninitvar.h
+++ b/lib/checkuninitvar.h
@@ -48,9 +48,9 @@ namespace tinyxml2 {
struct VariableValue {
- explicit VariableValue(MathLib::bigint val = 0) : value(val), notEqual(false) {}
+ explicit VariableValue(MathLib::bigint val = 0) : value(val) {}
MathLib::bigint value;
- bool notEqual;
+ bool notEqual{};
};
/// @addtogroup Checks
diff --git a/lib/checkunusedfunctions.h b/lib/checkunusedfunctions.h
index d635b817d3e..af008a17bd6 100644
--- a/lib/checkunusedfunctions.h
+++ b/lib/checkunusedfunctions.h
@@ -101,14 +101,11 @@ class CPPCHECKLIB CheckUnusedFunctions : public Check {
return "Check for functions that are never called\n";
}
- class CPPCHECKLIB FunctionUsage {
- public:
- FunctionUsage() : lineNumber(0), usedSameFile(false), usedOtherFile(false) {}
-
+ struct CPPCHECKLIB FunctionUsage {
std::string filename;
- unsigned int lineNumber;
- bool usedSameFile;
- bool usedOtherFile;
+ unsigned int lineNumber{};
+ bool usedSameFile{};
+ bool usedOtherFile{};
};
std::unordered_map mFunctions;
diff --git a/lib/checkunusedvar.cpp b/lib/checkunusedvar.cpp
index bd42a61824c..68366756fe8 100644
--- a/lib/checkunusedvar.cpp
+++ b/lib/checkunusedvar.cpp
@@ -635,7 +635,7 @@ static bool isPartOfClassStructUnion(const Token* tok)
if (tok->str() == "}" || tok->str() == ")")
tok = tok->link();
else if (tok->str() == "(")
- return (false);
+ return false;
else if (tok->str() == "{") {
return (tok->strAt(-1) == "struct" || tok->strAt(-2) == "struct" || tok->strAt(-1) == "class" || tok->strAt(-2) == "class" || tok->strAt(-1) == "union" || tok->strAt(-2) == "union");
}
@@ -1691,8 +1691,8 @@ bool CheckUnusedVar::isFunctionWithoutSideEffects(const Function& func, const To
}
// check if global variable is changed
if (bodyVariable->isGlobal() || (pointersToGlobals.find(bodyVariable) != pointersToGlobals.end())) {
- const int depth = 20;
- if (isVariableChanged(bodyToken, depth, mSettings, mTokenizer->isCPP())) {
+ const int indirect = bodyVariable->isArray() ? bodyVariable->dimensions().size() : bodyVariable->isPointer();
+ if (isVariableChanged(bodyToken, indirect, mSettings, mTokenizer->isCPP())) {
return false;
}
// check if pointer to global variable assigned to another variable (another_var = &global_var)
diff --git a/lib/clangimport.cpp b/lib/clangimport.cpp
index 328d6527507..7b91d6c4b07 100644
--- a/lib/clangimport.cpp
+++ b/lib/clangimport.cpp
@@ -205,10 +205,10 @@ static std::vector splitString(const std::string &line)
namespace clangimport {
struct Data {
struct Decl {
- explicit Decl(Scope *scope) : def(nullptr), enumerator(nullptr), function(nullptr), scope(scope), var(nullptr) {}
- Decl(Token *def, Variable *var) : def(def), enumerator(nullptr), function(nullptr), scope(nullptr), var(var) {}
- Decl(Token *def, Function *function) : def(def), enumerator(nullptr), function(function), scope(nullptr), var(nullptr) {}
- Decl(Token *def, Enumerator *enumerator) : def(def), enumerator(enumerator), function(nullptr), scope(nullptr), var(nullptr) {}
+ explicit Decl(Scope *scope) : scope(scope) {}
+ Decl(Token *def, Variable *var) : def(def), var(var) {}
+ Decl(Token *def, Function *function) : def(def), function(function) {}
+ Decl(Token *def, Enumerator *enumerator) : def(def), enumerator(enumerator) {}
void ref(Token *tok) const {
if (enumerator)
tok->enumerator(enumerator);
@@ -219,11 +219,11 @@ namespace clangimport {
tok->varId(var->declarationId());
}
}
- Token *def;
- Enumerator *enumerator;
- Function *function;
- Scope *scope;
- Variable *var;
+ Token* def{};
+ Enumerator* enumerator{};
+ Function* function{};
+ Scope* scope{};
+ Variable* var{};
};
const Settings *mSettings = nullptr;
diff --git a/lib/config.h b/lib/config.h
index a0cbee51685..2f45debe005 100644
--- a/lib/config.h
+++ b/lib/config.h
@@ -79,6 +79,13 @@
# define UNUSED
#endif
+// warn_unused
+#if (defined(__clang__) && (__clang_major__ >= 15))
+# define WARN_UNUSED [[gnu::warn_unused]]
+#else
+# define WARN_UNUSED
+#endif
+
#define REQUIRES(msg, ...) class=typename std::enable_if<__VA_ARGS__::value>::type
#include
diff --git a/lib/cppcheck.cpp b/lib/cppcheck.cpp
index f074abebc68..074e5ce71ca 100644
--- a/lib/cppcheck.cpp
+++ b/lib/cppcheck.cpp
@@ -391,10 +391,7 @@ CppCheck::CppCheck(ErrorLogger &errorLogger,
bool useGlobalSuppressions,
std::function,std::string,std::string&)> executeCommand)
: mErrorLogger(errorLogger)
- , mExitCode(0)
, mUseGlobalSuppressions(useGlobalSuppressions)
- , mTooManyConfigs(false)
- , mSimplify(true)
, mExecuteCommand(std::move(executeCommand))
{}
@@ -545,7 +542,7 @@ unsigned int CppCheck::check(const std::string &path)
tokenizer.list.appendFileIfNew(path);
clangimport::parseClangAstDump(&tokenizer, ast);
ValueFlow::setValues(tokenizer.list,
- const_cast(tokenizer.getSymbolDatabase()),
+ const_cast(*tokenizer.getSymbolDatabase()),
this,
&mSettings,
&s_timerResults);
diff --git a/lib/cppcheck.h b/lib/cppcheck.h
index d9b63f02fd7..925111ae75b 100644
--- a/lib/cppcheck.h
+++ b/lib/cppcheck.h
@@ -217,15 +217,15 @@ class CPPCHECKLIB CppCheck : ErrorLogger {
/** @brief Current preprocessor configuration */
std::string mCurrentConfig;
- unsigned int mExitCode;
+ unsigned int mExitCode{};
bool mUseGlobalSuppressions;
/** Are there too many configs? */
- bool mTooManyConfigs;
+ bool mTooManyConfigs{};
/** Simplify code? true by default */
- bool mSimplify;
+ bool mSimplify = true;
/** File info used for whole program analysis */
std::list mFileInfo;
diff --git a/lib/ctu.cpp b/lib/ctu.cpp
index ab3a7155d31..d62f91bfb86 100644
--- a/lib/ctu.cpp
+++ b/lib/ctu.cpp
@@ -158,7 +158,6 @@ std::string CTU::toString(const std::list &unsafeUsa
CTU::FileInfo::CallBase::CallBase(const Tokenizer *tokenizer, const Token *callToken)
: callId(getFunctionId(tokenizer, callToken->function()))
- , callArgNr(0)
, callFunctionName(callToken->next()->astOperand1()->expressionString())
, location(CTU::FileInfo::Location(tokenizer, callToken))
{}
@@ -166,7 +165,6 @@ CTU::FileInfo::CallBase::CallBase(const Tokenizer *tokenizer, const Token *callT
CTU::FileInfo::NestedCall::NestedCall(const Tokenizer *tokenizer, const Function *myFunction, const Token *callToken)
: CallBase(tokenizer, callToken)
, myId(getFunctionId(tokenizer, myFunction))
- , myArgNr(0)
{}
static std::string readAttrString(const tinyxml2::XMLElement *e, const char *attr, bool *error)
diff --git a/lib/forwardanalyzer.cpp b/lib/forwardanalyzer.cpp
index 494dbd13bba..fea0526eb5d 100644
--- a/lib/forwardanalyzer.cpp
+++ b/lib/forwardanalyzer.cpp
@@ -51,15 +51,15 @@ struct ForwardTraversal {
enum class Progress { Continue, Break, Skip };
enum class Terminate { None, Bail, Inconclusive };
ForwardTraversal(const ValuePtr& analyzer, const Settings& settings)
- : analyzer(analyzer), settings(settings), actions(Analyzer::Action::None), analyzeOnly(false), analyzeTerminate(false)
+ : analyzer(analyzer), settings(settings)
{}
ValuePtr analyzer;
const Settings& settings;
Analyzer::Action actions;
- bool analyzeOnly;
- bool analyzeTerminate;
+ bool analyzeOnly{};
+ bool analyzeTerminate{};
Analyzer::Terminate terminate = Analyzer::Terminate::None;
- std::vector loopEnds = {};
+ std::vector loopEnds;
Progress Break(Analyzer::Terminate t = Analyzer::Terminate::None) {
if ((!analyzeOnly || analyzeTerminate) && t != Analyzer::Terminate::None)
diff --git a/lib/fwdanalysis.h b/lib/fwdanalysis.h
index 847d1464e0c..0e83c22518b 100644
--- a/lib/fwdanalysis.h
+++ b/lib/fwdanalysis.h
@@ -37,7 +37,7 @@ class Library;
*/
class FwdAnalysis {
public:
- FwdAnalysis(bool cpp, const Library &library) : mCpp(cpp), mLibrary(library), mWhat(What::Reassign), mValueFlowKnown(true) {}
+ FwdAnalysis(bool cpp, const Library &library) : mCpp(cpp), mLibrary(library) {}
bool hasOperand(const Token *tok, const Token *lhs) const;
@@ -60,8 +60,8 @@ class FwdAnalysis {
bool unusedValue(const Token *expr, const Token *startToken, const Token *endToken);
struct KnownAndToken {
- bool known;
- const Token *token;
+ bool known{};
+ const Token* token{};
};
/** Is there some possible alias for given expression */
@@ -74,9 +74,9 @@ class FwdAnalysis {
/** Result of forward analysis */
struct Result {
enum class Type { NONE, READ, WRITE, BREAK, RETURN, BAILOUT } type;
- explicit Result(Type type) : type(type), token(nullptr) {}
+ explicit Result(Type type) : type(type) {}
Result(Type type, const Token *token) : type(type), token(token) {}
- const Token *token;
+ const Token* token{};
};
struct Result check(const Token *expr, const Token *startToken, const Token *endToken);
@@ -87,9 +87,9 @@ class FwdAnalysis {
const bool mCpp;
const Library &mLibrary;
- enum class What { Reassign, UnusedValue, ValueFlow } mWhat;
+ enum class What { Reassign, UnusedValue, ValueFlow } mWhat = What::Reassign;
std::vector mValueFlow;
- bool mValueFlowKnown;
+ bool mValueFlowKnown = true;
};
#endif // fwdanalysisH
diff --git a/lib/importproject.cpp b/lib/importproject.cpp
index c59bf288aa8..76403ff40db 100644
--- a/lib/importproject.cpp
+++ b/lib/importproject.cpp
@@ -502,7 +502,7 @@ bool ImportProject::importSln(std::istream &istr, const std::string &path, const
namespace {
struct ProjectConfiguration {
- explicit ProjectConfiguration(const tinyxml2::XMLElement *cfg) : platform(Unknown) {
+ explicit ProjectConfiguration(const tinyxml2::XMLElement *cfg) {
const char *a = cfg->Attribute("Include");
if (a)
name = a;
@@ -524,7 +524,7 @@ namespace {
}
std::string name;
std::string configuration;
- enum { Win32, x64, Unknown } platform;
+ enum { Win32, x64, Unknown } platform = Unknown;
std::string platformStr;
};
diff --git a/lib/importproject.h b/lib/importproject.h
index 704722edc19..1d7bb9ba72c 100644
--- a/lib/importproject.h
+++ b/lib/importproject.h
@@ -63,7 +63,6 @@ class CPPCHECKLIB ImportProject {
/** File settings. Multiple configurations for a file is allowed. */
struct CPPCHECKLIB FileSettings {
- FileSettings() : platformType(cppcheck::Platform::Type::Unspecified), msc(false), useMfc(false) {}
std::string cfg;
std::string filename;
std::string defines;
@@ -74,9 +73,9 @@ class CPPCHECKLIB ImportProject {
std::list includePaths;
std::list systemIncludePaths;
std::string standard;
- cppcheck::Platform::Type platformType;
- bool msc;
- bool useMfc;
+ cppcheck::Platform::Type platformType = cppcheck::Platform::Type::Unspecified;
+ bool msc{};
+ bool useMfc{};
void parseCommand(const std::string& command);
void setDefines(std::string defs);
diff --git a/lib/library.cpp b/lib/library.cpp
index 3744f455235..4142dcd8ae1 100644
--- a/lib/library.cpp
+++ b/lib/library.cpp
@@ -64,9 +64,6 @@ static void gettokenlistfromvalid(const std::string& valid, TokenList& tokenList
}
}
-Library::Library() : mAllocId(0)
-{}
-
Library::Error Library::load(const char exename[], const char path[])
{
if (std::strchr(path,',') != nullptr) {
diff --git a/lib/library.h b/lib/library.h
index 2e38a7332b0..300382d9fc7 100644
--- a/lib/library.h
+++ b/lib/library.h
@@ -58,7 +58,7 @@ class CPPCHECKLIB Library {
friend class TestProcessExecutor; // For testing only
public:
- Library();
+ Library() = default;
enum class ErrorCode { OK, FILE_NOT_FOUND, BAD_XML, UNKNOWN_ELEMENT, MISSING_ATTRIBUTE, BAD_ATTRIBUTE_VALUE, UNSUPPORTED_FORMAT, DUPLICATE_PLATFORM_TYPE, PLATFORM_TYPE_REDEFINED };
@@ -210,18 +210,7 @@ class CPPCHECKLIB Library {
class Container {
public:
- Container()
- : type_templateArgNo(-1),
- size_templateArgNo(-1),
- arrayLike_indexOp(false),
- stdStringLike(false),
- stdAssociativeLike(false),
- opLessAllowed(true),
- hasInitializerListConstructor(false),
- unstableErase(false),
- unstableInsert(false),
- view(false)
- {}
+ Container() = default;
enum class Action {
RESIZE,
@@ -259,17 +248,17 @@ class CPPCHECKLIB Library {
};
std::string startPattern, startPattern2, endPattern, itEndPattern;
std::map functions;
- int type_templateArgNo;
+ int type_templateArgNo = -1;
std::vector rangeItemRecordType;
- int size_templateArgNo;
- bool arrayLike_indexOp;
- bool stdStringLike;
- bool stdAssociativeLike;
- bool opLessAllowed;
- bool hasInitializerListConstructor;
- bool unstableErase;
- bool unstableInsert;
- bool view;
+ int size_templateArgNo = -1;
+ bool arrayLike_indexOp{};
+ bool stdStringLike{};
+ bool stdAssociativeLike{};
+ bool opLessAllowed = true;
+ bool hasInitializerListConstructor{};
+ bool unstableErase{};
+ bool unstableInsert{};
+ bool view{};
Action getAction(const std::string& function) const {
const std::map::const_iterator i = functions.find(function);
@@ -298,47 +287,31 @@ class CPPCHECKLIB Library {
const Container* detectIterator(const Token* typeStart) const;
const Container* detectContainerOrIterator(const Token* typeStart, bool* isIterator = nullptr, bool withoutStd = false) const;
- class ArgumentChecks {
- public:
- ArgumentChecks() :
- notbool(false),
- notnull(false),
- notuninit(-1),
- formatstr(false),
- strz(false),
- optional(false),
- variadic(false),
- iteratorInfo(),
- direction(Direction::DIR_UNKNOWN) {}
-
- bool notbool;
- bool notnull;
- int notuninit;
- bool formatstr;
- bool strz;
- bool optional;
- bool variadic;
+ struct ArgumentChecks {
+ bool notbool{};
+ bool notnull{};
+ int notuninit = -1;
+ bool formatstr{};
+ bool strz{};
+ bool optional{};
+ bool variadic{};
std::string valid;
- class IteratorInfo {
- public:
- IteratorInfo() : container(0), it(false), first(false), last(false) {}
-
- int container;
- bool it;
- bool first;
- bool last;
+ struct IteratorInfo {
+ int container{};
+ bool it{};
+ bool first{};
+ bool last{};
};
IteratorInfo iteratorInfo;
- class MinSize {
- public:
+ struct MinSize {
enum class Type { NONE, STRLEN, ARGVALUE, SIZEOF, MUL, VALUE };
- MinSize(Type t, int a) : type(t), arg(a), arg2(0), value(0) {}
+ MinSize(Type t, int a) : type(t), arg(a) {}
Type type;
int arg;
- int arg2;
- long long value;
+ int arg2 = 0;
+ long long value = 0;
std::string baseType;
};
std::vector minsizes;
@@ -349,36 +322,23 @@ class CPPCHECKLIB Library {
DIR_INOUT, ///< Input to called function, and output to caller. Data is passed by reference or address and is potentially modified.
DIR_UNKNOWN ///< direction not known / specified
};
- Direction direction;
+ Direction direction = Direction::DIR_UNKNOWN;
};
struct Function {
std::map argumentChecks; // argument nr => argument data
- bool use;
- bool leakignore;
- bool isconst;
- bool ispure;
- UseRetValType useretval;
- bool ignore; // ignore functions/macros from a library (gtk, qt etc)
- bool formatstr;
- bool formatstr_scan;
- bool formatstr_secure;
- Container::Action containerAction;
- Container::Yield containerYield;
+ bool use{};
+ bool leakignore{};
+ bool isconst{};
+ bool ispure{};
+ UseRetValType useretval = UseRetValType::NONE;
+ bool ignore{}; // ignore functions/macros from a library (gtk, qt etc)
+ bool formatstr{};
+ bool formatstr_scan{};
+ bool formatstr_secure{};
+ Container::Action containerAction = Container::Action::NO_ACTION;
+ Container::Yield containerYield = Container::Yield::NO_YIELD;
std::string returnType;
- Function()
- : use(false),
- leakignore(false),
- isconst(false),
- ispure(false),
- useretval(UseRetValType::NONE),
- ignore(false),
- formatstr(false),
- formatstr_scan(false),
- formatstr_secure(false),
- containerAction(Container::Action::NO_ACTION),
- containerYield(Container::Yield::NO_YIELD)
- {}
};
const Function *getFunction(const Token *ftok) const;
@@ -505,13 +465,6 @@ class CPPCHECKLIB Library {
}
struct PlatformType {
- PlatformType()
- : mSigned(false)
- , mUnsigned(false)
- , mLong(false)
- , mPointer(false)
- , mPtrPtr(false)
- , mConstPtr(false) {}
bool operator == (const PlatformType & type) const {
return (mSigned == type.mSigned &&
mUnsigned == type.mUnsigned &&
@@ -525,12 +478,12 @@ class CPPCHECKLIB Library {
return !(*this == type);
}
std::string mType;
- bool mSigned;
- bool mUnsigned;
- bool mLong;
- bool mPointer;
- bool mPtrPtr;
- bool mConstPtr;
+ bool mSigned{};
+ bool mUnsigned{};
+ bool mLong{};
+ bool mPointer{};
+ bool mPtrPtr{};
+ bool mConstPtr{};
};
struct Platform {
@@ -594,7 +547,7 @@ class CPPCHECKLIB Library {
};
class CodeBlock {
public:
- CodeBlock() : mOffset(0) {}
+ CodeBlock() = default;
void setStart(const char* s) {
mStart = s;
@@ -624,11 +577,11 @@ class CPPCHECKLIB Library {
private:
std::string mStart;
std::string mEnd;
- int mOffset;
+ int mOffset{};
std::set mBlocks;
};
enum class FalseTrueMaybe { False, True, Maybe };
- int mAllocId;
+ int mAllocId{};
std::set mFiles;
std::map mAlloc; // allocation functions
std::map mDealloc; // deallocation functions
diff --git a/lib/mathlib.cpp b/lib/mathlib.cpp
index 501b6805b8f..7feef1f8c57 100644
--- a/lib/mathlib.cpp
+++ b/lib/mathlib.cpp
@@ -37,8 +37,7 @@
const int MathLib::bigint_bits = 64;
-MathLib::value::value(const std::string &s) :
- mIntValue(0), mDoubleValue(0), mIsUnsigned(false)
+MathLib::value::value(const std::string &s)
{
if (MathLib::isFloat(s)) {
mType = MathLib::value::Type::FLOAT;
diff --git a/lib/mathlib.h b/lib/mathlib.h
index 709fb0e0bf9..9bab55a8d82 100644
--- a/lib/mathlib.h
+++ b/lib/mathlib.h
@@ -37,10 +37,10 @@ class CPPCHECKLIB MathLib {
/** @brief value class */
class value {
private:
- long long mIntValue;
- double mDoubleValue;
+ long long mIntValue{};
+ double mDoubleValue{};
enum class Type { INT, LONG, LONGLONG, FLOAT } mType;
- bool mIsUnsigned;
+ bool mIsUnsigned{};
void promote(const value &v);
diff --git a/lib/programmemory.cpp b/lib/programmemory.cpp
index 6c4261eafd6..05c42c461ca 100644
--- a/lib/programmemory.cpp
+++ b/lib/programmemory.cpp
@@ -429,7 +429,7 @@ static ProgramMemory getInitialProgramState(const Token* tok,
return pm;
}
-ProgramMemoryState::ProgramMemoryState(const Settings* s) : state(), origins(), settings(s) {}
+ProgramMemoryState::ProgramMemoryState(const Settings* s) : settings(s) {}
void ProgramMemoryState::insert(const ProgramMemory &pm, const Token* origin)
{
diff --git a/lib/settings.cpp b/lib/settings.cpp
index 3e40ef7c752..1efc55c9015 100644
--- a/lib/settings.cpp
+++ b/lib/settings.cpp
@@ -36,44 +36,6 @@ const char Settings::SafeChecks::XmlInternalFunctions[] = "internal-functions";
const char Settings::SafeChecks::XmlExternalVariables[] = "external-variables";
Settings::Settings()
- : checkAllConfigurations(true),
- checkConfiguration(false),
- checkHeaders(true),
- checkLibrary(false),
- checksMaxTime(0),
- checkUnusedTemplates(true),
- clang(false),
- clangExecutable("clang"),
- clangTidy(false),
- clearIncludeCache(false),
- daca(false),
- debugnormal(false),
- debugSimplified(false),
- debugtemplate(false),
- debugwarnings(false),
- dump(false),
- enforcedLang(Language::None),
- exceptionHandling(false),
- exitCode(0),
- force(false),
- inlineSuppressions(false),
- jobs(1),
- loadAverage(0),
- maxConfigs(12),
- maxCtuDepth(2),
- maxTemplateRecursion(100),
- performanceValueFlowMaxTime(-1),
- preprocessOnly(false),
- quiet(false),
- relativePaths(false),
- reportProgress(false),
- showtime(SHOWTIME_MODES::SHOWTIME_NONE),
- templateMaxTime(0),
- typedefMaxTime(0),
- valueFlowMaxIterations(4),
- verbose(false),
- xml(false),
- xml_version(2)
{
severity.setEnabled(Severity::error, true);
certainty.setEnabled(Certainty::normal, true);
diff --git a/lib/settings.h b/lib/settings.h
index c77ad2392cc..ab27b1dbd4d 100644
--- a/lib/settings.h
+++ b/lib/settings.h
@@ -90,7 +90,7 @@ class SimpleEnableGroup {
* to pass individual values to functions or constructors now or in the
* future when we might have even more detailed settings.
*/
-class CPPCHECKLIB Settings {
+class CPPCHECKLIB WARN_UNUSED Settings {
private:
/** @brief terminate checking */
@@ -114,39 +114,39 @@ class CPPCHECKLIB Settings {
std::string buildDir;
/** @brief check all configurations (false if -D or --max-configs is used */
- bool checkAllConfigurations;
+ bool checkAllConfigurations = true;
/** Is the 'configuration checking' wanted? */
- bool checkConfiguration;
+ bool checkConfiguration{};
/**
* Check code in the headers, this is on by default but can
* be turned off to save CPU */
- bool checkHeaders;
+ bool checkHeaders = true;
/** Check for incomplete info in library files? */
- bool checkLibrary;
+ bool checkLibrary{};
/** @brief The maximum time in seconds for the checks of a single file */
- int checksMaxTime;
+ int checksMaxTime{};
/** @brief check unknown function return values */
std::set checkUnknownFunctionReturn;
/** Check unused/uninstantiated templates */
- bool checkUnusedTemplates;
+ bool checkUnusedTemplates = true;
/** Use Clang */
- bool clang;
+ bool clang{};
/** Custom Clang executable */
- std::string clangExecutable;
+ std::string clangExecutable = "clang";
/** Use clang-tidy */
- bool clangTidy;
+ bool clangTidy{};
/** Internal: Clear the simplecpp non-existing include cache */
- bool clearIncludeCache;
+ bool clearIncludeCache{};
/** @brief include paths excluded from checking the configuration */
std::set configExcludePaths;
@@ -158,22 +158,22 @@ class CPPCHECKLIB Settings {
std::string cppcheckCfgAbout;
/** @brief Are we running from DACA script? */
- bool daca;
+ bool daca{};
/** @brief Is --debug-normal given? */
- bool debugnormal;
+ bool debugnormal{};
/** @brief Is --debug-simplified given? */
- bool debugSimplified;
+ bool debugSimplified{};
/** @brief Is --debug-template given? */
- bool debugtemplate;
+ bool debugtemplate{};
/** @brief Is --debug-warnings given? */
- bool debugwarnings;
+ bool debugwarnings{};
/** @brief Is --dump given? */
- bool dump;
+ bool dump{};
std::string dumpFile;
enum Language {
@@ -181,34 +181,34 @@ class CPPCHECKLIB Settings {
};
/** @brief Name of the language that is enforced. Empty per default. */
- Language enforcedLang;
+ Language enforcedLang{};
/** @brief Is --exception-handling given */
- bool exceptionHandling;
+ bool exceptionHandling{};
// argv[0]
std::string exename;
/** @brief If errors are found, this value is returned from main().
Default value is 0. */
- int exitCode;
+ int exitCode{};
/** @brief List of --file-filter for analyzing special files */
std::vector fileFilters;
/** @brief Force checking the files with "too many" configurations (--force). */
- bool force;
+ bool force{};
/** @brief List of include paths, e.g. "my/includes/" which should be used
for finding include files inside source files. (-I) */
std::list includePaths;
/** @brief Is --inline-suppr given? */
- bool inlineSuppressions;
+ bool inlineSuppressions{};
/** @brief How many processes/threads should do checking at the same
time. Default is 1. (-j N) */
- unsigned int jobs;
+ unsigned int jobs = 1;
/** @brief --library= */
std::list libraries;
@@ -217,17 +217,17 @@ class CPPCHECKLIB Settings {
Library library;
/** @brief Load average value */
- int loadAverage;
+ int loadAverage{};
/** @brief Maximum number of configurations to check before bailing.
Default is 12. (--max-configs=N) */
- int maxConfigs;
+ int maxConfigs = 12;
/** @brief --max-ctu-depth */
- int maxCtuDepth;
+ int maxCtuDepth = 2;
/** @brief max template recursion */
- int maxTemplateRecursion;
+ int maxTemplateRecursion = 100;
/** @brief suppress exitcode */
Suppressions nofail;
@@ -241,7 +241,7 @@ class CPPCHECKLIB Settings {
cppcheck::Platform platform;
/** @brief Experimental: --performance-valueflow-max-time=T */
- int performanceValueFlowMaxTime;
+ int performanceValueFlowMaxTime = -1;
/** @brief --performance-valueflow-max-if-count=C */
int performanceValueFlowMaxIfCount;
@@ -256,33 +256,26 @@ class CPPCHECKLIB Settings {
std::string premiumArgs;
/** @brief Using -E for debugging purposes */
- bool preprocessOnly;
+ bool preprocessOnly{};
ImportProject project;
/** @brief Is --quiet given? */
- bool quiet;
+ bool quiet{};
/** @brief Use relative paths in output. */
- bool relativePaths;
+ bool relativePaths{};
/** @brief --report-progress */
- bool reportProgress;
+ bool reportProgress{};
/** Rule */
- class CPPCHECKLIB Rule {
- public:
- Rule()
- : tokenlist("normal") // use normal tokenlist
- , id("rule") // default id
- , severity(Severity::style) { // default severity
- }
-
- std::string tokenlist;
+ struct CPPCHECKLIB Rule {
+ std::string tokenlist = "normal"; // use normal tokenlist
std::string pattern;
- std::string id;
+ std::string id = "rule"; // default id
std::string summary;
- Severity::SeverityType severity;
+ Severity::SeverityType severity = Severity::style; // default severity
};
#ifdef HAVE_RULES
@@ -293,9 +286,7 @@ class CPPCHECKLIB Settings {
#endif
/** Do not only check how interface is used. Also check that interface is safe. */
- class CPPCHECKLIB SafeChecks {
- public:
- SafeChecks() : classes(false), externalFunctions(false), internalFunctions(false), externalVariables(false) {}
+ struct CPPCHECKLIB SafeChecks {
static const char XmlRootName[];
static const char XmlClasses[];
@@ -313,26 +304,26 @@ class CPPCHECKLIB Settings {
* - public functions can be called in any order
* - public variables can have any value
*/
- bool classes;
+ bool classes{};
/**
* External functions
* - external functions can be called in any order
* - function parameters can have any values
*/
- bool externalFunctions;
+ bool externalFunctions{};
/**
* Experimental: assume that internal functions can be used in any way
* This is only available in the GUI.
*/
- bool internalFunctions;
+ bool internalFunctions{};
/**
* Global variables that can be modified outside the TU.
* - Such variable can have "any" value
*/
- bool externalVariables;
+ bool externalVariables{};
};
SafeChecks safeChecks;
@@ -342,7 +333,7 @@ class CPPCHECKLIB Settings {
SimpleEnableGroup checks;
/** @brief show timing information (--showtime=file|summary|top5) */
- SHOWTIME_MODES showtime;
+ SHOWTIME_MODES showtime{};
/** Struct contains standards settings */
Standards standards;
@@ -356,10 +347,10 @@ class CPPCHECKLIB Settings {
std::string templateLocation;
/** @brief The maximum time in seconds for the template instantiation */
- std::size_t templateMaxTime;
+ std::size_t templateMaxTime{};
/** @brief The maximum time in seconds for the typedef simplification */
- std::size_t typedefMaxTime;
+ std::size_t typedefMaxTime{};
/** @brief defines given by the user */
std::string userDefines;
@@ -371,16 +362,16 @@ class CPPCHECKLIB Settings {
std::list userIncludes;
/** @brief the maximum iterations of valueflow (--valueflow-max-iterations=T) */
- std::size_t valueFlowMaxIterations;
+ std::size_t valueFlowMaxIterations = 4;
/** @brief Is --verbose given? */
- bool verbose;
+ bool verbose{};
/** @brief write XML results (--xml) */
- bool xml;
+ bool xml{};
/** @brief XML version (--xml-version=..) */
- int xml_version;
+ int xml_version = 2;
/**
* @brief return true if a included file is to be excluded in Preprocessor::getConfigs
diff --git a/lib/standards.h b/lib/standards.h
index e92656287ad..ee56d88816c 100644
--- a/lib/standards.h
+++ b/lib/standards.h
@@ -35,17 +35,14 @@
*/
struct Standards {
/** C code standard */
- enum cstd_t { C89, C99, C11, CLatest=C11 } c;
+ enum cstd_t { C89, C99, C11, CLatest = C11 } c = CLatest;
/** C++ code standard */
- enum cppstd_t { CPP03, CPP11, CPP14, CPP17, CPP20, CPP23, CPPLatest=CPP23 } cpp;
+ enum cppstd_t { CPP03, CPP11, CPP14, CPP17, CPP20, CPP23, CPPLatest = CPP23 } cpp = CPPLatest;
/** --std value given on command line */
std::string stdValue;
- /** This constructor clear all the variables **/
- Standards() : c(CLatest), cpp(CPPLatest) {}
-
bool setC(const std::string& str) {
stdValue = str;
if (str == "c89" || str == "C89") {
diff --git a/lib/suppressions.h b/lib/suppressions.h
index 2f0b339ed81..cc64ee51cef 100644
--- a/lib/suppressions.h
+++ b/lib/suppressions.h
@@ -55,8 +55,8 @@ class CPPCHECKLIB Suppressions {
};
struct CPPCHECKLIB Suppression {
- Suppression() : lineNumber(NO_LINE), hash(0), thisAndNextLine(false), matched(false), checked(false) {}
- Suppression(std::string id, std::string file, int line=NO_LINE) : errorId(std::move(id)), fileName(std::move(file)), lineNumber(line), hash(0), thisAndNextLine(false), matched(false), checked(false) {}
+ Suppression() = default;
+ Suppression(std::string id, std::string file, int line=NO_LINE) : errorId(std::move(id)), fileName(std::move(file)), lineNumber(line) {}
bool operator<(const Suppression &other) const {
if (errorId != other.errorId)
@@ -103,12 +103,12 @@ class CPPCHECKLIB Suppressions {
std::string errorId;
std::string fileName;
- int lineNumber;
+ int lineNumber = NO_LINE;
std::string symbolName;
- std::size_t hash;
- bool thisAndNextLine; // Special case for backwards compatibility: { // cppcheck-suppress something
- bool matched;
- bool checked; // for inline suppressions, checked or not
+ std::size_t hash{};
+ bool thisAndNextLine{}; // Special case for backwards compatibility: { // cppcheck-suppress something
+ bool matched{};
+ bool checked{}; // for inline suppressions, checked or not
enum { NO_LINE = -1 };
};
diff --git a/lib/symboldatabase.cpp b/lib/symboldatabase.cpp
index b601689f48d..4712e646ec8 100644
--- a/lib/symboldatabase.cpp
+++ b/lib/symboldatabase.cpp
@@ -2086,8 +2086,7 @@ Variable::Variable(const Token *name_, const std::string &clangType, const Token
mAccess(access_),
mFlags(0),
mType(type_),
- mScope(scope_),
- mValueType(nullptr)
+ mScope(scope_)
{
if (!mTypeStartToken && mTypeEndToken) {
mTypeStartToken = mTypeEndToken;
@@ -2135,14 +2134,12 @@ Variable::Variable(const Token *name_, const std::string &clangType, const Token
}
Variable::Variable(const Variable &var, const Scope *scope)
- : mValueType(nullptr)
{
*this = var;
mScope = scope;
}
Variable::Variable(const Variable &var)
- : mValueType(nullptr)
{
*this = var;
}
@@ -2401,20 +2398,7 @@ Function::Function(const Tokenizer *mTokenizer,
const Token *tokArgDef)
: tokenDef(tokDef),
argDef(tokArgDef),
- token(nullptr),
- arg(nullptr),
- retDef(nullptr),
- retType(nullptr),
- functionScope(nullptr),
- nestedIn(scope),
- initArgCount(0),
- type(eFunction),
- noexceptArg(nullptr),
- throwArg(nullptr),
- templateDef(nullptr),
- functionPointerUsage(nullptr),
- access(AccessControl::Public),
- mFlags(0)
+ nestedIn(scope)
{
// operator function
if (::isOperator(tokenDef)) {
@@ -2519,22 +2503,7 @@ Function::Function(const Tokenizer *mTokenizer,
}
Function::Function(const Token *tokenDef, const std::string &clangType)
- : tokenDef(tokenDef),
- argDef(nullptr),
- token(nullptr),
- arg(nullptr),
- retDef(nullptr),
- retType(nullptr),
- functionScope(nullptr),
- nestedIn(nullptr),
- initArgCount(0),
- type(eFunction),
- noexceptArg(nullptr),
- throwArg(nullptr),
- templateDef(nullptr),
- functionPointerUsage(nullptr),
- access(AccessControl::Public),
- mFlags(0)
+ : tokenDef(tokenDef)
{
// operator function
if (::isOperator(tokenDef)) {
@@ -3881,12 +3850,9 @@ void SymbolDatabase::printOut(const char *title) const
}
std::cout << " retType: " << func->retType << std::endl;
- if (func->tokenDef->next()->valueType()) {
- const ValueType * valueType = func->tokenDef->next()->valueType();
+ if (const ValueType* valueType = func->tokenDef->next()->valueType()) {
std::cout << " valueType: " << valueType << std::endl;
- if (valueType) {
- std::cout << " " << valueType->str() << std::endl;
- }
+ std::cout << " " << valueType->str() << std::endl;
}
if (func->hasBody()) {
@@ -4461,14 +4427,7 @@ Scope::Scope(const SymbolDatabase *check_, const Token *classDef_, const Scope *
check(check_),
classDef(classDef_),
nestedIn(nestedIn_),
- numConstructors(0),
- numCopyOrMoveConstructors(0),
- type(type_),
- definedType(nullptr),
- functionOf(nullptr),
- function(nullptr),
- enumType(nullptr),
- enumClass(false)
+ type(type_)
{
setBodyStartEnd(start_);
}
@@ -4476,16 +4435,7 @@ Scope::Scope(const SymbolDatabase *check_, const Token *classDef_, const Scope *
Scope::Scope(const SymbolDatabase *check_, const Token *classDef_, const Scope *nestedIn_) :
check(check_),
classDef(classDef_),
- bodyStart(nullptr),
- bodyEnd(nullptr),
- nestedIn(nestedIn_),
- numConstructors(0),
- numCopyOrMoveConstructors(0),
- definedType(nullptr),
- functionOf(nullptr),
- function(nullptr),
- enumType(nullptr),
- enumClass(false)
+ nestedIn(nestedIn_)
{
const Token *nameTok = classDef;
if (!classDef) {
@@ -6414,8 +6364,12 @@ void SymbolDatabase::setValueType(Token* tok, const ValueType& valuetype, Source
if (it != typeScope->varlist.end())
var = &*it;
}
- if (var)
+ if (var) {
setValueType(parent, *var);
+ return;
+ }
+ if (const Enumerator* enu = parent->astOperand2()->enumerator())
+ setValueType(parent, *enu);
return;
}
diff --git a/lib/symboldatabase.h b/lib/symboldatabase.h
index aa7d644a69a..d7c50ee7a2a 100644
--- a/lib/symboldatabase.h
+++ b/lib/symboldatabase.h
@@ -60,11 +60,9 @@ enum class AccessControl { Public, Protected, Private, Global, Namespace, Argume
* @brief Array dimension information.
*/
struct Dimension {
- Dimension() : tok(nullptr), num(0), known(true) {}
-
- const Token *tok; ///< size token
- MathLib::bigint num; ///< (assumed) dimension length when size is a number, 0 if not known
- bool known; ///< Known size
+ const Token* tok{}; ///< size token
+ MathLib::bigint num{}; ///< (assumed) dimension length when size is a number, 0 if not known
+ bool known = true; ///< Known size
};
/** @brief Information about a class type. */
@@ -75,18 +73,14 @@ class CPPCHECKLIB Type {
const Scope* enclosingScope;
enum class NeedInitialization {
Unknown, True, False
- } needInitialization;
-
- class BaseInfo {
- public:
- BaseInfo() :
- type(nullptr), nameTok(nullptr), access(AccessControl::Public), isVirtual(false) {}
+ } needInitialization = NeedInitialization::Unknown;
+ struct BaseInfo {
std::string name;
- const Type* type;
- const Token* nameTok;
- AccessControl access; // public/protected/private
- bool isVirtual;
+ const Type* type{};
+ const Token* nameTok{};
+ AccessControl access{}; // public/protected/private
+ bool isVirtual{};
// allow ordering within containers
bool operator<(const BaseInfo& rhs) const {
return this->type < rhs.type;
@@ -94,29 +88,22 @@ class CPPCHECKLIB Type {
};
struct FriendInfo {
- FriendInfo() :
- nameStart(nullptr), nameEnd(nullptr), type(nullptr) {}
-
- const Token* nameStart;
- const Token* nameEnd;
- const Type* type;
+ const Token* nameStart{};
+ const Token* nameEnd{};
+ const Type* type{};
};
std::vector derivedFrom;
std::vector friendList;
- const Token * typeStart;
- const Token * typeEnd;
- MathLib::bigint sizeOf;
+ const Token* typeStart{};
+ const Token* typeEnd{};
+ MathLib::bigint sizeOf{};
explicit Type(const Token* classDef_ = nullptr, const Scope* classScope_ = nullptr, const Scope* enclosingScope_ = nullptr) :
classDef(classDef_),
classScope(classScope_),
- enclosingScope(enclosingScope_),
- needInitialization(NeedInitialization::Unknown),
- typeStart(nullptr),
- typeEnd(nullptr),
- sizeOf(0) {
+ enclosingScope(enclosingScope_) {
if (classDef_ && classDef_->str() == "enum")
needInitialization = NeedInitialization::True;
else if (classDef_ && classDef_->str() == "using") {
@@ -167,15 +154,14 @@ class CPPCHECKLIB Type {
bool isDerivedFrom(const std::string & ancestor) const;
};
-class CPPCHECKLIB Enumerator {
-public:
- explicit Enumerator(const Scope * scope_) : scope(scope_), name(nullptr), value(0), start(nullptr), end(nullptr), value_known(false) {}
+struct CPPCHECKLIB Enumerator {
+ explicit Enumerator(const Scope * scope_) : scope(scope_) {}
const Scope * scope;
- const Token * name;
- MathLib::bigint value;
- const Token * start;
- const Token * end;
- bool value_known;
+ const Token* name{};
+ MathLib::bigint value{};
+ const Token* start{};
+ const Token* end{};
+ bool value_known{};
};
/** @brief Information about a member variable. */
@@ -238,8 +224,7 @@ class CPPCHECKLIB Variable {
mAccess(access_),
mFlags(0),
mType(type_),
- mScope(scope_),
- mValueType(nullptr) {
+ mScope(scope_) {
evaluate(settings);
}
@@ -699,7 +684,7 @@ class CPPCHECKLIB Variable {
/** @brief pointer to scope this variable is in */
const Scope *mScope;
- const ValueType *mValueType;
+ const ValueType* mValueType{};
/** @brief array dimensions */
std::vector mDimensions;
@@ -914,22 +899,22 @@ class CPPCHECKLIB Function {
}
bool isSafe(const Settings *settings) const;
- const Token *tokenDef; ///< function name token in class definition
- const Token *argDef; ///< function argument start '(' in class definition
- const Token *token; ///< function name token in implementation
- const Token *arg; ///< function argument start '('
- const Token *retDef; ///< function return type token
- const ::Type *retType; ///< function return type
- const Scope *functionScope; ///< scope of function body
- const Scope* nestedIn; ///< Scope the function is declared in
+ const Token* tokenDef{}; ///< function name token in class definition
+ const Token* argDef{}; ///< function argument start '(' in class definition
+ const Token* token{}; ///< function name token in implementation
+ const Token* arg{}; ///< function argument start '('
+ const Token* retDef{}; ///< function return type token
+ const ::Type* retType{}; ///< function return type
+ const Scope* functionScope{}; ///< scope of function body
+ const Scope* nestedIn{}; ///< Scope the function is declared in
std::vector argumentList; ///< argument list
- nonneg int initArgCount; ///< number of args with default values
- Type type; ///< constructor, destructor, ...
- const Token *noexceptArg; ///< noexcept token
- const Token *throwArg; ///< throw token
- const Token *templateDef; ///< points to 'template <' before function
- const Token *functionPointerUsage; ///< function pointer usage
- AccessControl access; ///< public/protected/private
+ nonneg int initArgCount{}; ///< number of args with default values
+ Type type = eFunction; ///< constructor, destructor, ...
+ const Token* noexceptArg{}; ///< noexcept token
+ const Token* throwArg{}; ///< throw token
+ const Token* templateDef{}; ///< points to 'template <' before function
+ const Token* functionPointerUsage{}; ///< function pointer usage
+ AccessControl access{}; ///< public/protected/private
bool argsMatch(const Scope *scope, const Token *first, const Token *second, const std::string &path, nonneg int path_length) const;
@@ -959,7 +944,7 @@ class CPPCHECKLIB Function {
/** Recursively determine if this function overrides a virtual function in a base class */
const Function * getOverriddenFunctionRecursive(const ::Type* baseType, bool *foundAllBaseClasses) const;
- unsigned int mFlags;
+ unsigned int mFlags{};
void isInline(bool state) {
setFlag(fIsInline, state);
@@ -1039,31 +1024,31 @@ class CPPCHECKLIB Scope {
Scope(const SymbolDatabase *check_, const Token *classDef_, const Scope *nestedIn_);
Scope(const SymbolDatabase *check_, const Token *classDef_, const Scope *nestedIn_, ScopeType type_, const Token *start_);
- const SymbolDatabase *check;
+ const SymbolDatabase* check{};
std::string className;
- const Token *classDef; ///< class/struct/union/namespace token
- const Token *bodyStart; ///< '{' token
- const Token *bodyEnd; ///< '}' token
+ const Token* classDef{}; ///< class/struct/union/namespace token
+ const Token* bodyStart{}; ///< '{' token
+ const Token* bodyEnd{}; ///< '}' token
std::list functionList;
std::multimap functionMap;
std::list varlist;
- const Scope *nestedIn;
+ const Scope* nestedIn{};
std::vector nestedList;
- nonneg int numConstructors;
- nonneg int numCopyOrMoveConstructors;
+ nonneg int numConstructors{};
+ nonneg int numCopyOrMoveConstructors{};
std::vector usingList;
- ScopeType type;
- Type* definedType;
+ ScopeType type{};
+ Type* definedType{};
std::map definedTypesMap;
std::vector bodyStartList;
// function specific fields
- const Scope *functionOf; ///< scope this function belongs to
- Function *function; ///< function info for this function
+ const Scope* functionOf{}; ///< scope this function belongs to
+ Function* function{}; ///< function info for this function
// enum specific fields
- const Token * enumType;
- bool enumClass;
+ const Token* enumType{};
+ bool enumClass{};
std::vector enumeratorList;
@@ -1224,7 +1209,7 @@ enum class Reference {
/** Value type */
class CPPCHECKLIB ValueType {
public:
- enum Sign { UNKNOWN_SIGN, SIGNED, UNSIGNED } sign;
+ enum Sign { UNKNOWN_SIGN, SIGNED, UNSIGNED } sign = UNKNOWN_SIGN;
enum Type {
UNKNOWN_TYPE,
POD,
@@ -1245,80 +1230,42 @@ class CPPCHECKLIB ValueType {
FLOAT,
DOUBLE,
LONGDOUBLE
- } type;
- nonneg int bits; ///< bitfield bitcount
- nonneg int pointer; ///< 0=>not pointer, 1=>*, 2=>**, 3=>***, etc
- nonneg int constness; ///< bit 0=data, bit 1=*, bit 2=**
+ } type = UNKNOWN_TYPE;
+ nonneg int bits{}; ///< bitfield bitcount
+ nonneg int pointer{}; ///< 0=>not pointer, 1=>*, 2=>**, 3=>***, etc
+ nonneg int constness{}; ///< bit 0=data, bit 1=*, bit 2=**
Reference reference = Reference::None; ///< Is the outermost indirection of this type a reference or rvalue
///< reference or not? pointer=2, Reference=LValue would be a T**&
- const Scope* typeScope; ///< if the type definition is seen this point out the type scope
- const ::Type* smartPointerType; ///< Smart pointer type
- const Token* smartPointerTypeToken; ///< Smart pointer type token
- const Library::SmartPointer* smartPointer; ///< Smart pointer
- const Library::Container* container; ///< If the type is a container defined in a cfg file, this is the used
+ const Scope* typeScope{}; ///< if the type definition is seen this point out the type scope
+ const ::Type* smartPointerType{}; ///< Smart pointer type
+ const Token* smartPointerTypeToken{}; ///< Smart pointer type token
+ const Library::SmartPointer* smartPointer{}; ///< Smart pointer
+ const Library::Container* container{}; ///< If the type is a container defined in a cfg file, this is the used
///< container
- const Token* containerTypeToken; ///< The container type token. the template argument token that defines the
+ const Token* containerTypeToken{}; ///< The container type token. the template argument token that defines the
///< container element type.
std::string originalTypeName; ///< original type name as written in the source code. eg. this might be "uint8_t"
///< when type is CHAR.
ErrorPath debugPath; ///< debug path to the type
- ValueType()
- : sign(UNKNOWN_SIGN),
- type(UNKNOWN_TYPE),
- bits(0),
- pointer(0U),
- constness(0U),
- typeScope(nullptr),
- smartPointerType(nullptr),
- smartPointerTypeToken(nullptr),
- smartPointer(nullptr),
- container(nullptr),
- containerTypeToken(nullptr),
- debugPath()
- {}
+ ValueType() = default;
ValueType(enum Sign s, enum Type t, nonneg int p)
: sign(s),
type(t),
- bits(0),
- pointer(p),
- constness(0U),
- typeScope(nullptr),
- smartPointerType(nullptr),
- smartPointerTypeToken(nullptr),
- smartPointer(nullptr),
- container(nullptr),
- containerTypeToken(nullptr),
- debugPath()
+ pointer(p)
{}
ValueType(enum Sign s, enum Type t, nonneg int p, nonneg int c)
: sign(s),
type(t),
- bits(0),
pointer(p),
- constness(c),
- typeScope(nullptr),
- smartPointerType(nullptr),
- smartPointerTypeToken(nullptr),
- smartPointer(nullptr),
- container(nullptr),
- containerTypeToken(nullptr),
- debugPath()
+ constness(c)
{}
ValueType(enum Sign s, enum Type t, nonneg int p, nonneg int c, std::string otn)
: sign(s),
type(t),
- bits(0),
pointer(p),
constness(c),
- typeScope(nullptr),
- smartPointerType(nullptr),
- smartPointerTypeToken(nullptr),
- smartPointer(nullptr),
- container(nullptr),
- containerTypeToken(nullptr),
- originalTypeName(std::move(otn)),
- debugPath()
+ originalTypeName(std::move(otn))
{}
static ValueType parseDecl(const Token *type, const Settings &settings, bool isCpp);
diff --git a/lib/templatesimplifier.cpp b/lib/templatesimplifier.cpp
index 3ff539ae067..e551790a461 100644
--- a/lib/templatesimplifier.cpp
+++ b/lib/templatesimplifier.cpp
@@ -281,7 +281,7 @@ bool TemplateSimplifier::TokenAndName::isAliasToken(const Token *tok) const
TemplateSimplifier::TemplateSimplifier(Tokenizer &tokenizer)
: mTokenizer(tokenizer), mTokenList(mTokenizer.list), mSettings(*mTokenizer.mSettings),
- mErrorLogger(mTokenizer.mErrorLogger), mChanged(false)
+ mErrorLogger(mTokenizer.mErrorLogger)
{}
TemplateSimplifier::~TemplateSimplifier()
diff --git a/lib/templatesimplifier.h b/lib/templatesimplifier.h
index 23dad621bdd..763962ea24c 100644
--- a/lib/templatesimplifier.h
+++ b/lib/templatesimplifier.h
@@ -500,7 +500,7 @@ class CPPCHECKLIB TemplateSimplifier {
TokenList &mTokenList;
const Settings &mSettings;
ErrorLogger *mErrorLogger;
- bool mChanged;
+ bool mChanged{};
std::list mTemplateDeclarations;
std::list mTemplateForwardDeclarations;
diff --git a/lib/timer.cpp b/lib/timer.cpp
index c5d3dfd1282..4e04b58190a 100644
--- a/lib/timer.cpp
+++ b/lib/timer.cpp
@@ -101,9 +101,6 @@ Timer::Timer(std::string str, SHOWTIME_MODES showtimeMode, TimerResultsIntf* tim
Timer::Timer(bool fileTotal, std::string filename)
: mStr(std::move(filename))
- , mTimerResults(nullptr)
- , mStart(std::clock())
- , mShowTimeMode(SHOWTIME_MODES::SHOWTIME_FILE_TOTAL)
, mStopped(!fileTotal)
{}
diff --git a/lib/timer.h b/lib/timer.h
index 4bd8884c242..1fe246f417d 100644
--- a/lib/timer.h
+++ b/lib/timer.h
@@ -43,12 +43,8 @@ class CPPCHECKLIB TimerResultsIntf {
};
struct TimerResultsData {
- std::clock_t mClocks;
- long mNumberOfResults;
-
- TimerResultsData()
- : mClocks(0)
- , mNumberOfResults(0) {}
+ std::clock_t mClocks{};
+ long mNumberOfResults{};
double seconds() const {
const double ret = (double)((unsigned long)mClocks) / (double)CLOCKS_PER_SEC;
@@ -81,10 +77,10 @@ class CPPCHECKLIB Timer {
private:
const std::string mStr;
- TimerResultsIntf* mTimerResults;
- std::clock_t mStart;
- const SHOWTIME_MODES mShowTimeMode;
- bool mStopped;
+ TimerResultsIntf* mTimerResults{};
+ std::clock_t mStart = std::clock();
+ const SHOWTIME_MODES mShowTimeMode = SHOWTIME_MODES::SHOWTIME_FILE_TOTAL;
+ bool mStopped{};
};
//---------------------------------------------------------------------------
#endif // timerH
diff --git a/lib/token.cpp b/lib/token.cpp
index 390490e8637..0e9184626f3 100644
--- a/lib/token.cpp
+++ b/lib/token.cpp
@@ -56,12 +56,7 @@ namespace {
const std::list TokenImpl::mEmptyValueList;
Token::Token(TokensFrontBack *tokensFrontBack) :
- mTokensFrontBack(tokensFrontBack),
- mNext(nullptr),
- mPrevious(nullptr),
- mLink(nullptr),
- mTokType(eNone),
- mFlags(0)
+ mTokensFrontBack(tokensFrontBack)
{
mImpl = new TokenImpl();
}
diff --git a/lib/token.h b/lib/token.h
index 66016f33bf1..d04d365d445 100644
--- a/lib/token.h
+++ b/lib/token.h
@@ -39,7 +39,7 @@
#include
#include
-class Enumerator;
+struct Enumerator;
class Function;
class Scope;
class Settings;
@@ -54,48 +54,48 @@ class Token;
* @brief This struct stores pointers to the front and back tokens of the list this token is in.
*/
struct TokensFrontBack {
- Token *front;
- Token *back;
- const TokenList* list;
+ Token *front{};
+ Token* back{};
+ const TokenList* list{};
};
struct ScopeInfo2 {
ScopeInfo2(std::string name_, const Token *bodyEnd_, std::set usingNamespaces_ = std::set()) : name(std::move(name_)), bodyEnd(bodyEnd_), usingNamespaces(std::move(usingNamespaces_)) {}
std::string name;
- const Token * const bodyEnd;
+ const Token* const bodyEnd{};
std::set usingNamespaces;
};
enum class TokenDebug { None, ValueFlow, ValueType };
struct TokenImpl {
- nonneg int mVarId;
- nonneg int mFileIndex;
- nonneg int mLineNumber;
- nonneg int mColumn;
- nonneg int mExprId;
+ nonneg int mVarId{};
+ nonneg int mFileIndex{};
+ nonneg int mLineNumber{};
+ nonneg int mColumn{};
+ nonneg int mExprId{};
/**
* A value from 0-100 that provides a rough idea about where in the token
* list this token is located.
*/
- nonneg int mProgressValue;
+ nonneg int mProgressValue{};
/**
* Token index. Position in token list
*/
- nonneg int mIndex;
+ nonneg int mIndex{};
/** Bitfield bit count. */
- unsigned char mBits;
+ unsigned char mBits{};
// AST..
- Token *mAstOperand1;
- Token *mAstOperand2;
- Token *mAstParent;
+ Token* mAstOperand1{};
+ Token* mAstOperand2{};
+ Token* mAstParent{};
// symbol database information
- const Scope *mScope;
+ const Scope* mScope{};
union {
const Function *mFunction;
const Variable *mVariable;
@@ -104,60 +104,38 @@ struct TokenImpl {
};
// original name like size_t
- std::string* mOriginalName;
+ std::string* mOriginalName{};
// ValueType
- ValueType *mValueType;
+ ValueType* mValueType{};
// ValueFlow
- std::list* mValues;
+ std::list* mValues{};
static const std::list mEmptyValueList;
// Pointer to a template in the template simplifier
- std::set* mTemplateSimplifierPointers;
+ std::set* mTemplateSimplifierPointers{};
// Pointer to the object representing this token's scope
std::shared_ptr mScopeInfo;
// __cppcheck_in_range__
struct CppcheckAttributes {
- enum Type {LOW,HIGH} type;
- MathLib::bigint value;
- struct CppcheckAttributes *next;
+ enum Type { LOW, HIGH } type = LOW;
+ MathLib::bigint value{};
+ CppcheckAttributes* next{};
};
- struct CppcheckAttributes *mCppcheckAttributes;
+ CppcheckAttributes* mCppcheckAttributes{};
// For memoization, to speed up parsing of huge arrays #8897
- enum class Cpp11init {UNKNOWN, CPP11INIT, NOINIT} mCpp11init;
+ enum class Cpp11init { UNKNOWN, CPP11INIT, NOINIT } mCpp11init = Cpp11init::UNKNOWN;
- TokenDebug mDebug;
+ TokenDebug mDebug{};
void setCppcheckAttribute(CppcheckAttributes::Type type, MathLib::bigint value);
bool getCppcheckAttribute(CppcheckAttributes::Type type, MathLib::bigint &value) const;
- TokenImpl()
- : mVarId(0),
- mFileIndex(0),
- mLineNumber(0),
- mColumn(0),
- mExprId(0),
- mProgressValue(0),
- mIndex(0),
- mBits(0),
- mAstOperand1(nullptr),
- mAstOperand2(nullptr),
- mAstParent(nullptr),
- mScope(nullptr),
- mFunction(nullptr), // Initialize whole union
- mOriginalName(nullptr),
- mValueType(nullptr),
- mValues(nullptr),
- mTemplateSimplifierPointers(nullptr),
- mScopeInfo(nullptr),
- mCppcheckAttributes(nullptr),
- mCpp11init(Cpp11init::UNKNOWN),
- mDebug(TokenDebug::None)
- {}
+ TokenImpl() : mFunction(nullptr) {}
~TokenImpl();
};
@@ -177,7 +155,7 @@ struct TokenImpl {
*/
class CPPCHECKLIB Token {
private:
- TokensFrontBack* mTokensFrontBack;
+ TokensFrontBack* mTokensFrontBack{};
public:
Token(const Token &) = delete;
@@ -1301,9 +1279,9 @@ class CPPCHECKLIB Token {
std::string mStr;
- Token *mNext;
- Token *mPrevious;
- Token *mLink;
+ Token* mNext{};
+ Token* mPrevious{};
+ Token* mLink{};
enum : uint64_t {
fIsUnsigned = (1ULL << 0),
@@ -1355,11 +1333,11 @@ class CPPCHECKLIB Token {
efIsUnique = efMaxSize - 2,
};
- Token::Type mTokType;
+ Token::Type mTokType = eNone;
- uint64_t mFlags;
+ uint64_t mFlags{};
- TokenImpl *mImpl;
+ TokenImpl* mImpl{};
/**
* Get specified flag state.
diff --git a/lib/tokenize.cpp b/lib/tokenize.cpp
index 5af99c21ec2..1138285abf7 100644
--- a/lib/tokenize.cpp
+++ b/lib/tokenize.cpp
@@ -64,15 +64,14 @@ namespace {
// local struct used in setVarId
// in order to store information about the scope
struct VarIdScopeInfo {
- VarIdScopeInfo()
- : isExecutable(false), isStructInit(false), isEnum(false), startVarid(0) {}
+ VarIdScopeInfo() = default;
VarIdScopeInfo(bool isExecutable, bool isStructInit, bool isEnum, nonneg int startVarid)
: isExecutable(isExecutable), isStructInit(isStructInit), isEnum(isEnum), startVarid(startVarid) {}
- const bool isExecutable;
- const bool isStructInit;
- const bool isEnum;
- const nonneg int startVarid;
+ const bool isExecutable{};
+ const bool isStructInit{};
+ const bool isEnum{};
+ const nonneg int startVarid{};
};
}
@@ -162,12 +161,7 @@ Tokenizer::Tokenizer(const Settings *settings, ErrorLogger *errorLogger, const P
list(settings),
mSettings(settings),
mErrorLogger(errorLogger),
- mSymbolDatabase(nullptr),
mTemplateSimplifier(new TemplateSimplifier(*this)),
- mVarId(0),
- mUnnamedCount(0),
- mCodeWithTemplates(false), //is there any templates?
- mTimerResults(nullptr),
mPreprocessor(preprocessor)
{
// make sure settings are specified
@@ -405,11 +399,10 @@ Token * Tokenizer::deleteInvalidTypedef(Token *typeDef)
namespace {
struct Space {
- Space() : bodyEnd(nullptr), bodyEnd2(nullptr), isNamespace(false) {}
std::string className;
- const Token * bodyEnd; // for body contains typedef define
- const Token * bodyEnd2; // for body contains typedef using
- bool isNamespace;
+ const Token* bodyEnd{}; // for body contains typedef define
+ const Token* bodyEnd2{}; // for body contains typedef using
+ bool isNamespace{};
std::set recordTypes;
};
}
@@ -3346,8 +3339,10 @@ bool Tokenizer::simplifyTokens1(const std::string &configuration)
if (mTimerResults) {
Timer t("Tokenizer::simplifyTokens1::setValueType", mSettings->showtime, mTimerResults);
+ mSymbolDatabase->setValueTypeInTokenList(false);
mSymbolDatabase->setValueTypeInTokenList(true);
} else {
+ mSymbolDatabase->setValueTypeInTokenList(false);
mSymbolDatabase->setValueTypeInTokenList(true);
}
@@ -3361,9 +3356,9 @@ bool Tokenizer::simplifyTokens1(const std::string &configuration)
if (doValueFlow) {
if (mTimerResults) {
Timer t("Tokenizer::simplifyTokens1::ValueFlow", mSettings->showtime, mTimerResults);
- ValueFlow::setValues(list, mSymbolDatabase, mErrorLogger, mSettings, mTimerResults);
+ ValueFlow::setValues(list, *mSymbolDatabase, mErrorLogger, mSettings, mTimerResults);
} else {
- ValueFlow::setValues(list, mSymbolDatabase, mErrorLogger, mSettings, mTimerResults);
+ ValueFlow::setValues(list, *mSymbolDatabase, mErrorLogger, mSettings, mTimerResults);
}
}
@@ -4022,9 +4017,9 @@ class VariableMap {
std::map mVariableId;
std::map mVariableId_global;
std::stack>> mScopeInfo;
- mutable nonneg int mVarId;
+ mutable nonneg int mVarId{};
public:
- VariableMap() : mVarId(0) {}
+ VariableMap() = default;
void enterScope();
bool leaveScope();
void addVariable(const std::string& varname, bool globalNamespace);
diff --git a/lib/tokenize.h b/lib/tokenize.h
index f296f10ae04..cea8e513238 100644
--- a/lib/tokenize.h
+++ b/lib/tokenize.h
@@ -698,7 +698,7 @@ class CPPCHECKLIB Tokenizer {
ErrorLogger* const mErrorLogger;
/** Symbol database that all checks etc can use */
- SymbolDatabase *mSymbolDatabase;
+ SymbolDatabase* mSymbolDatabase{};
TemplateSimplifier * const mTemplateSimplifier;
@@ -719,21 +719,21 @@ class CPPCHECKLIB Tokenizer {
std::vector mTypedefInfo;
/** variable count */
- nonneg int mVarId;
+ nonneg int mVarId{};
/** unnamed count "Unnamed0", "Unnamed1", "Unnamed2", ... */
- nonneg int mUnnamedCount;
+ nonneg int mUnnamedCount{};
/**
* was there any templates? templates that are "unused" are
* removed from the token list
*/
- bool mCodeWithTemplates;
+ bool mCodeWithTemplates{};
/**
* TimerResults
*/
- TimerResults *mTimerResults;
+ TimerResults* mTimerResults{};
const Preprocessor * const mPreprocessor;
};
diff --git a/lib/tokenlist.cpp b/lib/tokenlist.cpp
index 6a8a5edc858..31077d831f5 100644
--- a/lib/tokenlist.cpp
+++ b/lib/tokenlist.cpp
@@ -49,10 +49,7 @@ static const int AST_MAX_DEPTH = 150;
TokenList::TokenList(const Settings* settings) :
- mTokensFrontBack(),
- mSettings(settings),
- mIsC(false),
- mIsCpp(false)
+ mSettings(settings)
{
mTokensFrontBack.list = this;
}
@@ -333,10 +330,15 @@ bool TokenList::createTokens(std::istream &code, const std::string& file0)
//---------------------------------------------------------------------------
+// NOLINTNEXTLINE(cppcoreguidelines-rvalue-reference-param-not-moved)
void TokenList::createTokens(simplecpp::TokenList&& tokenList)
{
- if (tokenList.cfront())
+ if (tokenList.cfront()) {
+ // this is a copy
+ // TODO: the same as TokenList.files - move that instead
+ // TODO: this points to mFiles when called from createTokens(std::istream &, const std::string&)
mOrigFiles = mFiles = tokenList.cfront()->location.files;
+ }
else
mFiles.clear();
@@ -344,6 +346,7 @@ void TokenList::createTokens(simplecpp::TokenList&& tokenList)
for (const simplecpp::Token *tok = tokenList.cfront(); tok;) {
+ // TODO: move from TokenList
std::string str = tok->str();
// Float literal
@@ -396,14 +399,14 @@ std::size_t TokenList::calculateHash() const
struct AST_state {
std::stack op;
- int depth;
- int inArrayAssignment;
+ int depth{};
+ int inArrayAssignment{};
bool cpp;
- int assign;
- bool inCase; // true from case to :
- bool stopAtColon; // help to properly parse ternary operators
- const Token *functionCallEndPar;
- explicit AST_state(bool cpp) : depth(0), inArrayAssignment(0), cpp(cpp), assign(0), inCase(false),stopAtColon(false), functionCallEndPar(nullptr) {}
+ int assign{};
+ bool inCase{}; // true from case to :
+ bool stopAtColon{}; // help to properly parse ternary operators
+ const Token* functionCallEndPar{};
+ explicit AST_state(bool cpp) : cpp(cpp) {}
};
static Token* skipDecl(Token* tok, std::vector* inner = nullptr)
diff --git a/lib/tokenlist.h b/lib/tokenlist.h
index 68b14523d8e..a150d36f360 100644
--- a/lib/tokenlist.h
+++ b/lib/tokenlist.h
@@ -205,11 +205,11 @@ class CPPCHECKLIB TokenList {
std::vector mOrigFiles;
/** settings */
- const Settings* mSettings;
+ const Settings* mSettings{};
/** File is known to be C/C++ code */
- bool mIsC;
- bool mIsCpp;
+ bool mIsC{};
+ bool mIsCpp{};
};
/// @}
diff --git a/lib/valueflow.cpp b/lib/valueflow.cpp
index 03765c69cdf..6f04d7ff6be 100644
--- a/lib/valueflow.cpp
+++ b/lib/valueflow.cpp
@@ -1925,10 +1925,9 @@ static void valueFlowImpossibleValues(TokenList& tokenList, const Settings* sett
}
}
-static void valueFlowEnumValue(SymbolDatabase * symboldatabase, const Settings * settings)
+static void valueFlowEnumValue(SymbolDatabase & symboldatabase, const Settings * settings)
{
-
- for (Scope & scope : symboldatabase->scopeList) {
+ for (Scope & scope : symboldatabase.scopeList) {
if (scope.type != Scope::eEnum)
continue;
MathLib::bigint value = 0;
@@ -2565,19 +2564,22 @@ struct ValueFlowAnalyzer : Analyzer {
return read;
}
- virtual Action isAliasModified(const Token* tok) const {
+ virtual Action isAliasModified(const Token* tok, int indirect = -1) const {
// Lambda function call
if (Token::Match(tok, "%var% ("))
// TODO: Check if modified in the lambda function
return Action::Invalid;
- int indirect = 0;
- if (const ValueType* vt = tok->valueType()) {
- indirect = vt->pointer;
- if (vt->type == ValueType::ITERATOR)
- ++indirect;
+ if (indirect == -1) {
+ indirect = 0;
+ if (const ValueType* vt = tok->valueType()) {
+ indirect = vt->pointer;
+ if (vt->type == ValueType::ITERATOR)
+ ++indirect;
+ }
}
- if (isVariableChanged(tok, indirect, getSettings(), isCPP()))
- return Action::Invalid;
+ for (int i = 0; i <= indirect; ++i)
+ if (isVariableChanged(tok, i, getSettings(), isCPP()))
+ return Action::Invalid;
return Action::None;
}
@@ -3111,18 +3113,14 @@ struct SingleValueFlowAnalyzer : ValueFlowAnalyzer {
struct ExpressionAnalyzer : SingleValueFlowAnalyzer {
const Token* expr;
- bool local;
- bool unknown;
- bool dependOnThis;
- bool uniqueExprId;
+ bool local = true;
+ bool unknown{};
+ bool dependOnThis{};
+ bool uniqueExprId{};
ExpressionAnalyzer(const Token* e, ValueFlow::Value val, const TokenList& t, const Settings* s)
: SingleValueFlowAnalyzer(std::move(val), t, s),
- expr(e),
- local(true),
- unknown(false),
- dependOnThis(false),
- uniqueExprId(false)
+ expr(e)
{
assert(e && e->exprId() != 0 && "Not a valid expression");
@@ -3214,6 +3212,12 @@ struct ExpressionAnalyzer : SingleValueFlowAnalyzer {
bool isVariable() const override {
return expr->varId() > 0;
}
+
+ Action isAliasModified(const Token* tok, int indirect) const override {
+ if (value.isSymbolicValue() && tok->exprId() == value.tokvalue->exprId())
+ indirect = 0;
+ return SingleValueFlowAnalyzer::isAliasModified(tok, indirect);
+ }
};
struct SameExpressionAnalyzer : ExpressionAnalyzer {
@@ -3232,7 +3236,7 @@ struct SameExpressionAnalyzer : ExpressionAnalyzer {
};
struct OppositeExpressionAnalyzer : ExpressionAnalyzer {
- bool isNot;
+ bool isNot{};
OppositeExpressionAnalyzer(bool pIsNot, const Token* e, ValueFlow::Value val, const TokenList& t, const Settings* s)
: ExpressionAnalyzer(e, std::move(val), t, s), isNot(pIsNot)
@@ -3934,23 +3938,21 @@ static void valueFlowForwardLifetime(Token * tok, TokenList &tokenlist, ErrorLog
}
struct LifetimeStore {
- const Token *argtok;
+ const Token* argtok{};
std::string message;
- ValueFlow::Value::LifetimeKind type;
+ ValueFlow::Value::LifetimeKind type = ValueFlow::Value::LifetimeKind::Object;
ErrorPath errorPath;
- bool inconclusive;
- bool forward;
+ bool inconclusive{};
+ bool forward = true;
struct Context {
- Token* tok;
- TokenList* tokenlist;
- ErrorLogger* errorLogger;
- const Settings* settings;
+ Token* tok{};
+ TokenList* tokenlist{};
+ ErrorLogger* errorLogger{};
+ const Settings* settings{};
};
- LifetimeStore()
- : argtok(nullptr), message(), type(), errorPath(), inconclusive(false), forward(true), mContext(nullptr)
- {}
+ LifetimeStore() = default;
LifetimeStore(const Token* argtok,
std::string message,
@@ -3959,10 +3961,7 @@ struct LifetimeStore {
: argtok(argtok),
message(std::move(message)),
type(type),
- errorPath(),
- inconclusive(inconclusive),
- forward(true),
- mContext(nullptr)
+ inconclusive(inconclusive)
{}
template
@@ -4218,7 +4217,7 @@ struct LifetimeStore {
}
private:
- Context* mContext;
+ Context* mContext{};
void forwardLifetime(Token* tok, TokenList& tokenlist, ErrorLogger* errorLogger, const Settings* settings) const {
if (mContext) {
mContext->tok = tok;
@@ -4652,12 +4651,6 @@ static void valueFlowLifetimeConstructor(Token* tok, TokenList& tokenlist, Error
struct Lambda {
explicit Lambda(const Token* tok)
- : capture(nullptr),
- arguments(nullptr),
- returnTok(nullptr),
- bodyTok(nullptr),
- explicitCaptures(),
- implicitCapture(LifetimeCapture::Undefined)
{
if (!Token::simpleMatch(tok, "[") || !tok->link())
return;
@@ -4693,12 +4686,12 @@ struct Lambda {
}
}
- const Token * capture;
- const Token * arguments;
- const Token * returnTok;
- const Token * bodyTok;
+ const Token* capture{};
+ const Token* arguments{};
+ const Token* returnTok{};
+ const Token* bodyTok{};
std::unordered_map> explicitCaptures;
- LifetimeCapture implicitCapture;
+ LifetimeCapture implicitCapture = LifetimeCapture::Undefined;
std::vector getCaptures() const {
return getArguments(capture);
@@ -4745,7 +4738,7 @@ static bool isContainerOfPointers(const Token* tok, const Settings* settings)
return vt.pointer > 0;
}
-static void valueFlowLifetime(TokenList &tokenlist, SymbolDatabase* /*db*/, ErrorLogger *errorLogger, const Settings *settings)
+static void valueFlowLifetime(TokenList &tokenlist, ErrorLogger *errorLogger, const Settings *settings)
{
for (Token *tok = tokenlist.front(); tok; tok = tok->next()) {
if (!tok->scope())
@@ -5076,11 +5069,11 @@ static const Token * findEndOfFunctionCallForParameter(const Token * parameterTo
return nextAfterAstRightmostLeaf(parent);
}
-static void valueFlowAfterMove(TokenList& tokenlist, const SymbolDatabase* symboldatabase, const Settings* settings)
+static void valueFlowAfterMove(TokenList& tokenlist, const SymbolDatabase& symboldatabase, const Settings* settings)
{
if (!tokenlist.isCPP() || settings->standards.cpp < Standards::CPP11)
return;
- for (const Scope * scope : symboldatabase->functionScopes) {
+ for (const Scope * scope : symboldatabase.functionScopes) {
if (!scope)
continue;
const Token * start = scope->bodyStart;
@@ -5215,9 +5208,9 @@ static const Scope* getLoopScope(const Token* tok)
}
//
-static void valueFlowConditionExpressions(TokenList &tokenlist, const SymbolDatabase* symboldatabase, ErrorLogger *errorLogger, const Settings &settings)
+static void valueFlowConditionExpressions(TokenList &tokenlist, const SymbolDatabase& symboldatabase, ErrorLogger *errorLogger, const Settings &settings)
{
- for (const Scope * scope : symboldatabase->functionScopes) {
+ for (const Scope * scope : symboldatabase.functionScopes) {
if (const Token* incompleteTok = findIncompleteVar(scope->bodyStart, scope->bodyEnd)) {
if (incompleteTok->isIncompleteVar()) {
if (settings.debugwarnings)
@@ -5345,9 +5338,9 @@ static std::set getVarIds(const Token* tok)
return result;
}
-static void valueFlowSymbolic(const TokenList& tokenlist, const SymbolDatabase* symboldatabase, const Settings* settings)
+static void valueFlowSymbolic(const TokenList& tokenlist, const SymbolDatabase& symboldatabase, const Settings* settings)
{
- for (const Scope* scope : symboldatabase->functionScopes) {
+ for (const Scope* scope : symboldatabase.functionScopes) {
for (Token* tok = const_cast(scope->bodyStart); tok != scope->bodyEnd; tok = tok->next()) {
if (!Token::simpleMatch(tok, "="))
continue;
@@ -5438,9 +5431,9 @@ static const Token* isStrlenOf(const Token* tok, const Token* expr, int depth =
static ValueFlow::Value inferCondition(const std::string& op, const Token* varTok, MathLib::bigint val);
-static void valueFlowSymbolicOperators(const SymbolDatabase* symboldatabase, const Settings* settings)
+static void valueFlowSymbolicOperators(const SymbolDatabase& symboldatabase, const Settings* settings)
{
- for (const Scope* scope : symboldatabase->functionScopes) {
+ for (const Scope* scope : symboldatabase.functionScopes) {
for (Token* tok = const_cast(scope->bodyStart); tok != scope->bodyEnd; tok = tok->next()) {
if (tok->hasKnownIntValue())
continue;
@@ -5549,9 +5542,9 @@ struct SymbolicInferModel : InferModel {
}
};
-static void valueFlowSymbolicInfer(const SymbolDatabase* symboldatabase, const Settings* settings)
+static void valueFlowSymbolicInfer(const SymbolDatabase& symboldatabase, const Settings* settings)
{
- for (const Scope* scope : symboldatabase->functionScopes) {
+ for (const Scope* scope : symboldatabase.functionScopes) {
for (Token* tok = const_cast(scope->bodyStart); tok != scope->bodyEnd; tok = tok->next()) {
if (!Token::Match(tok, "-|%comp%"))
continue;
@@ -5829,12 +5822,12 @@ static bool intersects(const C1& c1, const C2& c2)
}
static void valueFlowAfterAssign(TokenList &tokenlist,
- const SymbolDatabase* symboldatabase,
+ const SymbolDatabase& symboldatabase,
ErrorLogger *errorLogger,
const Settings *settings,
const std::set& skippedFunctions)
{
- for (const Scope * scope : symboldatabase->functionScopes) {
+ for (const Scope * scope : symboldatabase.functionScopes) {
if (skippedFunctions.count(scope))
continue;
std::unordered_map> backAssigns;
@@ -5966,11 +5959,11 @@ static std::vector getVariables(const Token* tok)
}
static void valueFlowAfterSwap(TokenList& tokenlist,
- const SymbolDatabase* symboldatabase,
+ const SymbolDatabase& symboldatabase,
ErrorLogger* errorLogger,
const Settings* settings)
{
- for (const Scope* scope : symboldatabase->functionScopes) {
+ for (const Scope* scope : symboldatabase.functionScopes) {
for (Token* tok = const_cast(scope->bodyStart); tok != scope->bodyEnd; tok = tok->next()) {
if (!Token::simpleMatch(tok, "swap ("))
continue;
@@ -6039,7 +6032,7 @@ static void insertNegateKnown(std::list& values, const std::li
struct ConditionHandler {
struct Condition {
- const Token *vartok;
+ const Token* vartok{};
std::list true_values;
std::list false_values;
bool inverted = false;
@@ -6101,8 +6094,6 @@ struct ConditionHandler {
return ctx;
}
-
- Condition() : vartok(nullptr), true_values(), false_values(), inverted(false), impossible(true) {}
};
virtual std::vector parse(const Token* tok, const Settings* settings) const = 0;
@@ -6140,12 +6131,12 @@ struct ConditionHandler {
}
void traverseCondition(const TokenList& tokenlist,
- const SymbolDatabase* symboldatabase,
+ const SymbolDatabase& symboldatabase,
const Settings* settings,
const std::set& skippedFunctions,
const std::function& f) const
{
- for (const Scope *scope : symboldatabase->functionScopes) {
+ for (const Scope *scope : symboldatabase.functionScopes) {
if (skippedFunctions.count(scope))
continue;
for (Token *tok = const_cast(scope->bodyStart); tok != scope->bodyEnd; tok = tok->next()) {
@@ -6178,7 +6169,7 @@ struct ConditionHandler {
}
void beforeCondition(TokenList& tokenlist,
- const SymbolDatabase* symboldatabase,
+ const SymbolDatabase& symboldatabase,
ErrorLogger* errorLogger,
const Settings* settings,
const std::set& skippedFunctions) const {
@@ -6326,7 +6317,7 @@ struct ConditionHandler {
}
void afterCondition(TokenList& tokenlist,
- const SymbolDatabase* symboldatabase,
+ const SymbolDatabase& symboldatabase,
ErrorLogger* errorLogger,
const Settings* settings,
const std::set& skippedFunctions) const {
@@ -6659,7 +6650,7 @@ struct ConditionHandler {
static void valueFlowCondition(const ValuePtr& handler,
TokenList& tokenlist,
- SymbolDatabase* symboldatabase,
+ SymbolDatabase& symboldatabase,
ErrorLogger* errorLogger,
const Settings* settings,
const std::set& skippedFunctions)
@@ -7082,9 +7073,9 @@ static void valueFlowForLoopSimplifyAfter(Token* fortok, nonneg int varid, const
}
}
-static void valueFlowForLoop(TokenList &tokenlist, const SymbolDatabase* symboldatabase, ErrorLogger *errorLogger, const Settings *settings)
+static void valueFlowForLoop(TokenList &tokenlist, const SymbolDatabase& symboldatabase, ErrorLogger *errorLogger, const Settings *settings)
{
- for (const Scope &scope : symboldatabase->scopeList) {
+ for (const Scope &scope : symboldatabase.scopeList) {
if (scope.type != Scope::eFor)
continue;
@@ -7158,10 +7149,9 @@ static void valueFlowForLoop(TokenList &tokenlist, const SymbolDatabase* symbold
struct MultiValueFlowAnalyzer : ValueFlowAnalyzer {
std::unordered_map values;
std::unordered_map vars;
- SymbolDatabase* symboldatabase;
- MultiValueFlowAnalyzer(const std::unordered_map& args, const TokenList& t, const Settings* set, SymbolDatabase* s)
- : ValueFlowAnalyzer(t, set), values(), vars(), symboldatabase(s) {
+ MultiValueFlowAnalyzer(const std::unordered_map& args, const TokenList& t, const Settings* set)
+ : ValueFlowAnalyzer(t, set) {
for (const auto& p:args) {
values[p.first->declarationId()] = p.second;
vars[p.first->declarationId()] = p.first;
@@ -7357,14 +7347,13 @@ bool productParams(const Settings* settings, const std::unordered_map>& vars)
{
const bool r = productParams(&settings, vars, [&](const std::unordered_map& arg) {
- MultiValueFlowAnalyzer a(arg, tokenlist, &settings, symboldatabase);
+ MultiValueFlowAnalyzer a(arg, tokenlist, &settings);
valueFlowGenericForward(const_cast(functionScope->bodyStart), functionScope->bodyEnd, a, settings);
});
if (!r) {
@@ -7399,9 +7388,9 @@ static void valueFlowInjectParameter(const TokenList& tokenlist,
settings);
}
-static void valueFlowSwitchVariable(TokenList &tokenlist, const SymbolDatabase* symboldatabase, ErrorLogger *errorLogger, const Settings *settings)
+static void valueFlowSwitchVariable(TokenList &tokenlist, const SymbolDatabase& symboldatabase, ErrorLogger *errorLogger, const Settings *settings)
{
- for (const Scope &scope : symboldatabase->scopeList) {
+ for (const Scope &scope : symboldatabase.scopeList) {
if (scope.type != Scope::ScopeType::eSwitch)
continue;
if (!Token::Match(scope.classDef, "switch ( %var% ) {"))
@@ -7535,10 +7524,10 @@ IteratorRange MakeIteratorRange(Iterator start, Iterator last)
return {start, last};
}
-static void valueFlowSubFunction(TokenList& tokenlist, SymbolDatabase* symboldatabase, ErrorLogger* errorLogger, const Settings& settings)
+static void valueFlowSubFunction(TokenList& tokenlist, SymbolDatabase& symboldatabase, ErrorLogger* errorLogger, const Settings& settings)
{
int id = 0;
- for (const Scope* scope : MakeIteratorRange(symboldatabase->functionScopes.crbegin(), symboldatabase->functionScopes.crend())) {
+ for (const Scope* scope : MakeIteratorRange(symboldatabase.functionScopes.crbegin(), symboldatabase.functionScopes.crend())) {
const Function* function = scope->function;
if (!function)
continue;
@@ -7612,17 +7601,17 @@ static void valueFlowSubFunction(TokenList& tokenlist, SymbolDatabase* symboldat
argvars[argvar] = argvalues;
}
- valueFlowInjectParameter(tokenlist, symboldatabase, errorLogger, settings, calledFunctionScope, argvars);
+ valueFlowInjectParameter(tokenlist, errorLogger, settings, calledFunctionScope, argvars);
}
}
}
-static void valueFlowFunctionDefaultParameter(const TokenList& tokenlist, const SymbolDatabase* symboldatabase, const Settings* settings)
+static void valueFlowFunctionDefaultParameter(const TokenList& tokenlist, const SymbolDatabase& symboldatabase, const Settings* settings)
{
if (!tokenlist.isCPP())
return;
- for (const Scope* scope : symboldatabase->functionScopes) {
+ for (const Scope* scope : symboldatabase.functionScopes) {
const Function* function = scope->function;
if (!function)
continue;
@@ -7947,7 +7936,7 @@ static Token* findStartToken(const Variable* var, Token* start, const Library* l
return tok;
}
-static void valueFlowUninit(TokenList& tokenlist, SymbolDatabase* /*symbolDatabase*/, const Settings* settings)
+static void valueFlowUninit(TokenList& tokenlist, const Settings* settings)
{
for (Token *tok = tokenlist.front(); tok; tok = tok->next()) {
if (!tok->scope()->isExecutable())
@@ -8677,13 +8666,13 @@ static const Scope* getFunctionScope(const Scope* scope) {
}
static void valueFlowContainerSize(TokenList& tokenlist,
- const SymbolDatabase* symboldatabase,
+ const SymbolDatabase& symboldatabase,
ErrorLogger* /*errorLogger*/,
const Settings* settings,
const std::set& skippedFunctions)
{
// declaration
- for (const Variable *var : symboldatabase->variableList()) {
+ for (const Variable *var : symboldatabase.variableList()) {
if (!var)
continue;
if (!var->scope() || !var->scope()->bodyEnd || !var->scope()->bodyStart)
@@ -8754,7 +8743,7 @@ static void valueFlowContainerSize(TokenList& tokenlist,
}
// after assignment
- for (const Scope *functionScope : symboldatabase->functionScopes) {
+ for (const Scope *functionScope : symboldatabase.functionScopes) {
for (Token* tok = const_cast(functionScope->bodyStart); tok != functionScope->bodyEnd; tok = tok->next()) {
if (Token::Match(tok, "%name%|;|{|} %var% = %str% ;")) {
Token* containerTok = tok->next();
@@ -8891,7 +8880,7 @@ struct ContainerConditionHandler : ConditionHandler {
}
};
-static void valueFlowDynamicBufferSize(const TokenList& tokenlist, const SymbolDatabase* symboldatabase, const Settings* settings)
+static void valueFlowDynamicBufferSize(const TokenList& tokenlist, const SymbolDatabase& symboldatabase, const Settings* settings)
{
auto getBufferSizeFromAllocFunc = [&](const Token* funcTok) -> MathLib::bigint {
MathLib::bigint sizeValue = -1;
@@ -8962,7 +8951,7 @@ static void valueFlowDynamicBufferSize(const TokenList& tokenlist, const SymbolD
return sizeValue;
};
- for (const Scope *functionScope : symboldatabase->functionScopes) {
+ for (const Scope *functionScope : symboldatabase.functionScopes) {
for (const Token *tok = functionScope->bodyStart; tok != functionScope->bodyEnd; tok = tok->next()) {
if (!Token::Match(tok, "[;{}] %var% ="))
continue;
@@ -8976,7 +8965,7 @@ static void valueFlowDynamicBufferSize(const TokenList& tokenlist, const SymbolD
if (!rhs)
continue;
- const bool isNew = symboldatabase->isCPP() && rhs->str() == "new";
+ const bool isNew = symboldatabase.isCPP() && rhs->str() == "new";
if (!isNew && !Token::Match(rhs->previous(), "%name% ("))
continue;
@@ -9060,9 +9049,9 @@ static bool getMinMaxValues(const std::string &typestr, const Settings *settings
return getMinMaxValues(&vt, settings->platform, minvalue, maxvalue);
}
-static void valueFlowSafeFunctions(TokenList& tokenlist, const SymbolDatabase* symboldatabase, const Settings* settings)
+static void valueFlowSafeFunctions(TokenList& tokenlist, const SymbolDatabase& symboldatabase, const Settings* settings)
{
- for (const Scope *functionScope : symboldatabase->functionScopes) {
+ for (const Scope *functionScope : symboldatabase.functionScopes) {
if (!functionScope->bodyStart)
continue;
const Function *function = functionScope->function;
@@ -9115,12 +9104,12 @@ static void valueFlowSafeFunctions(TokenList& tokenlist, const SymbolDatabase* s
std::list argValues;
argValues.emplace_back(0);
argValues.back().valueType = ValueFlow::Value::ValueType::FLOAT;
- argValues.back().floatValue = isLow ? low : -1E25f;
+ argValues.back().floatValue = isLow ? low : -1E25;
argValues.back().errorPath.emplace_back(arg.nameToken(), "Safe checks: Assuming argument has value " + MathLib::toString(argValues.back().floatValue));
argValues.back().safe = true;
argValues.emplace_back(0);
argValues.back().valueType = ValueFlow::Value::ValueType::FLOAT;
- argValues.back().floatValue = isHigh ? high : 1E25f;
+ argValues.back().floatValue = isHigh ? high : 1E25;
argValues.back().errorPath.emplace_back(arg.nameToken(), "Safe checks: Assuming argument has value " + MathLib::toString(argValues.back().floatValue));
argValues.back().safe = true;
valueFlowForward(const_cast(functionScope->bodyStart->next()),
@@ -9216,14 +9205,14 @@ const ValueFlow::Value *ValueFlow::valueFlowConstantFoldAST(Token *expr, const S
struct ValueFlowState {
explicit ValueFlowState(TokenList& tokenlist,
- SymbolDatabase* symboldatabase = nullptr,
+ SymbolDatabase& symboldatabase,
ErrorLogger* errorLogger = nullptr,
const Settings* settings = nullptr)
: tokenlist(tokenlist), symboldatabase(symboldatabase), errorLogger(errorLogger), settings(settings)
{}
TokenList& tokenlist;
- SymbolDatabase* symboldatabase = nullptr;
+ SymbolDatabase& symboldatabase;
ErrorLogger* errorLogger = nullptr;
const Settings* settings = nullptr;
std::set skippedFunctions = {};
@@ -9313,7 +9302,7 @@ struct ValueFlowPassRunner {
void setSkippedFunctions()
{
if (state.settings->performanceValueFlowMaxIfCount > 0) {
- for (const Scope* functionScope : state.symboldatabase->functionScopes) {
+ for (const Scope* functionScope : state.symboldatabase.functionScopes) {
int countIfScopes = 0;
std::vector scopes{functionScope};
while (!scopes.empty()) {
@@ -9386,7 +9375,7 @@ ValueFlowPassAdaptor makeValueFlowPassAdaptor(const char* name, bool cpp, F r
makeValueFlowPassAdaptor(#__VA_ARGS__, \
cpp, \
[](TokenList& tokenlist, \
- SymbolDatabase* symboldatabase, \
+ SymbolDatabase& symboldatabase, \
ErrorLogger* errorLogger, \
const Settings* settings, \
const std::set& skippedFunctions) { \
@@ -9402,7 +9391,7 @@ ValueFlowPassAdaptor makeValueFlowPassAdaptor(const char* name, bool cpp, F r
#define VFA_CPP(...) VALUEFLOW_ADAPTOR(true, __VA_ARGS__)
void ValueFlow::setValues(TokenList& tokenlist,
- SymbolDatabase* symboldatabase,
+ SymbolDatabase& symboldatabase,
ErrorLogger* errorLogger,
const Settings* settings,
TimerResultsIntf* timerResults)
@@ -9422,7 +9411,7 @@ void ValueFlow::setValues(TokenList& tokenlist,
VFA(valueFlowNumber(tokenlist, settings)),
VFA(valueFlowGlobalStaticVar(tokenlist, settings)),
VFA(valueFlowPointerAlias(tokenlist, settings)),
- VFA(valueFlowLifetime(tokenlist, symboldatabase, errorLogger, settings)),
+ VFA(valueFlowLifetime(tokenlist, errorLogger, settings)),
VFA(valueFlowSymbolic(tokenlist, symboldatabase, settings)),
VFA(valueFlowBitAnd(tokenlist, settings)),
VFA(valueFlowSameExpressions(tokenlist, settings)),
@@ -9445,9 +9434,9 @@ void ValueFlow::setValues(TokenList& tokenlist,
VFA(valueFlowForLoop(tokenlist, symboldatabase, errorLogger, settings)),
VFA(valueFlowSubFunction(tokenlist, symboldatabase, errorLogger, *settings)),
VFA(valueFlowFunctionReturn(tokenlist, errorLogger, settings)),
- VFA(valueFlowLifetime(tokenlist, symboldatabase, errorLogger, settings)),
+ VFA(valueFlowLifetime(tokenlist, errorLogger, settings)),
VFA(valueFlowFunctionDefaultParameter(tokenlist, symboldatabase, settings)),
- VFA(valueFlowUninit(tokenlist, symboldatabase, settings)),
+ VFA(valueFlowUninit(tokenlist, settings)),
VFA_CPP(valueFlowAfterMove(tokenlist, symboldatabase, settings)),
VFA_CPP(valueFlowSmartPointer(tokenlist, errorLogger, settings)),
VFA_CPP(valueFlowIterators(tokenlist, settings)),
diff --git a/lib/valueflow.h b/lib/valueflow.h
index d54de1e206a..02e81e6609c 100644
--- a/lib/valueflow.h
+++ b/lib/valueflow.h
@@ -52,7 +52,7 @@ namespace ValueFlow {
/// Perform valueflow analysis.
void setValues(TokenList& tokenlist,
- SymbolDatabase* symboldatabase,
+ SymbolDatabase& symboldatabase,
ErrorLogger* errorLogger,
const Settings* settings,
TimerResultsIntf* timerResults);
@@ -72,19 +72,19 @@ namespace ValueFlow {
bool isContainerSizeChanged(const Token* tok, int indirect, const Settings* settings = nullptr, int depth = 20);
struct LifetimeToken {
- const Token* token;
+ const Token* token{};
Value::ErrorPath errorPath;
- bool addressOf;
- bool inconclusive;
+ bool addressOf{};
+ bool inconclusive{};
- LifetimeToken() : token(nullptr), errorPath(), addressOf(false), inconclusive(false) {}
+ LifetimeToken() = default;
LifetimeToken(const Token* token, Value::ErrorPath errorPath)
- : token(token), errorPath(std::move(errorPath)), addressOf(false), inconclusive(false)
+ : token(token), errorPath(std::move(errorPath))
{}
LifetimeToken(const Token* token, bool addressOf, Value::ErrorPath errorPath)
- : token(token), errorPath(std::move(errorPath)), addressOf(addressOf), inconclusive(false)
+ : token(token), errorPath(std::move(errorPath)), addressOf(addressOf)
{}
static std::vector setAddressOf(std::vector v, bool b) {
diff --git a/lib/vfvalue.cpp b/lib/vfvalue.cpp
index 2c1da06cfbc..6a1ba6f3b9d 100644
--- a/lib/vfvalue.cpp
+++ b/lib/vfvalue.cpp
@@ -26,27 +26,10 @@
namespace ValueFlow {
Value::Value(const Token *c, long long val, Bound b)
- : valueType(ValueType::INT),
- bound(b),
+ : bound(b),
intvalue(val),
- tokvalue(nullptr),
- floatValue(0.0),
varvalue(val),
- condition(c),
- varId(0),
- safe(false),
- conditional(false),
- macro(false),
- defaultArg(false),
- indirect(0),
- moveKind(MoveKind::NonMovedVariable),
- path(0),
- wideintvalue(0),
- subexpressions(),
- capturetok(nullptr),
- lifetimeKind(LifetimeKind::Object),
- lifetimeScope(LifetimeScope::Local),
- valueKind(ValueKind::Possible) {
+ condition(c) {
errorPath.emplace_back(c, "Assuming that condition '" + c->expressionString() + "' is not redundant");
}
diff --git a/lib/vfvalue.h b/lib/vfvalue.h
index a32f86e990a..7f7089845a5 100644
--- a/lib/vfvalue.h
+++ b/lib/vfvalue.h
@@ -43,28 +43,11 @@ namespace ValueFlow
using ErrorPath = std::list;
enum class Bound { Upper, Lower, Point };
- explicit Value(long long val = 0, Bound b = Bound::Point)
- : valueType(ValueType::INT),
+ explicit Value(long long val = 0, Bound b = Bound::Point) :
bound(b),
intvalue(val),
- tokvalue(nullptr),
- floatValue(0.0),
varvalue(val),
- condition(nullptr),
- varId(0U),
- safe(false),
- conditional(false),
- macro(false),
- defaultArg(false),
- indirect(0),
- moveKind(MoveKind::NonMovedVariable),
- path(0),
- wideintvalue(val),
- subexpressions(),
- capturetok(nullptr),
- lifetimeKind(LifetimeKind::Object),
- lifetimeScope(LifetimeScope::Local),
- valueKind(ValueKind::Possible)
+ wideintvalue(val)
{}
Value(const Token* c, long long val, Bound b = Bound::Point);
@@ -220,7 +203,7 @@ namespace ValueFlow
ITERATOR_START,
ITERATOR_END,
SYMBOLIC
- } valueType;
+ } valueType = ValueType::INT;
bool isIntValue() const {
return valueType == ValueType::INT;
}
@@ -275,57 +258,57 @@ namespace ValueFlow
}
/** The value bound */
- Bound bound;
+ Bound bound = Bound::Point;
/** int value (or sometimes bool value?) */
- long long intvalue;
+ long long intvalue{};
/** token value - the token that has the value. this is used for pointer aliases, strings, etc. */
- const Token *tokvalue;
+ const Token* tokvalue{};
/** float value */
- double floatValue;
+ double floatValue{};
/** For calculated values - variable value that calculated value depends on */
- long long varvalue;
+ long long varvalue{};
/** Condition that this value depends on */
- const Token *condition;
+ const Token* condition{};
ErrorPath errorPath;
ErrorPath debugPath;
/** For calculated values - varId that calculated value depends on */
- nonneg int varId;
+ nonneg int varId{};
/** value relies on safe checking */
- bool safe;
+ bool safe{};
/** Conditional value */
- bool conditional;
+ bool conditional{};
/** Value is is from an expanded macro */
- bool macro;
+ bool macro{};
/** Is this value passed as default parameter to the function? */
- bool defaultArg;
+ bool defaultArg{};
- int indirect;
+ int indirect{};
/** kind of moved */
- enum class MoveKind {NonMovedVariable, MovedVariable, ForwardedVariable} moveKind;
+ enum class MoveKind { NonMovedVariable, MovedVariable, ForwardedVariable } moveKind = MoveKind::NonMovedVariable;
/** Path id */
- MathLib::bigint path;
+ MathLib::bigint path{};
/** int value before implicit truncation */
- long long wideintvalue;
+ long long wideintvalue{};
std::vector subexpressions;
// Set to where a lifetime is captured by value
- const Token* capturetok;
+ const Token* capturetok{};
enum class LifetimeKind {
// Pointer points to a member of lifetime
@@ -338,9 +321,9 @@ namespace ValueFlow
Iterator,
// A pointer that holds the address of the lifetime
Address
- } lifetimeKind;
+ } lifetimeKind = LifetimeKind::Object;
- enum class LifetimeScope { Local, Argument, SubFunction, ThisPointer, ThisValue } lifetimeScope;
+ enum class LifetimeScope { Local, Argument, SubFunction, ThisPointer, ThisValue } lifetimeScope = LifetimeScope::Local;
static const char* toString(MoveKind moveKind);
static const char* toString(LifetimeKind lifetimeKind);
@@ -357,7 +340,7 @@ namespace ValueFlow
Inconclusive,
/** Listed values are impossible */
Impossible
- } valueKind;
+ } valueKind = ValueKind::Possible;
void setKnown() {
valueKind = ValueKind::Known;
diff --git a/test/cli/test-other.py b/test/cli/test-other.py
index 29db8ea0c9f..d1e329434a1 100644
--- a/test/cli/test-other.py
+++ b/test/cli/test-other.py
@@ -60,4 +60,15 @@ def test_missing_include_inline_suppr(tmpdir):
args = ['--enable=missingInclude', '--inline-suppr', test_file]
_, _, stderr = cppcheck(args)
- assert stderr == ''
\ No newline at end of file
+ assert stderr == ''
+
+def test_invalid_library(tmpdir):
+ args = ['--library=none', '--library=posix', '--library=none2', '--platform=native', 'file.c']
+
+ exitcode, stdout, stderr = cppcheck(args)
+ assert exitcode == 1
+ assert (stdout == "cppcheck: Failed to load library configuration file 'none'. File not found\n"
+ "cppcheck: Failed to load library configuration file 'none2'. File not found\n")
+ assert stderr == ""
+
+# TODO: test missing std.cfg
\ No newline at end of file
diff --git a/test/fixture.cpp b/test/fixture.cpp
index 0f7c99bf398..e332fbf7aaf 100644
--- a/test/fixture.cpp
+++ b/test/fixture.cpp
@@ -79,10 +79,7 @@ std::size_t TestFixture::todos_counter = 0;
std::size_t TestFixture::succeeded_todos_counter = 0;
TestFixture::TestFixture(const char * const _name)
- : mVerbose(false),
- exename(),
- quiet_tests(false),
- classname(_name)
+ : classname(_name)
{
TestRegistry::theInstance().addTest(this);
}
@@ -402,6 +399,8 @@ void TestFixture::setTemplateFormat(const std::string &templateFormat)
}
TestFixture::SettingsBuilder& TestFixture::SettingsBuilder::library(const char lib[]) {
+ if (REDUNDANT_CHECK && std::find(settings.libraries.cbegin(), settings.libraries.cend(), lib) != settings.libraries.cend())
+ throw std::runtime_error("redundant setting: libraries (" + std::string(lib) + ")");
// TODO: exename is not yet set
LOAD_LIB_2_EXE(settings.library, lib, fixture.exename.c_str());
// strip extension
@@ -417,6 +416,11 @@ TestFixture::SettingsBuilder& TestFixture::SettingsBuilder::library(const char l
TestFixture::SettingsBuilder& TestFixture::SettingsBuilder::platform(cppcheck::Platform::Type type)
{
const std::string platformStr = cppcheck::Platform::toString(type);
+
+ // TODO: the default platform differs between Windows and Linux
+ //if (REDUNDANT_CHECK && settings.platform.type == type)
+ // throw std::runtime_error("redundant setting: platform (" + platformStr + ")");
+
std::string errstr;
// TODO: exename is not yet set
if (!settings.platform.set(platformStr, errstr, {fixture.exename}))
diff --git a/test/fixture.h b/test/fixture.h
index dd8264c8cd5..a09a193f0e6 100644
--- a/test/fixture.h
+++ b/test/fixture.h
@@ -47,7 +47,7 @@ class TestFixture : public ErrorLogger {
static std::size_t fails_counter;
static std::size_t todos_counter;
static std::size_t succeeded_todos_counter;
- bool mVerbose;
+ bool mVerbose{};
std::string mTemplateFormat;
std::string mTemplateLocation;
std::string mTestname;
@@ -55,7 +55,7 @@ class TestFixture : public ErrorLogger {
protected:
std::string exename;
std::string testToRun;
- bool quiet_tests;
+ bool quiet_tests{};
virtual void run() = 0;
@@ -130,7 +130,6 @@ class TestFixture : public ErrorLogger {
check.runChecks(tokenizer, settings, errorLogger);
}
- // TODO: bail out on redundant settings
class SettingsBuilder
{
public:
@@ -138,41 +137,59 @@ class TestFixture : public ErrorLogger {
SettingsBuilder(const TestFixture &fixture, Settings settings) : fixture(fixture), settings(std::move(settings)) {}
SettingsBuilder& severity(Severity::SeverityType sev, bool b = true) {
+ if (REDUNDANT_CHECK && settings.severity.isEnabled(sev) == b)
+ throw std::runtime_error("redundant setting: severity");
settings.severity.setEnabled(sev, b);
return *this;
}
SettingsBuilder& certainty(Certainty cert, bool b = true) {
+ if (REDUNDANT_CHECK && settings.certainty.isEnabled(cert) == b)
+ throw std::runtime_error("redundant setting: certainty");
settings.certainty.setEnabled(cert, b);
return *this;
}
SettingsBuilder& clang() {
+ if (REDUNDANT_CHECK && settings.clang)
+ throw std::runtime_error("redundant setting: clang");
settings.clang = true;
return *this;
}
SettingsBuilder& checkLibrary() {
+ if (REDUNDANT_CHECK && settings.checkLibrary)
+ throw std::runtime_error("redundant setting: checkLibrary");
settings.checkLibrary = true;
return *this;
}
SettingsBuilder& checkUnusedTemplates(bool b = true) {
+ if (REDUNDANT_CHECK && settings.checkUnusedTemplates == b)
+ throw std::runtime_error("redundant setting: checkUnusedTemplates");
settings.checkUnusedTemplates = b;
return *this;
}
SettingsBuilder& debugwarnings(bool b = true) {
+ if (REDUNDANT_CHECK && settings.debugwarnings == b)
+ throw std::runtime_error("redundant setting: debugwarnings");
settings.debugwarnings = b;
return *this;
}
SettingsBuilder& c(Standards::cstd_t std) {
+ // TODO: CLatest and C11 are the same - handle differently
+ //if (REDUNDANT_CHECK && settings.standards.c == std)
+ // throw std::runtime_error("redundant setting: standards.c");
settings.standards.c = std;
return *this;
}
SettingsBuilder& cpp(Standards::cppstd_t std) {
+ // TODO: CPPLatest and CPP20 are the same - handle differently
+ //if (REDUNDANT_CHECK && settings.standards.cpp == std)
+ // throw std::runtime_error("redundant setting: standards.cpp");
settings.standards.cpp = std;
return *this;
}
@@ -184,11 +201,15 @@ class TestFixture : public ErrorLogger {
SettingsBuilder& platform(cppcheck::Platform::Type type);
SettingsBuilder& checkConfiguration() {
+ if (REDUNDANT_CHECK && settings.checkConfiguration)
+ throw std::runtime_error("redundant setting: checkConfiguration");
settings.checkConfiguration = true;
return *this;
}
SettingsBuilder& checkHeaders(bool b = true) {
+ if (REDUNDANT_CHECK && settings.checkHeaders == b)
+ throw std::runtime_error("redundant setting: checkHeaders");
settings.checkHeaders = b;
return *this;
}
@@ -199,6 +220,8 @@ class TestFixture : public ErrorLogger {
private:
const TestFixture &fixture;
Settings settings;
+
+ const bool REDUNDANT_CHECK = false;
};
SettingsBuilder settingsBuilder() const {
diff --git a/test/helpers.h b/test/helpers.h
index 9699d6b1f84..113668141f3 100644
--- a/test/helpers.h
+++ b/test/helpers.h
@@ -106,17 +106,16 @@ class PreprocessorHelper
#define dinit(T, ...) \
([&] { T ${}; __VA_ARGS__; return $; }())
-#if (defined(__GNUC__) && (__GNUC__ >= 5)) || defined(__clang__)
-// work around Clang compilation error
+// Default construct object to avoid bug in clang
// error: default member initializer for 'y' needed within definition of enclosing class 'X' outside of member functions
-// work around GCC compilation error
-// error: default member initializer for ‘x::y::z’ required before the end of its enclosing class
// see https://stackoverflow.com/questions/53408962
-#define DINIT_NOEXCEPT noexcept
-#else
-// work around GCC 4.8 compilation error
-// error: function 'x()' defaulted on its first declaration with an exception-specification that differs from the implicit declaration 'x()'
-#define DINIT_NOEXCEPT
-#endif
+struct make_default_obj
+{
+ template
+ operator T() const // NOLINT
+ {
+ return T{};
+ }
+};
#endif // helpersH
diff --git a/test/testbufferoverrun.cpp b/test/testbufferoverrun.cpp
index 97841f45a7c..862add41981 100644
--- a/test/testbufferoverrun.cpp
+++ b/test/testbufferoverrun.cpp
@@ -76,7 +76,7 @@ class TestBufferOverrun : public TestFixture {
// Clear the error buffer..
errout.str("");
- const Settings settings = settingsBuilder(settings0).severity(Severity::style).severity(Severity::warning).severity(Severity::portability).severity(Severity::performance)
+ const Settings settings = settingsBuilder(settings0).severity(Severity::performance)
.c(Standards::CLatest).cpp(Standards::CPPLatest).certainty(Certainty::inconclusive).build();
// Raw tokens..
diff --git a/test/testcheck.cpp b/test/testcheck.cpp
new file mode 100644
index 00000000000..8e570712407
--- /dev/null
+++ b/test/testcheck.cpp
@@ -0,0 +1,53 @@
+/*
+ * Cppcheck - A tool for static C/C++ code analysis
+ * Copyright (C) 2007-2023 Cppcheck team.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+#include "check.h"
+#include "fixture.h"
+
+class TestCheck : public TestFixture {
+public:
+ TestCheck() : TestFixture("TestCheck") {}
+
+private:
+ void run() override {
+ TEST_CASE(instancesSorted);
+ TEST_CASE(classInfoFormat);
+ }
+
+ void instancesSorted() const {
+ for (std::list::const_iterator i = Check::instances().cbegin(); i != Check::instances().cend(); ++i) {
+ std::list::const_iterator j = i;
+ ++j;
+ if (j != Check::instances().cend()) {
+ ASSERT_EQUALS(true, (*i)->name() < (*j)->name());
+ }
+ }
+ }
+
+ void classInfoFormat() const {
+ for (std::list::const_iterator i = Check::instances().cbegin(); i != Check::instances().cend(); ++i) {
+ const std::string info = (*i)->classInfo();
+ if (!info.empty()) {
+ ASSERT('\n' != info[0]); // No \n in the beginning
+ ASSERT('\n' == info.back()); // \n at end
+ if (info.size() > 1)
+ ASSERT('\n' != info[info.length()-2]); // Only one \n at end
+ }
+ }
+ }
+};
diff --git a/test/testclass.cpp b/test/testclass.cpp
index 430fb6c0984..b2a343a4446 100644
--- a/test/testclass.cpp
+++ b/test/testclass.cpp
@@ -39,7 +39,7 @@ class TestClass : public TestFixture {
private:
Settings settings0 = settingsBuilder().severity(Severity::style).library("std.cfg").build();
- Settings settings1 = settingsBuilder().severity(Severity::warning).library("std.cfg").build();
+ const Settings settings1 = settingsBuilder().severity(Severity::warning).library("std.cfg").build();
void run() override {
TEST_CASE(virtualDestructor1); // Base class not found => no error
diff --git a/test/testcondition.cpp b/test/testcondition.cpp
index b9a7d6e5c34..96212fef676 100644
--- a/test/testcondition.cpp
+++ b/test/testcondition.cpp
@@ -127,7 +127,7 @@ class TestCondition : public TestFixture {
TEST_CASE(knownConditionIncrementLoop); // #9808
}
- void check(const char code[], Settings &settings, const char* filename = "test.cpp") {
+ void check(const char code[], const Settings &settings, const char* filename = "test.cpp") {
// Clear the error buffer..
errout.str("");
@@ -154,7 +154,7 @@ class TestCondition : public TestFixture {
}
void check(const char code[], const char* filename = "test.cpp", bool inconclusive = false) {
- Settings settings = settingsBuilder(settings0).certainty(Certainty::inconclusive, inconclusive).build();
+ const Settings settings = settingsBuilder(settings0).certainty(Certainty::inconclusive, inconclusive).build();
check(code, settings, filename);
}
@@ -5645,7 +5645,7 @@ class TestCondition : public TestFixture {
}
void compareOutOfTypeRange() {
- Settings settingsUnix64 = settingsBuilder().severity(Severity::style).platform(cppcheck::Platform::Type::Unix64).build();
+ const Settings settingsUnix64 = settingsBuilder().severity(Severity::style).platform(cppcheck::Platform::Type::Unix64).build();
check("void f(unsigned char c) {\n"
" if (c == 256) {}\n"
diff --git a/test/testcppcheck.cpp b/test/testcppcheck.cpp
index 08b1adcbd94..60726a425ea 100644
--- a/test/testcppcheck.cpp
+++ b/test/testcppcheck.cpp
@@ -16,7 +16,6 @@
* along with this program. If not, see .
*/
-#include "check.h"
#include "color.h"
#include "cppcheck.h"
#include "errorlogger.h"
@@ -45,33 +44,9 @@ class TestCppcheck : public TestFixture {
};
void run() override {
- TEST_CASE(instancesSorted);
- TEST_CASE(classInfoFormat);
TEST_CASE(getErrorMessages);
}
- void instancesSorted() const {
- for (std::list::const_iterator i = Check::instances().cbegin(); i != Check::instances().cend(); ++i) {
- std::list::const_iterator j = i;
- ++j;
- if (j != Check::instances().cend()) {
- ASSERT_EQUALS(true, (*i)->name() < (*j)->name());
- }
- }
- }
-
- void classInfoFormat() const {
- for (std::list::const_iterator i = Check::instances().cbegin(); i != Check::instances().cend(); ++i) {
- const std::string info = (*i)->classInfo();
- if (!info.empty()) {
- ASSERT('\n' != info[0]); // No \n in the beginning
- ASSERT('\n' == info.back()); // \n at end
- if (info.size() > 1)
- ASSERT('\n' != info[info.length()-2]); // Only one \n at end
- }
- }
- }
-
void getErrorMessages() const {
ErrorLogger2 errorLogger;
CppCheck::getErrorMessages(errorLogger);
diff --git a/test/testexceptionsafety.cpp b/test/testexceptionsafety.cpp
index 274a895a6cb..97df8227547 100644
--- a/test/testexceptionsafety.cpp
+++ b/test/testexceptionsafety.cpp
@@ -63,7 +63,7 @@ class TestExceptionSafety : public TestFixture {
// Clear the error buffer..
errout.str("");
- Settings settings1 = settingsBuilder(s ? *s : settings).certainty(Certainty::inconclusive, inconclusive).build();
+ const Settings settings1 = settingsBuilder(s ? *s : settings).certainty(Certainty::inconclusive, inconclusive).build();
// Tokenize..
Tokenizer tokenizer(&settings1, this);
@@ -397,7 +397,7 @@ class TestExceptionSafety : public TestFixture {
ASSERT_EQUALS("[test.cpp:3] -> [test.cpp:1]: (style, inconclusive) Unhandled exception specification when calling function f().\n"
"[test.cpp:6] -> [test.cpp:1]: (style, inconclusive) Unhandled exception specification when calling function f().\n", errout.str());
- const Settings s = settingsBuilder(settings).library("gnu.cfg").build();
+ const Settings s = settingsBuilder().library("gnu.cfg").build();
check(code, true, &s);
ASSERT_EQUALS("", errout.str());
}
diff --git a/test/testfunctions.cpp b/test/testfunctions.cpp
index 418f3613078..9d895dcecba 100644
--- a/test/testfunctions.cpp
+++ b/test/testfunctions.cpp
@@ -1562,18 +1562,21 @@ class TestFunctions : public TestFixture {
{
const char code[] = "int main(void) {}";
- Settings s;
+ {
+ const Settings s = settingsBuilder().c(Standards::C89).build();
- s.standards.c = Standards::C89;
- check(code, "test.c", &s); // c code (c89)
- ASSERT_EQUALS("[test.c:1]: (error) Found an exit path from function with non-void return type that has missing return statement\n", errout.str());
+ check(code, "test.c", &s); // c code (c89)
+ ASSERT_EQUALS("[test.c:1]: (error) Found an exit path from function with non-void return type that has missing return statement\n", errout.str());
+ }
- s.standards.c = Standards::C99;
- check(code, "test.c", &s); // c code (c99)
- ASSERT_EQUALS("", errout.str());
+ {
+ const Settings s = settingsBuilder().c(Standards::C99).build();
+ check(code, "test.c", &s); // c code (c99)
+ ASSERT_EQUALS("", errout.str());
- check(code, "test.cpp", &s); // c++ code
- ASSERT_EQUALS("", errout.str());
+ check(code, "test.cpp", &s); // c++ code
+ ASSERT_EQUALS("", errout.str());
+ }
}
check("F(A,B) { x=1; }");
@@ -1825,9 +1828,8 @@ class TestFunctions : public TestFixture {
}
void checkLibraryMatchFunctions() {
- Settings s = settingsBuilder(settings).checkLibrary().build();
+ Settings s = settingsBuilder(settings).checkLibrary().debugwarnings().build();
s.daca = true;
- s.debugwarnings = true;
check("void f() {\n"
" lib_func();"
diff --git a/test/testleakautovar.cpp b/test/testleakautovar.cpp
index 11eca62d325..c5e2dca4fbd 100644
--- a/test/testleakautovar.cpp
+++ b/test/testleakautovar.cpp
@@ -474,7 +474,7 @@ class TestLeakAutoVar : public TestFixture {
}
void assign23() {
- const Settings s = settingsBuilder(settings).library("posix.cfg").build();
+ const Settings s = settingsBuilder().library("posix.cfg").build();
check("void f() {\n"
" int n1, n2, n3, n4, n5, n6, n7, n8, n9, n10, n11, n12, n13, n14;\n"
" *&n1 = open(\"xx.log\", O_RDONLY);\n"
@@ -2764,8 +2764,6 @@ class TestLeakAutoVar : public TestFixture {
}
void functionCallCastConfig() { // #9652
- Settings settingsFunctionCall = settings;
-
const char xmldata[] = "\n"
"\n"
" \n"
@@ -2778,7 +2776,8 @@ class TestLeakAutoVar : public TestFixture {
" \n"
" \n"
"";
- ASSERT(settingsFunctionCall.library.loadxmldata(xmldata, sizeof(xmldata)));
+ const Settings settingsFunctionCall = settingsBuilder(settings).libraryxml(xmldata, sizeof(xmldata)).build();
+
check("void test_func()\n"
"{\n"
" char * buf = malloc(4);\n"
@@ -2810,7 +2809,7 @@ class TestLeakAutoVar : public TestFixture {
" \n"
" \n"
"\n";
- const Settings settingsLeakIgnore = settingsBuilder(settings).libraryxml(xmldata, sizeof(xmldata)).build();
+ const Settings settingsLeakIgnore = settingsBuilder().libraryxml(xmldata, sizeof(xmldata)).build();
check("void f() {\n"
" double* a = new double[1024];\n"
" SomeClass::someMethod(a);\n"
diff --git a/test/testother.cpp b/test/testother.cpp
index cc2be93e03d..eb1b300122f 100644
--- a/test/testother.cpp
+++ b/test/testother.cpp
@@ -3800,6 +3800,12 @@ class TestOther : public TestFixture {
" return strlen(p);\n"
"}\n");
ASSERT_EQUALS("[test.cpp:1]: (style) Parameter 'p' can be declared as pointer to const\n", errout.str());
+
+ check("void f(int* p) {\n" // #11862
+ " long long j = *(p++);\n"
+ "}\n");
+ ASSERT_EQUALS("[test.cpp:1]: (style) Parameter 'p' can be declared as pointer to const\n",
+ errout.str());
}
void switchRedundantAssignmentTest() {
@@ -8128,7 +8134,7 @@ class TestOther : public TestFixture {
"void packed_object_info(struct object_info *oi) {\n"
" if (*oi->typep < 0);\n"
"}");
- ASSERT_EQUALS("", errout.str());
+ ASSERT_EQUALS("[test.cpp:2]: (style) Parameter 'oi' can be declared as pointer to const\n", errout.str());
}
void checkSuspiciousSemicolon1() {
diff --git a/test/testprocessexecutor.cpp b/test/testprocessexecutor.cpp
index 100aaa580d8..5bd701eab58 100644
--- a/test/testprocessexecutor.cpp
+++ b/test/testprocessexecutor.cpp
@@ -48,7 +48,7 @@ class TestProcessExecutor : public TestFixture {
struct CheckOptions
{
- CheckOptions() DINIT_NOEXCEPT = default;
+ CheckOptions() = default;
SHOWTIME_MODES showtime = SHOWTIME_MODES::SHOWTIME_NONE;
const char* plistOutput = nullptr;
std::vector filesList;
@@ -58,7 +58,7 @@ class TestProcessExecutor : public TestFixture {
* Execute check using n jobs for y files which are have
* identical data, given within data.
*/
- void check(unsigned int jobs, int files, int result, const std::string &data, const CheckOptions &opt = {}) {
+ void check(unsigned int jobs, int files, int result, const std::string &data, const CheckOptions& opt = make_default_obj{}) {
errout.str("");
output.str("");
@@ -77,12 +77,13 @@ class TestProcessExecutor : public TestFixture {
}
}
- settings.jobs = jobs;
- settings.showtime = opt.showtime;
+ Settings s = settings;
+ s.jobs = jobs;
+ s.showtime = opt.showtime;
if (opt.plistOutput)
- settings.plistOutput = opt.plistOutput;
+ s.plistOutput = opt.plistOutput;
// TODO: test with settings.project.fileSettings;
- ProcessExecutor executor(filemap, settings, *this);
+ ProcessExecutor executor(filemap, s, s.nomsg, *this);
std::vector> scopedfiles;
scopedfiles.reserve(filemap.size());
for (std::map::const_iterator i = filemap.cbegin(); i != filemap.cend(); ++i)
@@ -229,6 +230,9 @@ class TestProcessExecutor : public TestFixture {
output.str());*/
settings = settingsOld;
}
+
+ // TODO: test clang-tidy
+ // TODO: test whole program analysis
};
REGISTER_TEST(TestProcessExecutor)
diff --git a/test/testrunner.vcxproj b/test/testrunner.vcxproj
index 79903520643..b0ed00c2f34 100755
--- a/test/testrunner.vcxproj
+++ b/test/testrunner.vcxproj
@@ -72,6 +72,7 @@
+
diff --git a/test/testsimplifytemplate.cpp b/test/testsimplifytemplate.cpp
index 92e66e36fdd..73b851991a3 100644
--- a/test/testsimplifytemplate.cpp
+++ b/test/testsimplifytemplate.cpp
@@ -38,7 +38,7 @@ class TestSimplifyTemplate : public TestFixture {
private:
// If there are unused templates, keep those
- const Settings settings = settingsBuilder().severity(Severity::portability).checkUnusedTemplates().build();
+ const Settings settings = settingsBuilder().severity(Severity::portability).build();
void run() override {
TEST_CASE(template1);
diff --git a/test/testsimplifytokens.cpp b/test/testsimplifytokens.cpp
index 574e364e6bd..1e633a0f0b2 100644
--- a/test/testsimplifytokens.cpp
+++ b/test/testsimplifytokens.cpp
@@ -34,11 +34,10 @@ class TestSimplifyTokens : public TestFixture {
private:
- // If there are unused templates, keep those
- const Settings settings0 = settingsBuilder().severity(Severity::portability).checkUnusedTemplates().build();
- const Settings settings1 = settingsBuilder().severity(Severity::style).checkUnusedTemplates().build();
- const Settings settings_std = settingsBuilder().library("std.cfg").checkUnusedTemplates().build();
- const Settings settings_windows = settingsBuilder().library("windows.cfg").severity(Severity::portability).checkUnusedTemplates().build();
+ const Settings settings0 = settingsBuilder().severity(Severity::portability).build();
+ const Settings settings1 = settingsBuilder().severity(Severity::style).build();
+ const Settings settings_std = settingsBuilder().library("std.cfg").build();
+ const Settings settings_windows = settingsBuilder().library("windows.cfg").severity(Severity::portability).build();
void run() override {
TEST_CASE(combine_strings);
diff --git a/test/testsimplifytypedef.cpp b/test/testsimplifytypedef.cpp
index 55b3c085c0f..a87595e3e87 100644
--- a/test/testsimplifytypedef.cpp
+++ b/test/testsimplifytypedef.cpp
@@ -40,10 +40,8 @@ class TestSimplifyTypedef : public TestFixture {
private:
- // If there are unused templates, keep those
- const Settings settings0 = settingsBuilder().severity(Severity::style).checkUnusedTemplates().build();
- const Settings settings1 = settingsBuilder().severity(Severity::portability).checkUnusedTemplates().build();
- const Settings settings2 = settingsBuilder().severity(Severity::style).checkUnusedTemplates().build();
+ const Settings settings0 = settingsBuilder().severity(Severity::style).build();
+ const Settings settings1 = settingsBuilder().severity(Severity::portability).build();
void run() override {
TEST_CASE(c1);
@@ -285,7 +283,7 @@ class TestSimplifyTypedef : public TestFixture {
errout.str("");
// Tokenize..
// show warnings about unhandled typedef
- const Settings settings = settingsBuilder(settings2).certainty(Certainty::inconclusive).debugwarnings().build();
+ const Settings settings = settingsBuilder(settings0).certainty(Certainty::inconclusive).debugwarnings().build();
Tokenizer tokenizer(&settings, this);
std::istringstream istr(code);
ASSERT_LOC(tokenizer.tokenize(istr, "test.cpp"), file, line);
diff --git a/test/testsimplifyusing.cpp b/test/testsimplifyusing.cpp
index fb6c92bb9ce..32287681a7c 100644
--- a/test/testsimplifyusing.cpp
+++ b/test/testsimplifyusing.cpp
@@ -39,10 +39,7 @@ class TestSimplifyUsing : public TestFixture {
private:
- // If there are unused templates, keep those
- const Settings settings0 = settingsBuilder().severity(Severity::style).checkUnusedTemplates().build();
- const Settings settings1 = settingsBuilder().checkUnusedTemplates().build();
- const Settings settings2 = settingsBuilder().severity(Severity::style).checkUnusedTemplates().build();
+ const Settings settings0 = settingsBuilder().severity(Severity::style).build();
void run() override {
TEST_CASE(simplifyUsing1);
diff --git a/test/testsingleexecutor.cpp b/test/testsingleexecutor.cpp
index beb1dd78f65..f80530f82c4 100644
--- a/test/testsingleexecutor.cpp
+++ b/test/testsingleexecutor.cpp
@@ -63,13 +63,16 @@ class TestSingleExecutorBase : public TestFixture {
struct CheckOptions
{
- CheckOptions() DINIT_NOEXCEPT = default;
+ CheckOptions() = default;
SHOWTIME_MODES showtime = SHOWTIME_MODES::SHOWTIME_NONE;
const char* plistOutput = nullptr;
std::vector filesList;
+ bool executeCommandCalled = false;
+ std::string exe;
+ std::vector args;
};
- void check(int files, int result, const std::string &data, const CheckOptions &opt = {}) {
+ void check(int files, int result, const std::string &data, const CheckOptions& opt = make_default_obj{}) {
errout.str("");
output.str("");
settings.project.fileSettings.clear();
@@ -101,9 +104,16 @@ class TestSingleExecutorBase : public TestFixture {
settings.showtime = opt.showtime;
if (opt.plistOutput)
settings.plistOutput = opt.plistOutput;
+
+ bool executeCommandCalled = false;
+ std::string exe;
+ std::vector args;
// NOLINTNEXTLINE(performance-unnecessary-value-param)
- CppCheck cppcheck(*this, true, [](std::string,std::vector,std::string,std::string&){
- return false;
+ CppCheck cppcheck(*this, true, [&executeCommandCalled, &exe, &args](std::string e,std::vector a,std::string,std::string&){
+ executeCommandCalled = true;
+ exe = std::move(e);
+ args = std::move(a);
+ return true;
});
cppcheck.settings() = settings;
@@ -117,8 +127,15 @@ class TestSingleExecutorBase : public TestFixture {
filemap.clear();
// TODO: test with settings.project.fileSettings;
- SingleExecutor executor(cppcheck, filemap, settings, *this);
+ SingleExecutor executor(cppcheck, filemap, settings, settings.nomsg, *this);
ASSERT_EQUALS(result, executor.check());
+ ASSERT_EQUALS(opt.executeCommandCalled, executeCommandCalled);
+ ASSERT_EQUALS(opt.exe, exe);
+ ASSERT_EQUALS(opt.args.size(), args.size());
+ for (int i = 0; i < args.size(); ++i)
+ {
+ ASSERT_EQUALS(opt.args[i], args[i]);
+ }
}
void run() override {
@@ -131,6 +148,7 @@ class TestSingleExecutorBase : public TestFixture {
TEST_CASE(one_error_less_files);
TEST_CASE(one_error_several_files);
TEST_CASE(markup);
+ TEST_CASE(clangTidy);
}
void many_files() {
@@ -246,7 +264,34 @@ class TestSingleExecutorBase : public TestFixture {
settings = settingsOld;
}
- // TODO: test clang-tidy
+ void clangTidy() {
+ // TODO: we currently only invoke it with ImportProject::FileSettings
+ if (!useFS)
+ return;
+
+ const Settings settingsOld = settings;
+ settings.clangTidy = true;
+
+#ifdef _WIN32
+ const char exe[] = "clang-tidy.exe";
+#else
+ const char exe[] = "clang-tidy";
+#endif
+
+ const std::string file = fprefix() + "_001.cpp";
+ check(1, 0,
+ "int main()\n"
+ "{\n"
+ " return 0;\n"
+ "}",
+ dinit(CheckOptions,
+ $.executeCommandCalled = true,
+ $.exe = exe,
+ $.args = {"-quiet", "-checks=*,-clang-analyzer-*,-llvm*", file, "--"}));
+ ASSERT_EQUALS("Checking " + file + " ...\n", output.str());
+ settings = settingsOld;
+ }
+
// TODO: test whole program analysis
};
diff --git a/test/teststl.cpp b/test/teststl.cpp
index b25a4443108..bb9f3ad7b57 100644
--- a/test/teststl.cpp
+++ b/test/teststl.cpp
@@ -2819,27 +2819,20 @@ class TestStl : public TestFixture {
}
void eraseOnVector() {
- check("void f(const std::vector& m_ImplementationMap) {\n"
- " std::vector::iterator aIt = m_ImplementationMap.begin();\n"
- " m_ImplementationMap.erase(something(unknown));\n" // All iterators become invalidated when erasing from std::vector
- " m_ImplementationMap.erase(aIt);\n"
- "}");
- ASSERT_EQUALS("[test.cpp:1] -> [test.cpp:2] -> [test.cpp:3] -> [test.cpp:1] -> [test.cpp:4]: (error) Using iterator to local container 'm_ImplementationMap' that may be invalid.\n", errout.str());
-
- check("void f(const std::vector& m_ImplementationMap) {\n"
- " std::vector::iterator aIt = m_ImplementationMap.begin();\n"
- " m_ImplementationMap.erase(*aIt);\n" // All iterators become invalidated when erasing from std::vector
- " m_ImplementationMap.erase(aIt);\n"
+ check("void f(std::vector& v) {\n"
+ " std::vector::iterator aIt = v.begin();\n"
+ " v.erase(something(unknown));\n" // All iterators become invalidated when erasing from std::vector
+ " v.erase(aIt);\n"
"}");
- ASSERT_EQUALS("[test.cpp:1] -> [test.cpp:2] -> [test.cpp:3] -> [test.cpp:1] -> [test.cpp:4]: (error) Using iterator to local container 'm_ImplementationMap' that may be invalid.\n", errout.str());
+ ASSERT_EQUALS("[test.cpp:1] -> [test.cpp:2] -> [test.cpp:3] -> [test.cpp:1] -> [test.cpp:4]: (error) Using iterator to local container 'v' that may be invalid.\n", errout.str());
- check("void f(const std::vector& m_ImplementationMap) {\n"
- " std::vector::iterator aIt = m_ImplementationMap.begin();\n"
- " std::vector::iterator bIt = m_ImplementationMap.begin();\n"
- " m_ImplementationMap.erase(*bIt);\n" // All iterators become invalidated when erasing from std::vector
- " aIt = m_ImplementationMap.erase(aIt);\n"
+ check("void f(std::vector& v) {\n"
+ " std::vector::iterator aIt = v.begin();\n"
+ " std::vector::iterator bIt = v.begin();\n"
+ " v.erase(bIt);\n" // All iterators become invalidated when erasing from std::vector
+ " aIt = v.erase(aIt);\n"
"}");
- ASSERT_EQUALS("[test.cpp:1] -> [test.cpp:2] -> [test.cpp:4] -> [test.cpp:1] -> [test.cpp:5]: (error) Using iterator to local container 'm_ImplementationMap' that may be invalid.\n", errout.str());
+ ASSERT_EQUALS("[test.cpp:1] -> [test.cpp:2] -> [test.cpp:4] -> [test.cpp:1] -> [test.cpp:5]: (error) Using iterator to local container 'v' that may be invalid.\n", errout.str());
}
void pushback1() {
diff --git a/test/testsuppressions.cpp b/test/testsuppressions.cpp
index 22061415bac..f1c6a7d8a47 100644
--- a/test/testsuppressions.cpp
+++ b/test/testsuppressions.cpp
@@ -206,7 +206,7 @@ class TestSuppressions : public TestFixture {
if (!suppression.empty()) {
EXPECT_EQ("", settings.nomsg.addSuppressionLine(suppression));
}
- SingleExecutor executor(cppCheck, files, settings, *this);
+ SingleExecutor executor(cppCheck, files, settings, settings.nomsg, *this);
std::vector> scopedfiles;
scopedfiles.reserve(files.size());
for (std::map::const_iterator i = f.cbegin(); i != f.cend(); ++i)
@@ -233,7 +233,7 @@ class TestSuppressions : public TestFixture {
if (!suppression.empty()) {
EXPECT_EQ("", settings.nomsg.addSuppressionLine(suppression));
}
- ThreadExecutor executor(files, settings, *this);
+ ThreadExecutor executor(files, settings, settings.nomsg, *this);
std::vector> scopedfiles;
scopedfiles.reserve(files.size());
for (std::map::const_iterator i = files.cbegin(); i != files.cend(); ++i)
@@ -261,7 +261,7 @@ class TestSuppressions : public TestFixture {
if (!suppression.empty()) {
EXPECT_EQ("", settings.nomsg.addSuppressionLine(suppression));
}
- ProcessExecutor executor(files, settings, *this);
+ ProcessExecutor executor(files, settings, settings.nomsg, *this);
std::vector> scopedfiles;
scopedfiles.reserve(files.size());
for (std::map::const_iterator i = files.cbegin(); i != files.cend(); ++i)
diff --git a/test/testsymboldatabase.cpp b/test/testsymboldatabase.cpp
index 8c2bec6bd8f..13e719e46c6 100644
--- a/test/testsymboldatabase.cpp
+++ b/test/testsymboldatabase.cpp
@@ -68,9 +68,8 @@ class TestSymbolDatabase : public TestFixture {
private:
const Token* vartok{nullptr};
const Token* typetok{nullptr};
- // If there are unused templates, keep those
- Settings settings1 = settingsBuilder().library("std.cfg").checkUnusedTemplates().build();
- const Settings settings2 = settingsBuilder().checkUnusedTemplates().platform(cppcheck::Platform::Type::Unspecified).build();
+ Settings settings1 = settingsBuilder().library("std.cfg").build();
+ const Settings settings2 = settingsBuilder().platform(cppcheck::Platform::Type::Unspecified).build();
void reset() {
vartok = nullptr;
@@ -384,6 +383,7 @@ class TestSymbolDatabase : public TestFixture {
TEST_CASE(enum10); // #11001
TEST_CASE(enum11);
TEST_CASE(enum12);
+ TEST_CASE(enum13);
TEST_CASE(sizeOfType);
@@ -509,6 +509,7 @@ class TestSymbolDatabase : public TestFixture {
TEST_CASE(auto17); // #11163
TEST_CASE(auto18);
TEST_CASE(auto19);
+ TEST_CASE(auto20);
TEST_CASE(unionWithConstructor);
@@ -5701,6 +5702,23 @@ class TestSymbolDatabase : public TestFixture {
ASSERT_EQUALS(e->enumerator(), E0);
}
+ void enum13() {
+ GET_SYMBOL_DB("struct S { enum E { E0, E1 }; };\n"
+ "void f(bool b) {\n"
+ " auto e = b ? S::E0 : S::E1;\n"
+ "}\n");
+ ASSERT(db != nullptr);
+ auto it = db->scopeList.begin();
+ std::advance(it, 2);
+ const Enumerator* E1 = it->findEnumerator("E1");
+ ASSERT(E1 && E1->value_known);
+ ASSERT_EQUALS(E1->value, 1);
+ const Token* const a = Token::findsimplematch(tokenizer.tokens(), "auto");
+ ASSERT(a && a->valueType());
+ TODO_ASSERT(E1->scope == a->valueType()->typeScope);
+ ASSERT_EQUALS(a->valueType()->type, ValueType::INT);
+ }
+
void sizeOfType() {
// #7615 - crash in Symboldatabase::sizeOfType()
GET_SYMBOL_DB("enum e;\n"
@@ -9419,6 +9437,22 @@ class TestSymbolDatabase : public TestFixture {
}
}
+ void auto20() {
+ GET_SYMBOL_DB("enum A { A0 };\n"
+ "enum B { B0 };\n"
+ "const int& g(A a);\n"
+ "const int& g(B b);\n"
+ "void f() {\n"
+ " const auto& r = g(B::B0);\n"
+ "}\n");
+ const Token* a = Token::findsimplematch(tokenizer.tokens(), "auto");
+ ASSERT(a && a->valueType());
+ ASSERT_EQUALS(a->valueType()->type, ValueType::INT);
+ const Token* g = Token::findsimplematch(a, "g ( B ::");
+ ASSERT(g && g->function());
+ ASSERT_EQUALS(g->function()->tokenDef->linenr(), 4);
+ }
+
void unionWithConstructor() {
GET_SYMBOL_DB("union Fred {\n"
" Fred(int x) : i(x) { }\n"
diff --git a/test/testthreadexecutor.cpp b/test/testthreadexecutor.cpp
index d438dfa13a0..e05eff6d50a 100644
--- a/test/testthreadexecutor.cpp
+++ b/test/testthreadexecutor.cpp
@@ -48,7 +48,7 @@ class TestThreadExecutor : public TestFixture {
struct CheckOptions
{
- CheckOptions() DINIT_NOEXCEPT = default;
+ CheckOptions() = default;
SHOWTIME_MODES showtime = SHOWTIME_MODES::SHOWTIME_NONE;
const char* plistOutput = nullptr;
std::vector filesList;
@@ -58,7 +58,7 @@ class TestThreadExecutor : public TestFixture {
* Execute check using n jobs for y files which are have
* identical data, given within data.
*/
- void check(unsigned int jobs, int files, int result, const std::string &data, const CheckOptions &opt = {}) {
+ void check(unsigned int jobs, int files, int result, const std::string &data, const CheckOptions& opt = make_default_obj{}) {
errout.str("");
output.str("");
@@ -83,7 +83,7 @@ class TestThreadExecutor : public TestFixture {
if (opt.plistOutput)
settings1.plistOutput = opt.plistOutput;
// TODO: test with settings.project.fileSettings;
- ThreadExecutor executor(filemap, settings1, *this);
+ ThreadExecutor executor(filemap, settings1, settings1.nomsg, *this);
std::vector> scopedfiles;
scopedfiles.reserve(filemap.size());
for (std::map::const_iterator i = filemap.cbegin(); i != filemap.cend(); ++i)
@@ -228,6 +228,9 @@ class TestThreadExecutor : public TestFixture {
output.str());*/
settings = settingsOld;
}
+
+ // TODO: test clang-tidy
+ // TODO: test whole program analysis
};
REGISTER_TEST(TestThreadExecutor)
diff --git a/test/testtoken.cpp b/test/testtoken.cpp
index f6c408ad03e..60f03db1a57 100644
--- a/test/testtoken.cpp
+++ b/test/testtoken.cpp
@@ -481,7 +481,7 @@ class TestToken : public TestFixture {
}
void deleteLast() const {
- TokensFrontBack listEnds{ nullptr };
+ TokensFrontBack listEnds;
Token ** const tokensBack = &(listEnds.back);
Token tok(&listEnds);
tok.insertToken("aba");
@@ -491,7 +491,7 @@ class TestToken : public TestFixture {
}
void deleteFirst() const {
- TokensFrontBack listEnds{ nullptr };
+ TokensFrontBack listEnds;
Token ** const tokensFront = &(listEnds.front);
Token tok(&listEnds);
diff --git a/test/testtokenize.cpp b/test/testtokenize.cpp
index 2e0972d07b8..e5814f6e5fc 100644
--- a/test/testtokenize.cpp
+++ b/test/testtokenize.cpp
@@ -44,11 +44,9 @@ class TestTokenizer : public TestFixture {
TestTokenizer() : TestFixture("TestTokenizer") {}
private:
- // If there are unused templates, keep those
- const Settings settings0 = settingsBuilder().library("qt.cfg").checkUnusedTemplates().build();
- const Settings settings1 = settingsBuilder().library("qt.cfg").library("std.cfg").checkUnusedTemplates().build();
- const Settings settings2 = settingsBuilder().library("qt.cfg").checkUnusedTemplates().build();
- const Settings settings_windows = settingsBuilder().library("windows.cfg").checkUnusedTemplates().build();
+ const Settings settings0 = settingsBuilder().library("qt.cfg").build();
+ const Settings settings1 = settingsBuilder().library("qt.cfg").library("std.cfg").build();
+ const Settings settings_windows = settingsBuilder().library("windows.cfg").build();
void run() override {
TEST_CASE(tokenize1);
@@ -522,7 +520,7 @@ class TestTokenizer : public TestFixture {
std::string tokenizeDebugListing_(const char* file, int line, const char code[], const char filename[] = "test.cpp") {
errout.str("");
- const Settings settings = settingsBuilder(settings2).c(Standards::C89).cpp(Standards::CPP03).build();
+ const Settings settings = settingsBuilder(settings0).c(Standards::C89).cpp(Standards::CPP03).build();
Tokenizer tokenizer(&settings, this);
std::istringstream istr(code);
@@ -946,7 +944,7 @@ class TestTokenizer : public TestFixture {
}
{
- const Settings s = settingsBuilder().checkUnusedTemplates().build();
+ const Settings s;
ASSERT_EQUALS("; template < typename T , u_int uBAR = 0 >\n"
"class Foo {\n"
"public:\n"
diff --git a/test/testvalueflow.cpp b/test/testvalueflow.cpp
index 4e322596175..8a50059ef89 100644
--- a/test/testvalueflow.cpp
+++ b/test/testvalueflow.cpp
@@ -349,7 +349,7 @@ class TestValueFlow : public TestFixture {
return false;
}
- bool testValueOfX_(const char* file, int line, const char code[], unsigned int linenr, float value, float diff) {
+ bool testValueOfX_(const char* file, int line, const char code[], unsigned int linenr, double value, double diff) {
// Tokenize..
Tokenizer tokenizer(&settings, this);
std::istringstream istr(code);
@@ -565,7 +565,7 @@ class TestValueFlow : public TestFixture {
void valueFlowNumber() {
ASSERT_EQUALS(123, valueOfTok("x=123;", "123").intvalue);
ASSERT_EQUALS_DOUBLE(192.0, valueOfTok("x=0x0.3p10;", "0x0.3p10").floatValue, 1e-5); // 3 * 16^-1 * 2^10 = 192
- ASSERT(std::fabs(valueOfTok("x=0.5;", "0.5").floatValue - 0.5f) < 0.1f);
+ ASSERT(std::fabs(valueOfTok("x=0.5;", "0.5").floatValue - 0.5) < 0.1);
ASSERT_EQUALS(10, valueOfTok("enum {A=10,B=15}; x=A+0;", "+").intvalue);
ASSERT_EQUALS(0, valueOfTok("x=false;", "false").intvalue);
ASSERT_EQUALS(1, valueOfTok("x=true;", "true").intvalue);
@@ -3491,7 +3491,7 @@ class TestValueFlow : public TestFixture {
void valueFlowForwardCompoundAssign() {
const char *code;
- code = "void f() {\n"
+ code = "int f() {\n"
" int x = 123;\n"
" x += 43;\n"
" return x;\n"
@@ -3501,19 +3501,26 @@ class TestValueFlow : public TestFixture {
"3,Compound assignment '+=', assigned value is 166\n",
getErrorPathForX(code, 4U));
- code = "void f() {\n"
+ code = "int f() {\n"
" int x = 123;\n"
" x /= 0;\n" // don't crash when evaluating x/=0
" return x;\n"
"}";
ASSERT_EQUALS(false, testValueOfX(code, 4U, 123));
- code = "void f() {\n"
- " float x = 123.45;\n"
+ code = "float f() {\n"
+ " float x = 123.45f;\n"
" x += 67;\n"
" return x;\n"
"}";
- ASSERT_EQUALS(true, testValueOfX(code, 4U, 123.45F + 67, 0.01F));
+ ASSERT_EQUALS(true, testValueOfX(code, 4U, (double)123.45f + 67, 0.01));
+
+ code = "double f() {\n"
+ " double x = 123.45;\n"
+ " x += 67;\n"
+ " return x;\n"
+ "}";
+ ASSERT_EQUALS(true, testValueOfX(code, 4U, 123.45 + 67, 0.01));
code = "void f() {\n"
" int x = 123;\n"
@@ -3522,7 +3529,7 @@ class TestValueFlow : public TestFixture {
"}";
ASSERT_EQUALS(true, testValueOfX(code, 4U, 61));
- code = "void f() {\n"
+ code = "int f() {\n"
" int x = 123;\n"
" x <<= 1;\n"
" return x;\n"
diff --git a/test/testvarid.cpp b/test/testvarid.cpp
index 90dfeafe604..341c24c2d9c 100644
--- a/test/testvarid.cpp
+++ b/test/testvarid.cpp
@@ -34,7 +34,7 @@ class TestVarID : public TestFixture {
TestVarID() : TestFixture("TestVarID") {}
private:
- Settings settings = settingsBuilder().c(Standards::C89).cpp(Standards::CPPLatest).checkUnusedTemplates().platform(cppcheck::Platform::Type::Unix64).build();
+ const Settings settings = settingsBuilder().c(Standards::C89).cpp(Standards::CPPLatest).platform(cppcheck::Platform::Type::Unix64).build();
void run() override {
TEST_CASE(varid1);
TEST_CASE(varid2);