[clang] [clang-tools-extra] [clang-tidy] Add portability-avoid-platform-specific-fundamental-types (PR #146970)
@@ -0,0 +1,260 @@
+//===--- AvoidPlatformSpecificFundamentalTypesCheck.cpp - clang-tidy
--===//
+//
+// 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 "AvoidPlatformSpecificFundamentalTypesCheck.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "clang/ASTMatchers/ASTMatchers.h"
+#include "clang/Basic/TargetInfo.h"
+
+using namespace clang::ast_matchers;
+
+namespace clang::tidy::portability {
+
+AvoidPlatformSpecificFundamentalTypesCheck::
+AvoidPlatformSpecificFundamentalTypesCheck(StringRef Name,
+ ClangTidyContext *Context)
+: ClangTidyCheck(Name, Context),
+ WarnOnFloats(Options.get("WarnOnFloats", true)),
+ WarnOnInts(Options.get("WarnOnInts", true)),
+ WarnOnChars(Options.get("WarnOnChars", true)),
+ IncludeInserter(Options.getLocalOrGlobal("IncludeStyle",
+ utils::IncludeSorter::IS_LLVM),
+ areDiagsSelfContained()) {}
+
+void AvoidPlatformSpecificFundamentalTypesCheck::registerPPCallbacks(
+const SourceManager &SM, Preprocessor *PP, Preprocessor *ModuleExpanderPP)
{
+ IncludeInserter.registerPreprocessor(PP);
+}
+
+void AvoidPlatformSpecificFundamentalTypesCheck::storeOptions(
+ClangTidyOptions::OptionMap &Opts) {
+ Options.store(Opts, "WarnOnFloats", WarnOnFloats);
+ Options.store(Opts, "WarnOnInts", WarnOnInts);
+ Options.store(Opts, "WarnOnChars", WarnOnChars);
+ Options.store(Opts, "IncludeStyle", IncludeInserter.getStyle());
+}
+
+std::string AvoidPlatformSpecificFundamentalTypesCheck::getFloatReplacement(
+const BuiltinType *BT, ASTContext &Context) const {
+ const TargetInfo &Target = Context.getTargetInfo();
+
+ auto GetReplacementType = [](unsigned Width) {
+switch (Width) {
+// This is ambiguous by default since it could be bfloat16 or float16
+case 16U:
+ return "";
+case 32U:
+ return "float32_t";
+case 64U:
+ return "float64_t";
+case 128U:
+ return "float128_t";
+default:
+ return "";
+}
+ };
+
+ switch (BT->getKind()) {
+ // Not an ambiguous type
+ case BuiltinType::BFloat16:
+return "bfloat16_t";
+ case BuiltinType::Half:
+return GetReplacementType(Target.getHalfWidth());
+ case BuiltinType::Float:
+return GetReplacementType(Target.getFloatWidth());
+ case BuiltinType::Double:
+return GetReplacementType(Target.getDoubleWidth());
+ default:
+return "";
+ }
+}
+
+void AvoidPlatformSpecificFundamentalTypesCheck::registerMatchers(
+MatchFinder *Finder) {
+ // Build the list of type strings to match
+ std::vector TypeStrings;
+
+ // Add integer types if the option is enabled
+ if (WarnOnInts) {
+TypeStrings.insert(TypeStrings.end(), {"short",
jj-marr wrote:
Resolving conversation since I believe I addressed this comment.
https://github.com/llvm/llvm-project/pull/146970
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang-tools-extra] [clang-tidy] Add portability-avoid-platform-specific-fundamental-types (PR #146970)
jj-marr wrote: Sorry for taking a while. I got caught up in my day job and took a vacation to decompress. https://github.com/llvm/llvm-project/pull/146970 ___ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang-tools-extra] [clang-tidy] Add portability-avoid-platform-specific-fundamental-types (PR #146970)
@@ -0,0 +1,183 @@
+//===--===//
+//
+// 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 "AvoidPlatformSpecificFundamentalTypesCheck.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/Type.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "clang/ASTMatchers/ASTMatchers.h"
+#include "clang/Basic/TargetInfo.h"
+
+using namespace clang::ast_matchers;
+
+namespace {
+
+AST_MATCHER(clang::QualType, isBuiltinInt) {
+ const auto *BT = Node->getAs();
+ if (!BT)
+return false;
+
+ // BT->isInteger() would detect char and bool
+ switch (BT->getKind()) {
+ case clang::BuiltinType::Short:
+ case clang::BuiltinType::UShort:
+ case clang::BuiltinType::Int:
+ case clang::BuiltinType::UInt:
+ case clang::BuiltinType::Long:
+ case clang::BuiltinType::ULong:
+ case clang::BuiltinType::LongLong:
+ case clang::BuiltinType::ULongLong:
+return true;
+ default:
+return false;
+ }
+}
+
+AST_MATCHER(clang::QualType, isBuiltinFloat) {
+ const auto *BT = Node->getAs();
+ if (!BT)
+return false;
+
+ return BT->isFloatingPoint();
+}
+
+} // namespace
+
+namespace clang::tidy::portability {
+
+AvoidPlatformSpecificFundamentalTypesCheck::
+AvoidPlatformSpecificFundamentalTypesCheck(StringRef Name,
+ ClangTidyContext *Context)
+: ClangTidyCheck(Name, Context),
+ WarnOnFloats(Options.get("WarnOnFloats", true)),
+ WarnOnInts(Options.get("WarnOnInts", true)),
+ WarnOnChars(Options.get("WarnOnChars", true)),
+ IncludeInserter(Options.getLocalOrGlobal("IncludeStyle",
+ utils::IncludeSorter::IS_LLVM),
+ areDiagsSelfContained()) {
+ if (!WarnOnFloats && !WarnOnInts && !WarnOnChars)
+this->configurationDiag(
+"The check 'portability-avoid-platform-specific-fundamental-types' "
+"will not perform any analysis because 'WarnOnFloats', 'WarnOnInts' "
+"and 'WarnOnChars' are all false.");
+}
+
+void AvoidPlatformSpecificFundamentalTypesCheck::registerPPCallbacks(
+const SourceManager &SM, Preprocessor *PP, Preprocessor *ModuleExpanderPP)
{
+ IncludeInserter.registerPreprocessor(PP);
+}
+
+void AvoidPlatformSpecificFundamentalTypesCheck::storeOptions(
+ClangTidyOptions::OptionMap &Opts) {
+ Options.store(Opts, "WarnOnFloats", WarnOnFloats);
+ Options.store(Opts, "WarnOnInts", WarnOnInts);
+ Options.store(Opts, "WarnOnChars", WarnOnChars);
+ Options.store(Opts, "IncludeStyle", IncludeInserter.getStyle());
+}
+
+static std::string getFloatReplacement(const BuiltinType *BT,
+ ASTContext &Context) {
+ const TargetInfo &Target = Context.getTargetInfo();
+
+ auto GetReplacementType = [](unsigned Width) {
+switch (Width) {
+// This is ambiguous by default since it could be bfloat16 or float16
+case 16U:
+ return "";
+case 32U:
+ return "float32_t";
+case 64U:
+ return "float64_t";
+case 128U:
+ return "float128_t";
+default:
+ return "";
+}
+ };
+
+ switch (BT->getKind()) {
+ // Not an ambiguous type
+ case BuiltinType::BFloat16:
+return "bfloat16_t";
+ case BuiltinType::Half:
+return GetReplacementType(Target.getHalfWidth());
+ case BuiltinType::Float:
+return GetReplacementType(Target.getFloatWidth());
+ case BuiltinType::Double:
+return GetReplacementType(Target.getDoubleWidth());
+ default:
+return "";
+ }
+}
+
+void AvoidPlatformSpecificFundamentalTypesCheck::registerMatchers(
+MatchFinder *Finder) {
+ auto PlatformSpecificFundamentalType = qualType(allOf(
+ builtinType(), anyOf(WarnOnInts ? isBuiltinInt() : unless(anything()),
+ WarnOnFloats ? isBuiltinFloat() :
unless(anything()),
+ WarnOnChars ? isChar() : unless(anything()),
+ WarnOnChars ? isWideChar() : unless(anything();
+
+ if (!WarnOnInts && !WarnOnFloats && !WarnOnChars)
+return;
+
+
Finder->addMatcher(typeLoc(loc(PlatformSpecificFundamentalType)).bind("type"),
+ this);
+}
+
+void AvoidPlatformSpecificFundamentalTypesCheck::check(
+const MatchFinder::MatchResult &Result) {
+ const auto *TL = Result.Nodes.getNodeAs("type");
+ if (!TL)
+return;
+
+ SourceLocation Loc = TL->getBeginLoc();
+ QualType QT = TL->getType();
+ SourceRange TypeRange = TL->getSourceRange();
+
+ // Skip implicit type locations, such as literals
+ if (!Loc.isValid() || !TypeRange.isValid())
+return;
+
+ const std::string TypeName = QT.getUnqualifiedType().getAsString();
+
+ const auto *BT = QT->getAs(
[clang] [clang-tools-extra] [clang-tidy] Add portability-avoid-platform-specific-fundamental-types (PR #146970)
@@ -0,0 +1,183 @@
+//===--===//
+//
+// 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 "AvoidPlatformSpecificFundamentalTypesCheck.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/Type.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "clang/ASTMatchers/ASTMatchers.h"
+#include "clang/Basic/TargetInfo.h"
+
+using namespace clang::ast_matchers;
+
+namespace {
+
+AST_MATCHER(clang::QualType, isBuiltinInt) {
+ const auto *BT = Node->getAs();
+ if (!BT)
+return false;
+
+ // BT->isInteger() would detect char and bool
+ switch (BT->getKind()) {
+ case clang::BuiltinType::Short:
+ case clang::BuiltinType::UShort:
+ case clang::BuiltinType::Int:
+ case clang::BuiltinType::UInt:
+ case clang::BuiltinType::Long:
+ case clang::BuiltinType::ULong:
+ case clang::BuiltinType::LongLong:
+ case clang::BuiltinType::ULongLong:
+return true;
+ default:
+return false;
+ }
+}
+
+AST_MATCHER(clang::QualType, isBuiltinFloat) {
+ const auto *BT = Node->getAs();
+ if (!BT)
+return false;
+
+ return BT->isFloatingPoint();
+}
+
+} // namespace
+
+namespace clang::tidy::portability {
+
+AvoidPlatformSpecificFundamentalTypesCheck::
+AvoidPlatformSpecificFundamentalTypesCheck(StringRef Name,
+ ClangTidyContext *Context)
+: ClangTidyCheck(Name, Context),
+ WarnOnFloats(Options.get("WarnOnFloats", true)),
+ WarnOnInts(Options.get("WarnOnInts", true)),
+ WarnOnChars(Options.get("WarnOnChars", true)),
+ IncludeInserter(Options.getLocalOrGlobal("IncludeStyle",
+ utils::IncludeSorter::IS_LLVM),
+ areDiagsSelfContained()) {
+ if (!WarnOnFloats && !WarnOnInts && !WarnOnChars)
+this->configurationDiag(
+"The check 'portability-avoid-platform-specific-fundamental-types' "
+"will not perform any analysis because 'WarnOnFloats', 'WarnOnInts' "
+"and 'WarnOnChars' are all false.");
+}
+
+void AvoidPlatformSpecificFundamentalTypesCheck::registerPPCallbacks(
+const SourceManager &SM, Preprocessor *PP, Preprocessor *ModuleExpanderPP)
{
+ IncludeInserter.registerPreprocessor(PP);
+}
+
+void AvoidPlatformSpecificFundamentalTypesCheck::storeOptions(
+ClangTidyOptions::OptionMap &Opts) {
+ Options.store(Opts, "WarnOnFloats", WarnOnFloats);
+ Options.store(Opts, "WarnOnInts", WarnOnInts);
+ Options.store(Opts, "WarnOnChars", WarnOnChars);
+ Options.store(Opts, "IncludeStyle", IncludeInserter.getStyle());
+}
+
+static std::string getFloatReplacement(const BuiltinType *BT,
+ ASTContext &Context) {
+ const TargetInfo &Target = Context.getTargetInfo();
+
+ auto GetReplacementType = [](unsigned Width) {
+switch (Width) {
+// This is ambiguous by default since it could be bfloat16 or float16
+case 16U:
+ return "";
+case 32U:
+ return "float32_t";
+case 64U:
+ return "float64_t";
+case 128U:
+ return "float128_t";
+default:
+ return "";
+}
+ };
+
+ switch (BT->getKind()) {
+ // Not an ambiguous type
+ case BuiltinType::BFloat16:
+return "bfloat16_t";
+ case BuiltinType::Half:
+return GetReplacementType(Target.getHalfWidth());
+ case BuiltinType::Float:
+return GetReplacementType(Target.getFloatWidth());
+ case BuiltinType::Double:
+return GetReplacementType(Target.getDoubleWidth());
+ default:
+return "";
+ }
+}
+
+void AvoidPlatformSpecificFundamentalTypesCheck::registerMatchers(
+MatchFinder *Finder) {
+ auto PlatformSpecificFundamentalType = qualType(allOf(
+ builtinType(), anyOf(WarnOnInts ? isBuiltinInt() : unless(anything()),
+ WarnOnFloats ? isBuiltinFloat() :
unless(anything()),
+ WarnOnChars ? isChar() : unless(anything()),
+ WarnOnChars ? isWideChar() : unless(anything();
+
+ if (!WarnOnInts && !WarnOnFloats && !WarnOnChars)
+return;
+
+
Finder->addMatcher(typeLoc(loc(PlatformSpecificFundamentalType)).bind("type"),
+ this);
+}
+
+void AvoidPlatformSpecificFundamentalTypesCheck::check(
+const MatchFinder::MatchResult &Result) {
+ const auto *TL = Result.Nodes.getNodeAs("type");
+ if (!TL)
+return;
vbvictor wrote:
```suggestion
assert(TL);
```
We expect matchers to work,
https://llvm.org/docs/CodingStandards.html#assert-liberally
https://github.com/llvm/llvm-project/pull/146970
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/li
[clang] [clang-tools-extra] [clang-tidy] Add portability-avoid-platform-specific-fundamental-types (PR #146970)
@@ -0,0 +1,147 @@ +.. title:: clang-tidy - portability-avoid-platform-specific-fundamental-types + +portability-avoid-platform-specific-fundamental-types += + +Detects fundamental types (``int``, ``short``, ``long``, ``long long``, ``char`` +, ``float``, etc) and warns against their use due to platform-dependent +behavior. + +This check detects fundamental types (``int``, ``short``, ``long``, ``float``, +``char`` and their ``unsigned`` or ``signed`` variants) and warns against their +use due to non-standard platform-dependent behavior. For example, ``long`` is +64 bits on Linux but 32 bits on Windows. There is no standard rationale or +intent for the sizes of these types. + +Instead of fundamental types, use fixed-width types such as ``int32_t`` or +implementation-defined types with standard semantics, e.g. ``int_fast32_t`` for +the fastest integer type greater than or equal to 32 bits. + +Examples + + +.. code-block:: c++ + + // Bad: platform-dependent fundamental types + int global_int = 42; + short global_short = 10; + // unsigned long is 32 bits on Windows and 64 bits on Mac/Linux, so this will + // overflow depending on platform. + unsigned long global_unsigned_long = 1 << 36; + // On many systems, loading into a register must be done at the processor's + // word size. On a 64-bit system with 32-bit integers, loading an element from + // slowVec could take multiple instructions. The first will load two elements, + // and additional instructions will delete the unneeded element. jj-marr wrote: not sure if true on x86_64, but on embedded systems this can cause problems. https://github.com/llvm/llvm-project/pull/146970 ___ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang-tools-extra] [clang-tidy] Add portability-avoid-platform-specific-fundamental-types (PR #146970)
https://github.com/jj-marr edited https://github.com/llvm/llvm-project/pull/146970 ___ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang-tools-extra] [clang-tidy] Add portability-avoid-platform-specific-fundamental-types (PR #146970)
@@ -0,0 +1,241 @@
+.. title:: clang-tidy - portability-avoid-platform-specific-fundamental-types
+
+portability-avoid-platform-specific-fundamental-types
+=
+
+Detects fundamental types (``int``, ``short``, ``long``, ``long long``,
``char``
+, ``float``, etc) and warns against their use due to platform-dependent
+behavior.
+
+This check detects fundamental types (``int``, ``short``, ``long``, ``float``,
+``char`` and their ``unsigned`` or ``signed`` variants) and warns against their
+use due to non-standard platform-dependent behavior. For example, ``long`` is
+64 bits on Linux but 32 bits on Windows. There is no standard rationale or
+intent for the sizes of these types.
+
+Instead of fundamental types, use fixed-width types such as ``int32_t`` or
+implementation-defined types with standard semantics, e.g. ``int_fast32_t`` for
+the fastest integer type greater than or equal to 32 bits.
+
+Examples
+
+
+.. code-block:: c++
+
+ // Bad: platform-dependent fundamental types
+ int global_int = 42;
+ short global_short = 10;
+ long global_long = 100L;
+ unsigned long global_unsigned_long = 100UL;
+
+ void function_with_int_param(int param) {
+// ...
+ }
+
+ int function_returning_int() {
+return 42;
+ }
+
+ struct MyStruct {
+int member_int;
+long member_long;
+ };
+
+.. code-block:: c++
+
+ // Good: use fixed-width types or typedefs
+ #include
+
+ int32_t global_int32 = 42;
+ int16_t global_int16 = 10;
+ int64_t global_int64 = 100L;
+ uint64_t global_uint64 = 100UL;
+
+ void function_with_int32_param(int32_t param) {
+// ...
+ }
+
+ int32_t function_returning_int32() {
+return 42;
+ }
+
+ struct MyStruct {
+int32_t member_int32;
+int64_t member_int64;
+ };
+
+The check will also warn about typedef declarations that use fundamental types
+as their underlying type:
+
+.. code-block:: c++
+
+ // Bad: typedef using fundamental type
+ typedef long long MyLongType;
+ using MyIntType = int;
+
+.. code-block:: c++
+
+ // Good: use descriptive names or fixed-width types
+ typedef int64_t TimestampType;
+ using CounterType = uint32_t;
+
+Rationale
+-
+
+Fundamental types have platform-dependent sizes and behavior:
+
+- ``int`` is typically 32 bits on modern platforms but is only guaranteed to be
+ 16 bits by the spec
+- ``long int`` is 32 bits on Windows but 64 bits on most Unix systems
+- ``double`` is typically 64-bit IEEE754, but on some microcontrollers without
+ a 64-bit FPU (e.g. certain Arduinos) it can be 32 bits
+- ``char`` is signed on ARM and unsigned on x86
+
+For historical reasons, the C++ standard allows the implementation to define
+the size and representation of these types. They communicate intent in
+non-standard ways and are often needlessly incompatible.
+
+For example, ``int`` was traditionally the word size of a given processor in
+16-bit and 32-bit computing and was a reasonable default for performance. This
+is no longer true on modern 64-bit computers, but the size of ``int`` remains
+fixed at 32 bits for backwards compatibility with code that relied on a 32-bit
+implementation of ``int``.
+
+If code is explicitly relying on the size of an ``int`` being 32 bits, it is
+better to say so in the typename with ``int32_t``. Otherwise, use an
+appropriate implementation-defined type such as ``fast_int32_t`` or
+``least_int32_t`` that communicates the appropriate time/space tradeoff.
+
+Likewise, ``float`` and ``double`` should be replaced by ``float32_t`` and
+``float64_t`` which are guaranteed to be standard IEEE754 floats for a given
+size.
+
+``char`` should be replaced by ``char8_t`` when used in the representation of
+Unicode text. When used to represent a byte on a given platform, ``std::byte``
+is an appropriate replacement.
+
+Types Not Flagged
+-
+
+The following types are intentionally not flagged:
+
+- ``bool`` (boolean type)
+- Standard library typedefs like ``size_t``, ``ptrdiff_t``, or ``uint32_t``.
+- Already typedef'd types, though the check will flag the typedef itself
+
+``bool`` is excluded because it can only be true or false, and is not
+vulnerable to overflow or narrowing issues that occur as a result of using
+types of an implementation-defined size.
+
+Options
+---
+
+.. option:: WarnOnInts
+
+ When `true`, the check will warn about fundamental integer types
+ (``short``, ``int``, ``long``, ``long long`` and their ``signed`` and
+ ``unsigned`` variants).
+ When `false`, integer types are not flagged. Default is `true`
+
+ Example with :option:`WarnOnInts` enabled:
jj-marr wrote:
@vbvictor The intent is to give examples of when you may choose different
alternatives. For `float` and `char` it is obvious, honestly
(`float`->`float32_t` on most platforms, `char`->`char8_t` unless doing
bit-level stuff). For replacing `int` it is less obvious. In my own experience,
I replace `int`
[clang] [clang-tools-extra] [clang-tidy] Add portability-avoid-platform-specific-fundamental-types (PR #146970)
@@ -0,0 +1,47 @@ +//==-- AvoidPlatformSpecificFundamentalTypesCheck.h - clang-tidy -*- C++ -*-==// EugeneZelenko wrote: ```suggestion //===--===// ``` https://github.com/llvm/llvm-project/pull/146970 ___ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang-tools-extra] [clang-tidy] Add portability-avoid-platform-specific-fundamental-types (PR #146970)
@@ -0,0 +1,183 @@ +//===--- AvoidPlatformSpecificFundamentalTypesCheck.cpp - clang-tidy --===// EugeneZelenko wrote: ```suggestion //===--===// ``` Emacs tags a no longer needed. See #153942. https://github.com/llvm/llvm-project/pull/146970 ___ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang-tools-extra] [clang-tidy] Add portability-avoid-platform-specific-fundamental-types (PR #146970)
@@ -0,0 +1,241 @@
+.. title:: clang-tidy - portability-avoid-platform-specific-fundamental-types
+
+portability-avoid-platform-specific-fundamental-types
+=
+
+Detects fundamental types (``int``, ``short``, ``long``, ``long long``,
``char``
+, ``float``, etc) and warns against their use due to platform-dependent
+behavior.
+
+This check detects fundamental types (``int``, ``short``, ``long``, ``float``,
+``char`` and their ``unsigned`` or ``signed`` variants) and warns against their
+use due to non-standard platform-dependent behavior. For example, ``long`` is
+64 bits on Linux but 32 bits on Windows. There is no standard rationale or
+intent for the sizes of these types.
+
+Instead of fundamental types, use fixed-width types such as ``int32_t`` or
+implementation-defined types with standard semantics, e.g. ``int_fast32_t`` for
+the fastest integer type greater than or equal to 32 bits.
+
+Examples
+
+
+.. code-block:: c++
+
+ // Bad: platform-dependent fundamental types
+ int global_int = 42;
+ short global_short = 10;
+ long global_long = 100L;
+ unsigned long global_unsigned_long = 100UL;
+
+ void function_with_int_param(int param) {
+// ...
+ }
+
+ int function_returning_int() {
+return 42;
+ }
+
+ struct MyStruct {
+int member_int;
+long member_long;
+ };
+
+.. code-block:: c++
+
+ // Good: use fixed-width types or typedefs
+ #include
+
+ int32_t global_int32 = 42;
+ int16_t global_int16 = 10;
+ int64_t global_int64 = 100L;
+ uint64_t global_uint64 = 100UL;
+
+ void function_with_int32_param(int32_t param) {
+// ...
+ }
+
+ int32_t function_returning_int32() {
+return 42;
+ }
+
+ struct MyStruct {
+int32_t member_int32;
+int64_t member_int64;
+ };
vbvictor wrote:
Same as other part
```suggestion
```
https://github.com/llvm/llvm-project/pull/146970
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang-tools-extra] [clang-tidy] Add portability-avoid-platform-specific-fundamental-types (PR #146970)
@@ -0,0 +1,183 @@
+//===--- AvoidPlatformSpecificFundamentalTypesCheck.cpp - clang-tidy
--===//
+//
+// 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 "AvoidPlatformSpecificFundamentalTypesCheck.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/Type.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "clang/ASTMatchers/ASTMatchers.h"
+#include "clang/Basic/TargetInfo.h"
+
+using namespace clang::ast_matchers;
+
+namespace {
+
+AST_MATCHER(clang::QualType, isBuiltinInt) {
+ const auto *BT = Node->getAs();
+ if (!BT)
+return false;
+
+ // BT->isInteger() would detect char and bool
+ switch (BT->getKind()) {
+ case clang::BuiltinType::Short:
+ case clang::BuiltinType::UShort:
+ case clang::BuiltinType::Int:
+ case clang::BuiltinType::UInt:
+ case clang::BuiltinType::Long:
+ case clang::BuiltinType::ULong:
+ case clang::BuiltinType::LongLong:
+ case clang::BuiltinType::ULongLong:
+return true;
+ default:
+return false;
+ }
+}
+
+AST_MATCHER(clang::QualType, isBuiltinFloat) {
+ const auto *BT = Node->getAs();
+ if (!BT)
+return false;
+
+ return BT->isFloatingPoint();
+}
+
+} // namespace
+
+namespace clang::tidy::portability {
+
+AvoidPlatformSpecificFundamentalTypesCheck::
+AvoidPlatformSpecificFundamentalTypesCheck(StringRef Name,
+ ClangTidyContext *Context)
+: ClangTidyCheck(Name, Context),
+ WarnOnFloats(Options.get("WarnOnFloats", true)),
+ WarnOnInts(Options.get("WarnOnInts", true)),
+ WarnOnChars(Options.get("WarnOnChars", true)),
+ IncludeInserter(Options.getLocalOrGlobal("IncludeStyle",
+ utils::IncludeSorter::IS_LLVM),
+ areDiagsSelfContained()) {
+ if (!WarnOnFloats && !WarnOnInts && !WarnOnChars)
+this->configurationDiag(
+"The check 'portability-avoid-platform-specific-fundamental-types' "
+"will not perform any analysis because 'WarnOnFloats', 'WarnOnInts' "
+"and 'WarnOnChars' are all false.");
+}
+
+void AvoidPlatformSpecificFundamentalTypesCheck::registerPPCallbacks(
+const SourceManager &SM, Preprocessor *PP, Preprocessor *ModuleExpanderPP)
{
+ IncludeInserter.registerPreprocessor(PP);
+}
+
+void AvoidPlatformSpecificFundamentalTypesCheck::storeOptions(
+ClangTidyOptions::OptionMap &Opts) {
+ Options.store(Opts, "WarnOnFloats", WarnOnFloats);
+ Options.store(Opts, "WarnOnInts", WarnOnInts);
+ Options.store(Opts, "WarnOnChars", WarnOnChars);
+ Options.store(Opts, "IncludeStyle", IncludeInserter.getStyle());
+}
+
+static std::string getFloatReplacement(const BuiltinType *BT,
+ ASTContext &Context) {
+ const TargetInfo &Target = Context.getTargetInfo();
+
+ auto GetReplacementType = [](unsigned Width) {
+switch (Width) {
+// This is ambiguous by default since it could be bfloat16 or float16
+case 16U:
+ return "";
+case 32U:
+ return "float32_t";
+case 64U:
+ return "float64_t";
+case 128U:
+ return "float128_t";
+default:
+ return "";
+}
+ };
+
+ switch (BT->getKind()) {
+ // Not an ambiguous type
+ case BuiltinType::BFloat16:
+return "bfloat16_t";
+ case BuiltinType::Half:
+return GetReplacementType(Target.getHalfWidth());
+ case BuiltinType::Float:
+return GetReplacementType(Target.getFloatWidth());
+ case BuiltinType::Double:
+return GetReplacementType(Target.getDoubleWidth());
+ default:
+return "";
+ }
+}
+
+void AvoidPlatformSpecificFundamentalTypesCheck::registerMatchers(
+MatchFinder *Finder) {
+ auto PlatformSpecificFundamentalType = qualType(allOf(
+ builtinType(), anyOf(WarnOnInts ? isBuiltinInt() : unless(anything()),
+ WarnOnFloats ? isBuiltinFloat() :
unless(anything()),
+ WarnOnChars ? isChar() : unless(anything()),
+ WarnOnChars ? isWideChar() : unless(anything();
+
+ if (!WarnOnInts && !WarnOnFloats && !WarnOnChars)
+return;
+
+
Finder->addMatcher(typeLoc(loc(PlatformSpecificFundamentalType)).bind("type"),
+ this);
+}
+
+void AvoidPlatformSpecificFundamentalTypesCheck::check(
+const MatchFinder::MatchResult &Result) {
+ const auto *TL = Result.Nodes.getNodeAs("type");
+ if (!TL)
+return;
+
+ SourceLocation Loc = TL->getBeginLoc();
+ QualType QT = TL->getType();
+ SourceRange TypeRange = TL->getSourceRange();
+
+ // Skip implicit type locations, such as literals
+ if (!Loc.isValid() || !TypeRange.isValid())
+return;
+
+ const std::string TypeName = QT.getUnqualifiedType().getAsString();
+
+ const auto *BT = QT->getAs
[clang] [clang-tools-extra] [clang-tidy] Add portability-avoid-platform-specific-fundamental-types (PR #146970)
@@ -0,0 +1,241 @@
+.. title:: clang-tidy - portability-avoid-platform-specific-fundamental-types
+
+portability-avoid-platform-specific-fundamental-types
+=
+
+Detects fundamental types (``int``, ``short``, ``long``, ``long long``,
``char``
+, ``float``, etc) and warns against their use due to platform-dependent
+behavior.
+
+This check detects fundamental types (``int``, ``short``, ``long``, ``float``,
+``char`` and their ``unsigned`` or ``signed`` variants) and warns against their
+use due to non-standard platform-dependent behavior. For example, ``long`` is
+64 bits on Linux but 32 bits on Windows. There is no standard rationale or
+intent for the sizes of these types.
+
+Instead of fundamental types, use fixed-width types such as ``int32_t`` or
+implementation-defined types with standard semantics, e.g. ``int_fast32_t`` for
+the fastest integer type greater than or equal to 32 bits.
+
+Examples
+
+
+.. code-block:: c++
+
+ // Bad: platform-dependent fundamental types
+ int global_int = 42;
+ short global_short = 10;
+ long global_long = 100L;
+ unsigned long global_unsigned_long = 100UL;
+
+ void function_with_int_param(int param) {
+// ...
+ }
+
+ int function_returning_int() {
+return 42;
+ }
+
+ struct MyStruct {
+int member_int;
+long member_long;
+ };
+
+.. code-block:: c++
+
+ // Good: use fixed-width types or typedefs
+ #include
+
+ int32_t global_int32 = 42;
+ int16_t global_int16 = 10;
+ int64_t global_int64 = 100L;
+ uint64_t global_uint64 = 100UL;
+
+ void function_with_int32_param(int32_t param) {
+// ...
+ }
+
+ int32_t function_returning_int32() {
+return 42;
+ }
+
+ struct MyStruct {
+int32_t member_int32;
+int64_t member_int64;
+ };
+
+The check will also warn about typedef declarations that use fundamental types
+as their underlying type:
+
+.. code-block:: c++
+
+ // Bad: typedef using fundamental type
+ typedef long long MyLongType;
+ using MyIntType = int;
+
+.. code-block:: c++
+
+ // Good: use descriptive names or fixed-width types
+ typedef int64_t TimestampType;
+ using CounterType = uint32_t;
+
+Rationale
+-
+
+Fundamental types have platform-dependent sizes and behavior:
+
+- ``int`` is typically 32 bits on modern platforms but is only guaranteed to be
+ 16 bits by the spec
+- ``long int`` is 32 bits on Windows but 64 bits on most Unix systems
+- ``double`` is typically 64-bit IEEE754, but on some microcontrollers without
+ a 64-bit FPU (e.g. certain Arduinos) it can be 32 bits
+- ``char`` is signed on ARM and unsigned on x86
+
+For historical reasons, the C++ standard allows the implementation to define
+the size and representation of these types. They communicate intent in
+non-standard ways and are often needlessly incompatible.
+
+For example, ``int`` was traditionally the word size of a given processor in
+16-bit and 32-bit computing and was a reasonable default for performance. This
+is no longer true on modern 64-bit computers, but the size of ``int`` remains
+fixed at 32 bits for backwards compatibility with code that relied on a 32-bit
+implementation of ``int``.
+
+If code is explicitly relying on the size of an ``int`` being 32 bits, it is
+better to say so in the typename with ``int32_t``. Otherwise, use an
+appropriate implementation-defined type such as ``fast_int32_t`` or
+``least_int32_t`` that communicates the appropriate time/space tradeoff.
+
+Likewise, ``float`` and ``double`` should be replaced by ``float32_t`` and
+``float64_t`` which are guaranteed to be standard IEEE754 floats for a given
+size.
+
+``char`` should be replaced by ``char8_t`` when used in the representation of
+Unicode text. When used to represent a byte on a given platform, ``std::byte``
+is an appropriate replacement.
+
+Types Not Flagged
+-
+
+The following types are intentionally not flagged:
+
+- ``bool`` (boolean type)
+- Standard library typedefs like ``size_t``, ``ptrdiff_t``, or ``uint32_t``.
+- Already typedef'd types, though the check will flag the typedef itself
+
+``bool`` is excluded because it can only be true or false, and is not
+vulnerable to overflow or narrowing issues that occur as a result of using
+types of an implementation-defined size.
+
+Options
+---
+
+.. option:: WarnOnInts
+
+ When `true`, the check will warn about fundamental integer types
+ (``short``, ``int``, ``long``, ``long long`` and their ``signed`` and
+ ``unsigned`` variants).
+ When `false`, integer types are not flagged. Default is `true`
vbvictor wrote:
```suggestion
When `false`, integer types are not flagged. Default is `true`.
```
https://github.com/llvm/llvm-project/pull/146970
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang-tools-extra] [clang-tidy] Add portability-avoid-platform-specific-fundamental-types (PR #146970)
@@ -0,0 +1,183 @@
+//===--- AvoidPlatformSpecificFundamentalTypesCheck.cpp - clang-tidy
--===//
+//
+// 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 "AvoidPlatformSpecificFundamentalTypesCheck.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/Type.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "clang/ASTMatchers/ASTMatchers.h"
+#include "clang/Basic/TargetInfo.h"
+
+using namespace clang::ast_matchers;
+
+namespace {
+
+AST_MATCHER(clang::QualType, isBuiltinInt) {
+ const auto *BT = Node->getAs();
+ if (!BT)
+return false;
+
+ // BT->isInteger() would detect char and bool
+ switch (BT->getKind()) {
+ case clang::BuiltinType::Short:
+ case clang::BuiltinType::UShort:
+ case clang::BuiltinType::Int:
+ case clang::BuiltinType::UInt:
+ case clang::BuiltinType::Long:
+ case clang::BuiltinType::ULong:
+ case clang::BuiltinType::LongLong:
+ case clang::BuiltinType::ULongLong:
+return true;
+ default:
+return false;
+ }
+}
+
+AST_MATCHER(clang::QualType, isBuiltinFloat) {
+ const auto *BT = Node->getAs();
+ if (!BT)
+return false;
+
+ return BT->isFloatingPoint();
+}
+
+} // namespace
+
+namespace clang::tidy::portability {
+
+AvoidPlatformSpecificFundamentalTypesCheck::
+AvoidPlatformSpecificFundamentalTypesCheck(StringRef Name,
+ ClangTidyContext *Context)
+: ClangTidyCheck(Name, Context),
+ WarnOnFloats(Options.get("WarnOnFloats", true)),
+ WarnOnInts(Options.get("WarnOnInts", true)),
+ WarnOnChars(Options.get("WarnOnChars", true)),
+ IncludeInserter(Options.getLocalOrGlobal("IncludeStyle",
+ utils::IncludeSorter::IS_LLVM),
+ areDiagsSelfContained()) {
+ if (!WarnOnFloats && !WarnOnInts && !WarnOnChars)
+this->configurationDiag(
+"The check 'portability-avoid-platform-specific-fundamental-types' "
+"will not perform any analysis because 'WarnOnFloats', 'WarnOnInts' "
+"and 'WarnOnChars' are all false.");
+}
+
+void AvoidPlatformSpecificFundamentalTypesCheck::registerPPCallbacks(
+const SourceManager &SM, Preprocessor *PP, Preprocessor *ModuleExpanderPP)
{
+ IncludeInserter.registerPreprocessor(PP);
+}
+
+void AvoidPlatformSpecificFundamentalTypesCheck::storeOptions(
+ClangTidyOptions::OptionMap &Opts) {
+ Options.store(Opts, "WarnOnFloats", WarnOnFloats);
+ Options.store(Opts, "WarnOnInts", WarnOnInts);
+ Options.store(Opts, "WarnOnChars", WarnOnChars);
+ Options.store(Opts, "IncludeStyle", IncludeInserter.getStyle());
+}
+
+static std::string getFloatReplacement(const BuiltinType *BT,
+ ASTContext &Context) {
+ const TargetInfo &Target = Context.getTargetInfo();
+
+ auto GetReplacementType = [](unsigned Width) {
+switch (Width) {
+// This is ambiguous by default since it could be bfloat16 or float16
+case 16U:
+ return "";
+case 32U:
+ return "float32_t";
+case 64U:
+ return "float64_t";
+case 128U:
+ return "float128_t";
+default:
+ return "";
+}
+ };
+
+ switch (BT->getKind()) {
+ // Not an ambiguous type
+ case BuiltinType::BFloat16:
+return "bfloat16_t";
+ case BuiltinType::Half:
+return GetReplacementType(Target.getHalfWidth());
+ case BuiltinType::Float:
+return GetReplacementType(Target.getFloatWidth());
+ case BuiltinType::Double:
+return GetReplacementType(Target.getDoubleWidth());
+ default:
+return "";
+ }
+}
+
+void AvoidPlatformSpecificFundamentalTypesCheck::registerMatchers(
+MatchFinder *Finder) {
+ auto PlatformSpecificFundamentalType = qualType(allOf(
+ builtinType(), anyOf(WarnOnInts ? isBuiltinInt() : unless(anything()),
+ WarnOnFloats ? isBuiltinFloat() :
unless(anything()),
+ WarnOnChars ? isChar() : unless(anything()),
+ WarnOnChars ? isWideChar() : unless(anything();
+
+ if (!WarnOnInts && !WarnOnFloats && !WarnOnChars)
+return;
+
+
Finder->addMatcher(typeLoc(loc(PlatformSpecificFundamentalType)).bind("type"),
+ this);
+}
+
+void AvoidPlatformSpecificFundamentalTypesCheck::check(
+const MatchFinder::MatchResult &Result) {
+ const auto *TL = Result.Nodes.getNodeAs("type");
+ if (!TL)
+return;
+
+ SourceLocation Loc = TL->getBeginLoc();
+ QualType QT = TL->getType();
+ SourceRange TypeRange = TL->getSourceRange();
+
+ // Skip implicit type locations, such as literals
+ if (!Loc.isValid() || !TypeRange.isValid())
+return;
+
+ const std::string TypeName = QT.getUnqualifiedType().getAsString();
+
+ const auto *BT = QT->getAs
[clang] [clang-tools-extra] [clang-tidy] Add portability-avoid-platform-specific-fundamental-types (PR #146970)
@@ -0,0 +1,241 @@
+.. title:: clang-tidy - portability-avoid-platform-specific-fundamental-types
+
+portability-avoid-platform-specific-fundamental-types
+=
+
+Detects fundamental types (``int``, ``short``, ``long``, ``long long``,
``char``
+, ``float``, etc) and warns against their use due to platform-dependent
+behavior.
+
+This check detects fundamental types (``int``, ``short``, ``long``, ``float``,
+``char`` and their ``unsigned`` or ``signed`` variants) and warns against their
+use due to non-standard platform-dependent behavior. For example, ``long`` is
+64 bits on Linux but 32 bits on Windows. There is no standard rationale or
+intent for the sizes of these types.
+
+Instead of fundamental types, use fixed-width types such as ``int32_t`` or
+implementation-defined types with standard semantics, e.g. ``int_fast32_t`` for
+the fastest integer type greater than or equal to 32 bits.
+
+Examples
+
+
+.. code-block:: c++
+
+ // Bad: platform-dependent fundamental types
+ int global_int = 42;
+ short global_short = 10;
+ long global_long = 100L;
+ unsigned long global_unsigned_long = 100UL;
+
+ void function_with_int_param(int param) {
+// ...
+ }
+
+ int function_returning_int() {
+return 42;
+ }
+
+ struct MyStruct {
+int member_int;
+long member_long;
+ };
vbvictor wrote:
IMO this could be removed to focus on main topic, user will expect the check to
work in params/members
I just _feel_ this doc is too big
```suggestion
```
https://github.com/llvm/llvm-project/pull/146970
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang-tools-extra] [clang-tidy] Add portability-avoid-platform-specific-fundamental-types (PR #146970)
@@ -0,0 +1,241 @@
+.. title:: clang-tidy - portability-avoid-platform-specific-fundamental-types
+
+portability-avoid-platform-specific-fundamental-types
+=
+
+Detects fundamental types (``int``, ``short``, ``long``, ``long long``,
``char``
+, ``float``, etc) and warns against their use due to platform-dependent
+behavior.
+
+This check detects fundamental types (``int``, ``short``, ``long``, ``float``,
+``char`` and their ``unsigned`` or ``signed`` variants) and warns against their
+use due to non-standard platform-dependent behavior. For example, ``long`` is
+64 bits on Linux but 32 bits on Windows. There is no standard rationale or
+intent for the sizes of these types.
+
+Instead of fundamental types, use fixed-width types such as ``int32_t`` or
+implementation-defined types with standard semantics, e.g. ``int_fast32_t`` for
+the fastest integer type greater than or equal to 32 bits.
+
+Examples
+
+
+.. code-block:: c++
+
+ // Bad: platform-dependent fundamental types
+ int global_int = 42;
+ short global_short = 10;
+ long global_long = 100L;
+ unsigned long global_unsigned_long = 100UL;
+
+ void function_with_int_param(int param) {
+// ...
+ }
+
+ int function_returning_int() {
+return 42;
+ }
+
+ struct MyStruct {
+int member_int;
+long member_long;
+ };
+
+.. code-block:: c++
+
+ // Good: use fixed-width types or typedefs
+ #include
+
+ int32_t global_int32 = 42;
+ int16_t global_int16 = 10;
+ int64_t global_int64 = 100L;
+ uint64_t global_uint64 = 100UL;
+
+ void function_with_int32_param(int32_t param) {
+// ...
+ }
+
+ int32_t function_returning_int32() {
+return 42;
+ }
+
+ struct MyStruct {
+int32_t member_int32;
+int64_t member_int64;
+ };
+
+The check will also warn about typedef declarations that use fundamental types
+as their underlying type:
+
+.. code-block:: c++
+
+ // Bad: typedef using fundamental type
+ typedef long long MyLongType;
+ using MyIntType = int;
+
+.. code-block:: c++
+
+ // Good: use descriptive names or fixed-width types
+ typedef int64_t TimestampType;
+ using CounterType = uint32_t;
+
+Rationale
+-
+
+Fundamental types have platform-dependent sizes and behavior:
+
+- ``int`` is typically 32 bits on modern platforms but is only guaranteed to be
+ 16 bits by the spec
+- ``long int`` is 32 bits on Windows but 64 bits on most Unix systems
+- ``double`` is typically 64-bit IEEE754, but on some microcontrollers without
+ a 64-bit FPU (e.g. certain Arduinos) it can be 32 bits
+- ``char`` is signed on ARM and unsigned on x86
+
+For historical reasons, the C++ standard allows the implementation to define
+the size and representation of these types. They communicate intent in
+non-standard ways and are often needlessly incompatible.
+
+For example, ``int`` was traditionally the word size of a given processor in
+16-bit and 32-bit computing and was a reasonable default for performance. This
+is no longer true on modern 64-bit computers, but the size of ``int`` remains
+fixed at 32 bits for backwards compatibility with code that relied on a 32-bit
+implementation of ``int``.
+
+If code is explicitly relying on the size of an ``int`` being 32 bits, it is
+better to say so in the typename with ``int32_t``. Otherwise, use an
+appropriate implementation-defined type such as ``fast_int32_t`` or
+``least_int32_t`` that communicates the appropriate time/space tradeoff.
+
+Likewise, ``float`` and ``double`` should be replaced by ``float32_t`` and
+``float64_t`` which are guaranteed to be standard IEEE754 floats for a given
+size.
+
+``char`` should be replaced by ``char8_t`` when used in the representation of
+Unicode text. When used to represent a byte on a given platform, ``std::byte``
+is an appropriate replacement.
+
+Types Not Flagged
+-
+
+The following types are intentionally not flagged:
+
+- ``bool`` (boolean type)
+- Standard library typedefs like ``size_t``, ``ptrdiff_t``, or ``uint32_t``.
+- Already typedef'd types, though the check will flag the typedef itself
+
+``bool`` is excluded because it can only be true or false, and is not
+vulnerable to overflow or narrowing issues that occur as a result of using
+types of an implementation-defined size.
+
+Options
+---
+
+.. option:: WarnOnInts
+
+ When `true`, the check will warn about fundamental integer types
+ (``short``, ``int``, ``long``, ``long long`` and their ``signed`` and
+ ``unsigned`` variants).
+ When `false`, integer types are not flagged. Default is `true`
+
+ Example with :option:`WarnOnInts` enabled:
vbvictor wrote:
I feel like `code-block` examples in options are excessive, option descriptions
are pretty straightforward and enough to understand what option does, WDYT?
https://github.com/llvm/llvm-project/pull/146970
___
cfe-commits mailing list
[email protected]
[clang] [clang-tools-extra] [clang-tidy] Add portability-avoid-platform-specific-fundamental-types (PR #146970)
@@ -0,0 +1,241 @@ +.. title:: clang-tidy - portability-avoid-platform-specific-fundamental-types + +portability-avoid-platform-specific-fundamental-types += + +Detects fundamental types (``int``, ``short``, ``long``, ``long long``, ``char`` +, ``float``, etc) and warns against their use due to platform-dependent +behavior. + +This check detects fundamental types (``int``, ``short``, ``long``, ``float``, +``char`` and their ``unsigned`` or ``signed`` variants) and warns against their +use due to non-standard platform-dependent behavior. For example, ``long`` is +64 bits on Linux but 32 bits on Windows. There is no standard rationale or +intent for the sizes of these types. vbvictor wrote: Remove duplication https://github.com/llvm/llvm-project/pull/146970 ___ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang-tools-extra] [clang-tidy] Add portability-avoid-platform-specific-fundamental-types (PR #146970)
https://github.com/jj-marr edited https://github.com/llvm/llvm-project/pull/146970 ___ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang-tools-extra] [clang-tidy] Add portability-avoid-platform-specific-fundamental-types (PR #146970)
@@ -1,75 +1,183 @@
-// RUN: %check_clang_tidy -std=c++11-or-later %s \
+// RUN: %check_clang_tidy -std=c++20-or-later %s \
// RUN: portability-avoid-platform-specific-fundamental-types %t -- \
// RUN: -config="{CheckOptions: \
// RUN: [{key:
portability-avoid-platform-specific-fundamental-types.WarnOnInts, \
// RUN: value: false}, \
// RUN: {key:
portability-avoid-platform-specific-fundamental-types.WarnOnFloats, \
// RUN: value: false}]}"
+// Mock byte
+// NOLINTBEGIN(portability-avoid-platform-specific-fundamental-types)
+namespace std {
+enum class byte : unsigned char {};
+}
+// NOLINTEND(portability-avoid-platform-specific-fundamental-types)
+
// Test character types that should trigger warnings when WarnOnChars is
enabled
char global_char = 'a';
-// CHECK-MESSAGES: :[[@LINE-1]]:6: warning: avoid using platform-dependent
character type 'char'; consider using 'char8_t' for text or 'std::byte' for
bytes [portability-avoid-platform-specific-fundamental-types]
+// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: avoid using platform-dependent
character type 'char'; consider using 'char8_t' for text or 'std::byte' for
bytes [portability-avoid-platform-specific-fundamental-types]
signed char global_signed_char = 'b';
-// CHECK-MESSAGES: :[[@LINE-1]]:13: warning: avoid using platform-dependent
character type 'signed char'; consider using 'char8_t' for text or 'std::byte'
for bytes [portability-avoid-platform-specific-fundamental-types]
+// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: avoid using platform-dependent
character type 'signed char'; consider using 'char8_t' for text or 'std::byte'
for bytes [portability-avoid-platform-specific-fundamental-types]
unsigned char global_unsigned_char = 'c';
-// CHECK-MESSAGES: :[[@LINE-1]]:15: warning: avoid using platform-dependent
character type 'unsigned char'; consider using 'char8_t' for text or
'std::byte' for bytes [portability-avoid-platform-specific-fundamental-types]
+// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: avoid using platform-dependent
character type 'unsigned char'; consider using 'char8_t' for text or
'std::byte' for bytes [portability-avoid-platform-specific-fundamental-types]
// Function parameters
void func_with_char_param(char param) {}
-// CHECK-MESSAGES: :[[@LINE-1]]:32: warning: avoid using platform-dependent
character type 'char'; consider using 'char8_t' for text or 'std::byte' for
bytes [portability-avoid-platform-specific-fundamental-types]
+// CHECK-MESSAGES: :[[@LINE-1]]:27: warning: avoid using platform-dependent
character type 'char'; consider using 'char8_t' for text or 'std::byte' for
bytes [portability-avoid-platform-specific-fundamental-types]
void func_with_signed_char_param(signed char param) {}
-// CHECK-MESSAGES: :[[@LINE-1]]:46: warning: avoid using platform-dependent
character type 'signed char'; consider using 'char8_t' for text or 'std::byte'
for bytes [portability-avoid-platform-specific-fundamental-types]
+// CHECK-MESSAGES: :[[@LINE-1]]:34: warning: avoid using platform-dependent
character type 'signed char'; consider using 'char8_t' for text or 'std::byte'
for bytes [portability-avoid-platform-specific-fundamental-types]
void func_with_unsigned_char_param(unsigned char param) {}
-// CHECK-MESSAGES: :[[@LINE-1]]:50: warning: avoid using platform-dependent
character type 'unsigned char'; consider using 'char8_t' for text or
'std::byte' for bytes [portability-avoid-platform-specific-fundamental-types]
+// CHECK-MESSAGES: :[[@LINE-1]]:36: warning: avoid using platform-dependent
character type 'unsigned char'; consider using 'char8_t' for text or
'std::byte' for bytes [portability-avoid-platform-specific-fundamental-types]
// Function return types
char func_returning_char() { return 'a'; }
-// CHECK-MESSAGES: :[[@LINE-1]]:6: warning: avoid using platform-dependent
character type 'char'; consider using 'char8_t' for text or 'std::byte' for
bytes [portability-avoid-platform-specific-fundamental-types]
+// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: avoid using platform-dependent
character type 'char'; consider using 'char8_t' for text or 'std::byte' for
bytes [portability-avoid-platform-specific-fundamental-types]
signed char func_returning_signed_char() { return 'b'; }
-// CHECK-MESSAGES: :[[@LINE-1]]:13: warning: avoid using platform-dependent
character type 'signed char'; consider using 'char8_t' for text or 'std::byte'
for bytes [portability-avoid-platform-specific-fundamental-types]
+// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: avoid using platform-dependent
character type 'signed char'; consider using 'char8_t' for text or 'std::byte'
for bytes [portability-avoid-platform-specific-fundamental-types]
unsigned char func_returning_unsigned_char() { return 'c'; }
-// CHECK-MESSAGES: :[[@LINE-1]]:15: warning: avoid using platform-dependent
character type 'unsigned char'; consider using 'char8_t' for text or
'std::byte' for bytes [portability-avoid-plat
[clang-tools-extra] [clang-tidy] Add portability-avoid-platform-specific-fundamental-types (PR #146970)
@@ -0,0 +1,240 @@ +.. title:: clang-tidy - portability-avoid-platform-specific-fundamental-types + +portability-avoid-platform-specific-fundamental-types += + +Finds fundamental types (e.g. ``int``, ``float``) and recommends using typedefs jj-marr wrote: Actually I didn't, but fixed. https://github.com/llvm/llvm-project/pull/146970 ___ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] Add portability-avoid-platform-specific-fundamental-types (PR #146970)
@@ -148,6 +148,13 @@ New checks Finds uses of ``std::lock_guard`` and suggests replacing them with C++17's alternative ``std::scoped_lock``. +- New :doc:`portability-avoid-platform-specific-fundamental-types + ` + check. + + Detects fundamental types (int, short, long, long long, char, float, etc) EugeneZelenko wrote: Please highlight types with double back-ticks. https://github.com/llvm/llvm-project/pull/146970 ___ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] Add portability-avoid-platform-specific-fundamental-types (PR #146970)
@@ -0,0 +1,240 @@ +.. title:: clang-tidy - portability-avoid-platform-specific-fundamental-types + +portability-avoid-platform-specific-fundamental-types += + +Finds fundamental types (e.g. ``int``, ``float``) and recommends using typedefs jj-marr wrote: I did, give me a few minutes to git oush https://github.com/llvm/llvm-project/pull/146970 ___ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] Add portability-avoid-platform-specific-fundamental-types (PR #146970)
@@ -0,0 +1,240 @@ +.. title:: clang-tidy - portability-avoid-platform-specific-fundamental-types + +portability-avoid-platform-specific-fundamental-types += + +Finds fundamental types (e.g. ``int``, ``float``) and recommends using typedefs EugeneZelenko wrote: Please synchronize with statement in Release Notes. https://github.com/llvm/llvm-project/pull/146970 ___ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] Add portability-avoid-platform-specific-fundamental-types (PR #146970)
@@ -0,0 +1,69 @@
+// RUN: %check_clang_tidy -std=c++11-or-later %s
portability-avoid-platform-specific-fundamental-types %t --
-config="{CheckOptions: [{key:
portability-avoid-platform-specific-fundamental-types.WarnOnInts, value:
false}, {key:
portability-avoid-platform-specific-fundamental-types.WarnOnFloats, value:
false}]}"
+
jj-marr wrote:
@vbvictor This case actually was covered in the
avoid-platform-specific-fundamental-types-floats.cpp, I just wasn't checking
for a warning because I didn't read my test case close enough. The other
suggestion to replace all the redundant matchers I've created surfaced this.
https://github.com/llvm/llvm-project/pull/146970
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] Add portability-avoid-platform-specific-fundamental-types (PR #146970)
@@ -0,0 +1,254 @@
+//===--- AvoidPlatformSpecificFundamentalTypesCheck.cpp - clang-tidy
--===//
+//
+// 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 "AvoidPlatformSpecificFundamentalTypesCheck.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/Type.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "clang/ASTMatchers/ASTMatchers.h"
+#include "clang/Basic/TargetInfo.h"
+
+using namespace clang::ast_matchers;
+
+namespace {
+
+static bool isCharType(const clang::BuiltinType *BT) {
+ using clang::BuiltinType;
+ switch (BT->getKind()) {
+ case BuiltinType::Char_S:
+ case BuiltinType::Char_U:
+ case BuiltinType::SChar:
+ case BuiltinType::UChar:
+return true;
+ default:
+return false;
+ }
+}
+
+AST_MATCHER(clang::QualType, isBuiltinInt) {
+ const auto *BT = Node->getAs();
+ if (!BT)
+return false;
+
+ switch (BT->getKind()) {
+ case clang::BuiltinType::Short:
+ case clang::BuiltinType::UShort:
+ case clang::BuiltinType::Int:
+ case clang::BuiltinType::UInt:
+ case clang::BuiltinType::Long:
+ case clang::BuiltinType::ULong:
+ case clang::BuiltinType::LongLong:
+ case clang::BuiltinType::ULongLong:
+return true;
+ default:
+return false;
+ }
+}
+
+AST_MATCHER(clang::QualType, isBuiltinFloat) {
+ const auto *BT = Node->getAs();
+ if (!BT)
+return false;
+
+ switch (BT->getKind()) {
+ case clang::BuiltinType::Half:
+ case clang::BuiltinType::BFloat16:
+ case clang::BuiltinType::Float:
+ case clang::BuiltinType::Double:
+ case clang::BuiltinType::LongDouble:
+return true;
+ default:
+return false;
+ }
+}
+
+AST_MATCHER(clang::QualType, isBuiltinChar) {
+ const auto *BT = Node->getAs();
+ if (!BT)
+return false;
+
+ return isCharType(BT);
+}
+} // namespace
+
+namespace clang::tidy::portability {
+
+AvoidPlatformSpecificFundamentalTypesCheck::
+AvoidPlatformSpecificFundamentalTypesCheck(StringRef Name,
+ ClangTidyContext *Context)
+: ClangTidyCheck(Name, Context),
+ WarnOnFloats(Options.get("WarnOnFloats", true)),
+ WarnOnInts(Options.get("WarnOnInts", true)),
+ WarnOnChars(Options.get("WarnOnChars", true)),
+ IncludeInserter(Options.getLocalOrGlobal("IncludeStyle",
+ utils::IncludeSorter::IS_LLVM),
+ areDiagsSelfContained()) {}
+
+void AvoidPlatformSpecificFundamentalTypesCheck::registerPPCallbacks(
+const SourceManager &SM, Preprocessor *PP, Preprocessor *ModuleExpanderPP)
{
+ IncludeInserter.registerPreprocessor(PP);
+}
+
+void AvoidPlatformSpecificFundamentalTypesCheck::storeOptions(
+ClangTidyOptions::OptionMap &Opts) {
+ Options.store(Opts, "WarnOnFloats", WarnOnFloats);
+ Options.store(Opts, "WarnOnInts", WarnOnInts);
+ Options.store(Opts, "WarnOnChars", WarnOnChars);
+ Options.store(Opts, "IncludeStyle", IncludeInserter.getStyle());
+}
+
+static std::string getFloatReplacement(const BuiltinType *BT,
+ ASTContext &Context) {
+ const TargetInfo &Target = Context.getTargetInfo();
+
+ auto GetReplacementType = [](unsigned Width) {
+switch (Width) {
+// This is ambiguous by default since it could be bfloat16 or float16
+case 16U:
+ return "";
+case 32U:
+ return "float32_t";
+case 64U:
+ return "float64_t";
+case 128U:
+ return "float128_t";
+default:
+ return "";
+}
+ };
+
+ switch (BT->getKind()) {
+ // Not an ambiguous type
+ case BuiltinType::BFloat16:
+return "bfloat16_t";
+ case BuiltinType::Half:
+return GetReplacementType(Target.getHalfWidth());
+ case BuiltinType::Float:
+return GetReplacementType(Target.getFloatWidth());
+ case BuiltinType::Double:
+return GetReplacementType(Target.getDoubleWidth());
+ default:
+return "";
+ }
+}
+
+void AvoidPlatformSpecificFundamentalTypesCheck::registerMatchers(
+MatchFinder *Finder) {
+ auto PlatformSpecificFundamentalType = qualType(
+ allOf(builtinType(),
+anyOf(WarnOnInts ? isBuiltinInt() : unless(anything()),
+ WarnOnFloats ? isBuiltinFloat() : unless(anything()),
+ WarnOnChars ? isBuiltinChar() : unless(anything();
+
+ if (!WarnOnInts && !WarnOnFloats && !WarnOnChars)
+return;
+
+ Finder->addMatcher(
+ varDecl(hasType(PlatformSpecificFundamentalType)).bind("var_decl"),
this);
+
+ Finder->addMatcher(
+ functionDecl(returns(PlatformSpecificFundamentalType)).bind("func_decl"),
+ this);
+
+ Finder->addMatcher(
+ parmVarDecl(hasType(PlatformSpecificFundamentalType)).bind("param_decl"),
+ this);
+
+ Finder->addMatcher(
+ fieldDecl(hasTyp
[clang-tools-extra] [clang-tidy] Add portability-avoid-platform-specific-fundamental-types (PR #146970)
@@ -0,0 +1,254 @@
+//===--- AvoidPlatformSpecificFundamentalTypesCheck.cpp - clang-tidy
--===//
+//
+// 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 "AvoidPlatformSpecificFundamentalTypesCheck.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/Type.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "clang/ASTMatchers/ASTMatchers.h"
+#include "clang/Basic/TargetInfo.h"
+
+using namespace clang::ast_matchers;
+
+namespace {
+
+static bool isCharType(const clang::BuiltinType *BT) {
+ using clang::BuiltinType;
+ switch (BT->getKind()) {
+ case BuiltinType::Char_S:
+ case BuiltinType::Char_U:
+ case BuiltinType::SChar:
+ case BuiltinType::UChar:
+return true;
+ default:
+return false;
+ }
+}
+
+AST_MATCHER(clang::QualType, isBuiltinInt) {
+ const auto *BT = Node->getAs();
+ if (!BT)
+return false;
+
+ switch (BT->getKind()) {
+ case clang::BuiltinType::Short:
+ case clang::BuiltinType::UShort:
+ case clang::BuiltinType::Int:
+ case clang::BuiltinType::UInt:
+ case clang::BuiltinType::Long:
+ case clang::BuiltinType::ULong:
+ case clang::BuiltinType::LongLong:
+ case clang::BuiltinType::ULongLong:
+return true;
+ default:
+return false;
+ }
+}
+
+AST_MATCHER(clang::QualType, isBuiltinFloat) {
+ const auto *BT = Node->getAs();
+ if (!BT)
+return false;
+
+ switch (BT->getKind()) {
jj-marr wrote:
I forgot to do the refactor here.
https://github.com/llvm/llvm-project/pull/146970
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] Add portability-avoid-platform-specific-fundamental-types (PR #146970)
@@ -0,0 +1,227 @@
+.. title:: clang-tidy - portability-avoid-platform-specific-fundamental-types
+
+portability-avoid-platform-specific-fundamental-types
+=
+
+Finds fundamental types (e.g. `int`, `float`) and recommends using typedefs
+or fixed-width types instead to improve portability across different platforms.
+
+This check detects fundamental types (``int``, ``short``, ``long``, ``float``,
+``char`` and their ``unsigned`` or ``signed`` variants) and warns against
their
+use due to non-standard platform-dependent behavior. For example, ``long`` is
+64 bits on Linux but 32 bits on Windows. There is no standard rationale or
+intent for the sizes of these types.
+
+Instead of fundamental types, use fixed-width types such as ``int32_t`` or
+implementation-defined types with standard semantics, e.g. ``int_fast32_t``
for
+the fastest integer type greater than or equal to 32 bits.
+
+Examples
+
+
+.. code-block:: c++
+
+ // Bad: platform-dependent fundamental types
+ int global_int = 42;
+ short global_short = 10;
+ long global_long = 100L;
+ unsigned long global_unsigned_long = 100UL;
+
+ void function_with_int_param(int param) {
+// ...
+ }
+
+ int function_returning_int() {
+return 42;
+ }
+
+ struct MyStruct {
+int member_int;
+long member_long;
+ };
+
+.. code-block:: c++
+
+ // Good: use fixed-width types or typedefs
+ #include
+
+ int32_t global_int32 = 42;
+ int16_t global_int16 = 10;
+ int64_t global_int64 = 100L;
+ uint64_t global_uint64 = 100UL;
+
+ void function_with_int32_param(int32_t param) {
+// ...
+ }
+
+ int32_t function_returning_int32() {
+return 42;
+ }
+
+ struct MyStruct {
+int32_t member_int32;
+int64_t member_int64;
+ };
+
+The check will also warn about typedef declarations that use fundamental types
+as their underlying type:
+
+.. code-block:: c++
+
+ // Bad: typedef using fundamental type
+ typedef long long MyLongType;
+ using MyIntType = int;
+
+.. code-block:: c++
+
+ // Good: use descriptive names or fixed-width types
+ typedef int64_t TimestampType;
+ using CounterType = uint32_t;
+
+Rationale
+-
+
+Fundamental types have platform-dependent sizes and behavior:
+
+- ``int`` is typically 32 bits on modern platforms but is only guaranteed to be
+ 16 bits by the spec
+- ``long int`` is 32 bits on Windows but 64 bits on most Unix systems
+- ``double`` is typically 64-bit IEEE754, but on some microcontrollers without
+ a 64-bit FPU (e.g. certain Arduinos) it can be 32 bits
+- ``char`` is signed on ARM and unsigned on x86
+
+The C++ specification does not define these types beyond their minimum sizes.
+That means they can communicate intent in non-standard ways and are often
+needlessly incompatible. For example, ``int`` was traditionally the word size
+of a given processor in 16-bit and 32-bit computing and was a reasonable
+default for performance. This is no longer true on modern 64-bit computers, but
+the size of ``int`` remains fixed at 32 bits for backwards compatibility with
+code that relied on a 32-bit implementation of ``int``.
+
+If code is explicitly relying on the size of an ``int`` being 32 bits, it is
+better to say so in the typename with ``int32_t``. Otherwise, use an
+appropriate implementation-defined type such as ``fast_int32_t`` or
+``least_int32_t`` that communicates the appropriate time/space tradeoff.
+
+Likewise, ``float`` and ``double`` should be replaced by ``float32_t`` and
+``float64_t`` which are guaranteed to be standard IEEE754 floats for a given
+size.
+
+``char`` should be replaced by ``char8_t`` when used in the representation of
+Unicode text. When used to represent a byte on a given platform, ``std::byte``
+is an appropriate replacement.
+
+Types Not Flagged
+-
+
+The following types are intentionally not flagged:
+
+- ``bool`` (boolean type)
+- Standard library typedefs like ``size_t``, ``ptrdiff_t``, or ``uint32_t``.
+- Already typedef'd types, though the check will flag the typedef itself
+
+``bool`` is excluded because it can only be true or false, and is not
vulnerable to overflow or
+narrowing issues that occur as a result of using implementation-defined types.
+
+Options
+---
+
+.. option:: WarnOnInts
+
+ When `true` (default), the check will warn about fundamental integer types
(``short``, ``int``, ``long``, ``long long`` and their ``signed`` and
``unsigned`` variants).
jj-marr wrote:
Done. Should the checks in readability be refactored to have default as the
last sentence?
https://github.com/llvm/llvm-project/pull/146970
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] Add portability-avoid-platform-specific-fundamental-types (PR #146970)
@@ -0,0 +1,227 @@
+.. title:: clang-tidy - portability-avoid-platform-specific-fundamental-types
+
+portability-avoid-platform-specific-fundamental-types
+=
+
+Finds fundamental types (e.g. ``int``, ``float``) and recommends using
typedefs
+or fixed-width types instead to improve portability across different platforms.
+
+This check detects fundamental types (``int``, ``short``, ``long``, ``float``,
+``char`` and their ``unsigned`` or ``signed`` variants) and warns against
their
+use due to non-standard platform-dependent behavior. For example, ``long`` is
+64 bits on Linux but 32 bits on Windows. There is no standard rationale or
+intent for the sizes of these types.
+
+Instead of fundamental types, use fixed-width types such as ``int32_t`` or
+implementation-defined types with standard semantics, e.g. ``int_fast32_t``
for
+the fastest integer type greater than or equal to 32 bits.
+
+Examples
+
+
+.. code-block:: c++
+
+ // Bad: platform-dependent fundamental types
+ int global_int = 42;
+ short global_short = 10;
+ long global_long = 100L;
+ unsigned long global_unsigned_long = 100UL;
+
+ void function_with_int_param(int param) {
+// ...
+ }
+
+ int function_returning_int() {
+return 42;
+ }
+
+ struct MyStruct {
+int member_int;
+long member_long;
+ };
+
+.. code-block:: c++
+
+ // Good: use fixed-width types or typedefs
+ #include
+
+ int32_t global_int32 = 42;
+ int16_t global_int16 = 10;
+ int64_t global_int64 = 100L;
+ uint64_t global_uint64 = 100UL;
+
+ void function_with_int32_param(int32_t param) {
+// ...
+ }
+
+ int32_t function_returning_int32() {
+return 42;
+ }
+
+ struct MyStruct {
+int32_t member_int32;
+int64_t member_int64;
+ };
+
+The check will also warn about typedef declarations that use fundamental types
+as their underlying type:
+
+.. code-block:: c++
+
+ // Bad: typedef using fundamental type
+ typedef long long MyLongType;
+ using MyIntType = int;
+
+.. code-block:: c++
+
+ // Good: use descriptive names or fixed-width types
+ typedef int64_t TimestampType;
+ using CounterType = uint32_t;
+
+Rationale
+-
+
+Fundamental types have platform-dependent sizes and behavior:
+
+- ``int`` is typically 32 bits on modern platforms but is only guaranteed to be
+ 16 bits by the spec
+- ``long int`` is 32 bits on Windows but 64 bits on most Unix systems
+- ``double`` is typically 64-bit IEEE754, but on some microcontrollers without
+ a 64-bit FPU (e.g. certain Arduinos) it can be 32 bits
+- ``char`` is signed on ARM and unsigned on x86
+
+The C++ specification does not define these types beyond their minimum sizes.
+That means they can communicate intent in non-standard ways and are often
+needlessly incompatible. For example, ``int`` was traditionally the word size
+of a given processor in 16-bit and 32-bit computing and was a reasonable
+default for performance. This is no longer true on modern 64-bit computers, but
+the size of ``int`` remains fixed at 32 bits for backwards compatibility with
+code that relied on a 32-bit implementation of ``int``.
+
+If code is explicitly relying on the size of an ``int`` being 32 bits, it is
+better to say so in the typename with ``int32_t``. Otherwise, use an
+appropriate implementation-defined type such as ``fast_int32_t`` or
+``least_int32_t`` that communicates the appropriate time/space tradeoff.
+
+Likewise, ``float`` and ``double`` should be replaced by ``float32_t`` and
+``float64_t`` which are guaranteed to be standard IEEE754 floats for a given
+size.
+
+``char`` should be replaced by ``char8_t`` when used in the representation of
+Unicode text. When used to represent a byte on a given platform, ``std::byte``
+is an appropriate replacement.
+
+Types Not Flagged
+-
+
+The following types are intentionally not flagged:
+
+- ``bool`` (boolean type)
+- Standard library typedefs like ``size_t``, ``ptrdiff_t``, or ``uint32_t``.
+- Already typedef'd types, though the check will flag the typedef itself
+
+``bool`` is excluded because it can only be true or false, and is not
vulnerable to overflow or
+narrowing issues that occur as a result of using implementation-defined types.
+
+Options
+---
+
+.. option:: WarnOnInts
+
+ When `true` (default), the check will warn about fundamental integer types
(``short``, ``int``, ``long``, ``long long`` and their ``signed`` and
``unsigned`` variants).
+ When `false`, integer types are not flagged.
+
+ Example with `WarnOnInts` enabled:
+
+ .. code-block:: c++
+
+ // Bad: platform-dependent integer types
+ #include
+
+ int counter = 0;
+ long timestamp = 12345L;
+ unsigned short port = 8080;
+
+ std::vector vec;
+ // If int is 32 bits and (vec.size > 2^31 - 1), this overflows
+ for(int i = 0; i
+ #include
+
+ int32_t counter = 0; // When you need exact
[clang-tools-extra] [clang-tidy] Add portability-avoid-platform-specific-fundamental-types (PR #146970)
https://github.com/EugeneZelenko edited https://github.com/llvm/llvm-project/pull/146970 ___ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] Add portability-avoid-platform-specific-fundamental-types (PR #146970)
jj-marr wrote: I broke my Gentoo installation during a system update so I haven't been able to work on this PR. TBD on when it'll be fixed. https://github.com/llvm/llvm-project/pull/146970 ___ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] Add portability-avoid-platform-specific-fundamental-types (PR #146970)
@@ -0,0 +1,254 @@
+//===--- AvoidPlatformSpecificFundamentalTypesCheck.cpp - clang-tidy
--===//
+//
+// 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 "AvoidPlatformSpecificFundamentalTypesCheck.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/Type.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "clang/ASTMatchers/ASTMatchers.h"
+#include "clang/Basic/TargetInfo.h"
+
+using namespace clang::ast_matchers;
+
+namespace {
+
+static bool isCharType(const clang::BuiltinType *BT) {
+ using clang::BuiltinType;
+ switch (BT->getKind()) {
+ case BuiltinType::Char_S:
+ case BuiltinType::Char_U:
+ case BuiltinType::SChar:
+ case BuiltinType::UChar:
+return true;
+ default:
+return false;
+ }
+}
+
+AST_MATCHER(clang::QualType, isBuiltinInt) {
+ const auto *BT = Node->getAs();
+ if (!BT)
+return false;
+
+ switch (BT->getKind()) {
+ case clang::BuiltinType::Short:
+ case clang::BuiltinType::UShort:
+ case clang::BuiltinType::Int:
+ case clang::BuiltinType::UInt:
+ case clang::BuiltinType::Long:
+ case clang::BuiltinType::ULong:
+ case clang::BuiltinType::LongLong:
+ case clang::BuiltinType::ULongLong:
+return true;
+ default:
+return false;
+ }
+}
+
+AST_MATCHER(clang::QualType, isBuiltinFloat) {
+ const auto *BT = Node->getAs();
+ if (!BT)
+return false;
+
+ switch (BT->getKind()) {
5chmidti wrote:
Why not `BT->isBuiltinFloatingPoint()` like in the `check` function
https://github.com/llvm/llvm-project/pull/146970
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] Add portability-avoid-platform-specific-fundamental-types (PR #146970)
@@ -0,0 +1,227 @@ +.. title:: clang-tidy - portability-avoid-platform-specific-fundamental-types + +portability-avoid-platform-specific-fundamental-types += + +Finds fundamental types (e.g. `int`, `float`) and recommends using typedefs +or fixed-width types instead to improve portability across different platforms. 5chmidti wrote: please remove the `instead` https://github.com/llvm/llvm-project/pull/146970 ___ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] Add portability-avoid-platform-specific-fundamental-types (PR #146970)
@@ -0,0 +1,254 @@
+//===--- AvoidPlatformSpecificFundamentalTypesCheck.cpp - clang-tidy
--===//
+//
+// 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 "AvoidPlatformSpecificFundamentalTypesCheck.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/Type.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "clang/ASTMatchers/ASTMatchers.h"
+#include "clang/Basic/TargetInfo.h"
+
+using namespace clang::ast_matchers;
+
+namespace {
+
+static bool isCharType(const clang::BuiltinType *BT) {
+ using clang::BuiltinType;
+ switch (BT->getKind()) {
+ case BuiltinType::Char_S:
+ case BuiltinType::Char_U:
+ case BuiltinType::SChar:
+ case BuiltinType::UChar:
+return true;
+ default:
+return false;
+ }
+}
+
+AST_MATCHER(clang::QualType, isBuiltinInt) {
+ const auto *BT = Node->getAs();
+ if (!BT)
+return false;
+
+ switch (BT->getKind()) {
+ case clang::BuiltinType::Short:
+ case clang::BuiltinType::UShort:
+ case clang::BuiltinType::Int:
+ case clang::BuiltinType::UInt:
+ case clang::BuiltinType::Long:
+ case clang::BuiltinType::ULong:
+ case clang::BuiltinType::LongLong:
+ case clang::BuiltinType::ULongLong:
+return true;
+ default:
+return false;
+ }
+}
+
+AST_MATCHER(clang::QualType, isBuiltinFloat) {
+ const auto *BT = Node->getAs();
+ if (!BT)
+return false;
+
+ switch (BT->getKind()) {
+ case clang::BuiltinType::Half:
+ case clang::BuiltinType::BFloat16:
+ case clang::BuiltinType::Float:
+ case clang::BuiltinType::Double:
+ case clang::BuiltinType::LongDouble:
+return true;
+ default:
+return false;
+ }
+}
+
+AST_MATCHER(clang::QualType, isBuiltinChar) {
+ const auto *BT = Node->getAs();
+ if (!BT)
+return false;
+
+ return isCharType(BT);
+}
+} // namespace
+
+namespace clang::tidy::portability {
+
+AvoidPlatformSpecificFundamentalTypesCheck::
+AvoidPlatformSpecificFundamentalTypesCheck(StringRef Name,
+ ClangTidyContext *Context)
+: ClangTidyCheck(Name, Context),
+ WarnOnFloats(Options.get("WarnOnFloats", true)),
+ WarnOnInts(Options.get("WarnOnInts", true)),
+ WarnOnChars(Options.get("WarnOnChars", true)),
+ IncludeInserter(Options.getLocalOrGlobal("IncludeStyle",
+ utils::IncludeSorter::IS_LLVM),
+ areDiagsSelfContained()) {}
+
+void AvoidPlatformSpecificFundamentalTypesCheck::registerPPCallbacks(
+const SourceManager &SM, Preprocessor *PP, Preprocessor *ModuleExpanderPP)
{
+ IncludeInserter.registerPreprocessor(PP);
+}
+
+void AvoidPlatformSpecificFundamentalTypesCheck::storeOptions(
+ClangTidyOptions::OptionMap &Opts) {
+ Options.store(Opts, "WarnOnFloats", WarnOnFloats);
+ Options.store(Opts, "WarnOnInts", WarnOnInts);
+ Options.store(Opts, "WarnOnChars", WarnOnChars);
+ Options.store(Opts, "IncludeStyle", IncludeInserter.getStyle());
+}
+
+static std::string getFloatReplacement(const BuiltinType *BT,
+ ASTContext &Context) {
+ const TargetInfo &Target = Context.getTargetInfo();
+
+ auto GetReplacementType = [](unsigned Width) {
+switch (Width) {
+// This is ambiguous by default since it could be bfloat16 or float16
+case 16U:
+ return "";
+case 32U:
+ return "float32_t";
+case 64U:
+ return "float64_t";
+case 128U:
+ return "float128_t";
+default:
+ return "";
+}
+ };
+
+ switch (BT->getKind()) {
+ // Not an ambiguous type
+ case BuiltinType::BFloat16:
+return "bfloat16_t";
+ case BuiltinType::Half:
+return GetReplacementType(Target.getHalfWidth());
+ case BuiltinType::Float:
+return GetReplacementType(Target.getFloatWidth());
+ case BuiltinType::Double:
+return GetReplacementType(Target.getDoubleWidth());
+ default:
+return "";
+ }
+}
+
+void AvoidPlatformSpecificFundamentalTypesCheck::registerMatchers(
+MatchFinder *Finder) {
+ auto PlatformSpecificFundamentalType = qualType(
+ allOf(builtinType(),
+anyOf(WarnOnInts ? isBuiltinInt() : unless(anything()),
+ WarnOnFloats ? isBuiltinFloat() : unless(anything()),
+ WarnOnChars ? isBuiltinChar() : unless(anything();
+
+ if (!WarnOnInts && !WarnOnFloats && !WarnOnChars)
+return;
+
+ Finder->addMatcher(
+ varDecl(hasType(PlatformSpecificFundamentalType)).bind("var_decl"),
this);
+
+ Finder->addMatcher(
+ functionDecl(returns(PlatformSpecificFundamentalType)).bind("func_decl"),
+ this);
+
+ Finder->addMatcher(
+ parmVarDecl(hasType(PlatformSpecificFundamentalType)).bind("param_decl"),
+ this);
+
+ Finder->addMatcher(
+ fieldDecl(hasTyp
[clang-tools-extra] [clang-tidy] Add portability-avoid-platform-specific-fundamental-types (PR #146970)
@@ -0,0 +1,254 @@
+//===--- AvoidPlatformSpecificFundamentalTypesCheck.cpp - clang-tidy
--===//
+//
+// 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 "AvoidPlatformSpecificFundamentalTypesCheck.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/Type.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "clang/ASTMatchers/ASTMatchers.h"
+#include "clang/Basic/TargetInfo.h"
+
+using namespace clang::ast_matchers;
+
+namespace {
+
+static bool isCharType(const clang::BuiltinType *BT) {
5chmidti wrote:
This function * `isBuiltinChar`: please use the existing `isAnyCharacter`
matcher. Though that one also matches wide character types
https://github.com/llvm/llvm-project/pull/146970
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] Add portability-avoid-platform-specific-fundamental-types (PR #146970)
@@ -0,0 +1,227 @@
+.. title:: clang-tidy - portability-avoid-platform-specific-fundamental-types
+
+portability-avoid-platform-specific-fundamental-types
+=
+
+Finds fundamental types (e.g. `int`, `float`) and recommends using typedefs
+or fixed-width types instead to improve portability across different platforms.
+
+This check detects fundamental types (``int``, ``short``, ``long``, ``float``,
+``char`` and their ``unsigned`` or ``signed`` variants) and warns against
their
+use due to non-standard platform-dependent behavior. For example, ``long`` is
+64 bits on Linux but 32 bits on Windows. There is no standard rationale or
+intent for the sizes of these types.
+
+Instead of fundamental types, use fixed-width types such as ``int32_t`` or
+implementation-defined types with standard semantics, e.g. ``int_fast32_t``
for
+the fastest integer type greater than or equal to 32 bits.
+
+Examples
+
+
+.. code-block:: c++
+
+ // Bad: platform-dependent fundamental types
+ int global_int = 42;
+ short global_short = 10;
+ long global_long = 100L;
+ unsigned long global_unsigned_long = 100UL;
+
+ void function_with_int_param(int param) {
+// ...
+ }
+
+ int function_returning_int() {
+return 42;
+ }
+
+ struct MyStruct {
+int member_int;
+long member_long;
+ };
+
+.. code-block:: c++
+
+ // Good: use fixed-width types or typedefs
+ #include
+
+ int32_t global_int32 = 42;
+ int16_t global_int16 = 10;
+ int64_t global_int64 = 100L;
+ uint64_t global_uint64 = 100UL;
+
+ void function_with_int32_param(int32_t param) {
+// ...
+ }
+
+ int32_t function_returning_int32() {
+return 42;
+ }
+
+ struct MyStruct {
+int32_t member_int32;
+int64_t member_int64;
+ };
+
+The check will also warn about typedef declarations that use fundamental types
+as their underlying type:
+
+.. code-block:: c++
+
+ // Bad: typedef using fundamental type
+ typedef long long MyLongType;
+ using MyIntType = int;
+
+.. code-block:: c++
+
+ // Good: use descriptive names or fixed-width types
+ typedef int64_t TimestampType;
+ using CounterType = uint32_t;
+
+Rationale
+-
+
+Fundamental types have platform-dependent sizes and behavior:
+
+- ``int`` is typically 32 bits on modern platforms but is only guaranteed to be
+ 16 bits by the spec
+- ``long int`` is 32 bits on Windows but 64 bits on most Unix systems
+- ``double`` is typically 64-bit IEEE754, but on some microcontrollers without
+ a 64-bit FPU (e.g. certain Arduinos) it can be 32 bits
+- ``char`` is signed on ARM and unsigned on x86
+
+The C++ specification does not define these types beyond their minimum sizes.
5chmidti wrote:
+- on the wording of this sentence, since the standard partially defines the
behavior of types (e.g., truncation is only defined for some, but still
something that is defined at least for some of these types)
https://github.com/llvm/llvm-project/pull/146970
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] Add portability-avoid-platform-specific-fundamental-types (PR #146970)
@@ -0,0 +1,254 @@
+//===--- AvoidPlatformSpecificFundamentalTypesCheck.cpp - clang-tidy
--===//
+//
+// 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 "AvoidPlatformSpecificFundamentalTypesCheck.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/Type.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "clang/ASTMatchers/ASTMatchers.h"
+#include "clang/Basic/TargetInfo.h"
+
+using namespace clang::ast_matchers;
+
+namespace {
+
+static bool isCharType(const clang::BuiltinType *BT) {
+ using clang::BuiltinType;
+ switch (BT->getKind()) {
+ case BuiltinType::Char_S:
+ case BuiltinType::Char_U:
+ case BuiltinType::SChar:
+ case BuiltinType::UChar:
+return true;
+ default:
+return false;
+ }
+}
+
+AST_MATCHER(clang::QualType, isBuiltinInt) {
+ const auto *BT = Node->getAs();
+ if (!BT)
+return false;
+
+ switch (BT->getKind()) {
+ case clang::BuiltinType::Short:
+ case clang::BuiltinType::UShort:
+ case clang::BuiltinType::Int:
+ case clang::BuiltinType::UInt:
+ case clang::BuiltinType::Long:
+ case clang::BuiltinType::ULong:
+ case clang::BuiltinType::LongLong:
+ case clang::BuiltinType::ULongLong:
+return true;
+ default:
+return false;
+ }
+}
+
+AST_MATCHER(clang::QualType, isBuiltinFloat) {
+ const auto *BT = Node->getAs();
+ if (!BT)
+return false;
+
+ switch (BT->getKind()) {
+ case clang::BuiltinType::Half:
+ case clang::BuiltinType::BFloat16:
+ case clang::BuiltinType::Float:
+ case clang::BuiltinType::Double:
+ case clang::BuiltinType::LongDouble:
+return true;
+ default:
+return false;
+ }
+}
+
+AST_MATCHER(clang::QualType, isBuiltinChar) {
+ const auto *BT = Node->getAs();
+ if (!BT)
+return false;
+
+ return isCharType(BT);
+}
+} // namespace
+
+namespace clang::tidy::portability {
+
+AvoidPlatformSpecificFundamentalTypesCheck::
+AvoidPlatformSpecificFundamentalTypesCheck(StringRef Name,
+ ClangTidyContext *Context)
+: ClangTidyCheck(Name, Context),
+ WarnOnFloats(Options.get("WarnOnFloats", true)),
+ WarnOnInts(Options.get("WarnOnInts", true)),
+ WarnOnChars(Options.get("WarnOnChars", true)),
+ IncludeInserter(Options.getLocalOrGlobal("IncludeStyle",
+ utils::IncludeSorter::IS_LLVM),
+ areDiagsSelfContained()) {}
+
+void AvoidPlatformSpecificFundamentalTypesCheck::registerPPCallbacks(
+const SourceManager &SM, Preprocessor *PP, Preprocessor *ModuleExpanderPP)
{
+ IncludeInserter.registerPreprocessor(PP);
+}
+
+void AvoidPlatformSpecificFundamentalTypesCheck::storeOptions(
+ClangTidyOptions::OptionMap &Opts) {
+ Options.store(Opts, "WarnOnFloats", WarnOnFloats);
+ Options.store(Opts, "WarnOnInts", WarnOnInts);
+ Options.store(Opts, "WarnOnChars", WarnOnChars);
+ Options.store(Opts, "IncludeStyle", IncludeInserter.getStyle());
+}
+
+static std::string getFloatReplacement(const BuiltinType *BT,
+ ASTContext &Context) {
+ const TargetInfo &Target = Context.getTargetInfo();
+
+ auto GetReplacementType = [](unsigned Width) {
+switch (Width) {
+// This is ambiguous by default since it could be bfloat16 or float16
+case 16U:
+ return "";
+case 32U:
+ return "float32_t";
+case 64U:
+ return "float64_t";
+case 128U:
+ return "float128_t";
+default:
+ return "";
+}
+ };
+
+ switch (BT->getKind()) {
+ // Not an ambiguous type
+ case BuiltinType::BFloat16:
+return "bfloat16_t";
+ case BuiltinType::Half:
+return GetReplacementType(Target.getHalfWidth());
+ case BuiltinType::Float:
+return GetReplacementType(Target.getFloatWidth());
+ case BuiltinType::Double:
+return GetReplacementType(Target.getDoubleWidth());
+ default:
+return "";
+ }
+}
+
+void AvoidPlatformSpecificFundamentalTypesCheck::registerMatchers(
+MatchFinder *Finder) {
+ auto PlatformSpecificFundamentalType = qualType(
+ allOf(builtinType(),
+anyOf(WarnOnInts ? isBuiltinInt() : unless(anything()),
+ WarnOnFloats ? isBuiltinFloat() : unless(anything()),
+ WarnOnChars ? isBuiltinChar() : unless(anything();
+
+ if (!WarnOnInts && !WarnOnFloats && !WarnOnChars)
+return;
+
+ Finder->addMatcher(
+ varDecl(hasType(PlatformSpecificFundamentalType)).bind("var_decl"),
this);
+
+ Finder->addMatcher(
+ functionDecl(returns(PlatformSpecificFundamentalType)).bind("func_decl"),
+ this);
+
+ Finder->addMatcher(
+ parmVarDecl(hasType(PlatformSpecificFundamentalType)).bind("param_decl"),
+ this);
+
+ Finder->addMatcher(
+ fieldDecl(hasTyp
[clang-tools-extra] [clang-tidy] Add portability-avoid-platform-specific-fundamental-types (PR #146970)
@@ -0,0 +1,254 @@
+//===--- AvoidPlatformSpecificFundamentalTypesCheck.cpp - clang-tidy
--===//
+//
+// 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 "AvoidPlatformSpecificFundamentalTypesCheck.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/Type.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "clang/ASTMatchers/ASTMatchers.h"
+#include "clang/Basic/TargetInfo.h"
+
+using namespace clang::ast_matchers;
+
+namespace {
+
+static bool isCharType(const clang::BuiltinType *BT) {
+ using clang::BuiltinType;
+ switch (BT->getKind()) {
+ case BuiltinType::Char_S:
+ case BuiltinType::Char_U:
+ case BuiltinType::SChar:
+ case BuiltinType::UChar:
+return true;
+ default:
+return false;
+ }
+}
+
+AST_MATCHER(clang::QualType, isBuiltinInt) {
+ const auto *BT = Node->getAs();
+ if (!BT)
+return false;
+
+ switch (BT->getKind()) {
+ case clang::BuiltinType::Short:
+ case clang::BuiltinType::UShort:
+ case clang::BuiltinType::Int:
+ case clang::BuiltinType::UInt:
+ case clang::BuiltinType::Long:
+ case clang::BuiltinType::ULong:
+ case clang::BuiltinType::LongLong:
+ case clang::BuiltinType::ULongLong:
+return true;
+ default:
+return false;
+ }
+}
+
+AST_MATCHER(clang::QualType, isBuiltinFloat) {
+ const auto *BT = Node->getAs();
+ if (!BT)
+return false;
+
+ switch (BT->getKind()) {
+ case clang::BuiltinType::Half:
+ case clang::BuiltinType::BFloat16:
+ case clang::BuiltinType::Float:
+ case clang::BuiltinType::Double:
+ case clang::BuiltinType::LongDouble:
+return true;
+ default:
+return false;
+ }
+}
+
+AST_MATCHER(clang::QualType, isBuiltinChar) {
+ const auto *BT = Node->getAs();
+ if (!BT)
+return false;
+
+ return isCharType(BT);
+}
+} // namespace
+
+namespace clang::tidy::portability {
+
+AvoidPlatformSpecificFundamentalTypesCheck::
+AvoidPlatformSpecificFundamentalTypesCheck(StringRef Name,
+ ClangTidyContext *Context)
+: ClangTidyCheck(Name, Context),
+ WarnOnFloats(Options.get("WarnOnFloats", true)),
+ WarnOnInts(Options.get("WarnOnInts", true)),
+ WarnOnChars(Options.get("WarnOnChars", true)),
+ IncludeInserter(Options.getLocalOrGlobal("IncludeStyle",
+ utils::IncludeSorter::IS_LLVM),
+ areDiagsSelfContained()) {}
+
+void AvoidPlatformSpecificFundamentalTypesCheck::registerPPCallbacks(
+const SourceManager &SM, Preprocessor *PP, Preprocessor *ModuleExpanderPP)
{
+ IncludeInserter.registerPreprocessor(PP);
+}
+
+void AvoidPlatformSpecificFundamentalTypesCheck::storeOptions(
+ClangTidyOptions::OptionMap &Opts) {
+ Options.store(Opts, "WarnOnFloats", WarnOnFloats);
+ Options.store(Opts, "WarnOnInts", WarnOnInts);
+ Options.store(Opts, "WarnOnChars", WarnOnChars);
+ Options.store(Opts, "IncludeStyle", IncludeInserter.getStyle());
+}
+
+static std::string getFloatReplacement(const BuiltinType *BT,
+ ASTContext &Context) {
+ const TargetInfo &Target = Context.getTargetInfo();
+
+ auto GetReplacementType = [](unsigned Width) {
+switch (Width) {
+// This is ambiguous by default since it could be bfloat16 or float16
+case 16U:
+ return "";
+case 32U:
+ return "float32_t";
+case 64U:
+ return "float64_t";
+case 128U:
+ return "float128_t";
+default:
+ return "";
+}
+ };
+
+ switch (BT->getKind()) {
+ // Not an ambiguous type
+ case BuiltinType::BFloat16:
+return "bfloat16_t";
+ case BuiltinType::Half:
+return GetReplacementType(Target.getHalfWidth());
+ case BuiltinType::Float:
+return GetReplacementType(Target.getFloatWidth());
+ case BuiltinType::Double:
+return GetReplacementType(Target.getDoubleWidth());
+ default:
+return "";
+ }
+}
+
+void AvoidPlatformSpecificFundamentalTypesCheck::registerMatchers(
+MatchFinder *Finder) {
+ auto PlatformSpecificFundamentalType = qualType(
+ allOf(builtinType(),
+anyOf(WarnOnInts ? isBuiltinInt() : unless(anything()),
+ WarnOnFloats ? isBuiltinFloat() : unless(anything()),
+ WarnOnChars ? isBuiltinChar() : unless(anything();
+
+ if (!WarnOnInts && !WarnOnFloats && !WarnOnChars)
+return;
+
+ Finder->addMatcher(
+ varDecl(hasType(PlatformSpecificFundamentalType)).bind("var_decl"),
this);
+
+ Finder->addMatcher(
+ functionDecl(returns(PlatformSpecificFundamentalType)).bind("func_decl"),
+ this);
+
+ Finder->addMatcher(
+ parmVarDecl(hasType(PlatformSpecificFundamentalType)).bind("param_decl"),
+ this);
+
+ Finder->addMatcher(
+ fieldDecl(hasTyp
[clang-tools-extra] [clang-tidy] Add portability-avoid-platform-specific-fundamental-types (PR #146970)
@@ -0,0 +1,50 @@
+//==-- AvoidPlatformSpecificFundamentalTypesCheck.h - clang-tidy -*- C++
-*-==//
+//
+// 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_PORTABILITY_AVOIDPLATFORMSPECIFICFUNDAMENTALTYPESCHECK_H
+#define
LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_PORTABILITY_AVOIDPLATFORMSPECIFICFUNDAMENTALTYPESCHECK_H
+
+#include "../ClangTidyCheck.h"
+#include "../utils/IncludeInserter.h"
+
+namespace clang::tidy::portability {
+
+/// Find fundamental platform-dependent types and recommend using typedefs or
+/// fixed-width types.
+///
+/// Detects fundamental types (int, short, long, long long, char, float, etc)
+/// and warns against their use due to platform-dependent behavior.
vbvictor wrote:
This description should be the same as in `ReleaseNotes.rst`
https://github.com/llvm/llvm-project/pull/146970
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] Add portability-avoid-platform-specific-fundamental-types (PR #146970)
@@ -0,0 +1,69 @@
+// RUN: %check_clang_tidy -std=c++11-or-later %s
portability-avoid-platform-specific-fundamental-types %t --
-config="{CheckOptions: [{key:
portability-avoid-platform-specific-fundamental-types.WarnOnInts, value:
false}, {key:
portability-avoid-platform-specific-fundamental-types.WarnOnFloats, value:
false}]}"
+
vbvictor wrote:
Look at tests in
`clang-tools-extra/test/clang-tidy/checkers/modernize/replace-auto-ptr.cpp`,
see what cases you have not covered and add them.
Consider also:
```cpp
template
void template_function() {}
template<>
void template_function() {} // Will this fire warning?
```
https://github.com/llvm/llvm-project/pull/146970
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] Add portability-avoid-platform-specific-fundamental-types (PR #146970)
@@ -0,0 +1,69 @@
+// RUN: %check_clang_tidy -std=c++11-or-later %s
portability-avoid-platform-specific-fundamental-types %t --
-config="{CheckOptions: [{key:
portability-avoid-platform-specific-fundamental-types.WarnOnInts, value:
false}, {key:
portability-avoid-platform-specific-fundamental-types.WarnOnFloats, value:
false}]}"
vbvictor wrote:
Split this line into multiple to avoid 200+ characters lines.
https://github.com/llvm/llvm-project/pull/146970
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] Add portability-avoid-platform-specific-fundamental-types (PR #146970)
@@ -0,0 +1,254 @@
+//===--- AvoidPlatformSpecificFundamentalTypesCheck.cpp - clang-tidy
--===//
+//
+// 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 "AvoidPlatformSpecificFundamentalTypesCheck.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/Type.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "clang/ASTMatchers/ASTMatchers.h"
+#include "clang/Basic/TargetInfo.h"
+
+using namespace clang::ast_matchers;
+
+namespace {
+
+static bool isCharType(const clang::BuiltinType *BT) {
+ using clang::BuiltinType;
+ switch (BT->getKind()) {
+ case BuiltinType::Char_S:
+ case BuiltinType::Char_U:
+ case BuiltinType::SChar:
+ case BuiltinType::UChar:
+return true;
+ default:
+return false;
+ }
+}
+
+AST_MATCHER(clang::QualType, isBuiltinInt) {
+ const auto *BT = Node->getAs();
+ if (!BT)
+return false;
+
+ switch (BT->getKind()) {
+ case clang::BuiltinType::Short:
+ case clang::BuiltinType::UShort:
+ case clang::BuiltinType::Int:
+ case clang::BuiltinType::UInt:
+ case clang::BuiltinType::Long:
+ case clang::BuiltinType::ULong:
+ case clang::BuiltinType::LongLong:
+ case clang::BuiltinType::ULongLong:
+return true;
+ default:
+return false;
+ }
+}
+
+AST_MATCHER(clang::QualType, isBuiltinFloat) {
+ const auto *BT = Node->getAs();
+ if (!BT)
+return false;
+
+ switch (BT->getKind()) {
+ case clang::BuiltinType::Half:
+ case clang::BuiltinType::BFloat16:
+ case clang::BuiltinType::Float:
+ case clang::BuiltinType::Double:
+ case clang::BuiltinType::LongDouble:
+return true;
+ default:
+return false;
+ }
+}
+
+AST_MATCHER(clang::QualType, isBuiltinChar) {
+ const auto *BT = Node->getAs();
+ if (!BT)
+return false;
+
+ return isCharType(BT);
+}
+} // namespace
+
+namespace clang::tidy::portability {
+
+AvoidPlatformSpecificFundamentalTypesCheck::
+AvoidPlatformSpecificFundamentalTypesCheck(StringRef Name,
+ ClangTidyContext *Context)
+: ClangTidyCheck(Name, Context),
+ WarnOnFloats(Options.get("WarnOnFloats", true)),
+ WarnOnInts(Options.get("WarnOnInts", true)),
+ WarnOnChars(Options.get("WarnOnChars", true)),
+ IncludeInserter(Options.getLocalOrGlobal("IncludeStyle",
+ utils::IncludeSorter::IS_LLVM),
+ areDiagsSelfContained()) {}
+
+void AvoidPlatformSpecificFundamentalTypesCheck::registerPPCallbacks(
+const SourceManager &SM, Preprocessor *PP, Preprocessor *ModuleExpanderPP)
{
+ IncludeInserter.registerPreprocessor(PP);
+}
+
+void AvoidPlatformSpecificFundamentalTypesCheck::storeOptions(
+ClangTidyOptions::OptionMap &Opts) {
+ Options.store(Opts, "WarnOnFloats", WarnOnFloats);
+ Options.store(Opts, "WarnOnInts", WarnOnInts);
+ Options.store(Opts, "WarnOnChars", WarnOnChars);
+ Options.store(Opts, "IncludeStyle", IncludeInserter.getStyle());
+}
+
+static std::string getFloatReplacement(const BuiltinType *BT,
+ ASTContext &Context) {
+ const TargetInfo &Target = Context.getTargetInfo();
+
+ auto GetReplacementType = [](unsigned Width) {
+switch (Width) {
+// This is ambiguous by default since it could be bfloat16 or float16
+case 16U:
+ return "";
+case 32U:
+ return "float32_t";
+case 64U:
+ return "float64_t";
+case 128U:
+ return "float128_t";
+default:
+ return "";
+}
+ };
+
+ switch (BT->getKind()) {
+ // Not an ambiguous type
+ case BuiltinType::BFloat16:
+return "bfloat16_t";
+ case BuiltinType::Half:
+return GetReplacementType(Target.getHalfWidth());
+ case BuiltinType::Float:
+return GetReplacementType(Target.getFloatWidth());
+ case BuiltinType::Double:
+return GetReplacementType(Target.getDoubleWidth());
+ default:
+return "";
+ }
+}
+
+void AvoidPlatformSpecificFundamentalTypesCheck::registerMatchers(
+MatchFinder *Finder) {
+ auto PlatformSpecificFundamentalType = qualType(
+ allOf(builtinType(),
+anyOf(WarnOnInts ? isBuiltinInt() : unless(anything()),
+ WarnOnFloats ? isBuiltinFloat() : unless(anything()),
+ WarnOnChars ? isBuiltinChar() : unless(anything();
+
+ if (!WarnOnInts && !WarnOnFloats && !WarnOnChars)
+return;
+
+ Finder->addMatcher(
+ varDecl(hasType(PlatformSpecificFundamentalType)).bind("var_decl"),
this);
+
+ Finder->addMatcher(
+ functionDecl(returns(PlatformSpecificFundamentalType)).bind("func_decl"),
+ this);
+
+ Finder->addMatcher(
+ parmVarDecl(hasType(PlatformSpecificFundamentalType)).bind("param_decl"),
+ this);
+
+ Finder->addMatcher(
+ fieldDecl(hasTyp
[clang-tools-extra] [clang-tidy] Add portability-avoid-platform-specific-fundamental-types (PR #146970)
@@ -0,0 +1,254 @@
+//===--- AvoidPlatformSpecificFundamentalTypesCheck.cpp - clang-tidy
--===//
+//
+// 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 "AvoidPlatformSpecificFundamentalTypesCheck.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/Type.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "clang/ASTMatchers/ASTMatchers.h"
+#include "clang/Basic/TargetInfo.h"
+
+using namespace clang::ast_matchers;
+
+namespace {
+
+static bool isCharType(const clang::BuiltinType *BT) {
+ using clang::BuiltinType;
+ switch (BT->getKind()) {
+ case BuiltinType::Char_S:
+ case BuiltinType::Char_U:
+ case BuiltinType::SChar:
+ case BuiltinType::UChar:
+return true;
+ default:
+return false;
+ }
+}
+
+AST_MATCHER(clang::QualType, isBuiltinInt) {
+ const auto *BT = Node->getAs();
+ if (!BT)
+return false;
+
+ switch (BT->getKind()) {
+ case clang::BuiltinType::Short:
+ case clang::BuiltinType::UShort:
+ case clang::BuiltinType::Int:
+ case clang::BuiltinType::UInt:
+ case clang::BuiltinType::Long:
+ case clang::BuiltinType::ULong:
+ case clang::BuiltinType::LongLong:
+ case clang::BuiltinType::ULongLong:
+return true;
+ default:
+return false;
+ }
+}
+
+AST_MATCHER(clang::QualType, isBuiltinFloat) {
+ const auto *BT = Node->getAs();
+ if (!BT)
+return false;
+
+ switch (BT->getKind()) {
+ case clang::BuiltinType::Half:
+ case clang::BuiltinType::BFloat16:
+ case clang::BuiltinType::Float:
+ case clang::BuiltinType::Double:
+ case clang::BuiltinType::LongDouble:
+return true;
+ default:
+return false;
+ }
+}
+
+AST_MATCHER(clang::QualType, isBuiltinChar) {
+ const auto *BT = Node->getAs();
+ if (!BT)
+return false;
+
+ return isCharType(BT);
+}
+} // namespace
+
+namespace clang::tidy::portability {
+
+AvoidPlatformSpecificFundamentalTypesCheck::
+AvoidPlatformSpecificFundamentalTypesCheck(StringRef Name,
+ ClangTidyContext *Context)
+: ClangTidyCheck(Name, Context),
+ WarnOnFloats(Options.get("WarnOnFloats", true)),
+ WarnOnInts(Options.get("WarnOnInts", true)),
+ WarnOnChars(Options.get("WarnOnChars", true)),
+ IncludeInserter(Options.getLocalOrGlobal("IncludeStyle",
+ utils::IncludeSorter::IS_LLVM),
+ areDiagsSelfContained()) {}
+
+void AvoidPlatformSpecificFundamentalTypesCheck::registerPPCallbacks(
+const SourceManager &SM, Preprocessor *PP, Preprocessor *ModuleExpanderPP)
{
+ IncludeInserter.registerPreprocessor(PP);
+}
+
+void AvoidPlatformSpecificFundamentalTypesCheck::storeOptions(
+ClangTidyOptions::OptionMap &Opts) {
+ Options.store(Opts, "WarnOnFloats", WarnOnFloats);
+ Options.store(Opts, "WarnOnInts", WarnOnInts);
+ Options.store(Opts, "WarnOnChars", WarnOnChars);
+ Options.store(Opts, "IncludeStyle", IncludeInserter.getStyle());
+}
+
+static std::string getFloatReplacement(const BuiltinType *BT,
+ ASTContext &Context) {
+ const TargetInfo &Target = Context.getTargetInfo();
+
+ auto GetReplacementType = [](unsigned Width) {
+switch (Width) {
+// This is ambiguous by default since it could be bfloat16 or float16
+case 16U:
+ return "";
+case 32U:
+ return "float32_t";
+case 64U:
+ return "float64_t";
+case 128U:
+ return "float128_t";
+default:
+ return "";
+}
+ };
+
+ switch (BT->getKind()) {
+ // Not an ambiguous type
+ case BuiltinType::BFloat16:
+return "bfloat16_t";
+ case BuiltinType::Half:
+return GetReplacementType(Target.getHalfWidth());
+ case BuiltinType::Float:
+return GetReplacementType(Target.getFloatWidth());
+ case BuiltinType::Double:
+return GetReplacementType(Target.getDoubleWidth());
+ default:
+return "";
+ }
+}
+
+void AvoidPlatformSpecificFundamentalTypesCheck::registerMatchers(
+MatchFinder *Finder) {
+ auto PlatformSpecificFundamentalType = qualType(
+ allOf(builtinType(),
+anyOf(WarnOnInts ? isBuiltinInt() : unless(anything()),
+ WarnOnFloats ? isBuiltinFloat() : unless(anything()),
+ WarnOnChars ? isBuiltinChar() : unless(anything();
+
+ if (!WarnOnInts && !WarnOnFloats && !WarnOnChars)
+return;
+
+ Finder->addMatcher(
+ varDecl(hasType(PlatformSpecificFundamentalType)).bind("var_decl"),
this);
+
+ Finder->addMatcher(
+ functionDecl(returns(PlatformSpecificFundamentalType)).bind("func_decl"),
+ this);
+
+ Finder->addMatcher(
+ parmVarDecl(hasType(PlatformSpecificFundamentalType)).bind("param_decl"),
+ this);
+
+ Finder->addMatcher(
+ fieldDecl(hasTyp
[clang-tools-extra] [clang-tidy] Add portability-avoid-platform-specific-fundamental-types (PR #146970)
@@ -0,0 +1,254 @@
+//===--- AvoidPlatformSpecificFundamentalTypesCheck.cpp - clang-tidy
--===//
+//
+// 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 "AvoidPlatformSpecificFundamentalTypesCheck.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/Type.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "clang/ASTMatchers/ASTMatchers.h"
+#include "clang/Basic/TargetInfo.h"
+
+using namespace clang::ast_matchers;
+
+namespace {
+
+static bool isCharType(const clang::BuiltinType *BT) {
vbvictor wrote:
Place function outside of anon-namespace.
https://github.com/llvm/llvm-project/pull/146970
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] Add portability-avoid-platform-specific-fundamental-types (PR #146970)
@@ -0,0 +1,254 @@
+//===--- AvoidPlatformSpecificFundamentalTypesCheck.cpp - clang-tidy
--===//
+//
+// 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 "AvoidPlatformSpecificFundamentalTypesCheck.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/Type.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "clang/ASTMatchers/ASTMatchers.h"
+#include "clang/Basic/TargetInfo.h"
+
+using namespace clang::ast_matchers;
+
+namespace {
+
+static bool isCharType(const clang::BuiltinType *BT) {
+ using clang::BuiltinType;
+ switch (BT->getKind()) {
+ case BuiltinType::Char_S:
+ case BuiltinType::Char_U:
+ case BuiltinType::SChar:
+ case BuiltinType::UChar:
+return true;
+ default:
+return false;
+ }
+}
+
+AST_MATCHER(clang::QualType, isBuiltinInt) {
+ const auto *BT = Node->getAs();
+ if (!BT)
+return false;
+
+ switch (BT->getKind()) {
+ case clang::BuiltinType::Short:
+ case clang::BuiltinType::UShort:
+ case clang::BuiltinType::Int:
+ case clang::BuiltinType::UInt:
+ case clang::BuiltinType::Long:
+ case clang::BuiltinType::ULong:
+ case clang::BuiltinType::LongLong:
+ case clang::BuiltinType::ULongLong:
+return true;
+ default:
+return false;
+ }
+}
+
+AST_MATCHER(clang::QualType, isBuiltinFloat) {
+ const auto *BT = Node->getAs();
+ if (!BT)
+return false;
+
+ switch (BT->getKind()) {
+ case clang::BuiltinType::Half:
+ case clang::BuiltinType::BFloat16:
+ case clang::BuiltinType::Float:
+ case clang::BuiltinType::Double:
+ case clang::BuiltinType::LongDouble:
+return true;
+ default:
+return false;
+ }
+}
+
+AST_MATCHER(clang::QualType, isBuiltinChar) {
+ const auto *BT = Node->getAs();
+ if (!BT)
+return false;
+
+ return isCharType(BT);
+}
+} // namespace
+
+namespace clang::tidy::portability {
+
+AvoidPlatformSpecificFundamentalTypesCheck::
+AvoidPlatformSpecificFundamentalTypesCheck(StringRef Name,
+ ClangTidyContext *Context)
+: ClangTidyCheck(Name, Context),
+ WarnOnFloats(Options.get("WarnOnFloats", true)),
+ WarnOnInts(Options.get("WarnOnInts", true)),
+ WarnOnChars(Options.get("WarnOnChars", true)),
+ IncludeInserter(Options.getLocalOrGlobal("IncludeStyle",
+ utils::IncludeSorter::IS_LLVM),
+ areDiagsSelfContained()) {}
+
+void AvoidPlatformSpecificFundamentalTypesCheck::registerPPCallbacks(
+const SourceManager &SM, Preprocessor *PP, Preprocessor *ModuleExpanderPP)
{
+ IncludeInserter.registerPreprocessor(PP);
+}
+
+void AvoidPlatformSpecificFundamentalTypesCheck::storeOptions(
+ClangTidyOptions::OptionMap &Opts) {
+ Options.store(Opts, "WarnOnFloats", WarnOnFloats);
+ Options.store(Opts, "WarnOnInts", WarnOnInts);
+ Options.store(Opts, "WarnOnChars", WarnOnChars);
+ Options.store(Opts, "IncludeStyle", IncludeInserter.getStyle());
+}
+
+static std::string getFloatReplacement(const BuiltinType *BT,
+ ASTContext &Context) {
+ const TargetInfo &Target = Context.getTargetInfo();
+
+ auto GetReplacementType = [](unsigned Width) {
+switch (Width) {
+// This is ambiguous by default since it could be bfloat16 or float16
+case 16U:
+ return "";
+case 32U:
+ return "float32_t";
+case 64U:
+ return "float64_t";
+case 128U:
+ return "float128_t";
+default:
+ return "";
+}
+ };
+
+ switch (BT->getKind()) {
+ // Not an ambiguous type
+ case BuiltinType::BFloat16:
+return "bfloat16_t";
+ case BuiltinType::Half:
+return GetReplacementType(Target.getHalfWidth());
+ case BuiltinType::Float:
+return GetReplacementType(Target.getFloatWidth());
+ case BuiltinType::Double:
+return GetReplacementType(Target.getDoubleWidth());
+ default:
+return "";
+ }
+}
+
+void AvoidPlatformSpecificFundamentalTypesCheck::registerMatchers(
+MatchFinder *Finder) {
+ auto PlatformSpecificFundamentalType = qualType(
+ allOf(builtinType(),
+anyOf(WarnOnInts ? isBuiltinInt() : unless(anything()),
+ WarnOnFloats ? isBuiltinFloat() : unless(anything()),
+ WarnOnChars ? isBuiltinChar() : unless(anything();
+
+ if (!WarnOnInts && !WarnOnFloats && !WarnOnChars)
+return;
+
+ Finder->addMatcher(
+ varDecl(hasType(PlatformSpecificFundamentalType)).bind("var_decl"),
this);
+
+ Finder->addMatcher(
+ functionDecl(returns(PlatformSpecificFundamentalType)).bind("func_decl"),
+ this);
+
+ Finder->addMatcher(
+ parmVarDecl(hasType(PlatformSpecificFundamentalType)).bind("param_decl"),
+ this);
+
+ Finder->addMatcher(
+ fieldDecl(hasTyp
[clang-tools-extra] [clang-tidy] Add portability-avoid-platform-specific-fundamental-types (PR #146970)
@@ -0,0 +1,254 @@
+//===--- AvoidPlatformSpecificFundamentalTypesCheck.cpp - clang-tidy
--===//
+//
+// 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 "AvoidPlatformSpecificFundamentalTypesCheck.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/Type.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "clang/ASTMatchers/ASTMatchers.h"
+#include "clang/Basic/TargetInfo.h"
+
+using namespace clang::ast_matchers;
+
+namespace {
+
+static bool isCharType(const clang::BuiltinType *BT) {
+ using clang::BuiltinType;
+ switch (BT->getKind()) {
+ case BuiltinType::Char_S:
+ case BuiltinType::Char_U:
+ case BuiltinType::SChar:
+ case BuiltinType::UChar:
+return true;
+ default:
+return false;
+ }
+}
+
+AST_MATCHER(clang::QualType, isBuiltinInt) {
+ const auto *BT = Node->getAs();
+ if (!BT)
+return false;
+
+ switch (BT->getKind()) {
+ case clang::BuiltinType::Short:
+ case clang::BuiltinType::UShort:
+ case clang::BuiltinType::Int:
+ case clang::BuiltinType::UInt:
+ case clang::BuiltinType::Long:
+ case clang::BuiltinType::ULong:
+ case clang::BuiltinType::LongLong:
+ case clang::BuiltinType::ULongLong:
+return true;
+ default:
+return false;
+ }
+}
+
+AST_MATCHER(clang::QualType, isBuiltinFloat) {
+ const auto *BT = Node->getAs();
+ if (!BT)
+return false;
+
+ switch (BT->getKind()) {
+ case clang::BuiltinType::Half:
+ case clang::BuiltinType::BFloat16:
+ case clang::BuiltinType::Float:
+ case clang::BuiltinType::Double:
+ case clang::BuiltinType::LongDouble:
+return true;
+ default:
+return false;
+ }
+}
+
+AST_MATCHER(clang::QualType, isBuiltinChar) {
+ const auto *BT = Node->getAs();
+ if (!BT)
+return false;
+
+ return isCharType(BT);
+}
+} // namespace
+
+namespace clang::tidy::portability {
+
+AvoidPlatformSpecificFundamentalTypesCheck::
+AvoidPlatformSpecificFundamentalTypesCheck(StringRef Name,
+ ClangTidyContext *Context)
+: ClangTidyCheck(Name, Context),
+ WarnOnFloats(Options.get("WarnOnFloats", true)),
+ WarnOnInts(Options.get("WarnOnInts", true)),
+ WarnOnChars(Options.get("WarnOnChars", true)),
+ IncludeInserter(Options.getLocalOrGlobal("IncludeStyle",
+ utils::IncludeSorter::IS_LLVM),
+ areDiagsSelfContained()) {}
+
+void AvoidPlatformSpecificFundamentalTypesCheck::registerPPCallbacks(
+const SourceManager &SM, Preprocessor *PP, Preprocessor *ModuleExpanderPP)
{
+ IncludeInserter.registerPreprocessor(PP);
+}
+
+void AvoidPlatformSpecificFundamentalTypesCheck::storeOptions(
+ClangTidyOptions::OptionMap &Opts) {
+ Options.store(Opts, "WarnOnFloats", WarnOnFloats);
+ Options.store(Opts, "WarnOnInts", WarnOnInts);
+ Options.store(Opts, "WarnOnChars", WarnOnChars);
+ Options.store(Opts, "IncludeStyle", IncludeInserter.getStyle());
+}
+
+static std::string getFloatReplacement(const BuiltinType *BT,
+ ASTContext &Context) {
+ const TargetInfo &Target = Context.getTargetInfo();
+
+ auto GetReplacementType = [](unsigned Width) {
+switch (Width) {
+// This is ambiguous by default since it could be bfloat16 or float16
+case 16U:
+ return "";
+case 32U:
+ return "float32_t";
+case 64U:
+ return "float64_t";
+case 128U:
+ return "float128_t";
+default:
+ return "";
+}
+ };
+
+ switch (BT->getKind()) {
+ // Not an ambiguous type
+ case BuiltinType::BFloat16:
+return "bfloat16_t";
+ case BuiltinType::Half:
+return GetReplacementType(Target.getHalfWidth());
+ case BuiltinType::Float:
+return GetReplacementType(Target.getFloatWidth());
+ case BuiltinType::Double:
+return GetReplacementType(Target.getDoubleWidth());
+ default:
+return "";
+ }
+}
+
+void AvoidPlatformSpecificFundamentalTypesCheck::registerMatchers(
+MatchFinder *Finder) {
+ auto PlatformSpecificFundamentalType = qualType(
+ allOf(builtinType(),
+anyOf(WarnOnInts ? isBuiltinInt() : unless(anything()),
+ WarnOnFloats ? isBuiltinFloat() : unless(anything()),
+ WarnOnChars ? isBuiltinChar() : unless(anything();
+
+ if (!WarnOnInts && !WarnOnFloats && !WarnOnChars)
+return;
vbvictor wrote:
You should give configuration warning in ctor for this case, see how it is done
in `ConstCorrectnessCheck.cpp`
https://github.com/llvm/llvm-project/pull/146970
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] Add portability-avoid-platform-specific-fundamental-types (PR #146970)
@@ -0,0 +1,260 @@
+//===--- AvoidPlatformSpecificFundamentalTypesCheck.cpp - clang-tidy
--===//
+//
+// 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 "AvoidPlatformSpecificFundamentalTypesCheck.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "clang/ASTMatchers/ASTMatchers.h"
+#include "clang/Basic/TargetInfo.h"
+
+using namespace clang::ast_matchers;
+
+namespace clang::tidy::portability {
+
+AvoidPlatformSpecificFundamentalTypesCheck::
+AvoidPlatformSpecificFundamentalTypesCheck(StringRef Name,
+ ClangTidyContext *Context)
+: ClangTidyCheck(Name, Context),
+ WarnOnFloats(Options.get("WarnOnFloats", true)),
+ WarnOnInts(Options.get("WarnOnInts", true)),
+ WarnOnChars(Options.get("WarnOnChars", true)),
+ IncludeInserter(Options.getLocalOrGlobal("IncludeStyle",
+ utils::IncludeSorter::IS_LLVM),
+ areDiagsSelfContained()) {}
+
+void AvoidPlatformSpecificFundamentalTypesCheck::registerPPCallbacks(
+const SourceManager &SM, Preprocessor *PP, Preprocessor *ModuleExpanderPP)
{
+ IncludeInserter.registerPreprocessor(PP);
+}
+
+void AvoidPlatformSpecificFundamentalTypesCheck::storeOptions(
+ClangTidyOptions::OptionMap &Opts) {
+ Options.store(Opts, "WarnOnFloats", WarnOnFloats);
+ Options.store(Opts, "WarnOnInts", WarnOnInts);
+ Options.store(Opts, "WarnOnChars", WarnOnChars);
+ Options.store(Opts, "IncludeStyle", IncludeInserter.getStyle());
+}
+
+std::string AvoidPlatformSpecificFundamentalTypesCheck::getFloatReplacement(
+const BuiltinType *BT, ASTContext &Context) const {
+ const TargetInfo &Target = Context.getTargetInfo();
+
+ auto GetReplacementType = [](unsigned Width) {
+switch (Width) {
+// This is ambiguous by default since it could be bfloat16 or float16
+case 16U:
+ return "";
+case 32U:
+ return "float32_t";
+case 64U:
+ return "float64_t";
+case 128U:
+ return "float128_t";
+default:
+ return "";
+}
+ };
+
+ switch (BT->getKind()) {
+ // Not an ambiguous type
+ case BuiltinType::BFloat16:
+return "bfloat16_t";
+ case BuiltinType::Half:
+return GetReplacementType(Target.getHalfWidth());
+ case BuiltinType::Float:
+return GetReplacementType(Target.getFloatWidth());
+ case BuiltinType::Double:
+return GetReplacementType(Target.getDoubleWidth());
+ default:
+return "";
+ }
+}
+
+void AvoidPlatformSpecificFundamentalTypesCheck::registerMatchers(
+MatchFinder *Finder) {
+ // Build the list of type strings to match
+ std::vector TypeStrings;
+
+ // Add integer types if the option is enabled
+ if (WarnOnInts) {
+TypeStrings.insert(TypeStrings.end(), {"short",
jj-marr wrote:
> You don't need to worry about `unit32_t` because clang-tidy usually suppress
> warning from system headers unless you explicitly use `--header-filter=*`.
> Usually people don't care what warnings system headers have.
If the warning triggers on `MyLong global_long = 100L; // Warning`, then it
would also trigger when I use `uint32_t global_long = 100U`, no? Assuming it's
triggered on use.
I also don't see the purpose of having this case because there will already be
a warning on `using MyLong = long;` If I want to silence the warning, I'd
rather `NOLINT` it when I define the typedef rather than everywhere I use it.
https://github.com/llvm/llvm-project/pull/146970
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] Add portability-avoid-platform-specific-fundamental-types (PR #146970)
@@ -0,0 +1,227 @@
+.. title:: clang-tidy - portability-avoid-platform-specific-fundamental-types
+
+portability-avoid-platform-specific-fundamental-types
+=
+
+Finds fundamental types (e.g. `int`, `float`) and recommends using typedefs
+or fixed-width types instead to improve portability across different platforms.
+
+This check detects fundamental types (``int``, ``short``, ``long``, ``float``,
+``char`` and their ``unsigned`` or ``signed`` variants) and warns against
their
+use due to non-standard platform-dependent behavior. For example, ``long`` is
+64 bits on Linux but 32 bits on Windows. There is no standard rationale or
+intent for the sizes of these types.
+
+Instead of fundamental types, use fixed-width types such as ``int32_t`` or
+implementation-defined types with standard semantics, e.g. ``int_fast32_t``
for
+the fastest integer type greater than or equal to 32 bits.
+
+Examples
+
+
+.. code-block:: c++
+
+ // Bad: platform-dependent fundamental types
+ int global_int = 42;
+ short global_short = 10;
+ long global_long = 100L;
+ unsigned long global_unsigned_long = 100UL;
+
+ void function_with_int_param(int param) {
+// ...
+ }
+
+ int function_returning_int() {
+return 42;
+ }
+
+ struct MyStruct {
+int member_int;
+long member_long;
+ };
+
+.. code-block:: c++
+
+ // Good: use fixed-width types or typedefs
+ #include
+
+ int32_t global_int32 = 42;
+ int16_t global_int16 = 10;
+ int64_t global_int64 = 100L;
+ uint64_t global_uint64 = 100UL;
+
+ void function_with_int32_param(int32_t param) {
+// ...
+ }
+
+ int32_t function_returning_int32() {
+return 42;
+ }
+
+ struct MyStruct {
+int32_t member_int32;
+int64_t member_int64;
+ };
+
+The check will also warn about typedef declarations that use fundamental types
+as their underlying type:
+
+.. code-block:: c++
+
+ // Bad: typedef using fundamental type
+ typedef long long MyLongType;
+ using MyIntType = int;
+
+.. code-block:: c++
+
+ // Good: use descriptive names or fixed-width types
+ typedef int64_t TimestampType;
+ using CounterType = uint32_t;
+
+Rationale
+-
+
+Fundamental types have platform-dependent sizes and behavior:
+
+- ``int`` is typically 32 bits on modern platforms but is only guaranteed to be
+ 16 bits by the spec
+- ``long int`` is 32 bits on Windows but 64 bits on most Unix systems
+- ``double`` is typically 64-bit IEEE754, but on some microcontrollers without
+ a 64-bit FPU (e.g. certain Arduinos) it can be 32 bits
+- ``char`` is signed on ARM and unsigned on x86
+
+The C++ specification does not define these types beyond their minimum sizes.
+That means they can communicate intent in non-standard ways and are often
+needlessly incompatible. For example, ``int`` was traditionally the word size
+of a given processor in 16-bit and 32-bit computing and was a reasonable
+default for performance. This is no longer true on modern 64-bit computers, but
+the size of ``int`` remains fixed at 32 bits for backwards compatibility with
+code that relied on a 32-bit implementation of ``int``.
+
+If code is explicitly relying on the size of an ``int`` being 32 bits, it is
+better to say so in the typename with ``int32_t``. Otherwise, use an
+appropriate implementation-defined type such as ``fast_int32_t`` or
+``least_int32_t`` that communicates the appropriate time/space tradeoff.
+
+Likewise, ``float`` and ``double`` should be replaced by ``float32_t`` and
+``float64_t`` which are guaranteed to be standard IEEE754 floats for a given
+size.
+
+``char`` should be replaced by ``char8_t`` when used in the representation of
+Unicode text. When used to represent a byte on a given platform, ``std::byte``
+is an appropriate replacement.
+
+Types Not Flagged
+-
+
+The following types are intentionally not flagged:
+
+- ``bool`` (boolean type)
+- Standard library typedefs like ``size_t``, ``ptrdiff_t``, or ``uint32_t``.
+- Already typedef'd types, though the check will flag the typedef itself
+
+``bool`` is excluded because it can only be true or false, and is not
vulnerable to overflow or
+narrowing issues that occur as a result of using implementation-defined types.
+
+Options
+---
+
+.. option:: WarnOnInts
+
+ When `true` (default), the check will warn about fundamental integer types
(``short``, ``int``, ``long``, ``long long`` and their ``signed`` and
``unsigned`` variants).
EugeneZelenko wrote:
Please follow 80 characters limit. Default should be last sentence.
https://github.com/llvm/llvm-project/pull/146970
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] Add portability-avoid-platform-specific-fundamental-types (PR #146970)
@@ -0,0 +1,227 @@
+.. title:: clang-tidy - portability-avoid-platform-specific-fundamental-types
+
+portability-avoid-platform-specific-fundamental-types
+=
+
+Finds fundamental types (e.g. `int`, `float`) and recommends using typedefs
+or fixed-width types instead to improve portability across different platforms.
+
+This check detects fundamental types (``int``, ``short``, ``long``, ``float``,
+``char`` and their ``unsigned`` or ``signed`` variants) and warns against
their
+use due to non-standard platform-dependent behavior. For example, ``long`` is
+64 bits on Linux but 32 bits on Windows. There is no standard rationale or
+intent for the sizes of these types.
+
+Instead of fundamental types, use fixed-width types such as ``int32_t`` or
+implementation-defined types with standard semantics, e.g. ``int_fast32_t``
for
+the fastest integer type greater than or equal to 32 bits.
+
+Examples
+
+
+.. code-block:: c++
+
+ // Bad: platform-dependent fundamental types
+ int global_int = 42;
+ short global_short = 10;
+ long global_long = 100L;
+ unsigned long global_unsigned_long = 100UL;
+
+ void function_with_int_param(int param) {
+// ...
+ }
+
+ int function_returning_int() {
+return 42;
+ }
+
+ struct MyStruct {
+int member_int;
+long member_long;
+ };
+
+.. code-block:: c++
+
+ // Good: use fixed-width types or typedefs
+ #include
+
+ int32_t global_int32 = 42;
+ int16_t global_int16 = 10;
+ int64_t global_int64 = 100L;
+ uint64_t global_uint64 = 100UL;
+
+ void function_with_int32_param(int32_t param) {
+// ...
+ }
+
+ int32_t function_returning_int32() {
+return 42;
+ }
+
+ struct MyStruct {
+int32_t member_int32;
+int64_t member_int64;
+ };
+
+The check will also warn about typedef declarations that use fundamental types
+as their underlying type:
+
+.. code-block:: c++
+
+ // Bad: typedef using fundamental type
+ typedef long long MyLongType;
+ using MyIntType = int;
+
+.. code-block:: c++
+
+ // Good: use descriptive names or fixed-width types
+ typedef int64_t TimestampType;
+ using CounterType = uint32_t;
+
+Rationale
+-
+
+Fundamental types have platform-dependent sizes and behavior:
+
+- ``int`` is typically 32 bits on modern platforms but is only guaranteed to be
+ 16 bits by the spec
+- ``long int`` is 32 bits on Windows but 64 bits on most Unix systems
+- ``double`` is typically 64-bit IEEE754, but on some microcontrollers without
+ a 64-bit FPU (e.g. certain Arduinos) it can be 32 bits
+- ``char`` is signed on ARM and unsigned on x86
+
+The C++ specification does not define these types beyond their minimum sizes.
+That means they can communicate intent in non-standard ways and are often
+needlessly incompatible. For example, ``int`` was traditionally the word size
+of a given processor in 16-bit and 32-bit computing and was a reasonable
+default for performance. This is no longer true on modern 64-bit computers, but
+the size of ``int`` remains fixed at 32 bits for backwards compatibility with
+code that relied on a 32-bit implementation of ``int``.
+
+If code is explicitly relying on the size of an ``int`` being 32 bits, it is
+better to say so in the typename with ``int32_t``. Otherwise, use an
+appropriate implementation-defined type such as ``fast_int32_t`` or
+``least_int32_t`` that communicates the appropriate time/space tradeoff.
+
+Likewise, ``float`` and ``double`` should be replaced by ``float32_t`` and
+``float64_t`` which are guaranteed to be standard IEEE754 floats for a given
+size.
+
+``char`` should be replaced by ``char8_t`` when used in the representation of
+Unicode text. When used to represent a byte on a given platform, ``std::byte``
+is an appropriate replacement.
+
+Types Not Flagged
+-
+
+The following types are intentionally not flagged:
+
+- ``bool`` (boolean type)
+- Standard library typedefs like ``size_t``, ``ptrdiff_t``, or ``uint32_t``.
+- Already typedef'd types, though the check will flag the typedef itself
+
+``bool`` is excluded because it can only be true or false, and is not
vulnerable to overflow or
+narrowing issues that occur as a result of using implementation-defined types.
+
+Options
+---
+
+.. option:: WarnOnInts
+
+ When `true` (default), the check will warn about fundamental integer types
(``short``, ``int``, ``long``, ``long long`` and their ``signed`` and
``unsigned`` variants).
+ When `false`, integer types are not flagged.
+
+ Example with ``WarnOnInts`` enabled (default):
+
+ .. code-block:: c++
+
+ // Bad: platform-dependent integer types
+ #include
+
+ int counter = 0;
+ long timestamp = 12345L;
+ unsigned short port = 8080;
+
+ std::vector vec;
+ // If int is 32 bits and (vec.size > 2^31 - 1), this overflows
+ for(int i = 0; i
+ #include
+
+ int32_t counter = 0; // When you nee
[clang-tools-extra] [clang-tidy] Add portability-avoid-platform-specific-fundamental-types (PR #146970)
@@ -0,0 +1,227 @@
+.. title:: clang-tidy - portability-avoid-platform-specific-fundamental-types
+
+portability-avoid-platform-specific-fundamental-types
+=
+
+Finds fundamental types (e.g. `int`, `float`) and recommends using typedefs
+or fixed-width types instead to improve portability across different platforms.
+
+This check detects fundamental types (``int``, ``short``, ``long``, ``float``,
+``char`` and their ``unsigned`` or ``signed`` variants) and warns against
their
+use due to non-standard platform-dependent behavior. For example, ``long`` is
+64 bits on Linux but 32 bits on Windows. There is no standard rationale or
+intent for the sizes of these types.
+
+Instead of fundamental types, use fixed-width types such as ``int32_t`` or
+implementation-defined types with standard semantics, e.g. ``int_fast32_t``
for
+the fastest integer type greater than or equal to 32 bits.
+
+Examples
+
+
+.. code-block:: c++
+
+ // Bad: platform-dependent fundamental types
+ int global_int = 42;
+ short global_short = 10;
+ long global_long = 100L;
+ unsigned long global_unsigned_long = 100UL;
+
+ void function_with_int_param(int param) {
+// ...
+ }
+
+ int function_returning_int() {
+return 42;
+ }
+
+ struct MyStruct {
+int member_int;
+long member_long;
+ };
+
+.. code-block:: c++
+
+ // Good: use fixed-width types or typedefs
+ #include
+
+ int32_t global_int32 = 42;
+ int16_t global_int16 = 10;
+ int64_t global_int64 = 100L;
+ uint64_t global_uint64 = 100UL;
+
+ void function_with_int32_param(int32_t param) {
+// ...
+ }
+
+ int32_t function_returning_int32() {
+return 42;
+ }
+
+ struct MyStruct {
+int32_t member_int32;
+int64_t member_int64;
+ };
+
+The check will also warn about typedef declarations that use fundamental types
+as their underlying type:
+
+.. code-block:: c++
+
+ // Bad: typedef using fundamental type
+ typedef long long MyLongType;
+ using MyIntType = int;
+
+.. code-block:: c++
+
+ // Good: use descriptive names or fixed-width types
+ typedef int64_t TimestampType;
+ using CounterType = uint32_t;
+
+Rationale
+-
+
+Fundamental types have platform-dependent sizes and behavior:
+
+- ``int`` is typically 32 bits on modern platforms but is only guaranteed to be
+ 16 bits by the spec
+- ``long int`` is 32 bits on Windows but 64 bits on most Unix systems
+- ``double`` is typically 64-bit IEEE754, but on some microcontrollers without
+ a 64-bit FPU (e.g. certain Arduinos) it can be 32 bits
+- ``char`` is signed on ARM and unsigned on x86
+
+The C++ specification does not define these types beyond their minimum sizes.
+That means they can communicate intent in non-standard ways and are often
+needlessly incompatible. For example, ``int`` was traditionally the word size
+of a given processor in 16-bit and 32-bit computing and was a reasonable
+default for performance. This is no longer true on modern 64-bit computers, but
+the size of ``int`` remains fixed at 32 bits for backwards compatibility with
+code that relied on a 32-bit implementation of ``int``.
+
+If code is explicitly relying on the size of an ``int`` being 32 bits, it is
+better to say so in the typename with ``int32_t``. Otherwise, use an
+appropriate implementation-defined type such as ``fast_int32_t`` or
+``least_int32_t`` that communicates the appropriate time/space tradeoff.
+
+Likewise, ``float`` and ``double`` should be replaced by ``float32_t`` and
+``float64_t`` which are guaranteed to be standard IEEE754 floats for a given
+size.
+
+``char`` should be replaced by ``char8_t`` when used in the representation of
+Unicode text. When used to represent a byte on a given platform, ``std::byte``
+is an appropriate replacement.
+
+Types Not Flagged
+-
+
+The following types are intentionally not flagged:
+
+- ``bool`` (boolean type)
+- Standard library typedefs like ``size_t``, ``ptrdiff_t``, or ``uint32_t``.
+- Already typedef'd types, though the check will flag the typedef itself
+
+``bool`` is excluded because it can only be true or false, and is not
vulnerable to overflow or
+narrowing issues that occur as a result of using implementation-defined types.
+
+Options
+---
+
+.. option:: WarnOnInts
+
+ When `true` (default), the check will warn about fundamental integer types
(``short``, ``int``, ``long``, ``long long`` and their ``signed`` and
``unsigned`` variants).
+ When `false`, integer types are not flagged.
+
+ Example with ``WarnOnInts`` enabled (default):
+
+ .. code-block:: c++
+
+ // Bad: platform-dependent integer types
+ #include
+
+ int counter = 0;
+ long timestamp = 12345L;
+ unsigned short port = 8080;
+
+ std::vector vec;
+ // If int is 32 bits and (vec.size > 2^31 - 1), this overflows
+ for(int i = 0; i
+ #include
+
+ int32_t counter = 0; // When you nee
[clang-tools-extra] [clang-tidy] Add portability-avoid-platform-specific-fundamental-types (PR #146970)
@@ -0,0 +1,227 @@
+.. title:: clang-tidy - portability-avoid-platform-specific-fundamental-types
+
+portability-avoid-platform-specific-fundamental-types
+=
+
+Finds fundamental types (e.g. `int`, `float`) and recommends using typedefs
+or fixed-width types instead to improve portability across different platforms.
+
+This check detects fundamental types (``int``, ``short``, ``long``, ``float``,
+``char`` and their ``unsigned`` or ``signed`` variants) and warns against
their
+use due to non-standard platform-dependent behavior. For example, ``long`` is
+64 bits on Linux but 32 bits on Windows. There is no standard rationale or
+intent for the sizes of these types.
+
+Instead of fundamental types, use fixed-width types such as ``int32_t`` or
+implementation-defined types with standard semantics, e.g. ``int_fast32_t``
for
+the fastest integer type greater than or equal to 32 bits.
+
+Examples
+
+
+.. code-block:: c++
+
+ // Bad: platform-dependent fundamental types
+ int global_int = 42;
+ short global_short = 10;
+ long global_long = 100L;
+ unsigned long global_unsigned_long = 100UL;
+
+ void function_with_int_param(int param) {
+// ...
+ }
+
+ int function_returning_int() {
+return 42;
+ }
+
+ struct MyStruct {
+int member_int;
+long member_long;
+ };
+
+.. code-block:: c++
+
+ // Good: use fixed-width types or typedefs
+ #include
+
+ int32_t global_int32 = 42;
+ int16_t global_int16 = 10;
+ int64_t global_int64 = 100L;
+ uint64_t global_uint64 = 100UL;
+
+ void function_with_int32_param(int32_t param) {
+// ...
+ }
+
+ int32_t function_returning_int32() {
+return 42;
+ }
+
+ struct MyStruct {
+int32_t member_int32;
+int64_t member_int64;
+ };
+
+The check will also warn about typedef declarations that use fundamental types
+as their underlying type:
+
+.. code-block:: c++
+
+ // Bad: typedef using fundamental type
+ typedef long long MyLongType;
+ using MyIntType = int;
+
+.. code-block:: c++
+
+ // Good: use descriptive names or fixed-width types
+ typedef int64_t TimestampType;
+ using CounterType = uint32_t;
+
+Rationale
+-
+
+Fundamental types have platform-dependent sizes and behavior:
+
+- ``int`` is typically 32 bits on modern platforms but is only guaranteed to be
+ 16 bits by the spec
+- ``long int`` is 32 bits on Windows but 64 bits on most Unix systems
+- ``double`` is typically 64-bit IEEE754, but on some microcontrollers without
+ a 64-bit FPU (e.g. certain Arduinos) it can be 32 bits
+- ``char`` is signed on ARM and unsigned on x86
+
+The C++ specification does not define these types beyond their minimum sizes.
+That means they can communicate intent in non-standard ways and are often
+needlessly incompatible. For example, ``int`` was traditionally the word size
+of a given processor in 16-bit and 32-bit computing and was a reasonable
+default for performance. This is no longer true on modern 64-bit computers, but
+the size of ``int`` remains fixed at 32 bits for backwards compatibility with
+code that relied on a 32-bit implementation of ``int``.
+
+If code is explicitly relying on the size of an ``int`` being 32 bits, it is
+better to say so in the typename with ``int32_t``. Otherwise, use an
+appropriate implementation-defined type such as ``fast_int32_t`` or
+``least_int32_t`` that communicates the appropriate time/space tradeoff.
+
+Likewise, ``float`` and ``double`` should be replaced by ``float32_t`` and
+``float64_t`` which are guaranteed to be standard IEEE754 floats for a given
+size.
+
+``char`` should be replaced by ``char8_t`` when used in the representation of
+Unicode text. When used to represent a byte on a given platform, ``std::byte``
+is an appropriate replacement.
+
+Types Not Flagged
+-
+
+The following types are intentionally not flagged:
+
+- ``bool`` (boolean type)
+- Standard library typedefs like ``size_t``, ``ptrdiff_t``, or ``uint32_t``.
+- Already typedef'd types, though the check will flag the typedef itself
+
+``bool`` is excluded because it can only be true or false, and is not
vulnerable to overflow or
+narrowing issues that occur as a result of using implementation-defined types.
+
+Options
+---
+
+.. option:: WarnOnInts
+
+ When `true` (default), the check will warn about fundamental integer types
(``short``, ``int``, ``long``, ``long long`` and their ``signed`` and
``unsigned`` variants).
+ When `false`, integer types are not flagged.
+
+ Example with ``WarnOnInts`` enabled (default):
+
+ .. code-block:: c++
+
+ // Bad: platform-dependent integer types
+ #include
+
+ int counter = 0;
+ long timestamp = 12345L;
+ unsigned short port = 8080;
+
+ std::vector vec;
+ // If int is 32 bits and (vec.size > 2^31 - 1), this overflows
+ for(int i = 0; i
+ #include
+
+ int32_t counter = 0; // When you nee
[clang-tools-extra] [clang-tidy] Add portability-avoid-platform-specific-fundamental-types (PR #146970)
@@ -0,0 +1,227 @@
+.. title:: clang-tidy - portability-avoid-platform-specific-fundamental-types
+
+portability-avoid-platform-specific-fundamental-types
+=
+
+Finds fundamental types (e.g. `int`, `float`) and recommends using typedefs
+or fixed-width types instead to improve portability across different platforms.
+
+This check detects fundamental types (``int``, ``short``, ``long``, ``float``,
+``char`` and their ``unsigned`` or ``signed`` variants) and warns against
their
+use due to non-standard platform-dependent behavior. For example, ``long`` is
+64 bits on Linux but 32 bits on Windows. There is no standard rationale or
+intent for the sizes of these types.
+
+Instead of fundamental types, use fixed-width types such as ``int32_t`` or
+implementation-defined types with standard semantics, e.g. ``int_fast32_t``
for
+the fastest integer type greater than or equal to 32 bits.
+
+Examples
+
+
+.. code-block:: c++
+
+ // Bad: platform-dependent fundamental types
+ int global_int = 42;
+ short global_short = 10;
+ long global_long = 100L;
+ unsigned long global_unsigned_long = 100UL;
+
+ void function_with_int_param(int param) {
+// ...
+ }
+
+ int function_returning_int() {
+return 42;
+ }
+
+ struct MyStruct {
+int member_int;
+long member_long;
+ };
+
+.. code-block:: c++
+
+ // Good: use fixed-width types or typedefs
+ #include
+
+ int32_t global_int32 = 42;
+ int16_t global_int16 = 10;
+ int64_t global_int64 = 100L;
+ uint64_t global_uint64 = 100UL;
+
+ void function_with_int32_param(int32_t param) {
+// ...
+ }
+
+ int32_t function_returning_int32() {
+return 42;
+ }
+
+ struct MyStruct {
+int32_t member_int32;
+int64_t member_int64;
+ };
+
+The check will also warn about typedef declarations that use fundamental types
+as their underlying type:
+
+.. code-block:: c++
+
+ // Bad: typedef using fundamental type
+ typedef long long MyLongType;
+ using MyIntType = int;
+
+.. code-block:: c++
+
+ // Good: use descriptive names or fixed-width types
+ typedef int64_t TimestampType;
+ using CounterType = uint32_t;
+
+Rationale
+-
+
+Fundamental types have platform-dependent sizes and behavior:
+
+- ``int`` is typically 32 bits on modern platforms but is only guaranteed to be
+ 16 bits by the spec
+- ``long int`` is 32 bits on Windows but 64 bits on most Unix systems
+- ``double`` is typically 64-bit IEEE754, but on some microcontrollers without
+ a 64-bit FPU (e.g. certain Arduinos) it can be 32 bits
+- ``char`` is signed on ARM and unsigned on x86
+
+The C++ specification does not define these types beyond their minimum sizes.
+That means they can communicate intent in non-standard ways and are often
+needlessly incompatible. For example, ``int`` was traditionally the word size
+of a given processor in 16-bit and 32-bit computing and was a reasonable
+default for performance. This is no longer true on modern 64-bit computers, but
+the size of ``int`` remains fixed at 32 bits for backwards compatibility with
+code that relied on a 32-bit implementation of ``int``.
+
+If code is explicitly relying on the size of an ``int`` being 32 bits, it is
+better to say so in the typename with ``int32_t``. Otherwise, use an
+appropriate implementation-defined type such as ``fast_int32_t`` or
+``least_int32_t`` that communicates the appropriate time/space tradeoff.
+
+Likewise, ``float`` and ``double`` should be replaced by ``float32_t`` and
+``float64_t`` which are guaranteed to be standard IEEE754 floats for a given
+size.
+
+``char`` should be replaced by ``char8_t`` when used in the representation of
+Unicode text. When used to represent a byte on a given platform, ``std::byte``
+is an appropriate replacement.
+
+Types Not Flagged
+-
+
+The following types are intentionally not flagged:
+
+- ``bool`` (boolean type)
+- Standard library typedefs like ``size_t``, ``ptrdiff_t``, or ``uint32_t``.
+- Already typedef'd types, though the check will flag the typedef itself
+
+``bool`` is excluded because it can only be true or false, and is not
vulnerable to overflow or
+narrowing issues that occur as a result of using implementation-defined types.
+
+Options
+---
+
+.. option:: WarnOnInts
+
+ When `true` (default), the check will warn about fundamental integer types
(``short``, ``int``, ``long``, ``long long`` and their ``signed`` and
``unsigned`` variants).
+ When `false`, integer types are not flagged.
+
+ Example with ``WarnOnInts`` enabled (default):
EugeneZelenko wrote:
```suggestion
Example with `WarnOnInts` enabled:
```
https://github.com/llvm/llvm-project/pull/146970
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] Add portability-avoid-platform-specific-fundamental-types (PR #146970)
@@ -0,0 +1,227 @@ +.. title:: clang-tidy - portability-avoid-platform-specific-fundamental-types + +portability-avoid-platform-specific-fundamental-types += + +Finds fundamental types (e.g. `int`, `float`) and recommends using typedefs EugeneZelenko wrote: ```suggestion Finds fundamental types (e.g. ``int``, ``float``) and recommends using typedefs ``` https://github.com/llvm/llvm-project/pull/146970 ___ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] Add portability-avoid-platform-specific-fundamental-types (PR #146970)
@@ -0,0 +1,227 @@
+.. title:: clang-tidy - portability-avoid-platform-specific-fundamental-types
+
+portability-avoid-platform-specific-fundamental-types
+=
+
+Finds fundamental types (e.g. `int`, `float`) and recommends using typedefs
+or fixed-width types instead to improve portability across different platforms.
+
+This check detects fundamental types (``int``, ``short``, ``long``, ``float``,
+``char`` and their ``unsigned`` or ``signed`` variants) and warns against
their
+use due to non-standard platform-dependent behavior. For example, ``long`` is
+64 bits on Linux but 32 bits on Windows. There is no standard rationale or
+intent for the sizes of these types.
+
+Instead of fundamental types, use fixed-width types such as ``int32_t`` or
+implementation-defined types with standard semantics, e.g. ``int_fast32_t``
for
+the fastest integer type greater than or equal to 32 bits.
+
+Examples
+
+
+.. code-block:: c++
+
+ // Bad: platform-dependent fundamental types
+ int global_int = 42;
+ short global_short = 10;
+ long global_long = 100L;
+ unsigned long global_unsigned_long = 100UL;
+
+ void function_with_int_param(int param) {
+// ...
+ }
+
+ int function_returning_int() {
+return 42;
+ }
+
+ struct MyStruct {
+int member_int;
+long member_long;
+ };
+
+.. code-block:: c++
+
+ // Good: use fixed-width types or typedefs
+ #include
+
+ int32_t global_int32 = 42;
+ int16_t global_int16 = 10;
+ int64_t global_int64 = 100L;
+ uint64_t global_uint64 = 100UL;
+
+ void function_with_int32_param(int32_t param) {
+// ...
+ }
+
+ int32_t function_returning_int32() {
+return 42;
+ }
+
+ struct MyStruct {
+int32_t member_int32;
+int64_t member_int64;
+ };
+
+The check will also warn about typedef declarations that use fundamental types
+as their underlying type:
+
+.. code-block:: c++
+
+ // Bad: typedef using fundamental type
+ typedef long long MyLongType;
+ using MyIntType = int;
+
+.. code-block:: c++
+
+ // Good: use descriptive names or fixed-width types
+ typedef int64_t TimestampType;
+ using CounterType = uint32_t;
+
+Rationale
+-
+
+Fundamental types have platform-dependent sizes and behavior:
+
+- ``int`` is typically 32 bits on modern platforms but is only guaranteed to be
+ 16 bits by the spec
+- ``long int`` is 32 bits on Windows but 64 bits on most Unix systems
+- ``double`` is typically 64-bit IEEE754, but on some microcontrollers without
+ a 64-bit FPU (e.g. certain Arduinos) it can be 32 bits
+- ``char`` is signed on ARM and unsigned on x86
+
+The C++ specification does not define these types beyond their minimum sizes.
+That means they can communicate intent in non-standard ways and are often
+needlessly incompatible. For example, ``int`` was traditionally the word size
+of a given processor in 16-bit and 32-bit computing and was a reasonable
+default for performance. This is no longer true on modern 64-bit computers, but
+the size of ``int`` remains fixed at 32 bits for backwards compatibility with
+code that relied on a 32-bit implementation of ``int``.
+
+If code is explicitly relying on the size of an ``int`` being 32 bits, it is
+better to say so in the typename with ``int32_t``. Otherwise, use an
+appropriate implementation-defined type such as ``fast_int32_t`` or
+``least_int32_t`` that communicates the appropriate time/space tradeoff.
+
+Likewise, ``float`` and ``double`` should be replaced by ``float32_t`` and
+``float64_t`` which are guaranteed to be standard IEEE754 floats for a given
+size.
+
+``char`` should be replaced by ``char8_t`` when used in the representation of
+Unicode text. When used to represent a byte on a given platform, ``std::byte``
+is an appropriate replacement.
+
+Types Not Flagged
+-
+
+The following types are intentionally not flagged:
+
+- ``bool`` (boolean type)
+- Standard library typedefs like ``size_t``, ``ptrdiff_t``, or ``uint32_t``.
+- Already typedef'd types, though the check will flag the typedef itself
+
+``bool`` is excluded because it can only be true or false, and is not
vulnerable to overflow or
+narrowing issues that occur as a result of using implementation-defined types.
+
+Options
+---
+
+.. option:: WarnOnInts
+
+ When `true` (default), the check will warn about fundamental integer types
(``short``, ``int``, ``long``, ``long long`` and their ``signed`` and
``unsigned`` variants).
+ When `false`, integer types are not flagged.
+
+ Example with ``WarnOnInts`` enabled (default):
+
+ .. code-block:: c++
+
+ // Bad: platform-dependent integer types
+ #include
+
+ int counter = 0;
+ long timestamp = 12345L;
+ unsigned short port = 8080;
+
+ std::vector vec;
+ // If int is 32 bits and (vec.size > 2^31 - 1), this overflows
+ for(int i = 0; i
+ #include
+
+ int32_t counter = 0; // When you nee
[clang-tools-extra] [clang-tidy] Add portability-avoid-platform-specific-fundamental-types (PR #146970)
@@ -148,6 +148,13 @@ New checks Finds uses of ``std::lock_guard`` and suggests replacing them with C++17's alternative ``std::scoped_lock``. +- New :doc:`portability-avoid-platform-specific-fundamental-types + ` + check. + + Finds fundamental types (e.g. `int`, `float`) and recommends using typedefs EugeneZelenko wrote: ```suggestion Finds fundamental types (e.g. ``int``, ``float``) and recommends using typedefs ``` https://github.com/llvm/llvm-project/pull/146970 ___ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] Add portability-avoid-platform-specific-fundamental-types (PR #146970)
vbvictor wrote: > > Please remove unnecessary comments that tell the same as code itself, > > speaking mostly about comments in `registerMatchers`. They mostly don't > > give any more information that matchers themselves. > > To be honest, this is because I coded 98% of this with AI (except for the > `.rst` documentation text which I mostly wrote myself). I am still getting > used to stripping out useless comments and also how `llvm`/compilers in > general work. In my experience, AI generally simplify things and try to compare types as "raw string" and match patters like text, not AST. To counter it, I'd always guide it to look at other checks and AST-dump to understand context. https://github.com/llvm/llvm-project/pull/146970 ___ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] Add portability-avoid-platform-specific-fundamental-types (PR #146970)
@@ -0,0 +1,260 @@
+//===--- AvoidPlatformSpecificFundamentalTypesCheck.cpp - clang-tidy
--===//
+//
+// 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 "AvoidPlatformSpecificFundamentalTypesCheck.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "clang/ASTMatchers/ASTMatchers.h"
+#include "clang/Basic/TargetInfo.h"
+
+using namespace clang::ast_matchers;
+
+namespace clang::tidy::portability {
+
+AvoidPlatformSpecificFundamentalTypesCheck::
+AvoidPlatformSpecificFundamentalTypesCheck(StringRef Name,
+ ClangTidyContext *Context)
+: ClangTidyCheck(Name, Context),
+ WarnOnFloats(Options.get("WarnOnFloats", true)),
+ WarnOnInts(Options.get("WarnOnInts", true)),
+ WarnOnChars(Options.get("WarnOnChars", true)),
+ IncludeInserter(Options.getLocalOrGlobal("IncludeStyle",
+ utils::IncludeSorter::IS_LLVM),
+ areDiagsSelfContained()) {}
+
+void AvoidPlatformSpecificFundamentalTypesCheck::registerPPCallbacks(
+const SourceManager &SM, Preprocessor *PP, Preprocessor *ModuleExpanderPP)
{
+ IncludeInserter.registerPreprocessor(PP);
+}
+
+void AvoidPlatformSpecificFundamentalTypesCheck::storeOptions(
+ClangTidyOptions::OptionMap &Opts) {
+ Options.store(Opts, "WarnOnFloats", WarnOnFloats);
+ Options.store(Opts, "WarnOnInts", WarnOnInts);
+ Options.store(Opts, "WarnOnChars", WarnOnChars);
+ Options.store(Opts, "IncludeStyle", IncludeInserter.getStyle());
+}
+
+std::string AvoidPlatformSpecificFundamentalTypesCheck::getFloatReplacement(
+const BuiltinType *BT, ASTContext &Context) const {
+ const TargetInfo &Target = Context.getTargetInfo();
+
+ auto GetReplacementType = [](unsigned Width) {
+switch (Width) {
+// This is ambiguous by default since it could be bfloat16 or float16
+case 16U:
+ return "";
+case 32U:
+ return "float32_t";
+case 64U:
+ return "float64_t";
+case 128U:
+ return "float128_t";
+default:
+ return "";
+}
+ };
+
+ switch (BT->getKind()) {
+ // Not an ambiguous type
+ case BuiltinType::BFloat16:
+return "bfloat16_t";
+ case BuiltinType::Half:
+return GetReplacementType(Target.getHalfWidth());
+ case BuiltinType::Float:
+return GetReplacementType(Target.getFloatWidth());
+ case BuiltinType::Double:
+return GetReplacementType(Target.getDoubleWidth());
+ default:
+return "";
+ }
+}
+
+void AvoidPlatformSpecificFundamentalTypesCheck::registerMatchers(
+MatchFinder *Finder) {
+ // Build the list of type strings to match
+ std::vector TypeStrings;
+
+ // Add integer types if the option is enabled
+ if (WarnOnInts) {
+TypeStrings.insert(TypeStrings.end(), {"short",
vbvictor wrote:
For `typedef`'s you would check underlying type with this type-matcher.
Also, You'll need to check for unqualified desugared types if you want to
detect this case:
```cpp
using MyLong = long;
MyLong global_long = 100L; // Warning
```
Or you deliberately want to omit this case?
https://github.com/llvm/llvm-project/pull/146970
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] Add portability-avoid-platform-specific-fundamental-types (PR #146970)
jj-marr wrote: > Please remove unnecessary comments that tell the same as code itself, > speaking mostly about comments in `registerMatchers`. They mostly don't give > any more information that matchers themselves. To be honest, this is because I coded 98% of this with AI (except for the `.rst` documentation text which I mostly wrote myself). I am still getting used to stripping out useless comments and also how `llvm`/compilers in general work. https://github.com/llvm/llvm-project/pull/146970 ___ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] Add portability-avoid-platform-specific-fundamental-types (PR #146970)
@@ -0,0 +1,260 @@
+//===--- AvoidPlatformSpecificFundamentalTypesCheck.cpp - clang-tidy
--===//
+//
+// 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 "AvoidPlatformSpecificFundamentalTypesCheck.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "clang/ASTMatchers/ASTMatchers.h"
+#include "clang/Basic/TargetInfo.h"
+
+using namespace clang::ast_matchers;
+
+namespace clang::tidy::portability {
+
+AvoidPlatformSpecificFundamentalTypesCheck::
+AvoidPlatformSpecificFundamentalTypesCheck(StringRef Name,
+ ClangTidyContext *Context)
+: ClangTidyCheck(Name, Context),
+ WarnOnFloats(Options.get("WarnOnFloats", true)),
+ WarnOnInts(Options.get("WarnOnInts", true)),
+ WarnOnChars(Options.get("WarnOnChars", true)),
+ IncludeInserter(Options.getLocalOrGlobal("IncludeStyle",
+ utils::IncludeSorter::IS_LLVM),
+ areDiagsSelfContained()) {}
+
+void AvoidPlatformSpecificFundamentalTypesCheck::registerPPCallbacks(
+const SourceManager &SM, Preprocessor *PP, Preprocessor *ModuleExpanderPP)
{
+ IncludeInserter.registerPreprocessor(PP);
+}
+
+void AvoidPlatformSpecificFundamentalTypesCheck::storeOptions(
+ClangTidyOptions::OptionMap &Opts) {
+ Options.store(Opts, "WarnOnFloats", WarnOnFloats);
+ Options.store(Opts, "WarnOnInts", WarnOnInts);
+ Options.store(Opts, "WarnOnChars", WarnOnChars);
+ Options.store(Opts, "IncludeStyle", IncludeInserter.getStyle());
+}
+
+std::string AvoidPlatformSpecificFundamentalTypesCheck::getFloatReplacement(
+const BuiltinType *BT, ASTContext &Context) const {
+ const TargetInfo &Target = Context.getTargetInfo();
+
+ auto GetReplacementType = [](unsigned Width) {
+switch (Width) {
+// This is ambiguous by default since it could be bfloat16 or float16
+case 16U:
+ return "";
+case 32U:
+ return "float32_t";
+case 64U:
+ return "float64_t";
+case 128U:
+ return "float128_t";
+default:
+ return "";
+}
+ };
+
+ switch (BT->getKind()) {
+ // Not an ambiguous type
+ case BuiltinType::BFloat16:
+return "bfloat16_t";
+ case BuiltinType::Half:
+return GetReplacementType(Target.getHalfWidth());
+ case BuiltinType::Float:
+return GetReplacementType(Target.getFloatWidth());
+ case BuiltinType::Double:
+return GetReplacementType(Target.getDoubleWidth());
+ default:
+return "";
+ }
+}
+
+void AvoidPlatformSpecificFundamentalTypesCheck::registerMatchers(
+MatchFinder *Finder) {
+ // Build the list of type strings to match
+ std::vector TypeStrings;
+
+ // Add integer types if the option is enabled
+ if (WarnOnInts) {
+TypeStrings.insert(TypeStrings.end(), {"short",
jj-marr wrote:
This makes more sense. I was thinking I couldn't check the type itself because
`typedef`s don't create a new type, but if it works for the Google check I
suppose it'll work for this one.
https://github.com/llvm/llvm-project/pull/146970
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] Add portability-avoid-platform-specific-fundamental-types (PR #146970)
https://github.com/vbvictor edited https://github.com/llvm/llvm-project/pull/146970 ___ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] Add portability-avoid-platform-specific-fundamental-types (PR #146970)
@@ -0,0 +1,52 @@
+//==-- AvoidPlatformSpecificFundamentalTypesCheck.h - clang-tidy -*- C++
-*-==//
+//
+// 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_PORTABILITY_AVOIDPLATFORMSPECIFICFUNDAMENTALTYPESCHECK_H
+#define
LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_PORTABILITY_AVOIDPLATFORMSPECIFICFUNDAMENTALTYPESCHECK_H
+
+#include "../ClangTidyCheck.h"
+#include "../utils/IncludeInserter.h"
+
+namespace clang::tidy::portability {
+
+/// Find fundamental platform-dependent types and recommend using typedefs or
+/// fixed-width types.
+///
+/// Detects fundamental types (int, short, long, long long, char, float, etc)
+/// and warns against their use due to platform-dependent behavior.
+///
+/// For the user-facing documentation see:
+///
http://clang.llvm.org/extra/clang-tidy/checks/portability/avoid-platform-specific-fundamental-types.html
+class AvoidPlatformSpecificFundamentalTypesCheck : public ClangTidyCheck {
+public:
+ AvoidPlatformSpecificFundamentalTypesCheck(StringRef Name,
+ ClangTidyContext *Context);
+ void registerPPCallbacks(const SourceManager &SM, Preprocessor *PP,
+ Preprocessor *ModuleExpanderPP) override;
+ void registerMatchers(ast_matchers::MatchFinder *Finder) override;
+ void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
+ void storeOptions(ClangTidyOptions::OptionMap &Opts) override;
+ bool isLanguageVersionSupported(const LangOptions &LangOpts) const override {
+return LangOpts.CPlusPlus11;
+ }
+ std::optional getCheckTraversalKind() const override {
+return TK_IgnoreUnlessSpelledInSource;
+ }
+
+private:
+ const bool WarnOnFloats;
+ const bool WarnOnInts;
+ const bool WarnOnChars;
+ utils::IncludeInserter IncludeInserter;
+ std::string getFloatReplacement(const BuiltinType *BT,
+ ASTContext &Context) const;
vbvictor wrote:
For checkers directory, I think we could have a more strict `clang-tidy` config
with `mist-const-correctness` and
`readability-convert-member-functions-to-static` enabled. I'm planning to make
an RFC for it.
https://github.com/llvm/llvm-project/pull/146970
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] Add portability-avoid-platform-specific-fundamental-types (PR #146970)
@@ -0,0 +1,52 @@
+//==-- AvoidPlatformSpecificFundamentalTypesCheck.h - clang-tidy -*- C++
-*-==//
+//
+// 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_PORTABILITY_AVOIDPLATFORMSPECIFICFUNDAMENTALTYPESCHECK_H
+#define
LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_PORTABILITY_AVOIDPLATFORMSPECIFICFUNDAMENTALTYPESCHECK_H
+
+#include "../ClangTidyCheck.h"
+#include "../utils/IncludeInserter.h"
+
+namespace clang::tidy::portability {
+
+/// Find fundamental platform-dependent types and recommend using typedefs or
+/// fixed-width types.
+///
+/// Detects fundamental types (int, short, long, long long, char, float, etc)
+/// and warns against their use due to platform-dependent behavior.
+///
+/// For the user-facing documentation see:
+///
http://clang.llvm.org/extra/clang-tidy/checks/portability/avoid-platform-specific-fundamental-types.html
+class AvoidPlatformSpecificFundamentalTypesCheck : public ClangTidyCheck {
+public:
+ AvoidPlatformSpecificFundamentalTypesCheck(StringRef Name,
+ ClangTidyContext *Context);
+ void registerPPCallbacks(const SourceManager &SM, Preprocessor *PP,
+ Preprocessor *ModuleExpanderPP) override;
+ void registerMatchers(ast_matchers::MatchFinder *Finder) override;
+ void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
+ void storeOptions(ClangTidyOptions::OptionMap &Opts) override;
+ bool isLanguageVersionSupported(const LangOptions &LangOpts) const override {
+return LangOpts.CPlusPlus11;
+ }
+ std::optional getCheckTraversalKind() const override {
+return TK_IgnoreUnlessSpelledInSource;
+ }
+
+private:
+ const bool WarnOnFloats;
+ const bool WarnOnInts;
+ const bool WarnOnChars;
+ utils::IncludeInserter IncludeInserter;
+ std::string getFloatReplacement(const BuiltinType *BT,
+ ASTContext &Context) const;
jj-marr wrote:
I'm used to having linters flag this (along with missed `const` declarations).
https://github.com/llvm/llvm-project/pull/146970
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] Add portability-avoid-platform-specific-fundamental-types (PR #146970)
https://github.com/vbvictor edited https://github.com/llvm/llvm-project/pull/146970 ___ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] Add portability-avoid-platform-specific-fundamental-types (PR #146970)
@@ -0,0 +1,147 @@
+// RUN: %check_clang_tidy %s
portability-avoid-platform-specific-fundamental-types %t --
-config="{CheckOptions: [{key:
portability-avoid-platform-specific-fundamental-types.WarnOnChars, value:
false}, {key:
portability-avoid-platform-specific-fundamental-types.WarnOnFloats, value:
false}]}" -header-filter=.* -- -std=c++11
vbvictor wrote:
```suggestion
// RUN: %check_clang_tidy -std=c++11-or-later %s
portability-avoid-platform-specific-fundamental-types %t --
-config="{CheckOptions: [{key:
portability-avoid-platform-specific-fundamental-types.WarnOnChars, value:
false}, {key:
portability-avoid-platform-specific-fundamental-types.WarnOnFloats, value:
false}]}" -header-filter=.*
```
https://github.com/llvm/llvm-project/pull/146970
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] Add portability-avoid-platform-specific-fundamental-types (PR #146970)
@@ -0,0 +1,121 @@ +//===--- AvoidPlatformSpecificFundamentalTypesCheck.cpp - clang-tidy +//---===// +// +// 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 "AvoidPlatformSpecificFundamentalTypesCheck.h" +#include "clang/AST/ASTContext.h" vbvictor wrote: Probably unused include ```suggestion ``` https://github.com/llvm/llvm-project/pull/146970 ___ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] Add portability-avoid-platform-specific-fundamental-types (PR #146970)
@@ -0,0 +1,260 @@
+//===--- AvoidPlatformSpecificFundamentalTypesCheck.cpp - clang-tidy
--===//
+//
+// 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 "AvoidPlatformSpecificFundamentalTypesCheck.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "clang/ASTMatchers/ASTMatchers.h"
+#include "clang/Basic/TargetInfo.h"
+
+using namespace clang::ast_matchers;
+
+namespace clang::tidy::portability {
+
+AvoidPlatformSpecificFundamentalTypesCheck::
+AvoidPlatformSpecificFundamentalTypesCheck(StringRef Name,
+ ClangTidyContext *Context)
+: ClangTidyCheck(Name, Context),
+ WarnOnFloats(Options.get("WarnOnFloats", true)),
+ WarnOnInts(Options.get("WarnOnInts", true)),
+ WarnOnChars(Options.get("WarnOnChars", true)),
+ IncludeInserter(Options.getLocalOrGlobal("IncludeStyle",
+ utils::IncludeSorter::IS_LLVM),
+ areDiagsSelfContained()) {}
+
+void AvoidPlatformSpecificFundamentalTypesCheck::registerPPCallbacks(
+const SourceManager &SM, Preprocessor *PP, Preprocessor *ModuleExpanderPP)
{
+ IncludeInserter.registerPreprocessor(PP);
+}
+
+void AvoidPlatformSpecificFundamentalTypesCheck::storeOptions(
+ClangTidyOptions::OptionMap &Opts) {
+ Options.store(Opts, "WarnOnFloats", WarnOnFloats);
+ Options.store(Opts, "WarnOnInts", WarnOnInts);
+ Options.store(Opts, "WarnOnChars", WarnOnChars);
+ Options.store(Opts, "IncludeStyle", IncludeInserter.getStyle());
+}
+
+std::string AvoidPlatformSpecificFundamentalTypesCheck::getFloatReplacement(
+const BuiltinType *BT, ASTContext &Context) const {
+ const TargetInfo &Target = Context.getTargetInfo();
+
+ auto GetReplacementType = [](unsigned Width) {
+switch (Width) {
+// This is ambiguous by default since it could be bfloat16 or float16
+case 16U:
+ return "";
+case 32U:
+ return "float32_t";
+case 64U:
+ return "float64_t";
+case 128U:
+ return "float128_t";
+default:
+ return "";
+}
+ };
+
+ switch (BT->getKind()) {
+ // Not an ambiguous type
+ case BuiltinType::BFloat16:
+return "bfloat16_t";
+ case BuiltinType::Half:
+return GetReplacementType(Target.getHalfWidth());
+ case BuiltinType::Float:
+return GetReplacementType(Target.getFloatWidth());
+ case BuiltinType::Double:
+return GetReplacementType(Target.getDoubleWidth());
+ default:
+return "";
+ }
+}
+
+void AvoidPlatformSpecificFundamentalTypesCheck::registerMatchers(
+MatchFinder *Finder) {
+ // Build the list of type strings to match
+ std::vector TypeStrings;
+
+ // Add integer types if the option is enabled
+ if (WarnOnInts) {
+TypeStrings.insert(TypeStrings.end(), {"short",
vbvictor wrote:
The approach with type-names seems bloated and error-prone IMO, could we reuse
some logic from `IntegerTypesCheck.cpp`? This one:
```cpp
switch (BuiltinLoc.getTypePtr()->getKind()) {
case BuiltinType::Short:
case BuiltinType::Long:
case BuiltinType::LongLong:
case BuiltinType::UShort:
case BuiltinType::ULong:
case BuiltinType::ULongLong:
return true;
default:
return false;
}
```
https://github.com/llvm/llvm-project/pull/146970
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] Add portability-avoid-platform-specific-fundamental-types (PR #146970)
https://github.com/vbvictor commented: Please remove unnecessary comments that tell the same as code itself, speaking mostly about `registerMatchers`. https://github.com/llvm/llvm-project/pull/146970 ___ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] Add portability-avoid-platform-specific-fundamental-types (PR #146970)
@@ -0,0 +1,52 @@
+//==-- AvoidPlatformSpecificFundamentalTypesCheck.h - clang-tidy -*- C++
-*-==//
+//
+// 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_PORTABILITY_AVOIDPLATFORMSPECIFICFUNDAMENTALTYPESCHECK_H
+#define
LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_PORTABILITY_AVOIDPLATFORMSPECIFICFUNDAMENTALTYPESCHECK_H
+
+#include "../ClangTidyCheck.h"
+#include "../utils/IncludeInserter.h"
+
+namespace clang::tidy::portability {
+
+/// Find fundamental platform-dependent types and recommend using typedefs or
+/// fixed-width types.
+///
+/// Detects fundamental types (int, short, long, long long, char, float, etc)
+/// and warns against their use due to platform-dependent behavior.
+///
+/// For the user-facing documentation see:
+///
http://clang.llvm.org/extra/clang-tidy/checks/portability/avoid-platform-specific-fundamental-types.html
+class AvoidPlatformSpecificFundamentalTypesCheck : public ClangTidyCheck {
+public:
+ AvoidPlatformSpecificFundamentalTypesCheck(StringRef Name,
+ ClangTidyContext *Context);
+ void registerPPCallbacks(const SourceManager &SM, Preprocessor *PP,
+ Preprocessor *ModuleExpanderPP) override;
+ void registerMatchers(ast_matchers::MatchFinder *Finder) override;
+ void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
+ void storeOptions(ClangTidyOptions::OptionMap &Opts) override;
+ bool isLanguageVersionSupported(const LangOptions &LangOpts) const override {
+return LangOpts.CPlusPlus11;
+ }
+ std::optional getCheckTraversalKind() const override {
+return TK_IgnoreUnlessSpelledInSource;
+ }
+
+private:
+ const bool WarnOnFloats;
+ const bool WarnOnInts;
+ const bool WarnOnChars;
+ utils::IncludeInserter IncludeInserter;
+ std::string getFloatReplacement(const BuiltinType *BT,
+ ASTContext &Context) const;
vbvictor wrote:
If function doesn't need check fields move it to .cpp with `static`
https://github.com/llvm/llvm-project/pull/146970
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] Add portability-avoid-platform-specific-fundamental-types (PR #146970)
@@ -0,0 +1,260 @@
+//===--- AvoidPlatformSpecificFundamentalTypesCheck.cpp - clang-tidy
--===//
+//
+// 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 "AvoidPlatformSpecificFundamentalTypesCheck.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "clang/ASTMatchers/ASTMatchers.h"
+#include "clang/Basic/TargetInfo.h"
+
+using namespace clang::ast_matchers;
+
+namespace clang::tidy::portability {
+
+AvoidPlatformSpecificFundamentalTypesCheck::
+AvoidPlatformSpecificFundamentalTypesCheck(StringRef Name,
+ ClangTidyContext *Context)
+: ClangTidyCheck(Name, Context),
+ WarnOnFloats(Options.get("WarnOnFloats", true)),
+ WarnOnInts(Options.get("WarnOnInts", true)),
+ WarnOnChars(Options.get("WarnOnChars", true)),
+ IncludeInserter(Options.getLocalOrGlobal("IncludeStyle",
+ utils::IncludeSorter::IS_LLVM),
+ areDiagsSelfContained()) {}
+
+void AvoidPlatformSpecificFundamentalTypesCheck::registerPPCallbacks(
+const SourceManager &SM, Preprocessor *PP, Preprocessor *ModuleExpanderPP)
{
+ IncludeInserter.registerPreprocessor(PP);
+}
+
+void AvoidPlatformSpecificFundamentalTypesCheck::storeOptions(
+ClangTidyOptions::OptionMap &Opts) {
+ Options.store(Opts, "WarnOnFloats", WarnOnFloats);
+ Options.store(Opts, "WarnOnInts", WarnOnInts);
+ Options.store(Opts, "WarnOnChars", WarnOnChars);
+ Options.store(Opts, "IncludeStyle", IncludeInserter.getStyle());
+}
+
+std::string AvoidPlatformSpecificFundamentalTypesCheck::getFloatReplacement(
+const BuiltinType *BT, ASTContext &Context) const {
+ const TargetInfo &Target = Context.getTargetInfo();
+
+ auto GetReplacementType = [](unsigned Width) {
+switch (Width) {
+// This is ambiguous by default since it could be bfloat16 or float16
+case 16U:
+ return "";
+case 32U:
+ return "float32_t";
+case 64U:
+ return "float64_t";
+case 128U:
+ return "float128_t";
+default:
+ return "";
+}
+ };
+
+ switch (BT->getKind()) {
+ // Not an ambiguous type
+ case BuiltinType::BFloat16:
+return "bfloat16_t";
+ case BuiltinType::Half:
+return GetReplacementType(Target.getHalfWidth());
+ case BuiltinType::Float:
+return GetReplacementType(Target.getFloatWidth());
+ case BuiltinType::Double:
+return GetReplacementType(Target.getDoubleWidth());
+ default:
+return "";
+ }
+}
+
+void AvoidPlatformSpecificFundamentalTypesCheck::registerMatchers(
+MatchFinder *Finder) {
+ // Build the list of type strings to match
+ std::vector TypeStrings;
+
+ // Add integer types if the option is enabled
+ if (WarnOnInts) {
+TypeStrings.insert(TypeStrings.end(), {"short",
+ "short int",
+ "signed short",
+ "signed short int",
+ "unsigned short",
+ "unsigned short int",
+ "int",
+ "signed",
+ "signed int",
+ "unsigned",
+ "unsigned int",
+ "long",
+ "long int",
+ "signed long",
+ "signed long int",
+ "unsigned long",
+ "unsigned long int",
+ "long long",
+ "long long int",
+ "signed long long",
+ "signed long long int",
+ "unsigned long long",
+ "unsigned long long int"});
+ }
+
+ // Add float types if the option is enabled
+ if (WarnOnFloats) {
+TypeStrings.insert(TypeStrings.end(),
+ {"half", "__bf16", "float", "double", "long double"});
+ }
+
+ // Add char types if the option is enabled
+ if (WarnOnChars) {
+TypeStrings.insert(TypeStrings.end(),
+ {"char", "signed char", "unsigned char"});
+ }
+
+ // If no types are enabled, return early
+ if (TypeStrings.empty()) {
+return;
+ }
vbvictor wrote:
```suggestion
if (TypeStrings.empty())
return;
```
https://l
[clang-tools-extra] [clang-tidy] Add portability-avoid-platform-specific-fundamental-types (PR #146970)
https://github.com/vbvictor edited https://github.com/llvm/llvm-project/pull/146970 ___ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] Add portability-avoid-platform-specific-fundamental-types (PR #146970)
@@ -0,0 +1,104 @@
+// RUN: %check_clang_tidy %s
portability-avoid-platform-specific-fundamental-types %t --
-config="{CheckOptions: [{key:
portability-avoid-platform-specific-fundamental-types.WarnOnInts, value:
false}, {key:
portability-avoid-platform-specific-fundamental-types.WarnOnChars, value:
false}]}" -header-filter=.* -- -std=c++23
vbvictor wrote:
```suggestion
// RUN: %check_clang_tidy -std=c++23-or-later %s
portability-avoid-platform-specific-fundamental-types %t --
-config="{CheckOptions: [{key:
portability-avoid-platform-specific-fundamental-types.WarnOnInts, value:
false}, {key:
portability-avoid-platform-specific-fundamental-types.WarnOnChars, value:
false}]}" -header-filter=.*
```
https://github.com/llvm/llvm-project/pull/146970
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] Add portability-avoid-platform-specific-fundamental-types (PR #146970)
@@ -0,0 +1,260 @@
+//===--- AvoidPlatformSpecificFundamentalTypesCheck.cpp - clang-tidy
--===//
+//
+// 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 "AvoidPlatformSpecificFundamentalTypesCheck.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "clang/ASTMatchers/ASTMatchers.h"
+#include "clang/Basic/TargetInfo.h"
+
+using namespace clang::ast_matchers;
+
+namespace clang::tidy::portability {
+
+AvoidPlatformSpecificFundamentalTypesCheck::
+AvoidPlatformSpecificFundamentalTypesCheck(StringRef Name,
+ ClangTidyContext *Context)
+: ClangTidyCheck(Name, Context),
+ WarnOnFloats(Options.get("WarnOnFloats", true)),
+ WarnOnInts(Options.get("WarnOnInts", true)),
+ WarnOnChars(Options.get("WarnOnChars", true)),
+ IncludeInserter(Options.getLocalOrGlobal("IncludeStyle",
+ utils::IncludeSorter::IS_LLVM),
+ areDiagsSelfContained()) {}
+
+void AvoidPlatformSpecificFundamentalTypesCheck::registerPPCallbacks(
+const SourceManager &SM, Preprocessor *PP, Preprocessor *ModuleExpanderPP)
{
+ IncludeInserter.registerPreprocessor(PP);
+}
+
+void AvoidPlatformSpecificFundamentalTypesCheck::storeOptions(
+ClangTidyOptions::OptionMap &Opts) {
+ Options.store(Opts, "WarnOnFloats", WarnOnFloats);
+ Options.store(Opts, "WarnOnInts", WarnOnInts);
+ Options.store(Opts, "WarnOnChars", WarnOnChars);
+ Options.store(Opts, "IncludeStyle", IncludeInserter.getStyle());
+}
+
+std::string AvoidPlatformSpecificFundamentalTypesCheck::getFloatReplacement(
+const BuiltinType *BT, ASTContext &Context) const {
+ const TargetInfo &Target = Context.getTargetInfo();
+
+ auto GetReplacementType = [](unsigned Width) {
+switch (Width) {
+// This is ambiguous by default since it could be bfloat16 or float16
+case 16U:
+ return "";
+case 32U:
+ return "float32_t";
+case 64U:
+ return "float64_t";
+case 128U:
+ return "float128_t";
+default:
+ return "";
+}
+ };
+
+ switch (BT->getKind()) {
+ // Not an ambiguous type
+ case BuiltinType::BFloat16:
+return "bfloat16_t";
+ case BuiltinType::Half:
+return GetReplacementType(Target.getHalfWidth());
+ case BuiltinType::Float:
+return GetReplacementType(Target.getFloatWidth());
+ case BuiltinType::Double:
+return GetReplacementType(Target.getDoubleWidth());
+ default:
+return "";
+ }
+}
+
+void AvoidPlatformSpecificFundamentalTypesCheck::registerMatchers(
+MatchFinder *Finder) {
+ // Build the list of type strings to match
+ std::vector TypeStrings;
+
+ // Add integer types if the option is enabled
+ if (WarnOnInts) {
+TypeStrings.insert(TypeStrings.end(), {"short",
vbvictor wrote:
You could create 3 custom matchers for `int`, `float`, `double` and later add
them like this:
```cpp
qualType(allOf(
builtinType(),
anyOf(
WarnOnInts ? isBuiltinInt() : unless(anything()),
WarnOnFloats ? isBuiltinFloat() : unless(anything()),
WarnOnFloats ? isBuiltinChar() : unless(anything())
)
))
```
https://github.com/llvm/llvm-project/pull/146970
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] Add portability-avoid-platform-specific-fundamental-types (PR #146970)
@@ -0,0 +1,43 @@
+//===--- AvoidPlatformSpecificFundamentalTypesCheck.h - clang-tidy ---*-
C++
+//-*-===//
+//
+// 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_PORTABILITY_AVOIDPLATFORMSPECIFICFUNDAMENTALTYPESCHECK_H
+#define
LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_PORTABILITY_AVOIDPLATFORMSPECIFICFUNDAMENTALTYPESCHECK_H
+
+#include "../ClangTidyCheck.h"
+
+namespace clang::tidy::portability {
+
+/// Find fundamental integer types and recommend using typedefs or fixed-width
+/// types.
+///
+/// Detects fundamental integer types (int, short, long, long long, and their
+/// unsigned variants) and warns against their use due to platform-dependent
+/// behavior. Excludes semantic types like char, bool, wchar_t, char16_t,
+/// char32_t, size_t, and ptrdiff_t.
vbvictor wrote:
This is redundant, we should place here only first sentence from docs
```suggestion
```
https://github.com/llvm/llvm-project/pull/146970
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] Add portability-avoid-platform-specific-fundamental-types (PR #146970)
@@ -0,0 +1,69 @@
+// RUN: %check_clang_tidy %s
portability-avoid-platform-specific-fundamental-types %t --
-config="{CheckOptions: [{key:
portability-avoid-platform-specific-fundamental-types.WarnOnInts, value:
false}, {key:
portability-avoid-platform-specific-fundamental-types.WarnOnFloats, value:
false}]}" -header-filter=.* -- -std=c++11
vbvictor wrote:
```suggestion
// RUN: %check_clang_tidy -std=c++11-or-later %s
portability-avoid-platform-specific-fundamental-types %t --
-config="{CheckOptions: [{key:
portability-avoid-platform-specific-fundamental-types.WarnOnInts, value:
false}, {key:
portability-avoid-platform-specific-fundamental-types.WarnOnFloats, value:
false}]}" -header-filter=.*
```
Do we need `-header-filter=.*`?
https://github.com/llvm/llvm-project/pull/146970
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] Add portability-avoid-platform-specific-fundamental-types (PR #146970)
@@ -0,0 +1,43 @@ +//===--- AvoidPlatformSpecificFundamentalTypesCheck.h - clang-tidy ---*- C++ +//-*-===// vbvictor wrote: Please format this as one-line https://github.com/llvm/llvm-project/pull/146970 ___ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] Add portability-avoid-platform-specific-fundamental-types (PR #146970)
@@ -0,0 +1,100 @@
+// RUN: %check_clang_tidy %s
portability-avoid-platform-specific-fundamental-types %t --
-config="{CheckOptions: [{key:
portability-avoid-platform-specific-fundamental-types.WarnOnFloats, value:
true}]}" -header-filter=.* -- -std=c++23
+
+// Mock fixed-width float types
+// In reality, these types are aliases to "extended floating point types", and
+// are not typedefs. However, there isn't a good way to mock extended floats as
+// they are not fundamental types.
+// NOLINTBEGIN(portability-avoid-platform-specific-fundamental-types)
+typedef float float32_t;
+typedef double float64_t;
+// NOLINTEND(portability-avoid-platform-specific-fundamental-types)
+
+// Test floating point types that should trigger warnings when WarnOnFloats is
enabled
+float global_float = 3.14f;
+// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: avoid using platform-dependent
floating point type 'float'; consider using 'float32_t' instead
[portability-avoid-platform-specific-fundamental-types]
+// CHECK-FIXES: float32_t global_float = 3.14f;
jj-marr wrote:
Not done. I want to make this another check, maybe
"`readability-inconsistent-literal-suffix`".
https://github.com/llvm/llvm-project/pull/146970
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] Add portability-avoid-platform-specific-fundamental-types (PR #146970)
@@ -0,0 +1,260 @@
+//===--- AvoidPlatformSpecificFundamentalTypesCheck.cpp - clang-tidy
--===//
+//
+// 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 "AvoidPlatformSpecificFundamentalTypesCheck.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "clang/ASTMatchers/ASTMatchers.h"
+#include "clang/Basic/TargetInfo.h"
+
+using namespace clang::ast_matchers;
+
+namespace clang::tidy::portability {
+
+AvoidPlatformSpecificFundamentalTypesCheck::
+AvoidPlatformSpecificFundamentalTypesCheck(StringRef Name,
+ ClangTidyContext *Context)
+: ClangTidyCheck(Name, Context),
+ WarnOnFloats(Options.get("WarnOnFloats", false)),
+ WarnOnInts(Options.get("WarnOnInts", true)),
+ WarnOnChars(Options.get("WarnOnChars", false)),
+ IncludeInserter(Options.getLocalOrGlobal("IncludeStyle",
+ utils::IncludeSorter::IS_LLVM),
+ areDiagsSelfContained()) {}
+
+void AvoidPlatformSpecificFundamentalTypesCheck::registerPPCallbacks(
+const SourceManager &SM, Preprocessor *PP, Preprocessor *ModuleExpanderPP)
{
+ IncludeInserter.registerPreprocessor(PP);
+}
+
+void AvoidPlatformSpecificFundamentalTypesCheck::storeOptions(
+ClangTidyOptions::OptionMap &Opts) {
+ Options.store(Opts, "WarnOnFloats", WarnOnFloats);
+ Options.store(Opts, "WarnOnInts", WarnOnInts);
+ Options.store(Opts, "WarnOnChars", WarnOnChars);
+ Options.store(Opts, "IncludeStyle", IncludeInserter.getStyle());
+}
+
+std::string AvoidPlatformSpecificFundamentalTypesCheck::getFloatReplacement(
+const BuiltinType *BT, ASTContext &Context) const {
+ const TargetInfo &Target = Context.getTargetInfo();
+
+ auto GetReplacementType = [](unsigned Width) {
+switch (Width) {
+// This is ambiguous by default since it could be bfloat16 or float16
+case 16U:
+ return "";
+case 32U:
+ return "float32_t";
+case 64U:
+ return "float64_t";
+case 128U:
+ return "float128_t";
+default:
+ return "";
+}
+ };
+
+ switch (BT->getKind()) {
+ // Not an ambiguous type
+ case BuiltinType::BFloat16:
+return "bfloat16_t";
+ case BuiltinType::Half:
+return GetReplacementType(Target.getHalfWidth());
+ case BuiltinType::Float:
+return GetReplacementType(Target.getFloatWidth());
+ case BuiltinType::Double:
+return GetReplacementType(Target.getDoubleWidth());
+ default:
+return "";
+ }
+}
+
+void AvoidPlatformSpecificFundamentalTypesCheck::registerMatchers(
+MatchFinder *Finder) {
+ // Build the list of type strings to match
+ std::vector TypeStrings;
+
+ // Add integer types if the option is enabled
+ if (WarnOnInts) {
+TypeStrings.insert(TypeStrings.end(), {"short",
+ "short int",
+ "signed short",
+ "signed short int",
+ "unsigned short",
+ "unsigned short int",
+ "int",
+ "signed",
+ "signed int",
+ "unsigned",
+ "unsigned int",
+ "long",
+ "long int",
+ "signed long",
+ "signed long int",
+ "unsigned long",
+ "unsigned long int",
+ "long long",
+ "long long int",
+ "signed long long",
+ "signed long long int",
+ "unsigned long long",
+ "unsigned long long int"});
+ }
+
+ // Add float types if the option is enabled
+ if (WarnOnFloats) {
+TypeStrings.insert(TypeStrings.end(),
+ {"half", "__bf16", "float", "double", "long double"});
+ }
+
+ // Add char types if the option is enabled
+ if (WarnOnChars) {
+TypeStrings.insert(TypeStrings.end(),
+ {"char", "signed char", "unsigned char"});
+ }
+
+ // If no types are enabled, return early
+ if (TypeStrings.empty()) {
+return;
+ }
+
+ // Create the matcher dynamically
+ auto TypeMatcher = asString(TypeStrings.front());
+ for
[clang-tools-extra] [clang-tidy] Add portability-avoid-platform-specific-fundamental-types (PR #146970)
@@ -0,0 +1,54 @@ +// clang-format off +//===--- AvoidPlatformSpecificFundamentalTypesCheck.h - clang-tidy -*- C++ -*-===// jj-marr wrote: Done. https://github.com/llvm/llvm-project/pull/146970 ___ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] Add portability-avoid-platform-specific-fundamental-types (PR #146970)
@@ -0,0 +1,54 @@ +// clang-format off +//===--- AvoidPlatformSpecificFundamentalTypesCheck.h - clang-tidy -*- C++ -*-===// +// +// 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 +// +//===-===// +// clang-format on jj-marr wrote: Done. https://github.com/llvm/llvm-project/pull/146970 ___ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] Add portability-avoid-platform-specific-fundamental-types (PR #146970)
@@ -0,0 +1,190 @@
+.. title:: clang-tidy - portability-avoid-platform-specific-fundamental-types
+
+portability-avoid-platform-specific-fundamental-types
+=
+
+Finds fundamental types (e.g. `int`, `float`) and recommends using typedefs
+or fixed-width types instead to improve portability across different platforms.
+
+This check detects fundamental types (``int``, ``short``, ``long``, ``float``,
+``char`` and their ``unsigned`` or ``signed`` variants) and warns against
their
+use due to non-standard platform-dependent behavior. For example, ``long`` is
+64 bits on Linux but 32 bits on Windows. There is no standard rationale or
+intent for the sizes of these types.
+
+Instead of fundamental types, use fixed-width types such as ``int32_t`` or
+implementation-defined types with standard semantics, e.g. ``int_fast32_t``
for
+the fastest integer type greater than or equal to 32 bits.
+
+Examples
+
+
+.. code-block:: c++
+
+ // Bad: platform-dependent fundamental types
+ int global_int = 42;
+ short global_short = 10;
+ long global_long = 100L;
+ unsigned long global_unsigned_long = 100UL;
+
+ void function_with_int_param(int param) {
+// ...
+ }
+
+ int function_returning_int() {
+return 42;
+ }
+
+ struct MyStruct {
+int member_int;
+long member_long;
+ };
+
+.. code-block:: c++
+
+ // Good: use fixed-width types or typedefs
+ #include
+
+ int32_t global_int32 = 42;
+ int16_t global_int16 = 10;
+ int64_t global_int64 = 100L;
+ uint64_t global_uint64 = 100UL;
+
+ void function_with_int32_param(int32_t param) {
+// ...
+ }
+
+ int32_t function_returning_int32() {
+return 42;
+ }
+
+ struct MyStruct {
+int32_t member_int32;
+int64_t member_int64;
+ };
+
+The check will also warn about typedef declarations that use fundamental types
+as their underlying type:
+
+.. code-block:: c++
+
+ // Bad: typedef using fundamental type
+ typedef long long MyLongType;
+ using MyIntType = int;
+
+.. code-block:: c++
+
+ // Good: use descriptive names or fixed-width types
+ typedef int64_t TimestampType;
+ using CounterType = uint32_t;
+
+Rationale
+-
+
+Fundamental types have platform-dependent sizes and behavior:
+
+- ``int`` is typically 32 bits on modern platforms but is only guaranteed to be
+ 16 bits by the spec
+- ``long int`` is 32 bits on Windows but 64 bits on most Unix systems
+- ``double`` is typically 64-bit IEEE754, but on some microcontrollers without
+ a 64-bit FPU (e.g. certain Arduinos) it can be 32 bits
+- ``char`` is signed on ARM and unsigned on x86
+
+The C++ specification does not define these types beyond their minimum sizes.
+That means they can communicate intent in non-standard ways and are often
+needlessly incompatible. For example, ``int``was traditionally the word size of
jj-marr wrote:
Done.
https://github.com/llvm/llvm-project/pull/146970
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] Add portability-avoid-platform-specific-fundamental-types (PR #146970)
@@ -0,0 +1,190 @@
+.. title:: clang-tidy - portability-avoid-platform-specific-fundamental-types
+
+portability-avoid-platform-specific-fundamental-types
+=
+
+Finds fundamental types (e.g. `int`, `float`) and recommends using typedefs
+or fixed-width types instead to improve portability across different platforms.
+
+This check detects fundamental types (``int``, ``short``, ``long``, ``float``,
+``char`` and their ``unsigned`` or ``signed`` variants) and warns against
their
+use due to non-standard platform-dependent behavior. For example, ``long`` is
+64 bits on Linux but 32 bits on Windows. There is no standard rationale or
+intent for the sizes of these types.
+
+Instead of fundamental types, use fixed-width types such as ``int32_t`` or
+implementation-defined types with standard semantics, e.g. ``int_fast32_t``
for
+the fastest integer type greater than or equal to 32 bits.
+
+Examples
+
+
+.. code-block:: c++
+
+ // Bad: platform-dependent fundamental types
+ int global_int = 42;
+ short global_short = 10;
+ long global_long = 100L;
+ unsigned long global_unsigned_long = 100UL;
+
+ void function_with_int_param(int param) {
+// ...
+ }
+
+ int function_returning_int() {
+return 42;
+ }
+
+ struct MyStruct {
+int member_int;
+long member_long;
+ };
+
+.. code-block:: c++
+
+ // Good: use fixed-width types or typedefs
+ #include
+
+ int32_t global_int32 = 42;
+ int16_t global_int16 = 10;
+ int64_t global_int64 = 100L;
+ uint64_t global_uint64 = 100UL;
+
+ void function_with_int32_param(int32_t param) {
+// ...
+ }
+
+ int32_t function_returning_int32() {
+return 42;
+ }
+
+ struct MyStruct {
+int32_t member_int32;
+int64_t member_int64;
+ };
+
+The check will also warn about typedef declarations that use fundamental types
+as their underlying type:
+
+.. code-block:: c++
+
+ // Bad: typedef using fundamental type
+ typedef long long MyLongType;
+ using MyIntType = int;
+
+.. code-block:: c++
+
+ // Good: use descriptive names or fixed-width types
+ typedef int64_t TimestampType;
+ using CounterType = uint32_t;
+
+Rationale
+-
+
+Fundamental types have platform-dependent sizes and behavior:
+
+- ``int`` is typically 32 bits on modern platforms but is only guaranteed to be
+ 16 bits by the spec
+- ``long int`` is 32 bits on Windows but 64 bits on most Unix systems
+- ``double`` is typically 64-bit IEEE754, but on some microcontrollers without
+ a 64-bit FPU (e.g. certain Arduinos) it can be 32 bits
+- ``char`` is signed on ARM and unsigned on x86
+
+The C++ specification does not define these types beyond their minimum sizes.
+That means they can communicate intent in non-standard ways and are often
+needlessly incompatible. For example, ``int``was traditionally the word size of
+a given processor in 16-bit and 32-bit computing and was a reasonable default
+for performance. This is no longer true on modern 64-bit computers, but the
+size of ``int`` remains fixed at 32 bits for backwards compatibility with code
+that relied on a 32-bit implementation of ``int``.
+
+If code is explicitly relying on the size of an ``int`` being 32 bits, it is
+better to say so in the typename with ``int32_t``. Otherwise, use an
+appropriate implementation-defined type such as ``fast_int32_t`` or
+``least_int32_t`` that communicates the appropriate time/space tradeoff.
+
+Likewise, ``float`` and ``double`` should be replaced by ``float32_t`` and
+``float64_t`` which are guaranteed to be standard IEEE754 floats for a given
+size.
+
+``char`` should be replaced by ``char8_t`` when used in the representation of
+Unicode text. When used to represent a byte on a given platform, ``std::byte``
+is an appropriate replacement.
+
+Types Not Flagged
+-
+
+The following types are intentionally not flagged:
+
+- ``bool`` (boolean type)
+- Standard library typedefs like ``size_t``, ``ptrdiff_t``, or ``uint32_t``.
+- Already typedef'd types, though the check will flag the typedef itself
+
+``bool`` is excluded because it can only be true or false, and is not
vulnerable to overflow or
+narrowing issues that occur as a result of using implementation-defined types.
+
+Options
+---
+
+.. option:: WarnOnFloats
+
+ When `true`, the check will warn about floating point types (``float`` and
``double``).
+ When `false` (default), floating point types are not flagged.
+
+ Floating point types can have platform-dependent behavior:
+
+ - ``float`` is typically 32-bit IEEE754, but can vary on some platforms
+ - ``double`` is typically 64-bit IEEE754, but on some microcontrollers
without
+ a 64-bit FPU it can be 32 bits
+
+ When this option is enabled, the check will suggest using ``float32_t`` and
``float64_t``
+ instead of ``float`` and ``double`` respectively, when the target platform
supports
+ standard IEEE754 sizes.
+
+
[clang-tools-extra] [clang-tidy] Add portability-avoid-platform-specific-fundamental-types (PR #146970)
@@ -0,0 +1,190 @@
+.. title:: clang-tidy - portability-avoid-platform-specific-fundamental-types
+
+portability-avoid-platform-specific-fundamental-types
+=
+
+Finds fundamental types (e.g. `int`, `float`) and recommends using typedefs
+or fixed-width types instead to improve portability across different platforms.
+
+This check detects fundamental types (``int``, ``short``, ``long``, ``float``,
+``char`` and their ``unsigned`` or ``signed`` variants) and warns against
their
+use due to non-standard platform-dependent behavior. For example, ``long`` is
+64 bits on Linux but 32 bits on Windows. There is no standard rationale or
+intent for the sizes of these types.
+
+Instead of fundamental types, use fixed-width types such as ``int32_t`` or
+implementation-defined types with standard semantics, e.g. ``int_fast32_t``
for
+the fastest integer type greater than or equal to 32 bits.
+
+Examples
+
+
+.. code-block:: c++
+
+ // Bad: platform-dependent fundamental types
+ int global_int = 42;
+ short global_short = 10;
+ long global_long = 100L;
+ unsigned long global_unsigned_long = 100UL;
+
+ void function_with_int_param(int param) {
+// ...
+ }
+
+ int function_returning_int() {
+return 42;
+ }
+
+ struct MyStruct {
+int member_int;
+long member_long;
+ };
+
+.. code-block:: c++
+
+ // Good: use fixed-width types or typedefs
+ #include
+
+ int32_t global_int32 = 42;
+ int16_t global_int16 = 10;
+ int64_t global_int64 = 100L;
+ uint64_t global_uint64 = 100UL;
+
+ void function_with_int32_param(int32_t param) {
+// ...
+ }
+
+ int32_t function_returning_int32() {
+return 42;
+ }
+
+ struct MyStruct {
+int32_t member_int32;
+int64_t member_int64;
+ };
+
+The check will also warn about typedef declarations that use fundamental types
+as their underlying type:
+
+.. code-block:: c++
+
+ // Bad: typedef using fundamental type
+ typedef long long MyLongType;
+ using MyIntType = int;
+
+.. code-block:: c++
+
+ // Good: use descriptive names or fixed-width types
+ typedef int64_t TimestampType;
+ using CounterType = uint32_t;
+
+Rationale
+-
+
+Fundamental types have platform-dependent sizes and behavior:
+
+- ``int`` is typically 32 bits on modern platforms but is only guaranteed to be
+ 16 bits by the spec
+- ``long int`` is 32 bits on Windows but 64 bits on most Unix systems
+- ``double`` is typically 64-bit IEEE754, but on some microcontrollers without
+ a 64-bit FPU (e.g. certain Arduinos) it can be 32 bits
+- ``char`` is signed on ARM and unsigned on x86
+
+The C++ specification does not define these types beyond their minimum sizes.
+That means they can communicate intent in non-standard ways and are often
+needlessly incompatible. For example, ``int``was traditionally the word size of
+a given processor in 16-bit and 32-bit computing and was a reasonable default
+for performance. This is no longer true on modern 64-bit computers, but the
+size of ``int`` remains fixed at 32 bits for backwards compatibility with code
+that relied on a 32-bit implementation of ``int``.
+
+If code is explicitly relying on the size of an ``int`` being 32 bits, it is
+better to say so in the typename with ``int32_t``. Otherwise, use an
+appropriate implementation-defined type such as ``fast_int32_t`` or
+``least_int32_t`` that communicates the appropriate time/space tradeoff.
+
+Likewise, ``float`` and ``double`` should be replaced by ``float32_t`` and
+``float64_t`` which are guaranteed to be standard IEEE754 floats for a given
+size.
+
+``char`` should be replaced by ``char8_t`` when used in the representation of
+Unicode text. When used to represent a byte on a given platform, ``std::byte``
+is an appropriate replacement.
+
+Types Not Flagged
+-
+
+The following types are intentionally not flagged:
+
+- ``bool`` (boolean type)
+- Standard library typedefs like ``size_t``, ``ptrdiff_t``, or ``uint32_t``.
+- Already typedef'd types, though the check will flag the typedef itself
+
+``bool`` is excluded because it can only be true or false, and is not
vulnerable to overflow or
+narrowing issues that occur as a result of using implementation-defined types.
+
+Options
jj-marr wrote:
no WarnOnInt option documentation
https://github.com/llvm/llvm-project/pull/146970
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] Add portability-avoid-platform-specific-fundamental-types (PR #146970)
@@ -0,0 +1,100 @@
+// RUN: %check_clang_tidy %s
portability-avoid-platform-specific-fundamental-types %t --
-config="{CheckOptions: [{key:
portability-avoid-platform-specific-fundamental-types.WarnOnFloats, value:
true}]}" -header-filter=.* -- -std=c++23
+
+// Mock fixed-width float types
+// In reality, these types are aliases to "extended floating point types", and
+// are not typedefs. However, there isn't a good way to mock extended floats as
+// they are not fundamental types.
+// NOLINTBEGIN(portability-avoid-platform-specific-fundamental-types)
+typedef float float32_t;
+typedef double float64_t;
+// NOLINTEND(portability-avoid-platform-specific-fundamental-types)
+
+// Test floating point types that should trigger warnings when WarnOnFloats is
enabled
+float global_float = 3.14f;
+// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: avoid using platform-dependent
floating point type 'float'; consider using 'float32_t' instead
[portability-avoid-platform-specific-fundamental-types]
+// CHECK-FIXES: float32_t global_float = 3.14f;
jj-marr wrote:
this should change the suffixes too if they exist
https://github.com/llvm/llvm-project/pull/146970
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] Add portability-avoid-platform-specific-fundamental-types (PR #146970)
@@ -0,0 +1,63 @@
+// RUN: %check_clang_tidy %s
portability-avoid-platform-specific-fundamental-types %t --
-config="{CheckOptions: [{key:
portability-avoid-platform-specific-fundamental-types.WarnOnChars, value:
true}]}" -header-filter=.* -- -std=c++11
jj-marr wrote:
should also ensure that ints aren't linted when WarnOnChars on its own is
enabled and the other two are disabled
https://github.com/llvm/llvm-project/pull/146970
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] Add portability-avoid-platform-specific-fundamental-types (PR #146970)
@@ -0,0 +1,190 @@
+.. title:: clang-tidy - portability-avoid-platform-specific-fundamental-types
+
+portability-avoid-platform-specific-fundamental-types
+=
+
+Finds fundamental types (e.g. `int`, `float`) and recommends using typedefs
+or fixed-width types instead to improve portability across different platforms.
+
+This check detects fundamental types (``int``, ``short``, ``long``, ``float``,
+``char`` and their ``unsigned`` or ``signed`` variants) and warns against
their
+use due to non-standard platform-dependent behavior. For example, ``long`` is
+64 bits on Linux but 32 bits on Windows. There is no standard rationale or
+intent for the sizes of these types.
+
+Instead of fundamental types, use fixed-width types such as ``int32_t`` or
+implementation-defined types with standard semantics, e.g. ``int_fast32_t``
for
+the fastest integer type greater than or equal to 32 bits.
+
+Examples
+
+
+.. code-block:: c++
+
+ // Bad: platform-dependent fundamental types
+ int global_int = 42;
+ short global_short = 10;
+ long global_long = 100L;
+ unsigned long global_unsigned_long = 100UL;
+
+ void function_with_int_param(int param) {
+// ...
+ }
+
+ int function_returning_int() {
+return 42;
+ }
+
+ struct MyStruct {
+int member_int;
+long member_long;
+ };
+
+.. code-block:: c++
+
+ // Good: use fixed-width types or typedefs
+ #include
+
+ int32_t global_int32 = 42;
+ int16_t global_int16 = 10;
+ int64_t global_int64 = 100L;
+ uint64_t global_uint64 = 100UL;
+
+ void function_with_int32_param(int32_t param) {
+// ...
+ }
+
+ int32_t function_returning_int32() {
+return 42;
+ }
+
+ struct MyStruct {
+int32_t member_int32;
+int64_t member_int64;
+ };
+
+The check will also warn about typedef declarations that use fundamental types
+as their underlying type:
+
+.. code-block:: c++
+
+ // Bad: typedef using fundamental type
+ typedef long long MyLongType;
+ using MyIntType = int;
+
+.. code-block:: c++
+
+ // Good: use descriptive names or fixed-width types
+ typedef int64_t TimestampType;
+ using CounterType = uint32_t;
+
+Rationale
+-
+
+Fundamental types have platform-dependent sizes and behavior:
+
+- ``int`` is typically 32 bits on modern platforms but is only guaranteed to be
+ 16 bits by the spec
+- ``long int`` is 32 bits on Windows but 64 bits on most Unix systems
+- ``double`` is typically 64-bit IEEE754, but on some microcontrollers without
+ a 64-bit FPU (e.g. certain Arduinos) it can be 32 bits
+- ``char`` is signed on ARM and unsigned on x86
+
+The C++ specification does not define these types beyond their minimum sizes.
+That means they can communicate intent in non-standard ways and are often
+needlessly incompatible. For example, ``int``was traditionally the word size of
+a given processor in 16-bit and 32-bit computing and was a reasonable default
+for performance. This is no longer true on modern 64-bit computers, but the
+size of ``int`` remains fixed at 32 bits for backwards compatibility with code
+that relied on a 32-bit implementation of ``int``.
+
+If code is explicitly relying on the size of an ``int`` being 32 bits, it is
+better to say so in the typename with ``int32_t``. Otherwise, use an
+appropriate implementation-defined type such as ``fast_int32_t`` or
+``least_int32_t`` that communicates the appropriate time/space tradeoff.
+
+Likewise, ``float`` and ``double`` should be replaced by ``float32_t`` and
+``float64_t`` which are guaranteed to be standard IEEE754 floats for a given
+size.
+
+``char`` should be replaced by ``char8_t`` when used in the representation of
+Unicode text. When used to represent a byte on a given platform, ``std::byte``
+is an appropriate replacement.
+
+Types Not Flagged
+-
+
+The following types are intentionally not flagged:
+
+- ``bool`` (boolean type)
+- Standard library typedefs like ``size_t``, ``ptrdiff_t``, or ``uint32_t``.
+- Already typedef'd types, though the check will flag the typedef itself
+
+``bool`` is excluded because it can only be true or false, and is not
vulnerable to overflow or
+narrowing issues that occur as a result of using implementation-defined types.
+
+Options
+---
+
+.. option:: WarnOnFloats
+
+ When `true`, the check will warn about floating point types (``float`` and
``double``).
jj-marr wrote:
should be true by default. Maybe only on C++23 and above?
https://github.com/llvm/llvm-project/pull/146970
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] Add portability-avoid-platform-specific-fundamental-types (PR #146970)
@@ -0,0 +1,54 @@ +// clang-format off +//===--- AvoidPlatformSpecificFundamentalTypesCheck.h - clang-tidy -*- C++ -*-===// EugeneZelenko wrote: ```suggestion //==-- AvoidPlatformSpecificFundamentalTypesCheck.h - clang-tidy -*- C++ -*-==// ``` https://github.com/llvm/llvm-project/pull/146970 ___ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] Add portability-avoid-platform-specific-fundamental-types (PR #146970)
@@ -0,0 +1,190 @@
+.. title:: clang-tidy - portability-avoid-platform-specific-fundamental-types
+
+portability-avoid-platform-specific-fundamental-types
+=
+
+Finds fundamental types (e.g. `int`, `float`) and recommends using typedefs
+or fixed-width types instead to improve portability across different platforms.
+
+This check detects fundamental types (``int``, ``short``, ``long``, ``float``,
+``char`` and their ``unsigned`` or ``signed`` variants) and warns against
their
+use due to non-standard platform-dependent behavior. For example, ``long`` is
+64 bits on Linux but 32 bits on Windows. There is no standard rationale or
+intent for the sizes of these types.
+
+Instead of fundamental types, use fixed-width types such as ``int32_t`` or
+implementation-defined types with standard semantics, e.g. ``int_fast32_t``
for
+the fastest integer type greater than or equal to 32 bits.
+
+Examples
+
+
+.. code-block:: c++
+
+ // Bad: platform-dependent fundamental types
+ int global_int = 42;
+ short global_short = 10;
+ long global_long = 100L;
+ unsigned long global_unsigned_long = 100UL;
+
+ void function_with_int_param(int param) {
+// ...
+ }
+
+ int function_returning_int() {
+return 42;
+ }
+
+ struct MyStruct {
+int member_int;
+long member_long;
+ };
+
+.. code-block:: c++
+
+ // Good: use fixed-width types or typedefs
+ #include
+
+ int32_t global_int32 = 42;
+ int16_t global_int16 = 10;
+ int64_t global_int64 = 100L;
+ uint64_t global_uint64 = 100UL;
+
+ void function_with_int32_param(int32_t param) {
+// ...
+ }
+
+ int32_t function_returning_int32() {
+return 42;
+ }
+
+ struct MyStruct {
+int32_t member_int32;
+int64_t member_int64;
+ };
+
+The check will also warn about typedef declarations that use fundamental types
+as their underlying type:
+
+.. code-block:: c++
+
+ // Bad: typedef using fundamental type
+ typedef long long MyLongType;
+ using MyIntType = int;
+
+.. code-block:: c++
+
+ // Good: use descriptive names or fixed-width types
+ typedef int64_t TimestampType;
+ using CounterType = uint32_t;
+
+Rationale
+-
+
+Fundamental types have platform-dependent sizes and behavior:
+
+- ``int`` is typically 32 bits on modern platforms but is only guaranteed to be
+ 16 bits by the spec
+- ``long int`` is 32 bits on Windows but 64 bits on most Unix systems
+- ``double`` is typically 64-bit IEEE754, but on some microcontrollers without
+ a 64-bit FPU (e.g. certain Arduinos) it can be 32 bits
+- ``char`` is signed on ARM and unsigned on x86
+
+The C++ specification does not define these types beyond their minimum sizes.
+That means they can communicate intent in non-standard ways and are often
+needlessly incompatible. For example, ``int``was traditionally the word size of
EugeneZelenko wrote:
```suggestion
needlessly incompatible. For example, ``int`` was traditionally the word size of
```
https://github.com/llvm/llvm-project/pull/146970
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] Add portability-avoid-platform-specific-fundamental-types (PR #146970)
@@ -0,0 +1,54 @@ +// clang-format off +//===--- AvoidPlatformSpecificFundamentalTypesCheck.h - clang-tidy -*- C++ -*-===// +// +// 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 +// +//===-===// +// clang-format on EugeneZelenko wrote: ```suggestion ``` https://github.com/llvm/llvm-project/pull/146970 ___ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] Add portability-avoid-platform-specific-fundamental-types (PR #146970)
@@ -0,0 +1,260 @@
+//===--- AvoidPlatformSpecificFundamentalTypesCheck.cpp - clang-tidy
--===//
+//
+// 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 "AvoidPlatformSpecificFundamentalTypesCheck.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "clang/ASTMatchers/ASTMatchers.h"
+#include "clang/Basic/TargetInfo.h"
+
+using namespace clang::ast_matchers;
+
+namespace clang::tidy::portability {
+
+AvoidPlatformSpecificFundamentalTypesCheck::
+AvoidPlatformSpecificFundamentalTypesCheck(StringRef Name,
+ ClangTidyContext *Context)
+: ClangTidyCheck(Name, Context),
+ WarnOnFloats(Options.get("WarnOnFloats", false)),
+ WarnOnInts(Options.get("WarnOnInts", true)),
+ WarnOnChars(Options.get("WarnOnChars", false)),
+ IncludeInserter(Options.getLocalOrGlobal("IncludeStyle",
+ utils::IncludeSorter::IS_LLVM),
+ areDiagsSelfContained()) {}
+
+void AvoidPlatformSpecificFundamentalTypesCheck::registerPPCallbacks(
+const SourceManager &SM, Preprocessor *PP, Preprocessor *ModuleExpanderPP)
{
+ IncludeInserter.registerPreprocessor(PP);
+}
+
+void AvoidPlatformSpecificFundamentalTypesCheck::storeOptions(
+ClangTidyOptions::OptionMap &Opts) {
+ Options.store(Opts, "WarnOnFloats", WarnOnFloats);
+ Options.store(Opts, "WarnOnInts", WarnOnInts);
+ Options.store(Opts, "WarnOnChars", WarnOnChars);
+ Options.store(Opts, "IncludeStyle", IncludeInserter.getStyle());
+}
+
+std::string AvoidPlatformSpecificFundamentalTypesCheck::getFloatReplacement(
+const BuiltinType *BT, ASTContext &Context) const {
+ const TargetInfo &Target = Context.getTargetInfo();
+
+ auto GetReplacementType = [](unsigned Width) {
+switch (Width) {
+// This is ambiguous by default since it could be bfloat16 or float16
+case 16U:
+ return "";
+case 32U:
+ return "float32_t";
+case 64U:
+ return "float64_t";
+case 128U:
+ return "float128_t";
+default:
+ return "";
+}
+ };
+
+ switch (BT->getKind()) {
+ // Not an ambiguous type
+ case BuiltinType::BFloat16:
+return "bfloat16_t";
+ case BuiltinType::Half:
+return GetReplacementType(Target.getHalfWidth());
+ case BuiltinType::Float:
+return GetReplacementType(Target.getFloatWidth());
+ case BuiltinType::Double:
+return GetReplacementType(Target.getDoubleWidth());
+ default:
+return "";
+ }
+}
+
+void AvoidPlatformSpecificFundamentalTypesCheck::registerMatchers(
+MatchFinder *Finder) {
+ // Build the list of type strings to match
+ std::vector TypeStrings;
+
+ // Add integer types if the option is enabled
+ if (WarnOnInts) {
+TypeStrings.insert(TypeStrings.end(), {"short",
+ "short int",
+ "signed short",
+ "signed short int",
+ "unsigned short",
+ "unsigned short int",
+ "int",
+ "signed",
+ "signed int",
+ "unsigned",
+ "unsigned int",
+ "long",
+ "long int",
+ "signed long",
+ "signed long int",
+ "unsigned long",
+ "unsigned long int",
+ "long long",
+ "long long int",
+ "signed long long",
+ "signed long long int",
+ "unsigned long long",
+ "unsigned long long int"});
+ }
+
+ // Add float types if the option is enabled
+ if (WarnOnFloats) {
+TypeStrings.insert(TypeStrings.end(),
+ {"half", "__bf16", "float", "double", "long double"});
+ }
+
+ // Add char types if the option is enabled
+ if (WarnOnChars) {
+TypeStrings.insert(TypeStrings.end(),
+ {"char", "signed char", "unsigned char"});
+ }
+
+ // If no types are enabled, return early
+ if (TypeStrings.empty()) {
+return;
+ }
+
+ // Create the matcher dynamically
+ auto TypeMatcher = asString(TypeStrings.front());
+ for
[clang-tools-extra] [clang-tidy] Add portability-avoid-platform-specific-fundamental-types (PR #146970)
https://github.com/jj-marr edited https://github.com/llvm/llvm-project/pull/146970 ___ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] Add portability-avoid-platform-specific-fundamental-types (PR #146970)
https://github.com/jj-marr commented: comments for myself https://github.com/llvm/llvm-project/pull/146970 ___ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] Add portability-avoid-platform-specific-fundamental-types (PR #146970)
https://github.com/jj-marr edited https://github.com/llvm/llvm-project/pull/146970 ___ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] Add portability-avoid-platform-specific-fundamental-types (PR #146970)
@@ -0,0 +1,246 @@
+//===--- AvoidPlatformSpecificFundamentalTypesCheck.cpp - clang-tidy
--===//
+//
+// 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 "AvoidPlatformSpecificFundamentalTypesCheck.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "clang/ASTMatchers/ASTMatchers.h"
+#include "clang/Basic/TargetInfo.h"
+
+using namespace clang::ast_matchers;
+
+namespace clang::tidy::portability {
+
+AvoidPlatformSpecificFundamentalTypesCheck::
+AvoidPlatformSpecificFundamentalTypesCheck(StringRef Name,
+ ClangTidyContext *Context)
+: ClangTidyCheck(Name, Context),
+ WarnOnFloats(Options.get("WarnOnFloats", false)),
+ IncludeInserter(Options.getLocalOrGlobal("IncludeStyle",
+ utils::IncludeSorter::IS_LLVM),
+ areDiagsSelfContained()) {}
+
+void AvoidPlatformSpecificFundamentalTypesCheck::registerPPCallbacks(
+const SourceManager &SM, Preprocessor *PP, Preprocessor *ModuleExpanderPP)
{
+ IncludeInserter.registerPreprocessor(PP);
+}
+
+void AvoidPlatformSpecificFundamentalTypesCheck::storeOptions(
+ClangTidyOptions::OptionMap &Opts) {
+ Options.store(Opts, "WarnOnFloats", WarnOnFloats);
+ Options.store(Opts, "IncludeStyle", IncludeInserter.getStyle());
+}
+
+std::string AvoidPlatformSpecificFundamentalTypesCheck::getFloatReplacement(
+const BuiltinType *BT, ASTContext &Context) const {
+ const TargetInfo &Target = Context.getTargetInfo();
+
+ auto GetReplacementType = [](unsigned Width) {
+switch (Width) {
+// This is ambiguous by default since it could be bfloat16 or float16
+case 16U:
+ return "";
+case 32U:
+ return "float32_t";
+case 64U:
+ return "float64_t";
+case 128U:
+ return "float128_t";
+default:
+ return "";
+}
+ };
+
+ switch (BT->getKind()) {
+ // Not an ambiguous type
+ case BuiltinType::BFloat16:
+return "bfloat16_t";
+ case BuiltinType::Half:
+return GetReplacementType(Target.getHalfWidth());
+ case BuiltinType::Float:
+return GetReplacementType(Target.getFloatWidth());
+ case BuiltinType::Double:
+return GetReplacementType(Target.getDoubleWidth());
+ default:
+return "";
+ }
+}
+
+void AvoidPlatformSpecificFundamentalTypesCheck::registerMatchers(
+MatchFinder *Finder) {
+ // Build the list of type strings to match
+ std::vector TypeStrings = {"short",
jj-marr wrote:
warn on int should also be a config option.
https://github.com/llvm/llvm-project/pull/146970
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] Add portability-avoid-platform-specific-fundamental-types (PR #146970)
@@ -0,0 +1,246 @@
+//===--- AvoidPlatformSpecificFundamentalTypesCheck.cpp - clang-tidy
--===//
+//
+// 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 "AvoidPlatformSpecificFundamentalTypesCheck.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "clang/ASTMatchers/ASTMatchers.h"
+#include "clang/Basic/TargetInfo.h"
+
+using namespace clang::ast_matchers;
+
+namespace clang::tidy::portability {
+
+AvoidPlatformSpecificFundamentalTypesCheck::
+AvoidPlatformSpecificFundamentalTypesCheck(StringRef Name,
+ ClangTidyContext *Context)
+: ClangTidyCheck(Name, Context),
+ WarnOnFloats(Options.get("WarnOnFloats", false)),
+ IncludeInserter(Options.getLocalOrGlobal("IncludeStyle",
+ utils::IncludeSorter::IS_LLVM),
+ areDiagsSelfContained()) {}
+
+void AvoidPlatformSpecificFundamentalTypesCheck::registerPPCallbacks(
+const SourceManager &SM, Preprocessor *PP, Preprocessor *ModuleExpanderPP)
{
+ IncludeInserter.registerPreprocessor(PP);
+}
+
+void AvoidPlatformSpecificFundamentalTypesCheck::storeOptions(
+ClangTidyOptions::OptionMap &Opts) {
+ Options.store(Opts, "WarnOnFloats", WarnOnFloats);
+ Options.store(Opts, "IncludeStyle", IncludeInserter.getStyle());
+}
+
+std::string AvoidPlatformSpecificFundamentalTypesCheck::getFloatReplacement(
+const BuiltinType *BT, ASTContext &Context) const {
+ const TargetInfo &Target = Context.getTargetInfo();
+
+ auto GetReplacementType = [](unsigned Width) {
+switch (Width) {
+// This is ambiguous by default since it could be bfloat16 or float16
+case 16U:
+ return "";
+case 32U:
+ return "float32_t";
+case 64U:
+ return "float64_t";
+case 128U:
+ return "float128_t";
+default:
+ return "";
+}
+ };
+
+ switch (BT->getKind()) {
+ // Not an ambiguous type
+ case BuiltinType::BFloat16:
+return "bfloat16_t";
+ case BuiltinType::Half:
+return GetReplacementType(Target.getHalfWidth());
+ case BuiltinType::Float:
+return GetReplacementType(Target.getFloatWidth());
+ case BuiltinType::Double:
+return GetReplacementType(Target.getDoubleWidth());
+ default:
+return "";
+ }
+}
+
+void AvoidPlatformSpecificFundamentalTypesCheck::registerMatchers(
+MatchFinder *Finder) {
+ // Build the list of type strings to match
+ std::vector TypeStrings = {"short",
+ "short int",
+ "signed short",
+ "signed short int",
+ "unsigned short",
+ "unsigned short int",
+ "int",
+ "signed",
+ "signed int",
+ "unsigned",
+ "unsigned int",
+ "long",
+ "long int",
+ "signed long",
+ "signed long int",
+ "unsigned long",
+ "unsigned long int",
+ "long long",
+ "long long int",
+ "signed long long",
+ "signed long long int",
+ "unsigned long long",
+ "unsigned long long int"};
+
+ // Add float types if the option is enabled
+ if (WarnOnFloats) {
+TypeStrings.push_back("half");
+TypeStrings.push_back("__bf16");
+TypeStrings.push_back("float");
+TypeStrings.push_back("double");
+TypeStrings.push_back("long double");
+ }
+
+ // Create the matcher dynamically
+ auto TypeMatcher = asString(TypeStrings[0]);
+ for (size_t i = 1; i < TypeStrings.size(); ++i) {
+TypeMatcher = anyOf(TypeMatcher, asString(TypeStrings[i]));
+ }
+
+ auto PlatformSpecificFundamentalType = qualType(allOf(
+ // Must be a builtin type directly (not through typedef)
+ builtinType(),
+ // Match the specific fundamental types we care about
+ TypeMatcher));
+
+ // Match variable declarations with platform-specific fundamental types
+ Finder->addMatcher(
+ varDecl(hasType(PlatformSpecificFundamentalType)).bind("var_decl"),
this);
+
+ // Match function declarations
[clang-tools-extra] [clang-tidy] Add portability-avoid-platform-specific-fundamental-types (PR #146970)
@@ -0,0 +1,43 @@ +//===--- AvoidPlatformSpecificFundamentalTypesCheck.h - clang-tidy ---*- C++ +//-*-===// jj-marr wrote: This requires turning off `clang-format` since line 1 is too long. https://github.com/llvm/llvm-project/pull/146970 ___ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] Add portability-avoid-platform-specific-fundamental-types (PR #146970)
jj-marr wrote: > You could make a universal option to configure autofixes. Make > semicolon-separated list of key-value pairs, e.g. > `int=int32_t;float=float32_t;char=char8_t`. User could specify any type he > wants, and remove/add fixes for `int`, `char` and so on. > > By default, we could even put fixes for all common types and let the user > delete/modify what doesn't like. This is a good idea but even the basic configuration I wanted to do adds a lot of scope to the PR. Autofix for `float` is implemented because it's easy to figure out w/o much ambiguity. Float/double/etc means "I want IEEE754" most of the time, with the only exception being `bfloat16`. https://github.com/llvm/llvm-project/pull/146970 ___ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] Add portability-avoid-platform-specific-fundamental-types (PR #146970)
@@ -0,0 +1,157 @@ +.. title:: clang-tidy - portability-avoid-platform-specific-fundamental-types + +portability-avoid-platform-specific-fundamental-types += + +Finds fundamental types and recommends using typedefs or fixed-width types instead. EugeneZelenko wrote: Please synchronize this statement with Release Notes. https://github.com/llvm/llvm-project/pull/146970 ___ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] Add portability-avoid-platform-specific-fundamental-types (PR #146970)
https://github.com/jj-marr edited https://github.com/llvm/llvm-project/pull/146970 ___ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] Add portability-avoid-platform-specific-fundamental-types (PR #146970)
https://github.com/jj-marr edited https://github.com/llvm/llvm-project/pull/146970 ___ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] Add portability-avoid-platform-specific-fundamental-types (PR #146970)
https://github.com/jj-marr edited https://github.com/llvm/llvm-project/pull/146970 ___ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] Add portability-avoid-platform-specific-fundamental-types (PR #146970)
https://github.com/jj-marr updated
https://github.com/llvm/llvm-project/pull/146970
>From 3ef4feb748551806c863529306fefb2bd914e5be Mon Sep 17 00:00:00 2001
From: JJ Marr
Date: Thu, 3 Jul 2025 17:17:06 -0400
Subject: [PATCH 01/14] AvoidFundamentalIntegerTypesCheck
---
.../AvoidFundamentalIntegerTypesCheck.cpp | 183 ++
.../AvoidFundamentalIntegerTypesCheck.h | 46 +
.../clang-tidy/modernize/CMakeLists.txt | 1 +
.../modernize/ModernizeTidyModule.cpp | 3 +
.../avoid-fundamental-integer-types.cpp | 108 +++
5 files changed, 341 insertions(+)
create mode 100644
clang-tools-extra/clang-tidy/modernize/AvoidFundamentalIntegerTypesCheck.cpp
create mode 100644
clang-tools-extra/clang-tidy/modernize/AvoidFundamentalIntegerTypesCheck.h
create mode 100644
clang-tools-extra/test/clang-tidy/checkers/modernize/avoid-fundamental-integer-types.cpp
diff --git
a/clang-tools-extra/clang-tidy/modernize/AvoidFundamentalIntegerTypesCheck.cpp
b/clang-tools-extra/clang-tidy/modernize/AvoidFundamentalIntegerTypesCheck.cpp
new file mode 100644
index 0..8a393bc894cfe
--- /dev/null
+++
b/clang-tools-extra/clang-tidy/modernize/AvoidFundamentalIntegerTypesCheck.cpp
@@ -0,0 +1,183 @@
+//===--- AvoidFundamentalIntegerTypesCheck.cpp - clang-tidy
---===//
+//
+// 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 "AvoidFundamentalIntegerTypesCheck.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "clang/ASTMatchers/ASTMatchers.h"
+
+using namespace clang::ast_matchers;
+
+namespace clang::tidy::modernize {
+
+namespace {
+
+AST_MATCHER(clang::TypeLoc, hasValidBeginLoc) {
+ return Node.getBeginLoc().isValid();
+}
+
+AST_MATCHER_P(clang::TypeLoc, hasType,
+ clang::ast_matchers::internal::Matcher,
+ InnerMatcher) {
+ const clang::Type *TypeNode = Node.getTypePtr();
+ return TypeNode != nullptr &&
+ InnerMatcher.matches(*TypeNode, Finder, Builder);
+}
+
+} // namespace
+
+AvoidFundamentalIntegerTypesCheck::AvoidFundamentalIntegerTypesCheck(
+StringRef Name, ClangTidyContext *Context)
+: ClangTidyCheck(Name, Context),
+ IgnoreTypedefs(Options.get("IgnoreTypedefs", false)) {}
+
+void AvoidFundamentalIntegerTypesCheck::storeOptions(
+ClangTidyOptions::OptionMap &Opts) {
+ Options.store(Opts, "IgnoreTypedefs", IgnoreTypedefs);
+}
+
+bool AvoidFundamentalIntegerTypesCheck::isFundamentalIntegerType(
+const Type *T) const {
+ if (!T->isBuiltinType())
+return false;
+
+ const auto *BT = T->getAs();
+ if (!BT)
+return false;
+
+ switch (BT->getKind()) {
+ case BuiltinType::Int:
+ case BuiltinType::UInt:
+ case BuiltinType::Short:
+ case BuiltinType::UShort:
+ case BuiltinType::Long:
+ case BuiltinType::ULong:
+ case BuiltinType::LongLong:
+ case BuiltinType::ULongLong:
+return true;
+ default:
+return false;
+ }
+}
+
+bool AvoidFundamentalIntegerTypesCheck::isSemanticType(const Type *T) const {
+ if (!T->isBuiltinType())
+return false;
+
+ const auto *BT = T->getAs();
+ if (!BT)
+return false;
+
+ switch (BT->getKind()) {
+ case BuiltinType::Bool:
+ case BuiltinType::Char_S:
+ case BuiltinType::Char_U:
+ case BuiltinType::SChar:
+ case BuiltinType::UChar:
+ case BuiltinType::WChar_S:
+ case BuiltinType::WChar_U:
+ case BuiltinType::Char8:
+ case BuiltinType::Char16:
+ case BuiltinType::Char32:
+return true;
+ default:
+return false;
+ }
+}
+
+void AvoidFundamentalIntegerTypesCheck::registerMatchers(MatchFinder *Finder) {
+ // Match variable declarations with fundamental integer types
+ Finder->addMatcher(
+ varDecl().bind("var_decl"),
+ this);
+
+ // Match function declarations with fundamental integer return types
+ Finder->addMatcher(
+ functionDecl().bind("func_decl"),
+ this);
+
+ // Match function parameters with fundamental integer types
+ Finder->addMatcher(
+ parmVarDecl().bind("param_decl"),
+ this);
+
+ // Match field declarations with fundamental integer types
+ Finder->addMatcher(
+ fieldDecl().bind("field_decl"),
+ this);
+
+ // Match typedef declarations if not ignoring them
+ if (!IgnoreTypedefs) {
+Finder->addMatcher(
+typedefDecl().bind("typedef_decl"),
+this);
+
+Finder->addMatcher(
+typeAliasDecl().bind("alias_decl"),
+this);
+ }
+}
+
+void AvoidFundamentalIntegerTypesCheck::check(
+const MatchFinder::MatchResult &Result) {
+ SourceLocation Loc;
+ QualType QT;
+ std::string DeclType;
+
+ if (const auto *VD = Result.Nodes.getNodeAs("var_decl")) {
+Loc = VD->getLocation();
+QT = VD->getType();
+DeclType = "variable";
+
[clang-tools-extra] [clang-tidy] Add portability-avoid-platform-specific-fundamental-types (PR #146970)
@@ -0,0 +1,43 @@ +//===--- AvoidPlatformSpecificFundamentalTypesCheck.h - clang-tidy ---*- C++ +//-*-===// jj-marr wrote: Done. https://github.com/llvm/llvm-project/pull/146970 ___ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
