Misc clang 21 fixes

* Use -O3 and other flags instead of -Ofast
  - https://discourse.llvm.org/t/rfc-deprecate-ofast/78687
  - https://gcc.gnu.org/onlinedocs/gcc/Optimize-Options.html
* Find libunwind library based on C++ compiler type, not C compiler type
* In stack_trace.cpp, pass stream modifiers to `std::stringstream` first, then send string to log
* In stack_trace.cpp, remove dead code related to `stack_trace_log` path
* Remove `virtual` method attributues from `final` class `cryptonote::core`
* Remove unused `this` capture in cryptonote protocol handler
* Remove unused variable `bad` in net node
* Use `std::make_unsigned` instead of `boost::make_unsigned`
  - https://github.com/boostorg/type_traits/issues/171
  - https://github.com/boostorg/type_traits/issues/202
  - https://github.com/boostorg/type_traits/pull/199
* Cleanup `include`s in pair serialization
* Test convergence b/t `std::make_unsigned` and `boost::make_unsigned`

Fixes compilation and silences warnings on:
clang version 21.1.6
Linux 6.18.8-3-cachyos
This commit is contained in:
jeffro256
2026-02-09 01:49:45 -07:00
parent 74dd968cd9
commit c93c4fc829
10 changed files with 82 additions and 37 deletions

View File

@@ -351,7 +351,7 @@ endif()
if(WIN32 OR ARM OR PPC64LE OR PPC64 OR PPC)
set(OPT_FLAGS_RELEASE "-O2")
else()
set(OPT_FLAGS_RELEASE "-Ofast")
set(OPT_FLAGS_RELEASE "-O3 -ffast-math -fno-semantic-interposition") # not present: -fallow-store-data-races
endif()
# BUILD_TAG is used to select the build type to check for a new version
@@ -508,7 +508,7 @@ if (APPLE OR NETBSD)
elseif (DEPENDS AND NOT LINUX)
set(DEFAULT_STACK_TRACE OFF)
set(LIBUNWIND_LIBRARIES "")
elseif(CMAKE_C_COMPILER_ID STREQUAL "GNU" AND NOT MINGW)
elseif(CMAKE_CXX_COMPILER_ID STREQUAL "GNU" AND NOT MINGW)
set(DEFAULT_STACK_TRACE ON)
set(STACK_TRACE_LIB "easylogging++") # for diag output only
set(LIBUNWIND_LIBRARIES "")

View File

@@ -35,6 +35,7 @@
#include <stdexcept>
#include <iomanip>
#include <sstream>
#ifdef USE_UNWIND
#define UNW_LOCAL_ONLY
#include <libunwind.h>
@@ -54,7 +55,9 @@
do { \
auto elpp = ELPP; \
if (elpp) { \
CINFO(el::base::Writer,el::base::DispatchAction::FileOnlyLog,MONERO_DEFAULT_LOG_CATEGORY) << x; \
std::stringstream ss; \
ss << x; \
CINFO(el::base::Writer,el::base::DispatchAction::FileOnlyLog,MONERO_DEFAULT_LOG_CATEGORY) << ss.str(); \
} \
else { \
std::cout << x << std::endl; \
@@ -105,19 +108,9 @@ void CXA_THROW(void *ex, CXA_THROW_INFO_T *info, void (*dest)(void*))
__real___cxa_throw(ex, info, dest);
}
namespace
{
std::string stack_trace_log;
}
namespace tools
{
void set_stack_trace_log(const std::string &log)
{
stack_trace_log = log;
}
void log_stack_trace(const char *msg)
{
#ifdef USE_UNWIND
@@ -127,7 +120,6 @@ void log_stack_trace(const char *msg)
unsigned level;
char sym[512], *dsym;
int status;
const char *log = stack_trace_log.empty() ? NULL : stack_trace_log.c_str();
#endif
if (msg)

View File

@@ -29,12 +29,9 @@
#ifndef MONERO_EXCEPTION_H
#define MONERO_EXCEPTION_H
#include <string>
namespace tools
{
void set_stack_trace_log(const std::string &log);
void log_stack_trace(const char *msg);
} // namespace tools

View File

@@ -227,15 +227,15 @@ namespace cryptonote
*
* @return true if the block was added to the main chain, otherwise false
*/
virtual bool handle_block_found(block& b, block_verification_context &bvc) override;
bool handle_block_found(block& b, block_verification_context &bvc) final;
/**
* @copydoc Blockchain::create_block_template
*
* @note see Blockchain::create_block_template
*/
virtual bool get_block_template(block& b, const account_public_address& adr, difficulty_type& diffic, uint64_t& height, uint64_t& expected_reward, uint64_t &cumulative_weight, const blobdata& ex_nonce, uint64_t &seed_height, crypto::hash &seed_hash) override;
virtual bool get_block_template(block& b, const crypto::hash *prev_block, const account_public_address& adr, difficulty_type& diffic, uint64_t& height, uint64_t& expected_reward, uint64_t &cumulative_weight, const blobdata& ex_nonce, uint64_t &seed_height, crypto::hash &seed_hash);
bool get_block_template(block& b, const account_public_address& adr, difficulty_type& diffic, uint64_t& height, uint64_t& expected_reward, uint64_t &cumulative_weight, const blobdata& ex_nonce, uint64_t &seed_height, crypto::hash &seed_hash) final;
bool get_block_template(block& b, const crypto::hash *prev_block, const account_public_address& adr, difficulty_type& diffic, uint64_t& height, uint64_t& expected_reward, uint64_t &cumulative_weight, const blobdata& ex_nonce, uint64_t &seed_height, crypto::hash &seed_hash);
/**
* @copydoc Blockchain::get_miner_data
@@ -248,7 +248,7 @@ namespace cryptonote
* @brief called when a transaction is relayed.
* @note Should only be invoked from `levin_notify`.
*/
virtual void on_transactions_relayed(epee::span<const cryptonote::blobdata> tx_blobs, relay_method tx_relay) final;
void on_transactions_relayed(epee::span<const cryptonote::blobdata> tx_blobs, relay_method tx_relay) final;
/**
@@ -340,7 +340,7 @@ namespace cryptonote
*
* @note see Blockchain::get_current_blockchain_height()
*/
virtual uint64_t get_current_blockchain_height() const final;
uint64_t get_current_blockchain_height() const final;
/**
* @brief get the hash and height of the most recent block
@@ -671,7 +671,7 @@ namespace cryptonote
*
* @return core synchronization status
*/
virtual bool is_synchronized() const final;
bool is_synchronized() const final;
/**
* @copydoc miner::on_synchronized

View File

@@ -2645,7 +2645,7 @@ skip:
{
// sort peers between fluffy ones and others
std::vector<std::pair<epee::net_utils::zone, boost::uuids::uuid>> fluffyConnections;
m_p2p->for_each_connection([this, &exclude_context, &fluffyConnections](connection_context& context, nodetool::peerid_type peer_id, uint32_t support_flags)
m_p2p->for_each_connection([&exclude_context, &fluffyConnections](connection_context& context, nodetool::peerid_type peer_id, uint32_t support_flags)
{
// peer_id also filters out connections before handshake
if (peer_id && exclude_context.m_connection_id != context.m_connection_id && context.m_remote_address.get_zone() == epee::net_utils::zone::public_)

View File

@@ -291,10 +291,6 @@ int main(int argc, char const * argv[])
// after logs initialized
tools::create_directories_if_necessary(data_dir.string());
#ifdef STACK_TRACE
tools::set_stack_trace_log(log_file_path.filename().string());
#endif // STACK_TRACE
if (!command_line::is_arg_defaulted(vm, daemon_args::arg_max_concurrency))
tools::set_max_concurrency(command_line::get_arg(vm, daemon_args::arg_max_concurrency));

View File

@@ -2153,7 +2153,7 @@ namespace nodetool
if (!tools::dns_utils::load_txt_records_from_dns(records, dns_urls))
return true;
unsigned good = 0, bad = 0;
unsigned good = 0;
for (const auto& record : records)
{
std::vector<std::string> ips;
@@ -2177,7 +2177,6 @@ namespace nodetool
continue;
}
MWARNING("Invalid IP address or subnet from DNS blocklist: " << ip << " - " << parsed_addr.error());
++bad;
}
}
if (good > 0)

View File

@@ -36,8 +36,10 @@
#include <cassert>
#include <iostream>
#include <iterator>
#include <type_traits>
#include <boost/endian/conversion.hpp>
#include <boost/type_traits/make_unsigned.hpp>
#include <boost/mpl/bool.hpp>
#include "common/varint.h"
#include "span.h"
@@ -106,7 +108,7 @@ struct binary_archive<false> : public binary_archive_base<false>
template <class T>
void serialize_int(T &v)
{
serialize_uint(*(typename boost::make_unsigned<T>::type *)&v);
serialize_uint(*(typename std::make_unsigned<T>::type *)&v);
}
/*! \fn serialize_uint
@@ -137,7 +139,7 @@ struct binary_archive<false> : public binary_archive_base<false>
template <class T>
void serialize_varint(T &v)
{
serialize_uvarint(*(typename boost::make_unsigned<T>::type *)(&v));
serialize_uvarint(*(typename std::make_unsigned<T>::type *)(&v));
}
template <class T>
@@ -190,7 +192,7 @@ struct binary_archive<true> : public binary_archive_base<true>
template <class T>
void serialize_int(T v)
{
serialize_uint(static_cast<typename boost::make_unsigned<T>::type>(v));
serialize_uint(static_cast<typename std::make_unsigned<T>::type>(v));
}
template <class T>
void serialize_uint(T v)
@@ -209,7 +211,7 @@ struct binary_archive<true> : public binary_archive_base<true>
template <class T>
void serialize_varint(T &v)
{
serialize_uvarint(*(typename boost::make_unsigned<T>::type *)(&v));
serialize_uvarint(*(typename std::make_unsigned<T>::type *)(&v));
}
template <class T>

View File

@@ -29,8 +29,9 @@
// Parts of this file are originally copyright (c) 2012-2013 The Cryptonote developers
#pragma once
#include <memory>
#include <boost/type_traits/make_unsigned.hpp>
#include <cstdint>
#include "serialization.h"
namespace serialization

View File

@@ -35,6 +35,7 @@
#include <vector>
#include <boost/foreach.hpp>
#include <boost/archive/portable_binary_iarchive.hpp>
#include <boost/type_traits/make_unsigned.hpp>
#include "cryptonote_basic/cryptonote_basic.h"
#include "cryptonote_basic/cryptonote_basic_impl.h"
#include "ringct/rctSigs.h"
@@ -56,6 +57,63 @@ static_assert(!std::is_trivially_copyable<std::vector<unsigned char>>(),
static_assert(!std::is_trivially_copyable<std::string>(),
"should fail to compile when applying blob serializer");
/**
* Test convergence of std::make_unsigned against boost::make_unsigned for
* scoped enums with explicit underlying types
*/
#define DEFINE_SCOPED_UNDERLYING_ENUM(u) \
enum class E_ ## u : u { A_##u = static_cast<u>(-1), B_##u = 0, C_##u }; \
static_assert(std::is_same_v<std::underlying_type_t<E_##u>, u>); \
static_assert(sizeof(std::make_unsigned_t<E_##u>) == sizeof(std::make_unsigned_t<u>)); \
static_assert(std::is_same_v<std::make_unsigned_t<E_##u>, boost::make_unsigned_t<E_##u>>);
DEFINE_SCOPED_UNDERLYING_ENUM(uint8_t)
DEFINE_SCOPED_UNDERLYING_ENUM(uint16_t)
DEFINE_SCOPED_UNDERLYING_ENUM(uint32_t)
DEFINE_SCOPED_UNDERLYING_ENUM(uint64_t)
//DEFINE_SCOPED_UNDERLYING_ENUM(__uint128_t)
DEFINE_SCOPED_UNDERLYING_ENUM(int8_t)
DEFINE_SCOPED_UNDERLYING_ENUM(int16_t)
DEFINE_SCOPED_UNDERLYING_ENUM(int32_t)
DEFINE_SCOPED_UNDERLYING_ENUM(int64_t)
//DEFINE_SCOPED_UNDERLYING_ENUM(__int128_t)
DEFINE_SCOPED_UNDERLYING_ENUM(size_t)
/**
* Test convergence of std::make_unsigned against boost::make_unsigned for
* unscoped enums with explicit underlying types
*/
#define DEFINE_UNSCOPED_UNDERLYING_ENUM(u) \
enum class UE_ ## u : u { A_##u = static_cast<u>(-1), B_##u = 0, C_##u }; \
static_assert(std::is_same_v<std::underlying_type_t<UE_##u>, u>); \
static_assert(sizeof(std::make_unsigned_t<UE_##u>) == sizeof(std::make_unsigned_t<u>)); \
static_assert(std::is_same_v<std::make_unsigned_t<UE_##u>, boost::make_unsigned_t<UE_##u>>);
DEFINE_UNSCOPED_UNDERLYING_ENUM(uint8_t)
DEFINE_UNSCOPED_UNDERLYING_ENUM(uint16_t)
DEFINE_UNSCOPED_UNDERLYING_ENUM(uint32_t)
DEFINE_UNSCOPED_UNDERLYING_ENUM(uint64_t)
//DEFINE_UNSCOPED_UNDERLYING_ENUM(__uint128_t)
DEFINE_UNSCOPED_UNDERLYING_ENUM(int8_t)
DEFINE_UNSCOPED_UNDERLYING_ENUM(int16_t)
DEFINE_UNSCOPED_UNDERLYING_ENUM(int32_t)
DEFINE_UNSCOPED_UNDERLYING_ENUM(int64_t)
//DEFINE_UNSCOPED_UNDERLYING_ENUM(__int128_t)
DEFINE_UNSCOPED_UNDERLYING_ENUM(size_t)
/**
* Test convergence of std::make_unsigned against boost::make_unsigned for
* unscoped enums with implicit underlying types
*/
#define TEST_MAKE_UNSIGNED_ENUM(e) \
static_assert(std::is_same_v<std::make_unsigned_t<e>, boost::make_unsigned_t<e>>);
enum IUE1 { A1, B1, C1 };
#if defined(__GNUC__) && !defined(__clang__)
TEST_MAKE_UNSIGNED_ENUM(IUE1) // may break for GCC later too, or Boost might fix it first
#endif
enum IUE2 { A2 = -1, B2, C2 };
TEST_MAKE_UNSIGNED_ENUM(IUE2)
struct Struct
{
int32_t a;