[clang-tidy] Enable the misc-no-recursion check

Co-authored-by: stickies-v <stickies-v@protonmail.com>
Co-authored-by: Gloria Zhao <gloriajzhao@gmail.com>
This commit is contained in:
dergoegge 2024-03-21 11:35:11 +00:00
parent f0794cbd40
commit 78407b99ed
17 changed files with 39 additions and 0 deletions

View File

@ -115,6 +115,8 @@ code.
Use `reinterpret_cast` and `const_cast` as appropriate. Use `reinterpret_cast` and `const_cast` as appropriate.
- Prefer [`list initialization ({})`](https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#Res-list) where possible. - Prefer [`list initialization ({})`](https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#Res-list) where possible.
For example `int x{0};` instead of `int x = 0;` or `int x(0);` For example `int x{0};` instead of `int x = 0;` or `int x(0);`
- Recursion is checked by clang-tidy and thus must be made explicit. Use
`NOLINTNEXTLINE(misc-no-recursion)` to suppress the check.
For function calls a namespace should be specified explicitly, unless such functions have been declared within it. For function calls a namespace should be specified explicitly, unless such functions have been declared within it.
Otherwise, [argument-dependent lookup](https://en.cppreference.com/w/cpp/language/adl), also known as ADL, could be Otherwise, [argument-dependent lookup](https://en.cppreference.com/w/cpp/language/adl), also known as ADL, could be

View File

@ -6,6 +6,7 @@ bugprone-string-constructor,
bugprone-use-after-move, bugprone-use-after-move,
bugprone-lambda-function-name, bugprone-lambda-function-name,
misc-unused-using-decls, misc-unused-using-decls,
misc-no-recursion,
modernize-use-default-member-init, modernize-use-default-member-init,
modernize-use-emplace, modernize-use-emplace,
modernize-use-noexcept, modernize-use-noexcept,

View File

@ -54,6 +54,7 @@ CMerkleBlock::CMerkleBlock(const CBlock& block, CBloomFilter* filter, const std:
txn = CPartialMerkleTree(vHashes, vMatch); txn = CPartialMerkleTree(vHashes, vMatch);
} }
// NOLINTNEXTLINE(misc-no-recursion)
uint256 CPartialMerkleTree::CalcHash(int height, unsigned int pos, const std::vector<uint256> &vTxid) { uint256 CPartialMerkleTree::CalcHash(int height, unsigned int pos, const std::vector<uint256> &vTxid) {
//we can never have zero txs in a merkle block, we always need the coinbase tx //we can never have zero txs in a merkle block, we always need the coinbase tx
//if we do not have this assert, we can hit a memory access violation when indexing into vTxid //if we do not have this assert, we can hit a memory access violation when indexing into vTxid
@ -74,6 +75,7 @@ uint256 CPartialMerkleTree::CalcHash(int height, unsigned int pos, const std::ve
} }
} }
// NOLINTNEXTLINE(misc-no-recursion)
void CPartialMerkleTree::TraverseAndBuild(int height, unsigned int pos, const std::vector<uint256> &vTxid, const std::vector<bool> &vMatch) { void CPartialMerkleTree::TraverseAndBuild(int height, unsigned int pos, const std::vector<uint256> &vTxid, const std::vector<bool> &vMatch) {
// determine whether this node is the parent of at least one matched txid // determine whether this node is the parent of at least one matched txid
bool fParentOfMatch = false; bool fParentOfMatch = false;
@ -92,6 +94,7 @@ void CPartialMerkleTree::TraverseAndBuild(int height, unsigned int pos, const st
} }
} }
// NOLINTNEXTLINE(misc-no-recursion)
uint256 CPartialMerkleTree::TraverseAndExtract(int height, unsigned int pos, unsigned int &nBitsUsed, unsigned int &nHashUsed, std::vector<uint256> &vMatch, std::vector<unsigned int> &vnIndex) { uint256 CPartialMerkleTree::TraverseAndExtract(int height, unsigned int pos, unsigned int &nBitsUsed, unsigned int &nHashUsed, std::vector<uint256> &vMatch, std::vector<unsigned int> &vnIndex) {
if (nBitsUsed >= vBits.size()) { if (nBitsUsed >= vBits.size()) {
// overflowed the bits array - failure // overflowed the bits array - failure

View File

@ -406,6 +406,7 @@ public:
NodeContext* m_context{nullptr}; NodeContext* m_context{nullptr};
}; };
// NOLINTNEXTLINE(misc-no-recursion)
bool FillBlock(const CBlockIndex* index, const FoundBlock& block, UniqueLock<RecursiveMutex>& lock, const CChain& active, const BlockManager& blockman) bool FillBlock(const CBlockIndex* index, const FoundBlock& block, UniqueLock<RecursiveMutex>& lock, const CChain& active, const BlockManager& blockman)
{ {
if (!index) return false; if (!index) return false;

View File

@ -396,6 +396,7 @@ bool OptionsModel::setData(const QModelIndex & index, const QVariant & value, in
return successful; return successful;
} }
// NOLINTNEXTLINE(misc-no-recursion)
QVariant OptionsModel::getOption(OptionID option, const std::string& suffix) const QVariant OptionsModel::getOption(OptionID option, const std::string& suffix) const
{ {
auto setting = [&]{ return node().getPersistentSetting(SettingName(option) + suffix); }; auto setting = [&]{ return node().getPersistentSetting(SettingName(option) + suffix); };
@ -508,6 +509,7 @@ QFont OptionsModel::getFontForMoney() const
return getFontForChoice(m_font_money); return getFontForChoice(m_font_money);
} }
// NOLINTNEXTLINE(misc-no-recursion)
bool OptionsModel::setOption(OptionID option, const QVariant& value, const std::string& suffix) bool OptionsModel::setOption(OptionID option, const QVariant& value, const std::string& suffix)
{ {
auto changed = [&] { return value.isValid() && value != getOption(option, suffix); }; auto changed = [&] { return value.isValid() && value != getOption(option, suffix); };

View File

@ -414,6 +414,7 @@ struct Sections {
/** /**
* Recursive helper to translate an RPCArg into sections * Recursive helper to translate an RPCArg into sections
*/ */
// NOLINTNEXTLINE(misc-no-recursion)
void Push(const RPCArg& arg, const size_t current_indent = 5, const OuterType outer_type = OuterType::NONE) void Push(const RPCArg& arg, const size_t current_indent = 5, const OuterType outer_type = OuterType::NONE)
{ {
const auto indent = std::string(current_indent, ' '); const auto indent = std::string(current_indent, ' ');
@ -953,6 +954,7 @@ std::string RPCArg::ToDescriptionString(bool is_named_arg) const
return ret; return ret;
} }
// NOLINTNEXTLINE(misc-no-recursion)
void RPCResult::ToSections(Sections& sections, const OuterType outer_type, const int current_indent) const void RPCResult::ToSections(Sections& sections, const OuterType outer_type, const int current_indent) const
{ {
// Indentation // Indentation
@ -1086,6 +1088,7 @@ static std::optional<UniValue::VType> ExpectedType(RPCResult::Type type)
NONFATAL_UNREACHABLE(); NONFATAL_UNREACHABLE();
} }
// NOLINTNEXTLINE(misc-no-recursion)
UniValue RPCResult::MatchesType(const UniValue& result) const UniValue RPCResult::MatchesType(const UniValue& result) const
{ {
if (m_skip_type_check) { if (m_skip_type_check) {
@ -1164,6 +1167,7 @@ void RPCResult::CheckInnerDoc() const
CHECK_NONFATAL(inner_needed != m_inner.empty()); CHECK_NONFATAL(inner_needed != m_inner.empty());
} }
// NOLINTNEXTLINE(misc-no-recursion)
std::string RPCArg::ToStringObj(const bool oneline) const std::string RPCArg::ToStringObj(const bool oneline) const
{ {
std::string res; std::string res;
@ -1202,6 +1206,7 @@ std::string RPCArg::ToStringObj(const bool oneline) const
NONFATAL_UNREACHABLE(); NONFATAL_UNREACHABLE();
} }
// NOLINTNEXTLINE(misc-no-recursion)
std::string RPCArg::ToString(const bool oneline) const std::string RPCArg::ToString(const bool oneline) const
{ {
if (oneline && !m_opts.oneline_description.empty()) { if (oneline && !m_opts.oneline_description.empty()) {
@ -1228,6 +1233,7 @@ std::string RPCArg::ToString(const bool oneline) const
case Type::OBJ: case Type::OBJ:
case Type::OBJ_NAMED_PARAMS: case Type::OBJ_NAMED_PARAMS:
case Type::OBJ_USER_KEYS: { case Type::OBJ_USER_KEYS: {
// NOLINTNEXTLINE(misc-no-recursion)
const std::string res = Join(m_inner, ",", [&](const RPCArg& i) { return i.ToStringObj(oneline); }); const std::string res = Join(m_inner, ",", [&](const RPCArg& i) { return i.ToStringObj(oneline); });
if (m_type == Type::OBJ) { if (m_type == Type::OBJ) {
return "{" + res + "}"; return "{" + res + "}";

View File

@ -162,6 +162,7 @@ struct RPCArgOptions {
//!< methods set the also_positional flag and read values from both positions. //!< methods set the also_positional flag and read values from both positions.
}; };
// NOLINTNEXTLINE(misc-no-recursion)
struct RPCArg { struct RPCArg {
enum class Type { enum class Type {
OBJ, OBJ,
@ -271,6 +272,7 @@ struct RPCArg {
std::string ToDescriptionString(bool is_named_arg) const; std::string ToDescriptionString(bool is_named_arg) const;
}; };
// NOLINTNEXTLINE(misc-no-recursion)
struct RPCResult { struct RPCResult {
enum class Type { enum class Type {
OBJ, OBJ,

View File

@ -599,6 +599,7 @@ public:
COMPAT, // string calculation that mustn't change over time to stay compatible with previous software versions COMPAT, // string calculation that mustn't change over time to stay compatible with previous software versions
}; };
// NOLINTNEXTLINE(misc-no-recursion)
bool IsSolvable() const override bool IsSolvable() const override
{ {
for (const auto& arg : m_subdescriptor_args) { for (const auto& arg : m_subdescriptor_args) {
@ -607,6 +608,7 @@ public:
return true; return true;
} }
// NOLINTNEXTLINE(misc-no-recursion)
bool IsRange() const final bool IsRange() const final
{ {
for (const auto& pubkey : m_pubkey_args) { for (const auto& pubkey : m_pubkey_args) {
@ -618,6 +620,7 @@ public:
return false; return false;
} }
// NOLINTNEXTLINE(misc-no-recursion)
virtual bool ToStringSubScriptHelper(const SigningProvider* arg, std::string& ret, const StringType type, const DescriptorCache* cache = nullptr) const virtual bool ToStringSubScriptHelper(const SigningProvider* arg, std::string& ret, const StringType type, const DescriptorCache* cache = nullptr) const
{ {
size_t pos = 0; size_t pos = 0;
@ -630,6 +633,7 @@ public:
return true; return true;
} }
// NOLINTNEXTLINE(misc-no-recursion)
virtual bool ToStringHelper(const SigningProvider* arg, std::string& out, const StringType type, const DescriptorCache* cache = nullptr) const virtual bool ToStringHelper(const SigningProvider* arg, std::string& out, const StringType type, const DescriptorCache* cache = nullptr) const
{ {
std::string extra = ToStringExtra(); std::string extra = ToStringExtra();
@ -682,6 +686,7 @@ public:
return ret; return ret;
} }
// NOLINTNEXTLINE(misc-no-recursion)
bool ExpandHelper(int pos, const SigningProvider& arg, const DescriptorCache* read_cache, std::vector<CScript>& output_scripts, FlatSigningProvider& out, DescriptorCache* write_cache) const bool ExpandHelper(int pos, const SigningProvider& arg, const DescriptorCache* read_cache, std::vector<CScript>& output_scripts, FlatSigningProvider& out, DescriptorCache* write_cache) const
{ {
std::vector<std::pair<CPubKey, KeyOriginInfo>> entries; std::vector<std::pair<CPubKey, KeyOriginInfo>> entries;
@ -723,6 +728,7 @@ public:
return ExpandHelper(pos, DUMMY_SIGNING_PROVIDER, &read_cache, output_scripts, out, nullptr); return ExpandHelper(pos, DUMMY_SIGNING_PROVIDER, &read_cache, output_scripts, out, nullptr);
} }
// NOLINTNEXTLINE(misc-no-recursion)
void ExpandPrivate(int pos, const SigningProvider& provider, FlatSigningProvider& out) const final void ExpandPrivate(int pos, const SigningProvider& provider, FlatSigningProvider& out) const final
{ {
for (const auto& p : m_pubkey_args) { for (const auto& p : m_pubkey_args) {
@ -750,6 +756,7 @@ public:
std::optional<int64_t> MaxSatisfactionElems() const override { return {}; } std::optional<int64_t> MaxSatisfactionElems() const override { return {}; }
// NOLINTNEXTLINE(misc-no-recursion)
void GetPubKeys(std::set<CPubKey>& pubkeys, std::set<CExtPubKey>& ext_pubs) const override void GetPubKeys(std::set<CPubKey>& pubkeys, std::set<CExtPubKey>& ext_pubs) const override
{ {
for (const auto& p : m_pubkey_args) { for (const auto& p : m_pubkey_args) {
@ -1579,6 +1586,7 @@ struct KeyParser {
}; };
/** Parse a script in a particular context. */ /** Parse a script in a particular context. */
// NOLINTNEXTLINE(misc-no-recursion)
std::unique_ptr<DescriptorImpl> ParseScript(uint32_t& key_exp_index, Span<const char>& sp, ParseScriptContext ctx, FlatSigningProvider& out, std::string& error) std::unique_ptr<DescriptorImpl> ParseScript(uint32_t& key_exp_index, Span<const char>& sp, ParseScriptContext ctx, FlatSigningProvider& out, std::string& error)
{ {
using namespace spanparsing; using namespace spanparsing;
@ -1886,6 +1894,7 @@ std::unique_ptr<DescriptorImpl> InferMultiA(const CScript& script, ParseScriptCo
return std::make_unique<MultiADescriptor>(match->first, std::move(keys)); return std::make_unique<MultiADescriptor>(match->first, std::move(keys));
} }
// NOLINTNEXTLINE(misc-no-recursion)
std::unique_ptr<DescriptorImpl> InferScript(const CScript& script, ParseScriptContext ctx, const SigningProvider& provider) std::unique_ptr<DescriptorImpl> InferScript(const CScript& script, ParseScriptContext ctx, const SigningProvider& provider)
{ {
if (ctx == ParseScriptContext::P2TR && script.size() == 34 && script[0] == 32 && script[33] == OP_CHECKSIG) { if (ctx == ParseScriptContext::P2TR && script.size() == 34 && script[0] == 32 && script[33] == OP_CHECKSIG) {

View File

@ -297,6 +297,7 @@ using miniscript::operator"" _mst;
using Node = miniscript::Node<CPubKey>; using Node = miniscript::Node<CPubKey>;
/** Compute all challenges (pubkeys, hashes, timelocks) that occur in a given Miniscript. */ /** Compute all challenges (pubkeys, hashes, timelocks) that occur in a given Miniscript. */
// NOLINTNEXTLINE(misc-no-recursion)
std::set<Challenge> FindChallenges(const NodeRef& ref) { std::set<Challenge> FindChallenges(const NodeRef& ref) {
std::set<Challenge> chal; std::set<Challenge> chal;
for (const auto& key : ref->keys) { for (const auto& key : ref->keys) {

View File

@ -127,6 +127,7 @@ std::shared_ptr<const CBlock> MinerTestingSetup::BadBlock(const uint256& prev_ha
return ret; return ret;
} }
// NOLINTNEXTLINE(misc-no-recursion)
void MinerTestingSetup::BuildChain(const uint256& root, int height, const unsigned int invalid_rate, const unsigned int branch_rate, const unsigned int max_size, std::vector<std::shared_ptr<const CBlock>>& blocks) void MinerTestingSetup::BuildChain(const uint256& root, int height, const unsigned int invalid_rate, const unsigned int branch_rate, const unsigned int max_size, std::vector<std::shared_ptr<const CBlock>>& blocks)
{ {
if (height <= 0 || blocks.size() >= max_size) return; if (height <= 0 || blocks.size() >= max_size) return;

View File

@ -18,6 +18,7 @@
#include <utility> #include <utility>
#include <vector> #include <vector>
// NOLINTNEXTLINE(misc-no-recursion)
class UniValue { class UniValue {
public: public:
enum VType { VNULL, VOBJ, VARR, VSTR, VNUM, VBOOL, }; enum VType { VNULL, VOBJ, VARR, VSTR, VNUM, VBOOL, };

View File

@ -27,6 +27,7 @@ static std::string json_escape(const std::string& inS)
return outS; return outS;
} }
// NOLINTNEXTLINE(misc-no-recursion)
std::string UniValue::write(unsigned int prettyIndent, std::string UniValue::write(unsigned int prettyIndent,
unsigned int indentLevel) const unsigned int indentLevel) const
{ {
@ -66,6 +67,7 @@ static void indentStr(unsigned int prettyIndent, unsigned int indentLevel, std::
s.append(prettyIndent * indentLevel, ' '); s.append(prettyIndent * indentLevel, ' ');
} }
// NOLINTNEXTLINE(misc-no-recursion)
void UniValue::writeArray(unsigned int prettyIndent, unsigned int indentLevel, std::string& s) const void UniValue::writeArray(unsigned int prettyIndent, unsigned int indentLevel, std::string& s) const
{ {
s += "["; s += "[";
@ -88,6 +90,7 @@ void UniValue::writeArray(unsigned int prettyIndent, unsigned int indentLevel, s
s += "]"; s += "]";
} }
// NOLINTNEXTLINE(misc-no-recursion)
void UniValue::writeObject(unsigned int prettyIndent, unsigned int indentLevel, std::string& s) const void UniValue::writeObject(unsigned int prettyIndent, unsigned int indentLevel, std::string& s) const
{ {
s += "{"; s += "{";

View File

@ -65,6 +65,7 @@ void ReplaceAll(std::string& in_out, const std::string& search, const std::strin
* @param unary_op Apply this operator to each item * @param unary_op Apply this operator to each item
*/ */
template <typename C, typename S, typename UnaryOp> template <typename C, typename S, typename UnaryOp>
// NOLINTNEXTLINE(misc-no-recursion)
auto Join(const C& container, const S& separator, UnaryOp unary_op) auto Join(const C& container, const S& separator, UnaryOp unary_op)
{ {
decltype(unary_op(*container.begin())) ret; decltype(unary_op(*container.begin())) ret;

View File

@ -253,6 +253,7 @@ bool CachedTxIsFromMe(const CWallet& wallet, const CWalletTx& wtx, const isminef
return (CachedTxGetDebit(wallet, wtx, filter) > 0); return (CachedTxGetDebit(wallet, wtx, filter) > 0);
} }
// NOLINTNEXTLINE(misc-no-recursion)
bool CachedTxIsTrusted(const CWallet& wallet, const CWalletTx& wtx, std::set<uint256>& trusted_parents) bool CachedTxIsTrusted(const CWallet& wallet, const CWalletTx& wtx, std::set<uint256>& trusted_parents)
{ {
AssertLockHeld(wallet.cs_wallet); AssertLockHeld(wallet.cs_wallet);

View File

@ -395,6 +395,7 @@ class DescribeWalletAddressVisitor
public: public:
const SigningProvider * const provider; const SigningProvider * const provider;
// NOLINTNEXTLINE(misc-no-recursion)
void ProcessSubScript(const CScript& subscript, UniValue& obj) const void ProcessSubScript(const CScript& subscript, UniValue& obj) const
{ {
// Always present: script type and redeemscript // Always present: script type and redeemscript
@ -445,6 +446,7 @@ public:
return obj; return obj;
} }
// NOLINTNEXTLINE(misc-no-recursion)
UniValue operator()(const ScriptHash& scripthash) const UniValue operator()(const ScriptHash& scripthash) const
{ {
UniValue obj(UniValue::VOBJ); UniValue obj(UniValue::VOBJ);
@ -465,6 +467,7 @@ public:
return obj; return obj;
} }
// NOLINTNEXTLINE(misc-no-recursion)
UniValue operator()(const WitnessV0ScriptHash& id) const UniValue operator()(const WitnessV0ScriptHash& id) const
{ {
UniValue obj(UniValue::VOBJ); UniValue obj(UniValue::VOBJ);

View File

@ -854,6 +854,7 @@ enum class ScriptContext
// Analyse the provided scriptPubKey, determining which keys and which redeem scripts from the ImportData struct are needed to spend it, and mark them as used. // Analyse the provided scriptPubKey, determining which keys and which redeem scripts from the ImportData struct are needed to spend it, and mark them as used.
// Returns an error string, or the empty string for success. // Returns an error string, or the empty string for success.
// NOLINTNEXTLINE(misc-no-recursion)
static std::string RecurseImportData(const CScript& script, ImportData& import_data, const ScriptContext script_ctx) static std::string RecurseImportData(const CScript& script, ImportData& import_data, const ScriptContext script_ctx)
{ {
// Use Solver to obtain script type and parsed pubkeys or hashes: // Use Solver to obtain script type and parsed pubkeys or hashes:

View File

@ -97,6 +97,7 @@ bool HaveKeys(const std::vector<valtype>& pubkeys, const LegacyScriptPubKeyMan&
//! @param recurse_scripthash whether to recurse into nested p2sh and p2wsh //! @param recurse_scripthash whether to recurse into nested p2sh and p2wsh
//! scripts or simply treat any script that has been //! scripts or simply treat any script that has been
//! stored in the keystore as spendable //! stored in the keystore as spendable
// NOLINTNEXTLINE(misc-no-recursion)
IsMineResult IsMineInner(const LegacyScriptPubKeyMan& keystore, const CScript& scriptPubKey, IsMineSigVersion sigversion, bool recurse_scripthash=true) IsMineResult IsMineInner(const LegacyScriptPubKeyMan& keystore, const CScript& scriptPubKey, IsMineSigVersion sigversion, bool recurse_scripthash=true)
{ {
IsMineResult ret = IsMineResult::NO; IsMineResult ret = IsMineResult::NO;