[clang] [clang-tools-extra] [clang-tidy] Add portability-avoid-platform-specific-fundamental-types (PR #146970)

2025-09-20 Thread JJ Marr via cfe-commits


@@ -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)

2025-09-17 Thread JJ Marr via cfe-commits

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)

2025-08-26 Thread Baranov Victor via cfe-commits


@@ -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)

2025-08-26 Thread Baranov Victor via cfe-commits


@@ -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)

2025-08-24 Thread JJ Marr via cfe-commits


@@ -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)

2025-08-24 Thread JJ Marr via cfe-commits

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)

2025-08-24 Thread JJ Marr via cfe-commits


@@ -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)

2025-08-19 Thread via cfe-commits


@@ -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)

2025-08-19 Thread via cfe-commits


@@ -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)

2025-08-19 Thread Baranov Victor via cfe-commits


@@ -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)

2025-08-19 Thread Baranov Victor via cfe-commits


@@ -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)

2025-08-19 Thread Baranov Victor via cfe-commits


@@ -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)

2025-08-19 Thread Baranov Victor via cfe-commits


@@ -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)

2025-08-19 Thread Baranov Victor via cfe-commits


@@ -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)

2025-08-19 Thread Baranov Victor via cfe-commits


@@ -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)

2025-08-19 Thread Baranov Victor via cfe-commits


@@ -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)

2025-08-09 Thread JJ Marr via cfe-commits

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)

2025-08-09 Thread JJ Marr via cfe-commits


@@ -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)

2025-08-09 Thread JJ Marr via cfe-commits


@@ -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)

2025-08-09 Thread via cfe-commits


@@ -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)

2025-08-09 Thread JJ Marr via cfe-commits


@@ -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)

2025-08-09 Thread via cfe-commits


@@ -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)

2025-08-09 Thread JJ Marr via cfe-commits


@@ -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)

2025-08-09 Thread JJ Marr via cfe-commits


@@ -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)

2025-08-09 Thread JJ Marr via cfe-commits


@@ -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)

2025-08-09 Thread JJ Marr via cfe-commits


@@ -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)

2025-08-03 Thread via cfe-commits


@@ -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)

2025-08-03 Thread via cfe-commits

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)

2025-07-25 Thread JJ Marr via cfe-commits

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)

2025-07-12 Thread Julian Schmidt via cfe-commits


@@ -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)

2025-07-12 Thread Julian Schmidt via cfe-commits


@@ -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)

2025-07-12 Thread Julian Schmidt via cfe-commits


@@ -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)

2025-07-12 Thread Julian Schmidt via cfe-commits


@@ -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)

2025-07-12 Thread Julian Schmidt via cfe-commits


@@ -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)

2025-07-10 Thread Baranov Victor via cfe-commits


@@ -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)

2025-07-10 Thread Baranov Victor via cfe-commits


@@ -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)

2025-07-10 Thread Baranov Victor via cfe-commits


@@ -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)

2025-07-10 Thread Baranov Victor via cfe-commits


@@ -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)

2025-07-10 Thread Baranov Victor via cfe-commits


@@ -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)

2025-07-10 Thread Baranov Victor via cfe-commits


@@ -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)

2025-07-10 Thread Baranov Victor via cfe-commits


@@ -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)

2025-07-10 Thread Baranov Victor via cfe-commits


@@ -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)

2025-07-10 Thread Baranov Victor via cfe-commits


@@ -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)

2025-07-10 Thread Baranov Victor via cfe-commits


@@ -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)

2025-07-10 Thread JJ Marr via cfe-commits


@@ -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)

2025-07-10 Thread via cfe-commits


@@ -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)

2025-07-10 Thread via cfe-commits


@@ -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)

2025-07-10 Thread via cfe-commits


@@ -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)

2025-07-10 Thread via cfe-commits


@@ -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)

2025-07-10 Thread via cfe-commits


@@ -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)

2025-07-10 Thread via cfe-commits


@@ -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)

2025-07-10 Thread via cfe-commits


@@ -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)

2025-07-10 Thread via cfe-commits


@@ -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)

2025-07-09 Thread Baranov Victor via cfe-commits

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)

2025-07-08 Thread Baranov Victor via cfe-commits


@@ -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)

2025-07-06 Thread JJ Marr via cfe-commits

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)

2025-07-06 Thread JJ Marr via cfe-commits


@@ -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)

2025-07-06 Thread Baranov Victor via cfe-commits

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)

2025-07-06 Thread Baranov Victor via cfe-commits


@@ -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)

2025-07-06 Thread JJ Marr via cfe-commits


@@ -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)

2025-07-06 Thread Baranov Victor via cfe-commits

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)

2025-07-06 Thread Baranov Victor via cfe-commits


@@ -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)

2025-07-06 Thread Baranov Victor via cfe-commits


@@ -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)

2025-07-06 Thread Baranov Victor via cfe-commits


@@ -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)

2025-07-06 Thread Baranov Victor via cfe-commits

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)

2025-07-06 Thread Baranov Victor via cfe-commits


@@ -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)

2025-07-06 Thread Baranov Victor via cfe-commits


@@ -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)

2025-07-06 Thread Baranov Victor via cfe-commits

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)

2025-07-06 Thread Baranov Victor via cfe-commits


@@ -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)

2025-07-06 Thread Baranov Victor via cfe-commits


@@ -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)

2025-07-06 Thread Baranov Victor via cfe-commits


@@ -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)

2025-07-06 Thread Baranov Victor via cfe-commits


@@ -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)

2025-07-06 Thread Baranov Victor via cfe-commits


@@ -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)

2025-07-06 Thread JJ Marr via cfe-commits


@@ -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)

2025-07-06 Thread JJ Marr via cfe-commits


@@ -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)

2025-07-06 Thread JJ Marr via cfe-commits


@@ -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)

2025-07-06 Thread JJ Marr via cfe-commits


@@ -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)

2025-07-06 Thread JJ Marr via cfe-commits


@@ -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)

2025-07-06 Thread JJ Marr via cfe-commits


@@ -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)

2025-07-06 Thread JJ Marr via cfe-commits


@@ -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)

2025-07-06 Thread JJ Marr via cfe-commits


@@ -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)

2025-07-06 Thread JJ Marr via cfe-commits


@@ -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)

2025-07-06 Thread JJ Marr via cfe-commits


@@ -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)

2025-07-06 Thread via cfe-commits


@@ -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)

2025-07-06 Thread via cfe-commits


@@ -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)

2025-07-06 Thread via cfe-commits


@@ -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)

2025-07-06 Thread via cfe-commits


@@ -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)

2025-07-05 Thread JJ Marr via cfe-commits

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)

2025-07-05 Thread JJ Marr via cfe-commits

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)

2025-07-05 Thread JJ Marr via cfe-commits

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)

2025-07-05 Thread JJ Marr via cfe-commits


@@ -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)

2025-07-05 Thread JJ Marr via cfe-commits


@@ -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)

2025-07-05 Thread JJ Marr via cfe-commits


@@ -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)

2025-07-05 Thread JJ Marr via cfe-commits

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)

2025-07-05 Thread via cfe-commits


@@ -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)

2025-07-05 Thread JJ Marr via cfe-commits

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)

2025-07-05 Thread JJ Marr via cfe-commits

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)

2025-07-05 Thread JJ Marr via cfe-commits

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)

2025-07-05 Thread JJ Marr via cfe-commits

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)

2025-07-05 Thread JJ Marr via cfe-commits


@@ -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


  1   2   >