diff --git a/.github/workflows/clang-tidy.yml b/.github/workflows/clang-tidy.yml
new file mode 100644
index 0000000..62f7a3d
--- /dev/null
+++ b/.github/workflows/clang-tidy.yml
@@ -0,0 +1,30 @@
+name: clang-tidy
+
+on: [push, pull_request]
+
+jobs:
+ clang-tidy:
+
+ runs-on: ubuntu-22.04
+
+ steps:
+ - name: Install clang
+ run: |
+ wget https://apt.llvm.org/llvm.sh
+ chmod +x llvm.sh
+ sudo ./llvm.sh 16
+ sudo apt-get install -y clang-tidy-16
+
+ - name: Verify clang-tidy configuration
+ run: |
+ clang-tidy-16 --verify-config
+
+ - name: Checkout repository
+ uses: actions/checkout@v3
+ with:
+ submodules: true
+
+ - name: Run clang-tidy
+ run: |
+ cd src
+ clang-tidy-16 *.cpp -checks=-clang-diagnostic-undefined-internal -warnings-as-errors=* -- -I../external/src/robin-hood-hashing/src/include -I../external/src/rapidjson/include -I../external/src/cryptonote -I../external/src/RandomX/src -I../external/src/cppzmq -I../external/src/libuv/include -I../external/src/libzmq/include -I../external/src/curl/include -I../external/src -DCLANG_TIDY -DSIZE_MAX=UINT64_MAX -DRAPIDJSON_ENDIAN=RAPIDJSON_LITTLEENDIAN -DRAPIDJSON_PARSE_DEFAULT_FLAGS=kParseTrailingCommasFlag
diff --git a/README.md b/README.md
index fdf5551..55bce3d 100644
--- a/README.md
+++ b/README.md
@@ -24,6 +24,7 @@ Reddit discussions: [original announcement](https://www.reddit.com/r/MoneroMinin
+![clang-tidy](https://github.com/SChernykh/p2pool/actions/workflows/clang-tidy.yml/badge.svg)
# Contents
- [Pool mining vs Solo mining vs P2Pool mining](#pool-mining-vs-solo-mining-vs-p2pool-mining)
- [Features](#features)
diff --git a/src/common.h b/src/common.h
index c618bf5..b5a2dfd 100644
--- a/src/common.h
+++ b/src/common.h
@@ -204,7 +204,7 @@ struct
{
#ifdef _MSC_VER
_addcarry_u64(_addcarry_u64(0, lo, b.lo, &lo), hi, b.hi, &hi);
-#elif __GNUC__
+#elif defined(__GNUC__) && !defined(CLANG_TIDY)
*reinterpret_cast(this) += *reinterpret_cast(&b);
#else
const uint64_t t = lo;
@@ -221,7 +221,7 @@ struct
{
#ifdef _MSC_VER
_subborrow_u64(_subborrow_u64(0, lo, b.lo, &lo), hi, b.hi, &hi);
-#elif __GNUC__
+#elif defined(__GNUC__) && !defined(CLANG_TIDY)
*reinterpret_cast(this) -= *reinterpret_cast(&b);
#else
const uint64_t t = b.lo;
diff --git a/src/log.h b/src/log.h
index 1a1f698..e51967b 100644
--- a/src/log.h
+++ b/src/log.h
@@ -65,7 +65,7 @@ struct Stream
return *this;
}
- template
+ template
NOINLINE void writeInt(T data)
{
static_assert(1 < base && base <= 64, "Invalid base");
@@ -78,11 +78,13 @@ struct Stream
size_t k = sizeof(buf);
int w = m_numberWidth;
+ std::make_unsigned_t udata = static_cast>(data);
+
do {
- buf[--k] = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ+/"[data % base];
- data /= base;
+ buf[--k] = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ+/"[udata % base];
+ udata /= base;
--w;
- } while ((data > 0) || (w > 0));
+ } while (udata || (w > 0));
if (negative) {
buf[--k] = '-';
diff --git a/src/p2pool.cpp b/src/p2pool.cpp
index dcc234a..8b7c384 100644
--- a/src/p2pool.cpp
+++ b/src/p2pool.cpp
@@ -804,13 +804,13 @@ bool p2pool::get_timestamps(uint64_t (×tamps)[TIMESTAMP_WINDOW]) const
{
ReadLock lock(m_mainchainLock);
- if (m_mainchainByHeight.size() <= TIMESTAMP_WINDOW) {
+ if (m_mainchainByHeight.size() < TIMESTAMP_WINDOW) {
return false;
}
auto it = m_mainchainByHeight.end();
- for (int i = 0; (i < TIMESTAMP_WINDOW) && (it != m_mainchainByHeight.begin()); ++i) {
+ for (int i = 0; i < TIMESTAMP_WINDOW; ++i) {
--it;
timestamps[i] = it->second.timestamp;
}