[clang-tools-extra] ed9dded - [Clang-Tidy] Add google-runtime-float Clang-Tidy check (#156763)
via cfe-commits
cfe-commits at lists.llvm.org
Tue Sep 9 13:55:08 PDT 2025
Author: brenfwd
Date: 2025-09-09T13:55:04-07:00
New Revision: ed9dded83f5bc147757c31be76c7583b1a019fb3
URL: https://github.com/llvm/llvm-project/commit/ed9dded83f5bc147757c31be76c7583b1a019fb3
DIFF: https://github.com/llvm/llvm-project/commit/ed9dded83f5bc147757c31be76c7583b1a019fb3.diff
LOG: [Clang-Tidy] Add google-runtime-float Clang-Tidy check (#156763)
Add a new checker to clang-tidy for use of the `long double` type [per
Google style
guide](https://google.github.io/styleguide/cppguide.html#Floating-Point_Types).
Added:
clang-tools-extra/clang-tidy/google/FloatTypesCheck.cpp
clang-tools-extra/clang-tidy/google/FloatTypesCheck.h
clang-tools-extra/docs/clang-tidy/checks/google/runtime-float.rst
clang-tools-extra/test/clang-tidy/checkers/google/runtime-float.cpp
Modified:
clang-tools-extra/clang-tidy/google/CMakeLists.txt
clang-tools-extra/clang-tidy/google/GoogleTidyModule.cpp
clang-tools-extra/docs/ReleaseNotes.rst
clang-tools-extra/docs/clang-tidy/checks/list.rst
Removed:
################################################################################
diff --git a/clang-tools-extra/clang-tidy/google/CMakeLists.txt b/clang-tools-extra/clang-tidy/google/CMakeLists.txt
index 2470c089ef7ca..1d4229ebb7b09 100644
--- a/clang-tools-extra/clang-tidy/google/CMakeLists.txt
+++ b/clang-tools-extra/clang-tidy/google/CMakeLists.txt
@@ -11,6 +11,7 @@ add_clang_library(clangTidyGoogleModule STATIC
DefaultArgumentsCheck.cpp
ExplicitConstructorCheck.cpp
ExplicitMakePairCheck.cpp
+ FloatTypesCheck.cpp
FunctionNamingCheck.cpp
GlobalNamesInHeadersCheck.cpp
GlobalVariableDeclarationCheck.cpp
diff --git a/clang-tools-extra/clang-tidy/google/FloatTypesCheck.cpp b/clang-tools-extra/clang-tidy/google/FloatTypesCheck.cpp
new file mode 100644
index 0000000000000..3d5fb021db296
--- /dev/null
+++ b/clang-tools-extra/clang-tidy/google/FloatTypesCheck.cpp
@@ -0,0 +1,77 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "FloatTypesCheck.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "clang/Lex/Lexer.h"
+
+namespace clang {
+
+using namespace ast_matchers;
+
+namespace {
+
+AST_POLYMORPHIC_MATCHER(isValidAndNotInMacro,
+ AST_POLYMORPHIC_SUPPORTED_TYPES(TypeLoc,
+ FloatingLiteral)) {
+ const SourceLocation Loc = Node.getBeginLoc();
+ return Loc.isValid() && !Loc.isMacroID();
+}
+
+AST_MATCHER(TypeLoc, isLongDoubleType) {
+ TypeLoc TL = Node;
+ if (const auto QualLoc = Node.getAs<QualifiedTypeLoc>())
+ TL = QualLoc.getUnqualifiedLoc();
+
+ const auto BuiltinLoc = TL.getAs<BuiltinTypeLoc>();
+ if (!BuiltinLoc)
+ return false;
+
+ if (const auto *BT = BuiltinLoc.getTypePtr())
+ return BT->getKind() == BuiltinType::LongDouble;
+ return false;
+}
+
+AST_MATCHER(FloatingLiteral, isLongDoubleLiteral) {
+ if (const auto *BT =
+ dyn_cast_if_present<BuiltinType>(Node.getType().getTypePtr()))
+ return BT->getKind() == BuiltinType::LongDouble;
+ return false;
+}
+
+} // namespace
+
+namespace tidy::google::runtime {
+
+void RuntimeFloatCheck::registerMatchers(MatchFinder *Finder) {
+ Finder->addMatcher(typeLoc(loc(realFloatingPointType()),
+ isValidAndNotInMacro(), isLongDoubleType())
+ .bind("longDoubleTypeLoc"),
+ this);
+ Finder->addMatcher(floatLiteral(isValidAndNotInMacro(), isLongDoubleLiteral())
+ .bind("longDoubleFloatLiteral"),
+ this);
+}
+
+void RuntimeFloatCheck::check(const MatchFinder::MatchResult &Result) {
+ if (const auto *TL = Result.Nodes.getNodeAs<TypeLoc>("longDoubleTypeLoc")) {
+ diag(TL->getBeginLoc(), "%0 type is not portable and should not be used")
+ << TL->getType();
+ }
+
+ if (const auto *FL =
+ Result.Nodes.getNodeAs<FloatingLiteral>("longDoubleFloatLiteral")) {
+ diag(FL->getBeginLoc(), "%0 type from literal suffix 'L' is not portable "
+ "and should not be used")
+ << FL->getType();
+ }
+}
+
+} // namespace tidy::google::runtime
+
+} // namespace clang
diff --git a/clang-tools-extra/clang-tidy/google/FloatTypesCheck.h b/clang-tools-extra/clang-tidy/google/FloatTypesCheck.h
new file mode 100644
index 0000000000000..b5534c046e68f
--- /dev/null
+++ b/clang-tools-extra/clang-tidy/google/FloatTypesCheck.h
@@ -0,0 +1,34 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_GOOGLE_FLOATTYPESCHECK_H
+#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_GOOGLE_FLOATTYPESCHECK_H
+
+#include "../ClangTidyCheck.h"
+
+namespace clang::tidy::google::runtime {
+
+/// Finds usages of `long double` and suggests against their use due to lack
+/// of portability.
+///
+/// For the user-facing documentation see:
+/// http://clang.llvm.org/extra/clang-tidy/checks/google/runtime-float.html
+class RuntimeFloatCheck : public ClangTidyCheck {
+public:
+ RuntimeFloatCheck(StringRef Name, ClangTidyContext *Context)
+ : ClangTidyCheck(Name, Context) {}
+ void registerMatchers(ast_matchers::MatchFinder *Finder) override;
+ void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
+ bool isLanguageVersionSupported(const LangOptions &LangOpts) const override {
+ return LangOpts.CPlusPlus && !LangOpts.ObjC;
+ }
+};
+
+} // namespace clang::tidy::google::runtime
+
+#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_GOOGLE_FLOATTYPESCHECK_H
diff --git a/clang-tools-extra/clang-tidy/google/GoogleTidyModule.cpp b/clang-tools-extra/clang-tidy/google/GoogleTidyModule.cpp
index 5343e2b3a5975..eb5666be62bcf 100644
--- a/clang-tools-extra/clang-tidy/google/GoogleTidyModule.cpp
+++ b/clang-tools-extra/clang-tidy/google/GoogleTidyModule.cpp
@@ -19,6 +19,7 @@
#include "DefaultArgumentsCheck.h"
#include "ExplicitConstructorCheck.h"
#include "ExplicitMakePairCheck.h"
+#include "FloatTypesCheck.h"
#include "FunctionNamingCheck.h"
#include "GlobalNamesInHeadersCheck.h"
#include "GlobalVariableDeclarationCheck.h"
@@ -57,6 +58,8 @@ class GoogleModule : public ClangTidyModule {
"google-objc-function-naming");
CheckFactories.registerCheck<objc::GlobalVariableDeclarationCheck>(
"google-objc-global-variable-declaration");
+ CheckFactories.registerCheck<runtime::RuntimeFloatCheck>(
+ "google-runtime-float");
CheckFactories.registerCheck<runtime::IntegerTypesCheck>(
"google-runtime-int");
CheckFactories.registerCheck<runtime::OverloadedUnaryAndCheck>(
diff --git a/clang-tools-extra/docs/ReleaseNotes.rst b/clang-tools-extra/docs/ReleaseNotes.rst
index 28620a92e4205..23d757b5e6f2e 100644
--- a/clang-tools-extra/docs/ReleaseNotes.rst
+++ b/clang-tools-extra/docs/ReleaseNotes.rst
@@ -155,6 +155,12 @@ New checks
Finds calls to ``operator[]`` in STL containers and suggests replacing them
with safe alternatives.
+- New :doc:`google-runtime-float
+ <clang-tidy/checks/google/runtime-float>` check.
+
+ Finds uses of ``long double`` and suggests against their use due to lack of
+ portability.
+
- New :doc:`llvm-mlir-op-builder
<clang-tidy/checks/llvm/use-new-mlir-op-builder>` check.
diff --git a/clang-tools-extra/docs/clang-tidy/checks/google/runtime-float.rst b/clang-tools-extra/docs/clang-tidy/checks/google/runtime-float.rst
new file mode 100644
index 0000000000000..4b853ad56021d
--- /dev/null
+++ b/clang-tools-extra/docs/clang-tidy/checks/google/runtime-float.rst
@@ -0,0 +1,10 @@
+.. title:: clang-tidy - google-runtime-float
+
+google-runtime-float
+====================
+
+Finds uses of ``long double`` and suggests against their use due to lack of
+portability.
+
+The corresponding style guide rule:
+https://google.github.io/styleguide/cppguide.html#Floating-Point_Types
diff --git a/clang-tools-extra/docs/clang-tidy/checks/list.rst b/clang-tools-extra/docs/clang-tidy/checks/list.rst
index 89ad491935f7f..c490d2ece2e0a 100644
--- a/clang-tools-extra/docs/clang-tidy/checks/list.rst
+++ b/clang-tools-extra/docs/clang-tidy/checks/list.rst
@@ -238,6 +238,7 @@ Clang-Tidy Checks
:doc:`google-readability-avoid-underscore-in-googletest-name <google/readability-avoid-underscore-in-googletest-name>`,
:doc:`google-readability-casting <google/readability-casting>`,
:doc:`google-readability-todo <google/readability-todo>`,
+ :doc:`google-runtime-float <google/runtime-float>`,
:doc:`google-runtime-int <google/runtime-int>`,
:doc:`google-runtime-operator <google/runtime-operator>`,
:doc:`google-upgrade-googletest-case <google/upgrade-googletest-case>`, "Yes"
diff --git a/clang-tools-extra/test/clang-tidy/checkers/google/runtime-float.cpp b/clang-tools-extra/test/clang-tidy/checkers/google/runtime-float.cpp
new file mode 100644
index 0000000000000..5c9cc11dbef2a
--- /dev/null
+++ b/clang-tools-extra/test/clang-tidy/checkers/google/runtime-float.cpp
@@ -0,0 +1,40 @@
+// RUN: %check_clang_tidy %s google-runtime-float %t
+
+long double foo;
+// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: 'long double' type is not portable and should not be used [google-runtime-float]
+
+typedef long double MyLongDouble;
+// CHECK-MESSAGES: :[[@LINE-1]]:9: warning: 'long double' type is not portable and should not be used [google-runtime-float]
+
+typedef long double MyOtherLongDouble; // NOLINT
+
+template <typename T>
+void tmpl() { T i; }
+
+long volatile double v = 10;
+// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: 'volatile long double' type is not portable and should not be used [google-runtime-float]
+
+long double h(long const double aaa, long double bbb = 0.5L) {
+ // CHECK-MESSAGES: :[[@LINE-1]]:1: warning: 'long double' type is not portable and should not be used [google-runtime-float]
+ // CHECK-MESSAGES: :[[@LINE-2]]:15: warning: 'const long double' type is not portable and should not be used [google-runtime-float]
+ // CHECK-MESSAGES: :[[@LINE-3]]:38: warning: 'long double' type is not portable and should not be used [google-runtime-float]
+ // CHECK-MESSAGES: :[[@LINE-4]]:56: warning: 'long double' type from literal suffix 'L' is not portable and should not be used [google-runtime-float]
+ double x = 0.1;
+ double y = 0.2L;
+ // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: 'long double' type from literal suffix 'L' is not portable and should not be used [google-runtime-float]
+#define ldtype long double
+ ldtype z;
+ tmpl<long double>();
+ // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: 'long double' type is not portable and should not be used [google-runtime-float]
+ return 0;
+}
+
+struct S{};
+constexpr S operator"" _baz(unsigned long long) {
+ long double j;
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: 'long double' type is not portable and should not be used [google-runtime-float]
+ MyOtherLongDouble x;
+ long int a = 1L;
+ return S{};
+}
+
More information about the cfe-commits
mailing list