It is possible to write a clang-tidy check for this, but I am not sure if people want this. cc @theuni
diff --git a/contrib/devtools/bitcoin-tidy/CMakeLists.txt b/contrib/devtools/bitcoin-tidy/CMakeLists.txt
index 35e60d1d87..b523692b12 100644
--- a/contrib/devtools/bitcoin-tidy/CMakeLists.txt
+++ b/contrib/devtools/bitcoin-tidy/CMakeLists.txt
@@ -14,7 +14,10 @@ find_program(CLANG_TIDY_EXE NAMES "clang-tidy-${LLVM_VERSION_MAJOR}" "clang-tidy
message(STATUS "Found LLVM ${LLVM_PACKAGE_VERSION}")
message(STATUS "Found clang-tidy: ${CLANG_TIDY_EXE}")
-add_library(bitcoin-tidy MODULE bitcoin-tidy.cpp logprintf.cpp)
+add_library(bitcoin-tidy MODULE bitcoin-tidy.cpp
+ chrono.cpp
+ logprintf.cpp
+)
target_include_directories(bitcoin-tidy SYSTEM PRIVATE ${LLVM_INCLUDE_DIRS})
# Disable RTTI and exceptions as necessary
@@ -47,7 +50,10 @@ else()
endif()
# Create a dummy library that runs clang-tidy tests as a side-effect of building
-add_library(bitcoin-tidy-tests OBJECT EXCLUDE_FROM_ALL example_logprintf.cpp)
+add_library(bitcoin-tidy-tests OBJECT EXCLUDE_FROM_ALL
+ example_chrono.cpp
+ example_logprintf.cpp
+)
add_dependencies(bitcoin-tidy-tests bitcoin-tidy)
set_target_properties(bitcoin-tidy-tests PROPERTIES CXX_CLANG_TIDY "${CLANG_TIDY_COMMAND}")
diff --git a/contrib/devtools/bitcoin-tidy/bitcoin-tidy.cpp b/contrib/devtools/bitcoin-tidy/bitcoin-tidy.cpp
index 0f34d37793..bc7c05ca45 100644
--- a/contrib/devtools/bitcoin-tidy/bitcoin-tidy.cpp
+++ b/contrib/devtools/bitcoin-tidy/bitcoin-tidy.cpp
@@ -2,6 +2,7 @@
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+#include "chrono.h"
#include "logprintf.h"
#include <clang-tidy/ClangTidyModule.h>
@@ -12,6 +13,7 @@ class BitcoinModule final : public clang::tidy::ClangTidyModule
public:
void addCheckFactories(clang::tidy::ClangTidyCheckFactories& CheckFactories) override
{
+ CheckFactories.registerCheck<bitcoin::ChronoCheck>("bitcoin-chrono-count");
CheckFactories.registerCheck<bitcoin::LogPrintfCheck>("bitcoin-unterminated-logprintf");
}
};
diff --git a/contrib/devtools/bitcoin-tidy/chrono.cpp b/contrib/devtools/bitcoin-tidy/chrono.cpp
new file mode 100644
index 0000000000..163cf0b9e8
--- /dev/null
+++ b/contrib/devtools/bitcoin-tidy/chrono.cpp
@@ -0,0 +1,37 @@
+// Copyright (c) The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or https://opensource.org/license/mit/.
+
+#include "chrono.h"
+
+#include <clang/AST/ASTContext.h>
+#include <clang/ASTMatchers/ASTMatchFinder.h>
+
+namespace bitcoin {
+
+void ChronoCheck::registerMatchers(clang::ast_matchers::MatchFinder* finder)
+{
+ using namespace clang::ast_matchers;
+
+ finder->addMatcher(
+ cxxMemberCallExpr(
+ callee(cxxMethodDecl(hasName("count"))),
+ thisPointerType(qualType(hasDeclaration(cxxRecordDecl(
+ hasName("std::chrono::duration")
+ )))),
+
+ expr().bind("count_call")),
+ this);
+}
+
+void ChronoCheck::check(const clang::ast_matchers::MatchFinder::MatchResult& Result)
+{
+ if (const auto* call = Result.Nodes.getNodeAs<clang::Expr>("count_call")) {
+ const clang::ASTContext& ctx = *Result.Context;
+ const auto user_diag = diag(call->getEndLoc(), "Fragile call to std::chrono::duration::count(), Use Ticks or TicksSinceEpoch");
+ //const auto& loc = call->getLocationOfByte(call->getByteLength(), *Result.SourceManager, ctx.getLangOpts(), ctx.getTargetInfo());
+ user_diag ;//<< clang::FixItHint::CreateInsertion(loc, "\\n");
+ }
+}
+
+} // namespace bitcoin
diff --git a/contrib/devtools/bitcoin-tidy/chrono.h b/contrib/devtools/bitcoin-tidy/chrono.h
new file mode 100644
index 0000000000..c455d786ed
--- /dev/null
+++ b/contrib/devtools/bitcoin-tidy/chrono.h
@@ -0,0 +1,28 @@
+// Copyright (c) The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or https://opensource.org/license/mit/.
+
+#ifndef CHRONO_CHECK_H
+#define CHRONO_CHECK_H
+
+#include <clang-tidy/ClangTidyCheck.h>
+
+namespace bitcoin {
+
+class ChronoCheck final : public clang::tidy::ClangTidyCheck
+{
+public:
+ ChronoCheck(clang::StringRef Name, clang::tidy::ClangTidyContext* Context)
+ : clang::tidy::ClangTidyCheck(Name, Context) {}
+
+ bool isLanguageVersionSupported(const clang::LangOptions& LangOpts) const override
+ {
+ return LangOpts.CPlusPlus;
+ }
+ void registerMatchers(clang::ast_matchers::MatchFinder* Finder) override;
+ void check(const clang::ast_matchers::MatchFinder::MatchResult& Result) override;
+};
+
+} // namespace bitcoin
+
+#endif // CHRONO_CHECK_H
diff --git a/contrib/devtools/bitcoin-tidy/example_chrono.cpp b/contrib/devtools/bitcoin-tidy/example_chrono.cpp
new file mode 100644
index 0000000000..1bf2f0a353
--- /dev/null
+++ b/contrib/devtools/bitcoin-tidy/example_chrono.cpp
@@ -0,0 +1,18 @@
+// Copyright (c) The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or https://opensource.org/license/mit/.
+
+#include <chrono>
+
+void good_func()
+{
+std::chrono::seconds a{1};
+++a;
+a.zero();
+}
+void bad_func()
+{
+std::chrono::seconds{1}.count();
+std::chrono::seconds a{1};
+a.count();
+}
diff --git a/src/.clang-tidy b/src/.clang-tidy
index b4d50135dd..4deb5a85a5 100644
--- a/src/.clang-tidy
+++ b/src/.clang-tidy
@@ -1,6 +1,6 @@
Checks: '
-*,
-bitcoin-unterminated-logprintf,
+bitcoin-*,
bugprone-argument-comment,
bugprone-use-after-move,
misc-unused-using-decls,