2021-08-01 21:28:25 +02:00
|
|
|
#!/usr/bin/env bash
|
|
|
|
#
|
|
|
|
# Copyright (c) 2019 The Bitcoin Core developers
|
|
|
|
# Distributed under the MIT software license, see the accompanying
|
|
|
|
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
|
|
|
#
|
|
|
|
|
|
|
|
export LC_ALL=C
|
|
|
|
|
|
|
|
ENABLED_CHECKS=(
|
|
|
|
"Class '.*' has a constructor with 1 argument that is not explicit."
|
|
|
|
"Struct '.*' has a constructor with 1 argument that is not explicit."
|
|
|
|
"Function parameter '.*' should be passed by const reference."
|
|
|
|
"Comparison of modulo result is predetermined"
|
|
|
|
"Local variable '.*' shadows outer argument"
|
|
|
|
"Redundant initialization for '.*'. The initialized value is overwritten before it is read."
|
|
|
|
"Dereferencing '.*' after it is deallocated / released"
|
|
|
|
"The scope of the variable '.*' can be reduced."
|
|
|
|
"Parameter '.*' can be declared with const"
|
|
|
|
"Variable '.*' can be declared with const"
|
|
|
|
"Variable '.*' is assigned a value that is never used."
|
|
|
|
"Unused variable"
|
|
|
|
"The function '.*' overrides a function in a base class but is not marked with a 'override' specifier."
|
2024-07-04 13:51:31 +02:00
|
|
|
# Enable to catch all warnings
|
2021-12-28 22:54:50 +01:00
|
|
|
".*"
|
2021-08-01 21:28:25 +02:00
|
|
|
)
|
|
|
|
|
|
|
|
IGNORED_WARNINGS=(
|
|
|
|
"src/bls/bls.h:.* Struct 'CBLSIdImplicit' has a constructor with 1 argument that is not explicit."
|
2021-12-28 22:54:50 +01:00
|
|
|
"src/rpc/masternode.cpp:.*:21: warning: Consider using std::copy algorithm instead of a raw loop." # UniValue doesn't support std::copy
|
2023-04-16 19:08:33 +02:00
|
|
|
"src/cachemultimap.h:.*: warning: Variable 'mapIt' can be declared as reference to const"
|
2023-07-10 18:23:09 +02:00
|
|
|
"src/evo/simplifiedmns.cpp:.*:20: warning: Consider using std::copy algorithm instead of a raw loop."
|
test: supress any_of suggestions in cppcheck-dash
even it maybe useful lint message for some particular case, sometimes it asks
to make an refactoring that will be over-complex.
For example, it asks to refactor external loop to std::any_of:
```
for (const auto& inner_entry : vecEntries) {
if (ranges::any_of(inner_entry.vecTxDSIn,
[&txin](const auto& txdsin){
return txdsin.prevout == txin.prevout;
})) {
LogPrint(BCLog::COINJOIN, "CCoinJoinServer::%s -- ERROR: already have this txin in entries\n", __func__);
nMessageIDRet = ERR_ALREADY_HAVE;
// Two peers sent the same input? Can't really say who is the malicious one here,
// could be that someone is picking someone else's inputs randomly trying to force
// collateral consumption. Do not punish.
return false;
}
}
```
That's possible to refactor, but that's unreasonable complexity to have an
lambda inside an lambda... That's unreasonable.
Some other suggestion are also non-trivial.
One more suppression for any_of in llmq/commitment which is false-alarm:
There's used index but linter doesn't see it:
```
for (const auto i : irange::range(members.size(), size_t(llmq_params.size))) {
if (validMembers[i]) {
LogPrintfFinalCommitment("q[%s] invalid validMembers bitset. bit %d should not be set\n", quorumHash.ToString(), i);
return false;
}
if (signers[i]) {
LogPrintfFinalCommitment("q[%s] invalid signers bitset. bit %d should not be set\n", quorumHash.ToString(), i);
return false;
}
}
```
2024-02-23 10:42:26 +01:00
|
|
|
"src/llmq/commitment.cpp.* warning: Consider using std::all_of or std::none_of algorithm instead of a raw loop. \[useStlAlgorithm\]"
|
2024-03-03 12:06:53 +01:00
|
|
|
"src/rpc/.*cpp:.*: note: Function pointer used here."
|
|
|
|
"src/masternode/sync.cpp:.*: warning: Variable 'pnode' can be declared as pointer to const \[constVariableReference\]"
|
2024-03-21 22:03:56 +01:00
|
|
|
"src/wallet/bip39.cpp.*: warning: The scope of the variable 'ssCurrentWord' can be reduced. \[variableScope\]"
|
2024-07-04 13:51:31 +02:00
|
|
|
"src/.*:.*: warning: Local variable '_' shadows outer function \[shadowFunction\]"
|
2024-03-03 12:06:53 +01:00
|
|
|
|
|
|
|
"src/stacktraces.cpp:.*: .*: Parameter 'info' can be declared as pointer to const"
|
|
|
|
"src/stacktraces.cpp:.*: note: You might need to cast the function pointer here"
|
|
|
|
|
2024-02-23 12:13:56 +01:00
|
|
|
"[note|warning]: Return value 'state.Invalid(.*)' is always false"
|
|
|
|
"note: Calling function 'Invalid' returns 0"
|
2024-07-04 13:51:31 +02:00
|
|
|
"note: Shadow variable"
|
test: supress any_of suggestions in cppcheck-dash
even it maybe useful lint message for some particular case, sometimes it asks
to make an refactoring that will be over-complex.
For example, it asks to refactor external loop to std::any_of:
```
for (const auto& inner_entry : vecEntries) {
if (ranges::any_of(inner_entry.vecTxDSIn,
[&txin](const auto& txdsin){
return txdsin.prevout == txin.prevout;
})) {
LogPrint(BCLog::COINJOIN, "CCoinJoinServer::%s -- ERROR: already have this txin in entries\n", __func__);
nMessageIDRet = ERR_ALREADY_HAVE;
// Two peers sent the same input? Can't really say who is the malicious one here,
// could be that someone is picking someone else's inputs randomly trying to force
// collateral consumption. Do not punish.
return false;
}
}
```
That's possible to refactor, but that's unreasonable complexity to have an
lambda inside an lambda... That's unreasonable.
Some other suggestion are also non-trivial.
One more suppression for any_of in llmq/commitment which is false-alarm:
There's used index but linter doesn't see it:
```
for (const auto i : irange::range(members.size(), size_t(llmq_params.size))) {
if (validMembers[i]) {
LogPrintfFinalCommitment("q[%s] invalid validMembers bitset. bit %d should not be set\n", quorumHash.ToString(), i);
return false;
}
if (signers[i]) {
LogPrintfFinalCommitment("q[%s] invalid signers bitset. bit %d should not be set\n", quorumHash.ToString(), i);
return false;
}
}
```
2024-02-23 10:42:26 +01:00
|
|
|
|
2021-08-01 21:28:25 +02:00
|
|
|
# General catchall, for some reason any value named 'hash' is viewed as never used.
|
|
|
|
"Variable 'hash' is assigned a value that is never used."
|
|
|
|
|
|
|
|
# The following can be useful to ignore when the catch all is used
|
|
|
|
# "Consider performing initialization in initialization list."
|
2021-12-28 22:54:50 +01:00
|
|
|
"Consider using std::transform algorithm instead of a raw loop."
|
|
|
|
"Consider using std::accumulate algorithm instead of a raw loop."
|
test: supress any_of suggestions in cppcheck-dash
even it maybe useful lint message for some particular case, sometimes it asks
to make an refactoring that will be over-complex.
For example, it asks to refactor external loop to std::any_of:
```
for (const auto& inner_entry : vecEntries) {
if (ranges::any_of(inner_entry.vecTxDSIn,
[&txin](const auto& txdsin){
return txdsin.prevout == txin.prevout;
})) {
LogPrint(BCLog::COINJOIN, "CCoinJoinServer::%s -- ERROR: already have this txin in entries\n", __func__);
nMessageIDRet = ERR_ALREADY_HAVE;
// Two peers sent the same input? Can't really say who is the malicious one here,
// could be that someone is picking someone else's inputs randomly trying to force
// collateral consumption. Do not punish.
return false;
}
}
```
That's possible to refactor, but that's unreasonable complexity to have an
lambda inside an lambda... That's unreasonable.
Some other suggestion are also non-trivial.
One more suppression for any_of in llmq/commitment which is false-alarm:
There's used index but linter doesn't see it:
```
for (const auto i : irange::range(members.size(), size_t(llmq_params.size))) {
if (validMembers[i]) {
LogPrintfFinalCommitment("q[%s] invalid validMembers bitset. bit %d should not be set\n", quorumHash.ToString(), i);
return false;
}
if (signers[i]) {
LogPrintfFinalCommitment("q[%s] invalid signers bitset. bit %d should not be set\n", quorumHash.ToString(), i);
return false;
}
}
```
2024-02-23 10:42:26 +01:00
|
|
|
"Consider using std::any_of algorithm instead of a raw loop."
|
|
|
|
"Consider using std::copy_if algorithm instead of a raw loop."
|
2021-08-01 21:28:25 +02:00
|
|
|
# "Consider using std::count_if algorithm instead of a raw loop."
|
|
|
|
# "Consider using std::find_if algorithm instead of a raw loop."
|
2021-12-28 22:54:50 +01:00
|
|
|
# "Member variable '.*' is not initialized in the constructor."
|
2022-04-27 20:14:40 +02:00
|
|
|
|
|
|
|
"unusedFunction"
|
2022-08-11 01:05:44 +02:00
|
|
|
"unknownMacro"
|
|
|
|
"unusedStructMember"
|
2021-08-01 21:28:25 +02:00
|
|
|
)
|
|
|
|
|
|
|
|
# We should attempt to update this with all dash specific code
|
2024-03-21 21:33:17 +01:00
|
|
|
FILES=$(git ls-files -- $(cat test/util/data/non-backported.txt))
|
2021-08-01 21:28:25 +02:00
|
|
|
|
|
|
|
|
|
|
|
if ! command -v cppcheck > /dev/null; then
|
|
|
|
echo "Skipping cppcheck linting since cppcheck is not installed."
|
|
|
|
exit 0
|
|
|
|
fi
|
|
|
|
|
|
|
|
function join_array {
|
|
|
|
local IFS="$1"
|
|
|
|
shift
|
|
|
|
echo "$*"
|
|
|
|
}
|
|
|
|
|
|
|
|
ENABLED_CHECKS_REGEXP=$(join_array "|" "${ENABLED_CHECKS[@]}")
|
|
|
|
IGNORED_WARNINGS_REGEXP=$(join_array "|" "${IGNORED_WARNINGS[@]}")
|
|
|
|
FILES_REGEXP=$(join_array "|" "${FILES[@]}")
|
2022-04-27 20:14:40 +02:00
|
|
|
SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )
|
2024-08-04 09:43:00 +02:00
|
|
|
# Check if CACHE_DIR is set and non-empty, otherwise use default .cppcheck/ directory
|
|
|
|
if [[ -n "$CACHE_DIR" ]]; then
|
|
|
|
CPPCHECK_DIR=$CACHE_DIR/cppcheck/
|
|
|
|
else
|
|
|
|
CPPCHECK_DIR=$SCRIPT_DIR/.cppcheck/
|
|
|
|
fi
|
2022-04-27 20:14:40 +02:00
|
|
|
if [ ! -d $CPPCHECK_DIR ]
|
|
|
|
then
|
2024-08-04 09:43:00 +02:00
|
|
|
mkdir -p $CPPCHECK_DIR
|
2022-04-27 20:14:40 +02:00
|
|
|
fi
|
2021-08-01 21:28:25 +02:00
|
|
|
WARNINGS=$(echo "${FILES}" | \
|
2024-06-12 17:17:56 +02:00
|
|
|
xargs cppcheck --enable=all --inline-suppr --suppress=missingIncludeSystem --cppcheck-build-dir=$CPPCHECK_DIR -j "$(getconf _NPROCESSORS_ONLN)" --language=c++ --std=c++17 --template=gcc -D__cplusplus -DENABLE_WALLET -DCLIENT_VERSION_BUILD -DCLIENT_VERSION_IS_RELEASE -DCLIENT_VERSION_MAJOR -DCLIENT_VERSION_MINOR -DCOPYRIGHT_YEAR -DDEBUG -DUSE_EPOLL -DCHAR_BIT=8 -I src/ -q 2>&1 | sort -u | \
|
2021-08-01 21:28:25 +02:00
|
|
|
grep -E "${ENABLED_CHECKS_REGEXP}" | \
|
|
|
|
grep -vE "${IGNORED_WARNINGS_REGEXP}" | \
|
|
|
|
grep -E "${FILES_REGEXP}")
|
|
|
|
|
|
|
|
if [[ ${WARNINGS} != "" ]]; then
|
|
|
|
echo "${WARNINGS}"
|
|
|
|
echo
|
|
|
|
echo "Advice not applicable in this specific case? Add an exception by updating"
|
|
|
|
echo "IGNORED_WARNINGS in $0"
|
|
|
|
# Uncomment to enforce the linter / comment to run locally
|
|
|
|
exit 1
|
|
|
|
fi
|
|
|
|
exit 0
|