From 3ef4feb748551806c863529306fefb2bd914e5be Mon Sep 17 00:00:00 2001 From: JJ Marr Date: Thu, 3 Jul 2025 17:17:06 -0400 Subject: [PATCH 01/83] 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 0000000000000..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"; + } else if (const auto *FD = Result.Nodes.getNodeAs("func_decl")) { + Loc = FD->getLocation(); + QT = FD->getReturnType(); + DeclType = "function return type"; + } else if (const auto *PD = Result.Nodes.getNodeAs("param_decl")) { + Loc = PD->getLocation(); + QT = PD->getType(); + DeclType = "function parameter"; + } else if (const auto *FD = Result.Nodes.getNodeAs("field_decl")) { + Loc = FD->getLocation(); + QT = FD->getType(); + DeclType = "field"; + } else if (const auto *TD = Result.Nodes.getNodeAs("typedef_decl")) { + Loc = TD->getLocation(); + QT = TD->getUnderlyingType(); + DeclType = "typedef"; + } else if (const auto *AD = Result.Nodes.getNodeAs("alias_decl")) { + Loc = AD->getLocation(); + QT = AD->getUnderlyingType(); + DeclType = "type alias"; + } else { + return; + } + + if (Loc.isInvalid() || QT.isNull()) + return; + + const Type *T = QT.getCanonicalType().getTypePtr(); + if (!T) + return; + + // Skip if not a fundamental integer type + if (!isFundamentalIntegerType(T)) + return; + + // Skip semantic types + if (isSemanticType(T)) + return; + + // Get the type name for the diagnostic + std::string TypeName = QT.getAsString(); + + diag(Loc, "avoid using platform-dependent fundamental integer type '%0'; " + "consider using a typedef or fixed-width type instead") + << TypeName; +} + +} // namespace clang::tidy::modernize \ No newline at end of file diff --git a/clang-tools-extra/clang-tidy/modernize/AvoidFundamentalIntegerTypesCheck.h b/clang-tools-extra/clang-tidy/modernize/AvoidFundamentalIntegerTypesCheck.h new file mode 100644 index 0000000000000..41e8cd5ceb87e --- /dev/null +++ b/clang-tools-extra/clang-tidy/modernize/AvoidFundamentalIntegerTypesCheck.h @@ -0,0 +1,46 @@ +//===--- AvoidFundamentalIntegerTypesCheck.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_MODERNIZE_AVOIDFUNDAMENTALINTEGERTYPESCHECK_H +#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MODERNIZE_AVOIDFUNDAMENTALINTEGERTYPESCHECK_H + +#include "../ClangTidyCheck.h" + +namespace clang::tidy::modernize { + +/// 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. +/// +/// For the user-facing documentation see: +/// http://clang.llvm.org/extra/clang-tidy/checks/modernize/avoid-fundamental-integer-types.html +class AvoidFundamentalIntegerTypesCheck : public ClangTidyCheck { +public: + AvoidFundamentalIntegerTypesCheck(StringRef Name, ClangTidyContext *Context); + 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 IgnoreTypedefs; + bool isFundamentalIntegerType(const Type *T) const; + bool isSemanticType(const Type *T) const; +}; + +} // namespace clang::tidy::modernize + +#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MODERNIZE_AVOIDFUNDAMENTALINTEGERTYPESCHECK_H \ No newline at end of file diff --git a/clang-tools-extra/clang-tidy/modernize/CMakeLists.txt b/clang-tools-extra/clang-tidy/modernize/CMakeLists.txt index 619a27b2f9bb6..deb37c1ad9fb3 100644 --- a/clang-tools-extra/clang-tidy/modernize/CMakeLists.txt +++ b/clang-tools-extra/clang-tidy/modernize/CMakeLists.txt @@ -6,6 +6,7 @@ set(LLVM_LINK_COMPONENTS add_clang_library(clangTidyModernizeModule STATIC AvoidBindCheck.cpp AvoidCArraysCheck.cpp + AvoidFundamentalIntegerTypesCheck.cpp ConcatNestedNamespacesCheck.cpp DeprecatedHeadersCheck.cpp DeprecatedIosBaseAliasesCheck.cpp diff --git a/clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp b/clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp index fdf38bc4b6308..a42d55b26a311 100644 --- a/clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp +++ b/clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp @@ -11,6 +11,7 @@ #include "../ClangTidyModuleRegistry.h" #include "AvoidBindCheck.h" #include "AvoidCArraysCheck.h" +#include "AvoidFundamentalIntegerTypesCheck.h" #include "ConcatNestedNamespacesCheck.h" #include "DeprecatedHeadersCheck.h" #include "DeprecatedIosBaseAliasesCheck.h" @@ -63,6 +64,8 @@ class ModernizeModule : public ClangTidyModule { void addCheckFactories(ClangTidyCheckFactories &CheckFactories) override { CheckFactories.registerCheck("modernize-avoid-bind"); CheckFactories.registerCheck("modernize-avoid-c-arrays"); + CheckFactories.registerCheck( + "modernize-avoid-fundamental-integer-types"); CheckFactories.registerCheck( "modernize-concat-nested-namespaces"); CheckFactories.registerCheck( diff --git a/clang-tools-extra/test/clang-tidy/checkers/modernize/avoid-fundamental-integer-types.cpp b/clang-tools-extra/test/clang-tidy/checkers/modernize/avoid-fundamental-integer-types.cpp new file mode 100644 index 0000000000000..7d4860d95a3ce --- /dev/null +++ b/clang-tools-extra/test/clang-tidy/checkers/modernize/avoid-fundamental-integer-types.cpp @@ -0,0 +1,108 @@ +// RUN: %check_clang_tidy %s modernize-avoid-fundamental-integer-types %t + +// Test fundamental integer types that should trigger warnings +int global_int = 42; +// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: avoid using platform-dependent fundamental integer type 'int'; consider using a typedef or fixed-width type instead [modernize-avoid-fundamental-integer-types] + +short global_short = 10; +// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: avoid using platform-dependent fundamental integer type 'short'; consider using a typedef or fixed-width type instead [modernize-avoid-fundamental-integer-types] + +long global_long = 100L; +// CHECK-MESSAGES: :[[@LINE-1]]:6: warning: avoid using platform-dependent fundamental integer type 'long'; consider using a typedef or fixed-width type instead [modernize-avoid-fundamental-integer-types] + +long long global_long_long = 1000LL; +// CHECK-MESSAGES: :[[@LINE-1]]:11: warning: avoid using platform-dependent fundamental integer type 'long long'; consider using a typedef or fixed-width type instead [modernize-avoid-fundamental-integer-types] + +unsigned int global_unsigned_int = 42U; +// CHECK-MESSAGES: :[[@LINE-1]]:14: warning: avoid using platform-dependent fundamental integer type 'unsigned int'; consider using a typedef or fixed-width type instead [modernize-avoid-fundamental-integer-types] + +unsigned short global_unsigned_short = 10U; +// CHECK-MESSAGES: :[[@LINE-1]]:16: warning: avoid using platform-dependent fundamental integer type 'unsigned short'; consider using a typedef or fixed-width type instead [modernize-avoid-fundamental-integer-types] + +unsigned long global_unsigned_long = 100UL; +// CHECK-MESSAGES: :[[@LINE-1]]:15: warning: avoid using platform-dependent fundamental integer type 'unsigned long'; consider using a typedef or fixed-width type instead [modernize-avoid-fundamental-integer-types] + +unsigned long long global_unsigned_long_long = 1000ULL; +// CHECK-MESSAGES: :[[@LINE-1]]:20: warning: avoid using platform-dependent fundamental integer type 'unsigned long long'; consider using a typedef or fixed-width type instead [modernize-avoid-fundamental-integer-types] + +// Test semantic types that should NOT trigger warnings +char global_char = 'a'; +signed char global_signed_char = 'b'; +unsigned char global_unsigned_char = 'c'; +bool global_bool = true; +wchar_t global_wchar = L'w'; + +// Test function parameters +void function_with_int_param(int param) { +// CHECK-MESSAGES: :[[@LINE-1]]:34: warning: avoid using platform-dependent fundamental integer type 'int'; consider using a typedef or fixed-width type instead [modernize-avoid-fundamental-integer-types] +} + +void function_with_short_param(short param) { +// CHECK-MESSAGES: :[[@LINE-1]]:38: warning: avoid using platform-dependent fundamental integer type 'short'; consider using a typedef or fixed-width type instead [modernize-avoid-fundamental-integer-types] +} + +// Test function return types +int function_returning_int() { +// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: avoid using platform-dependent fundamental integer type 'int'; consider using a typedef or fixed-width type instead [modernize-avoid-fundamental-integer-types] + return 42; +} + +long function_returning_long() { +// CHECK-MESSAGES: :[[@LINE-1]]:6: warning: avoid using platform-dependent fundamental integer type 'long'; consider using a typedef or fixed-width type instead [modernize-avoid-fundamental-integer-types] + return 100L; +} + +// Test local variables +void test_local_variables() { + int local_int = 10; + // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: avoid using platform-dependent fundamental integer type 'int'; consider using a typedef or fixed-width type instead [modernize-avoid-fundamental-integer-types] + + short local_short = 5; + // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: avoid using platform-dependent fundamental integer type 'short'; consider using a typedef or fixed-width type instead [modernize-avoid-fundamental-integer-types] + + unsigned long local_unsigned_long = 200UL; + // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: avoid using platform-dependent fundamental integer type 'unsigned long'; consider using a typedef or fixed-width type instead [modernize-avoid-fundamental-integer-types] + + // These should not trigger warnings + char local_char = 'x'; + bool local_bool = false; +} + +// Test struct/class members +struct TestStruct { + int member_int; + // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: avoid using platform-dependent fundamental integer type 'int'; consider using a typedef or fixed-width type instead [modernize-avoid-fundamental-integer-types] + + long member_long; + // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: avoid using platform-dependent fundamental integer type 'long'; consider using a typedef or fixed-width type instead [modernize-avoid-fundamental-integer-types] + + // These should not trigger warnings + char member_char; + bool member_bool; +}; + +class TestClass { +public: + unsigned int public_member; + // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: avoid using platform-dependent fundamental integer type 'unsigned int'; consider using a typedef or fixed-width type instead [modernize-avoid-fundamental-integer-types] + +private: + short private_member; + // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: avoid using platform-dependent fundamental integer type 'short'; consider using a typedef or fixed-width type instead [modernize-avoid-fundamental-integer-types] +}; + +// Test typedefs and type aliases +typedef int MyInt; +// CHECK-MESSAGES: :[[@LINE-1]]:13: warning: avoid using platform-dependent fundamental integer type 'int'; consider using a typedef or fixed-width type instead [modernize-avoid-fundamental-integer-types] + +using MyLong = long; +// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: avoid using platform-dependent fundamental integer type 'long'; consider using a typedef or fixed-width type instead [modernize-avoid-fundamental-integer-types] + +// Test template parameters +template +void template_function(T param) {} + +template<> +void template_function(int param) { +// CHECK-MESSAGES: :[[@LINE-1]]:33: warning: avoid using platform-dependent fundamental integer type 'int'; consider using a typedef or fixed-width type instead [modernize-avoid-fundamental-integer-types] +} \ No newline at end of file From 48598ef4bd01a096a5bde29515df3e472cae2e0f Mon Sep 17 00:00:00 2001 From: JJ Marr Date: Thu, 3 Jul 2025 17:33:54 -0400 Subject: [PATCH 02/83] Test typedefs properly --- .../AvoidFundamentalIntegerTypesCheck.cpp | 32 ++++++++--------- .../AvoidFundamentalIntegerTypesCheck.h | 4 +-- .../avoid-fundamental-integer-types.cpp | 35 ++++++++++++++++++- 3 files changed, 50 insertions(+), 21 deletions(-) diff --git a/clang-tools-extra/clang-tidy/modernize/AvoidFundamentalIntegerTypesCheck.cpp b/clang-tools-extra/clang-tidy/modernize/AvoidFundamentalIntegerTypesCheck.cpp index 8a393bc894cfe..b5e2484e6396a 100644 --- a/clang-tools-extra/clang-tidy/modernize/AvoidFundamentalIntegerTypesCheck.cpp +++ b/clang-tools-extra/clang-tidy/modernize/AvoidFundamentalIntegerTypesCheck.cpp @@ -33,13 +33,7 @@ AST_MATCHER_P(clang::TypeLoc, hasType, 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); -} + : ClangTidyCheck(Name, Context) {} bool AvoidFundamentalIntegerTypesCheck::isFundamentalIntegerType( const Type *T) const { @@ -111,16 +105,14 @@ void AvoidFundamentalIntegerTypesCheck::registerMatchers(MatchFinder *Finder) { fieldDecl().bind("field_decl"), this); - // Match typedef declarations if not ignoring them - if (!IgnoreTypedefs) { - Finder->addMatcher( - typedefDecl().bind("typedef_decl"), - this); + // Match typedef declarations to check their underlying types + Finder->addMatcher( + typedefDecl().bind("typedef_decl"), + this); - Finder->addMatcher( - typeAliasDecl().bind("alias_decl"), - this); - } + Finder->addMatcher( + typeAliasDecl().bind("alias_decl"), + this); } void AvoidFundamentalIntegerTypesCheck::check( @@ -160,6 +152,12 @@ void AvoidFundamentalIntegerTypesCheck::check( if (Loc.isInvalid() || QT.isNull()) return; + // Check if the type is already a typedef - if so, don't warn + // since the user is already using a typedef (which is what we want) + if (QT->getAs()) { + return; + } + const Type *T = QT.getCanonicalType().getTypePtr(); if (!T) return; @@ -180,4 +178,4 @@ void AvoidFundamentalIntegerTypesCheck::check( << TypeName; } -} // namespace clang::tidy::modernize \ No newline at end of file +} // namespace clang::tidy::modernize diff --git a/clang-tools-extra/clang-tidy/modernize/AvoidFundamentalIntegerTypesCheck.h b/clang-tools-extra/clang-tidy/modernize/AvoidFundamentalIntegerTypesCheck.h index 41e8cd5ceb87e..c1e4fb4748e5d 100644 --- a/clang-tools-extra/clang-tidy/modernize/AvoidFundamentalIntegerTypesCheck.h +++ b/clang-tools-extra/clang-tidy/modernize/AvoidFundamentalIntegerTypesCheck.h @@ -27,7 +27,6 @@ class AvoidFundamentalIntegerTypesCheck : public ClangTidyCheck { AvoidFundamentalIntegerTypesCheck(StringRef Name, ClangTidyContext *Context); 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; } @@ -36,11 +35,10 @@ class AvoidFundamentalIntegerTypesCheck : public ClangTidyCheck { } private: - const bool IgnoreTypedefs; bool isFundamentalIntegerType(const Type *T) const; bool isSemanticType(const Type *T) const; }; } // namespace clang::tidy::modernize -#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MODERNIZE_AVOIDFUNDAMENTALINTEGERTYPESCHECK_H \ No newline at end of file +#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MODERNIZE_AVOIDFUNDAMENTALINTEGERTYPESCHECK_H diff --git a/clang-tools-extra/test/clang-tidy/checkers/modernize/avoid-fundamental-integer-types.cpp b/clang-tools-extra/test/clang-tidy/checkers/modernize/avoid-fundamental-integer-types.cpp index 7d4860d95a3ce..ad2c4e6884e57 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/modernize/avoid-fundamental-integer-types.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/modernize/avoid-fundamental-integer-types.cpp @@ -1,5 +1,17 @@ // RUN: %check_clang_tidy %s modernize-avoid-fundamental-integer-types %t +// Mock fixed-width integer types +// NOLINTBEGIN(modernize-avoid-fundamental-integer-types) +typedef unsigned int uint32_t; +typedef int int32_t; +typedef unsigned long long uint64_t; +typedef long long int64_t; + +// Mock standard library semantic types +typedef unsigned long size_t; +typedef long ptrdiff_t; +// NOLINTEND(modernize-avoid-fundamental-integer-types) + // Test fundamental integer types that should trigger warnings int global_int = 42; // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: avoid using platform-dependent fundamental integer type 'int'; consider using a typedef or fixed-width type instead [modernize-avoid-fundamental-integer-types] @@ -32,6 +44,16 @@ unsigned char global_unsigned_char = 'c'; bool global_bool = true; wchar_t global_wchar = L'w'; +// Test fixed-width types that should NOT trigger warnings +uint32_t global_uint32 = 42U; +int32_t global_int32 = 42; +uint64_t global_uint64 = 100ULL; +int64_t global_int64 = 100LL; + +// Test semantic standard library types that should NOT trigger warnings +size_t global_size = 100; +ptrdiff_t global_ptrdiff = 50; + // Test function parameters void function_with_int_param(int param) { // CHECK-MESSAGES: :[[@LINE-1]]:34: warning: avoid using platform-dependent fundamental integer type 'int'; consider using a typedef or fixed-width type instead [modernize-avoid-fundamental-integer-types] @@ -66,6 +88,14 @@ void test_local_variables() { // These should not trigger warnings char local_char = 'x'; bool local_bool = false; + + // Fixed-width types should not trigger warnings + uint32_t local_uint32 = 42U; + int64_t local_int64 = 100LL; + + // Standard library semantic types should not trigger warnings + size_t local_size = 200; + ptrdiff_t local_ptrdiff = 10; } // Test struct/class members @@ -98,6 +128,9 @@ typedef int MyInt; using MyLong = long; // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: avoid using platform-dependent fundamental integer type 'long'; consider using a typedef or fixed-width type instead [modernize-avoid-fundamental-integer-types] +typedef long long customType; +// CHECK-MESSAGES: :[[@LINE-1]]:19: warning: avoid using platform-dependent fundamental integer type 'long long'; consider using a typedef or fixed-width type instead [modernize-avoid-fundamental-integer-types] + // Test template parameters template void template_function(T param) {} @@ -105,4 +138,4 @@ void template_function(T param) {} template<> void template_function(int param) { // CHECK-MESSAGES: :[[@LINE-1]]:33: warning: avoid using platform-dependent fundamental integer type 'int'; consider using a typedef or fixed-width type instead [modernize-avoid-fundamental-integer-types] -} \ No newline at end of file +} From 524fdd8c480cb3f3652c354a305b27a34fe53e45 Mon Sep 17 00:00:00 2001 From: JJ Marr Date: Thu, 3 Jul 2025 18:26:31 -0400 Subject: [PATCH 03/83] Document properly --- .../docs/clang-tidy/checks/list.rst | 1 + .../avoid-fundamental-integer-types.rst | 111 ++++++++++++++++++ 2 files changed, 112 insertions(+) create mode 100644 clang-tools-extra/docs/clang-tidy/checks/modernize/avoid-fundamental-integer-types.rst diff --git a/clang-tools-extra/docs/clang-tidy/checks/list.rst b/clang-tools-extra/docs/clang-tidy/checks/list.rst index 5098582d0c42b..33c2911fd9ae5 100644 --- a/clang-tools-extra/docs/clang-tidy/checks/list.rst +++ b/clang-tools-extra/docs/clang-tidy/checks/list.rst @@ -280,6 +280,7 @@ Clang-Tidy Checks :doc:`misc-use-internal-linkage `, "Yes" :doc:`modernize-avoid-bind `, "Yes" :doc:`modernize-avoid-c-arrays `, + :doc:`modernize-avoid-fundamental-integer-types `, :doc:`modernize-concat-nested-namespaces `, "Yes" :doc:`modernize-deprecated-headers `, "Yes" :doc:`modernize-deprecated-ios-base-aliases `, "Yes" diff --git a/clang-tools-extra/docs/clang-tidy/checks/modernize/avoid-fundamental-integer-types.rst b/clang-tools-extra/docs/clang-tidy/checks/modernize/avoid-fundamental-integer-types.rst new file mode 100644 index 0000000000000..df511e084701f --- /dev/null +++ b/clang-tools-extra/docs/clang-tidy/checks/modernize/avoid-fundamental-integer-types.rst @@ -0,0 +1,111 @@ +.. title:: clang-tidy - modernize-avoid-fundamental-integer-types + +modernize-avoid-fundamental-integer-types +========================================== + +Finds fundamental integer types and recommends using typedefs or fixed-width types instead. + +This check detects fundamental integer types (``int``, ``short``, ``long``, ``long long``, and their +``unsigned`` 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 integer 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 + +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 that +communicates your intent. + +Types Not Flagged +----------------- + +The following types are intentionally not flagged: + +- ``char``, ``signed char``, ``unsigned char`` (character types) +- ``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 + +``char`` is excluded because it is implementation-defined to always be 1 byte, regardless of the +platform's definition of a byte. + +``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. From d5fd2e798ecc6e9fcfd1863f37995c3f179d56c7 Mon Sep 17 00:00:00 2001 From: JJ Marr Date: Thu, 3 Jul 2025 21:50:01 -0400 Subject: [PATCH 04/83] Rename files --- .../AvoidPlatformSpecificFundamentalTypesCheck.cpp} | 0 .../AvoidPlatformSpecificFundamentalTypesCheck.h} | 0 .../avoid-platform-specific-fundamental-types.rst} | 0 .../avoid-platform-specific-fundamental-types.cpp} | 0 4 files changed, 0 insertions(+), 0 deletions(-) rename clang-tools-extra/clang-tidy/{modernize/AvoidFundamentalIntegerTypesCheck.cpp => portability/AvoidPlatformSpecificFundamentalTypesCheck.cpp} (100%) rename clang-tools-extra/clang-tidy/{modernize/AvoidFundamentalIntegerTypesCheck.h => portability/AvoidPlatformSpecificFundamentalTypesCheck.h} (100%) rename clang-tools-extra/docs/clang-tidy/checks/{modernize/avoid-fundamental-integer-types.rst => portability/avoid-platform-specific-fundamental-types.rst} (100%) rename clang-tools-extra/test/clang-tidy/checkers/{modernize/avoid-fundamental-integer-types.cpp => portability/avoid-platform-specific-fundamental-types.cpp} (100%) diff --git a/clang-tools-extra/clang-tidy/modernize/AvoidFundamentalIntegerTypesCheck.cpp b/clang-tools-extra/clang-tidy/portability/AvoidPlatformSpecificFundamentalTypesCheck.cpp similarity index 100% rename from clang-tools-extra/clang-tidy/modernize/AvoidFundamentalIntegerTypesCheck.cpp rename to clang-tools-extra/clang-tidy/portability/AvoidPlatformSpecificFundamentalTypesCheck.cpp diff --git a/clang-tools-extra/clang-tidy/modernize/AvoidFundamentalIntegerTypesCheck.h b/clang-tools-extra/clang-tidy/portability/AvoidPlatformSpecificFundamentalTypesCheck.h similarity index 100% rename from clang-tools-extra/clang-tidy/modernize/AvoidFundamentalIntegerTypesCheck.h rename to clang-tools-extra/clang-tidy/portability/AvoidPlatformSpecificFundamentalTypesCheck.h diff --git a/clang-tools-extra/docs/clang-tidy/checks/modernize/avoid-fundamental-integer-types.rst b/clang-tools-extra/docs/clang-tidy/checks/portability/avoid-platform-specific-fundamental-types.rst similarity index 100% rename from clang-tools-extra/docs/clang-tidy/checks/modernize/avoid-fundamental-integer-types.rst rename to clang-tools-extra/docs/clang-tidy/checks/portability/avoid-platform-specific-fundamental-types.rst diff --git a/clang-tools-extra/test/clang-tidy/checkers/modernize/avoid-fundamental-integer-types.cpp b/clang-tools-extra/test/clang-tidy/checkers/portability/avoid-platform-specific-fundamental-types.cpp similarity index 100% rename from clang-tools-extra/test/clang-tidy/checkers/modernize/avoid-fundamental-integer-types.cpp rename to clang-tools-extra/test/clang-tidy/checkers/portability/avoid-platform-specific-fundamental-types.cpp From 25425cc0f12d96d86619d83222d0222bc1d17538 Mon Sep 17 00:00:00 2001 From: JJ Marr Date: Thu, 3 Jul 2025 22:27:08 -0400 Subject: [PATCH 05/83] Other renaming for portability change --- .../clang-tidy/modernize/CMakeLists.txt | 1 - .../modernize/ModernizeTidyModule.cpp | 3 -- ...dPlatformSpecificFundamentalTypesCheck.cpp | 18 +++---- ...oidPlatformSpecificFundamentalTypesCheck.h | 18 +++---- .../clang-tidy/portability/CMakeLists.txt | 1 + .../portability/PortabilityTidyModule.cpp | 3 ++ .../docs/clang-tidy/checks/list.rst | 2 +- ...id-platform-specific-fundamental-types.rst | 6 +-- ...id-platform-specific-fundamental-types.cpp | 52 +++++++++---------- 9 files changed, 52 insertions(+), 52 deletions(-) diff --git a/clang-tools-extra/clang-tidy/modernize/CMakeLists.txt b/clang-tools-extra/clang-tidy/modernize/CMakeLists.txt index deb37c1ad9fb3..619a27b2f9bb6 100644 --- a/clang-tools-extra/clang-tidy/modernize/CMakeLists.txt +++ b/clang-tools-extra/clang-tidy/modernize/CMakeLists.txt @@ -6,7 +6,6 @@ set(LLVM_LINK_COMPONENTS add_clang_library(clangTidyModernizeModule STATIC AvoidBindCheck.cpp AvoidCArraysCheck.cpp - AvoidFundamentalIntegerTypesCheck.cpp ConcatNestedNamespacesCheck.cpp DeprecatedHeadersCheck.cpp DeprecatedIosBaseAliasesCheck.cpp diff --git a/clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp b/clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp index a42d55b26a311..fdf38bc4b6308 100644 --- a/clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp +++ b/clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp @@ -11,7 +11,6 @@ #include "../ClangTidyModuleRegistry.h" #include "AvoidBindCheck.h" #include "AvoidCArraysCheck.h" -#include "AvoidFundamentalIntegerTypesCheck.h" #include "ConcatNestedNamespacesCheck.h" #include "DeprecatedHeadersCheck.h" #include "DeprecatedIosBaseAliasesCheck.h" @@ -64,8 +63,6 @@ class ModernizeModule : public ClangTidyModule { void addCheckFactories(ClangTidyCheckFactories &CheckFactories) override { CheckFactories.registerCheck("modernize-avoid-bind"); CheckFactories.registerCheck("modernize-avoid-c-arrays"); - CheckFactories.registerCheck( - "modernize-avoid-fundamental-integer-types"); CheckFactories.registerCheck( "modernize-concat-nested-namespaces"); CheckFactories.registerCheck( diff --git a/clang-tools-extra/clang-tidy/portability/AvoidPlatformSpecificFundamentalTypesCheck.cpp b/clang-tools-extra/clang-tidy/portability/AvoidPlatformSpecificFundamentalTypesCheck.cpp index b5e2484e6396a..7eb9619577200 100644 --- a/clang-tools-extra/clang-tidy/portability/AvoidPlatformSpecificFundamentalTypesCheck.cpp +++ b/clang-tools-extra/clang-tidy/portability/AvoidPlatformSpecificFundamentalTypesCheck.cpp @@ -1,4 +1,4 @@ -//===--- AvoidFundamentalIntegerTypesCheck.cpp - clang-tidy ---------------===// +//===--- 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. @@ -6,14 +6,14 @@ // //===----------------------------------------------------------------------===// -#include "AvoidFundamentalIntegerTypesCheck.h" +#include "AvoidPlatformSpecificFundamentalTypesCheck.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 clang::tidy::portability { namespace { @@ -31,11 +31,11 @@ AST_MATCHER_P(clang::TypeLoc, hasType, } // namespace -AvoidFundamentalIntegerTypesCheck::AvoidFundamentalIntegerTypesCheck( +AvoidPlatformSpecificFundamentalTypesCheck::AvoidPlatformSpecificFundamentalTypesCheck( StringRef Name, ClangTidyContext *Context) : ClangTidyCheck(Name, Context) {} -bool AvoidFundamentalIntegerTypesCheck::isFundamentalIntegerType( +bool AvoidPlatformSpecificFundamentalTypesCheck::isFundamentalIntegerType( const Type *T) const { if (!T->isBuiltinType()) return false; @@ -59,7 +59,7 @@ bool AvoidFundamentalIntegerTypesCheck::isFundamentalIntegerType( } } -bool AvoidFundamentalIntegerTypesCheck::isSemanticType(const Type *T) const { +bool AvoidPlatformSpecificFundamentalTypesCheck::isSemanticType(const Type *T) const { if (!T->isBuiltinType()) return false; @@ -84,7 +84,7 @@ bool AvoidFundamentalIntegerTypesCheck::isSemanticType(const Type *T) const { } } -void AvoidFundamentalIntegerTypesCheck::registerMatchers(MatchFinder *Finder) { +void AvoidPlatformSpecificFundamentalTypesCheck::registerMatchers(MatchFinder *Finder) { // Match variable declarations with fundamental integer types Finder->addMatcher( varDecl().bind("var_decl"), @@ -115,7 +115,7 @@ void AvoidFundamentalIntegerTypesCheck::registerMatchers(MatchFinder *Finder) { this); } -void AvoidFundamentalIntegerTypesCheck::check( +void AvoidPlatformSpecificFundamentalTypesCheck::check( const MatchFinder::MatchResult &Result) { SourceLocation Loc; QualType QT; @@ -178,4 +178,4 @@ void AvoidFundamentalIntegerTypesCheck::check( << TypeName; } -} // namespace clang::tidy::modernize +} // namespace clang::tidy::portability diff --git a/clang-tools-extra/clang-tidy/portability/AvoidPlatformSpecificFundamentalTypesCheck.h b/clang-tools-extra/clang-tidy/portability/AvoidPlatformSpecificFundamentalTypesCheck.h index c1e4fb4748e5d..0b5c8053b5bfe 100644 --- a/clang-tools-extra/clang-tidy/portability/AvoidPlatformSpecificFundamentalTypesCheck.h +++ b/clang-tools-extra/clang-tidy/portability/AvoidPlatformSpecificFundamentalTypesCheck.h @@ -1,4 +1,4 @@ -//===--- AvoidFundamentalIntegerTypesCheck.h - clang-tidy -------*- C++ -*-===// +//===--- 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. @@ -6,12 +6,12 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MODERNIZE_AVOIDFUNDAMENTALINTEGERTYPESCHECK_H -#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MODERNIZE_AVOIDFUNDAMENTALINTEGERTYPESCHECK_H +#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::modernize { +namespace clang::tidy::portability { /// Find fundamental integer types and recommend using typedefs or fixed-width types. /// @@ -21,10 +21,10 @@ namespace clang::tidy::modernize { /// char32_t, size_t, and ptrdiff_t. /// /// For the user-facing documentation see: -/// http://clang.llvm.org/extra/clang-tidy/checks/modernize/avoid-fundamental-integer-types.html -class AvoidFundamentalIntegerTypesCheck : public ClangTidyCheck { +/// http://clang.llvm.org/extra/clang-tidy/checks/portability/avoid-platform-specific-fundamental-types.html +class AvoidPlatformSpecificFundamentalTypesCheck : public ClangTidyCheck { public: - AvoidFundamentalIntegerTypesCheck(StringRef Name, ClangTidyContext *Context); + AvoidPlatformSpecificFundamentalTypesCheck(StringRef Name, ClangTidyContext *Context); void registerMatchers(ast_matchers::MatchFinder *Finder) override; void check(const ast_matchers::MatchFinder::MatchResult &Result) override; bool isLanguageVersionSupported(const LangOptions &LangOpts) const override { @@ -39,6 +39,6 @@ class AvoidFundamentalIntegerTypesCheck : public ClangTidyCheck { bool isSemanticType(const Type *T) const; }; -} // namespace clang::tidy::modernize +} // namespace clang::tidy::portability -#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MODERNIZE_AVOIDFUNDAMENTALINTEGERTYPESCHECK_H +#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_PORTABILITY_AVOIDPLATFORMSPECIFICFUNDAMENTALTYPESCHECK_H diff --git a/clang-tools-extra/clang-tidy/portability/CMakeLists.txt b/clang-tools-extra/clang-tidy/portability/CMakeLists.txt index 73d74a550afc0..014c1ea883547 100644 --- a/clang-tools-extra/clang-tidy/portability/CMakeLists.txt +++ b/clang-tools-extra/clang-tidy/portability/CMakeLists.txt @@ -5,6 +5,7 @@ set(LLVM_LINK_COMPONENTS ) add_clang_library(clangTidyPortabilityModule STATIC + AvoidPlatformSpecificFundamentalTypesCheck.cpp AvoidPragmaOnceCheck.cpp PortabilityTidyModule.cpp RestrictSystemIncludesCheck.cpp diff --git a/clang-tools-extra/clang-tidy/portability/PortabilityTidyModule.cpp b/clang-tools-extra/clang-tidy/portability/PortabilityTidyModule.cpp index 98853556588b3..2e2ddb91934f3 100644 --- a/clang-tools-extra/clang-tidy/portability/PortabilityTidyModule.cpp +++ b/clang-tools-extra/clang-tidy/portability/PortabilityTidyModule.cpp @@ -9,6 +9,7 @@ #include "../ClangTidy.h" #include "../ClangTidyModule.h" #include "../ClangTidyModuleRegistry.h" +#include "AvoidPlatformSpecificFundamentalTypesCheck.h" #include "AvoidPragmaOnceCheck.h" #include "RestrictSystemIncludesCheck.h" #include "SIMDIntrinsicsCheck.h" @@ -21,6 +22,8 @@ namespace portability { class PortabilityModule : public ClangTidyModule { public: void addCheckFactories(ClangTidyCheckFactories &CheckFactories) override { + CheckFactories.registerCheck( + "portability-avoid-platform-specific-fundamental-types"); CheckFactories.registerCheck( "portability-avoid-pragma-once"); CheckFactories.registerCheck( diff --git a/clang-tools-extra/docs/clang-tidy/checks/list.rst b/clang-tools-extra/docs/clang-tidy/checks/list.rst index 33c2911fd9ae5..73d9ef7039ac4 100644 --- a/clang-tools-extra/docs/clang-tidy/checks/list.rst +++ b/clang-tools-extra/docs/clang-tidy/checks/list.rst @@ -280,7 +280,6 @@ Clang-Tidy Checks :doc:`misc-use-internal-linkage `, "Yes" :doc:`modernize-avoid-bind `, "Yes" :doc:`modernize-avoid-c-arrays `, - :doc:`modernize-avoid-fundamental-integer-types `, :doc:`modernize-concat-nested-namespaces `, "Yes" :doc:`modernize-deprecated-headers `, "Yes" :doc:`modernize-deprecated-ios-base-aliases `, "Yes" @@ -354,6 +353,7 @@ Clang-Tidy Checks :doc:`performance-type-promotion-in-math-fn `, "Yes" :doc:`performance-unnecessary-copy-initialization `, "Yes" :doc:`performance-unnecessary-value-param `, "Yes" + :doc:`portability-avoid-platform-specific-fundamental-types `, :doc:`portability-avoid-pragma-once `, :doc:`portability-restrict-system-includes `, "Yes" :doc:`portability-simd-intrinsics `, diff --git a/clang-tools-extra/docs/clang-tidy/checks/portability/avoid-platform-specific-fundamental-types.rst b/clang-tools-extra/docs/clang-tidy/checks/portability/avoid-platform-specific-fundamental-types.rst index df511e084701f..3da0b19658343 100644 --- a/clang-tools-extra/docs/clang-tidy/checks/portability/avoid-platform-specific-fundamental-types.rst +++ b/clang-tools-extra/docs/clang-tidy/checks/portability/avoid-platform-specific-fundamental-types.rst @@ -1,9 +1,9 @@ -.. title:: clang-tidy - modernize-avoid-fundamental-integer-types +.. title:: clang-tidy - portability-avoid-platform-specific-fundamental-types -modernize-avoid-fundamental-integer-types +portability-avoid-platform-specific-fundamental-types ========================================== -Finds fundamental integer types and recommends using typedefs or fixed-width types instead. +Finds fundamental types and recommends using typedefs or fixed-width types instead. This check detects fundamental integer types (``int``, ``short``, ``long``, ``long long``, and their ``unsigned`` variants) and warns against their use due to non-standard platform-dependent behavior. diff --git a/clang-tools-extra/test/clang-tidy/checkers/portability/avoid-platform-specific-fundamental-types.cpp b/clang-tools-extra/test/clang-tidy/checkers/portability/avoid-platform-specific-fundamental-types.cpp index ad2c4e6884e57..3eb2b3b8a3074 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/portability/avoid-platform-specific-fundamental-types.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/portability/avoid-platform-specific-fundamental-types.cpp @@ -1,7 +1,7 @@ -// RUN: %check_clang_tidy %s modernize-avoid-fundamental-integer-types %t +// RUN: %check_clang_tidy %s portability-avoid-platform-specific-fundamental-types %t // Mock fixed-width integer types -// NOLINTBEGIN(modernize-avoid-fundamental-integer-types) +// NOLINTBEGIN(portability-avoid-platform-specific-fundamental-types) typedef unsigned int uint32_t; typedef int int32_t; typedef unsigned long long uint64_t; @@ -10,32 +10,32 @@ typedef long long int64_t; // Mock standard library semantic types typedef unsigned long size_t; typedef long ptrdiff_t; -// NOLINTEND(modernize-avoid-fundamental-integer-types) +// NOLINTEND(portability-avoid-platform-specific-fundamental-types) // Test fundamental integer types that should trigger warnings int global_int = 42; -// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: avoid using platform-dependent fundamental integer type 'int'; consider using a typedef or fixed-width type instead [modernize-avoid-fundamental-integer-types] +// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: avoid using platform-dependent fundamental integer type 'int'; consider using a typedef or fixed-width type instead [portability-avoid-platform-specific-fundamental-types] short global_short = 10; -// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: avoid using platform-dependent fundamental integer type 'short'; consider using a typedef or fixed-width type instead [modernize-avoid-fundamental-integer-types] +// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: avoid using platform-dependent fundamental integer type 'short'; consider using a typedef or fixed-width type instead [portability-avoid-platform-specific-fundamental-types] long global_long = 100L; -// CHECK-MESSAGES: :[[@LINE-1]]:6: warning: avoid using platform-dependent fundamental integer type 'long'; consider using a typedef or fixed-width type instead [modernize-avoid-fundamental-integer-types] +// CHECK-MESSAGES: :[[@LINE-1]]:6: warning: avoid using platform-dependent fundamental integer type 'long'; consider using a typedef or fixed-width type instead [portability-avoid-platform-specific-fundamental-types] long long global_long_long = 1000LL; -// CHECK-MESSAGES: :[[@LINE-1]]:11: warning: avoid using platform-dependent fundamental integer type 'long long'; consider using a typedef or fixed-width type instead [modernize-avoid-fundamental-integer-types] +// CHECK-MESSAGES: :[[@LINE-1]]:11: warning: avoid using platform-dependent fundamental integer type 'long long'; consider using a typedef or fixed-width type instead [portability-avoid-platform-specific-fundamental-types] unsigned int global_unsigned_int = 42U; -// CHECK-MESSAGES: :[[@LINE-1]]:14: warning: avoid using platform-dependent fundamental integer type 'unsigned int'; consider using a typedef or fixed-width type instead [modernize-avoid-fundamental-integer-types] +// CHECK-MESSAGES: :[[@LINE-1]]:14: warning: avoid using platform-dependent fundamental integer type 'unsigned int'; consider using a typedef or fixed-width type instead [portability-avoid-platform-specific-fundamental-types] unsigned short global_unsigned_short = 10U; -// CHECK-MESSAGES: :[[@LINE-1]]:16: warning: avoid using platform-dependent fundamental integer type 'unsigned short'; consider using a typedef or fixed-width type instead [modernize-avoid-fundamental-integer-types] +// CHECK-MESSAGES: :[[@LINE-1]]:16: warning: avoid using platform-dependent fundamental integer type 'unsigned short'; consider using a typedef or fixed-width type instead [portability-avoid-platform-specific-fundamental-types] unsigned long global_unsigned_long = 100UL; -// CHECK-MESSAGES: :[[@LINE-1]]:15: warning: avoid using platform-dependent fundamental integer type 'unsigned long'; consider using a typedef or fixed-width type instead [modernize-avoid-fundamental-integer-types] +// CHECK-MESSAGES: :[[@LINE-1]]:15: warning: avoid using platform-dependent fundamental integer type 'unsigned long'; consider using a typedef or fixed-width type instead [portability-avoid-platform-specific-fundamental-types] unsigned long long global_unsigned_long_long = 1000ULL; -// CHECK-MESSAGES: :[[@LINE-1]]:20: warning: avoid using platform-dependent fundamental integer type 'unsigned long long'; consider using a typedef or fixed-width type instead [modernize-avoid-fundamental-integer-types] +// CHECK-MESSAGES: :[[@LINE-1]]:20: warning: avoid using platform-dependent fundamental integer type 'unsigned long long'; consider using a typedef or fixed-width type instead [portability-avoid-platform-specific-fundamental-types] // Test semantic types that should NOT trigger warnings char global_char = 'a'; @@ -56,34 +56,34 @@ ptrdiff_t global_ptrdiff = 50; // Test function parameters void function_with_int_param(int param) { -// CHECK-MESSAGES: :[[@LINE-1]]:34: warning: avoid using platform-dependent fundamental integer type 'int'; consider using a typedef or fixed-width type instead [modernize-avoid-fundamental-integer-types] +// CHECK-MESSAGES: :[[@LINE-1]]:34: warning: avoid using platform-dependent fundamental integer type 'int'; consider using a typedef or fixed-width type instead [portability-avoid-platform-specific-fundamental-types] } void function_with_short_param(short param) { -// CHECK-MESSAGES: :[[@LINE-1]]:38: warning: avoid using platform-dependent fundamental integer type 'short'; consider using a typedef or fixed-width type instead [modernize-avoid-fundamental-integer-types] +// CHECK-MESSAGES: :[[@LINE-1]]:38: warning: avoid using platform-dependent fundamental integer type 'short'; consider using a typedef or fixed-width type instead [portability-avoid-platform-specific-fundamental-types] } // Test function return types int function_returning_int() { -// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: avoid using platform-dependent fundamental integer type 'int'; consider using a typedef or fixed-width type instead [modernize-avoid-fundamental-integer-types] +// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: avoid using platform-dependent fundamental integer type 'int'; consider using a typedef or fixed-width type instead [portability-avoid-platform-specific-fundamental-types] return 42; } long function_returning_long() { -// CHECK-MESSAGES: :[[@LINE-1]]:6: warning: avoid using platform-dependent fundamental integer type 'long'; consider using a typedef or fixed-width type instead [modernize-avoid-fundamental-integer-types] +// CHECK-MESSAGES: :[[@LINE-1]]:6: warning: avoid using platform-dependent fundamental integer type 'long'; consider using a typedef or fixed-width type instead [portability-avoid-platform-specific-fundamental-types] return 100L; } // Test local variables void test_local_variables() { int local_int = 10; - // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: avoid using platform-dependent fundamental integer type 'int'; consider using a typedef or fixed-width type instead [modernize-avoid-fundamental-integer-types] + // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: avoid using platform-dependent fundamental integer type 'int'; consider using a typedef or fixed-width type instead [portability-avoid-platform-specific-fundamental-types] short local_short = 5; - // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: avoid using platform-dependent fundamental integer type 'short'; consider using a typedef or fixed-width type instead [modernize-avoid-fundamental-integer-types] + // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: avoid using platform-dependent fundamental integer type 'short'; consider using a typedef or fixed-width type instead [portability-avoid-platform-specific-fundamental-types] unsigned long local_unsigned_long = 200UL; - // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: avoid using platform-dependent fundamental integer type 'unsigned long'; consider using a typedef or fixed-width type instead [modernize-avoid-fundamental-integer-types] + // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: avoid using platform-dependent fundamental integer type 'unsigned long'; consider using a typedef or fixed-width type instead [portability-avoid-platform-specific-fundamental-types] // These should not trigger warnings char local_char = 'x'; @@ -101,10 +101,10 @@ void test_local_variables() { // Test struct/class members struct TestStruct { int member_int; - // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: avoid using platform-dependent fundamental integer type 'int'; consider using a typedef or fixed-width type instead [modernize-avoid-fundamental-integer-types] + // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: avoid using platform-dependent fundamental integer type 'int'; consider using a typedef or fixed-width type instead [portability-avoid-platform-specific-fundamental-types] long member_long; - // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: avoid using platform-dependent fundamental integer type 'long'; consider using a typedef or fixed-width type instead [modernize-avoid-fundamental-integer-types] + // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: avoid using platform-dependent fundamental integer type 'long'; consider using a typedef or fixed-width type instead [portability-avoid-platform-specific-fundamental-types] // These should not trigger warnings char member_char; @@ -114,22 +114,22 @@ struct TestStruct { class TestClass { public: unsigned int public_member; - // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: avoid using platform-dependent fundamental integer type 'unsigned int'; consider using a typedef or fixed-width type instead [modernize-avoid-fundamental-integer-types] + // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: avoid using platform-dependent fundamental integer type 'unsigned int'; consider using a typedef or fixed-width type instead [portability-avoid-platform-specific-fundamental-types] private: short private_member; - // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: avoid using platform-dependent fundamental integer type 'short'; consider using a typedef or fixed-width type instead [modernize-avoid-fundamental-integer-types] + // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: avoid using platform-dependent fundamental integer type 'short'; consider using a typedef or fixed-width type instead [portability-avoid-platform-specific-fundamental-types] }; // Test typedefs and type aliases typedef int MyInt; -// CHECK-MESSAGES: :[[@LINE-1]]:13: warning: avoid using platform-dependent fundamental integer type 'int'; consider using a typedef or fixed-width type instead [modernize-avoid-fundamental-integer-types] +// CHECK-MESSAGES: :[[@LINE-1]]:13: warning: avoid using platform-dependent fundamental integer type 'int'; consider using a typedef or fixed-width type instead [portability-avoid-platform-specific-fundamental-types] using MyLong = long; -// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: avoid using platform-dependent fundamental integer type 'long'; consider using a typedef or fixed-width type instead [modernize-avoid-fundamental-integer-types] +// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: avoid using platform-dependent fundamental integer type 'long'; consider using a typedef or fixed-width type instead [portability-avoid-platform-specific-fundamental-types] typedef long long customType; -// CHECK-MESSAGES: :[[@LINE-1]]:19: warning: avoid using platform-dependent fundamental integer type 'long long'; consider using a typedef or fixed-width type instead [modernize-avoid-fundamental-integer-types] +// CHECK-MESSAGES: :[[@LINE-1]]:19: warning: avoid using platform-dependent fundamental integer type 'long long'; consider using a typedef or fixed-width type instead [portability-avoid-platform-specific-fundamental-types] // Test template parameters template @@ -137,5 +137,5 @@ void template_function(T param) {} template<> void template_function(int param) { -// CHECK-MESSAGES: :[[@LINE-1]]:33: warning: avoid using platform-dependent fundamental integer type 'int'; consider using a typedef or fixed-width type instead [modernize-avoid-fundamental-integer-types] +// CHECK-MESSAGES: :[[@LINE-1]]:33: warning: avoid using platform-dependent fundamental integer type 'int'; consider using a typedef or fixed-width type instead [portability-avoid-platform-specific-fundamental-types] } From 86787ec25d3ebba2afeb570f930e0a3eb5ced730 Mon Sep 17 00:00:00 2001 From: JJ Marr Date: Thu, 3 Jul 2025 22:29:08 -0400 Subject: [PATCH 06/83] Formatting fix --- ...dPlatformSpecificFundamentalTypesCheck.cpp | 50 +++++++++---------- ...oidPlatformSpecificFundamentalTypesCheck.h | 9 ++-- 2 files changed, 29 insertions(+), 30 deletions(-) diff --git a/clang-tools-extra/clang-tidy/portability/AvoidPlatformSpecificFundamentalTypesCheck.cpp b/clang-tools-extra/clang-tidy/portability/AvoidPlatformSpecificFundamentalTypesCheck.cpp index 7eb9619577200..2c04e8020ff3a 100644 --- a/clang-tools-extra/clang-tidy/portability/AvoidPlatformSpecificFundamentalTypesCheck.cpp +++ b/clang-tools-extra/clang-tidy/portability/AvoidPlatformSpecificFundamentalTypesCheck.cpp @@ -1,4 +1,5 @@ -//===--- AvoidPlatformSpecificFundamentalTypesCheck.cpp - clang-tidy ---------------===// +//===--- 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. @@ -31,8 +32,9 @@ AST_MATCHER_P(clang::TypeLoc, hasType, } // namespace -AvoidPlatformSpecificFundamentalTypesCheck::AvoidPlatformSpecificFundamentalTypesCheck( - StringRef Name, ClangTidyContext *Context) +AvoidPlatformSpecificFundamentalTypesCheck:: + AvoidPlatformSpecificFundamentalTypesCheck(StringRef Name, + ClangTidyContext *Context) : ClangTidyCheck(Name, Context) {} bool AvoidPlatformSpecificFundamentalTypesCheck::isFundamentalIntegerType( @@ -59,7 +61,8 @@ bool AvoidPlatformSpecificFundamentalTypesCheck::isFundamentalIntegerType( } } -bool AvoidPlatformSpecificFundamentalTypesCheck::isSemanticType(const Type *T) const { +bool AvoidPlatformSpecificFundamentalTypesCheck::isSemanticType( + const Type *T) const { if (!T->isBuiltinType()) return false; @@ -84,35 +87,24 @@ bool AvoidPlatformSpecificFundamentalTypesCheck::isSemanticType(const Type *T) c } } -void AvoidPlatformSpecificFundamentalTypesCheck::registerMatchers(MatchFinder *Finder) { +void AvoidPlatformSpecificFundamentalTypesCheck::registerMatchers( + MatchFinder *Finder) { // Match variable declarations with fundamental integer types - Finder->addMatcher( - varDecl().bind("var_decl"), - this); + Finder->addMatcher(varDecl().bind("var_decl"), this); // Match function declarations with fundamental integer return types - Finder->addMatcher( - functionDecl().bind("func_decl"), - this); + Finder->addMatcher(functionDecl().bind("func_decl"), this); // Match function parameters with fundamental integer types - Finder->addMatcher( - parmVarDecl().bind("param_decl"), - this); + Finder->addMatcher(parmVarDecl().bind("param_decl"), this); // Match field declarations with fundamental integer types - Finder->addMatcher( - fieldDecl().bind("field_decl"), - this); + Finder->addMatcher(fieldDecl().bind("field_decl"), this); // Match typedef declarations to check their underlying types - Finder->addMatcher( - typedefDecl().bind("typedef_decl"), - this); + Finder->addMatcher(typedefDecl().bind("typedef_decl"), this); - Finder->addMatcher( - typeAliasDecl().bind("alias_decl"), - this); + Finder->addMatcher(typeAliasDecl().bind("alias_decl"), this); } void AvoidPlatformSpecificFundamentalTypesCheck::check( @@ -125,11 +117,13 @@ void AvoidPlatformSpecificFundamentalTypesCheck::check( Loc = VD->getLocation(); QT = VD->getType(); DeclType = "variable"; - } else if (const auto *FD = Result.Nodes.getNodeAs("func_decl")) { + } else if (const auto *FD = + Result.Nodes.getNodeAs("func_decl")) { Loc = FD->getLocation(); QT = FD->getReturnType(); DeclType = "function return type"; - } else if (const auto *PD = Result.Nodes.getNodeAs("param_decl")) { + } else if (const auto *PD = + Result.Nodes.getNodeAs("param_decl")) { Loc = PD->getLocation(); QT = PD->getType(); DeclType = "function parameter"; @@ -137,11 +131,13 @@ void AvoidPlatformSpecificFundamentalTypesCheck::check( Loc = FD->getLocation(); QT = FD->getType(); DeclType = "field"; - } else if (const auto *TD = Result.Nodes.getNodeAs("typedef_decl")) { + } else if (const auto *TD = + Result.Nodes.getNodeAs("typedef_decl")) { Loc = TD->getLocation(); QT = TD->getUnderlyingType(); DeclType = "typedef"; - } else if (const auto *AD = Result.Nodes.getNodeAs("alias_decl")) { + } else if (const auto *AD = + Result.Nodes.getNodeAs("alias_decl")) { Loc = AD->getLocation(); QT = AD->getUnderlyingType(); DeclType = "type alias"; diff --git a/clang-tools-extra/clang-tidy/portability/AvoidPlatformSpecificFundamentalTypesCheck.h b/clang-tools-extra/clang-tidy/portability/AvoidPlatformSpecificFundamentalTypesCheck.h index 0b5c8053b5bfe..7c446328c8ea0 100644 --- a/clang-tools-extra/clang-tidy/portability/AvoidPlatformSpecificFundamentalTypesCheck.h +++ b/clang-tools-extra/clang-tidy/portability/AvoidPlatformSpecificFundamentalTypesCheck.h @@ -1,4 +1,5 @@ -//===--- AvoidPlatformSpecificFundamentalTypesCheck.h - clang-tidy -------*- C++ -*-===// +//===--- 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. @@ -13,7 +14,8 @@ namespace clang::tidy::portability { -/// Find fundamental integer types and recommend using typedefs or fixed-width types. +/// 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 @@ -24,7 +26,8 @@ namespace clang::tidy::portability { /// 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); + AvoidPlatformSpecificFundamentalTypesCheck(StringRef Name, + ClangTidyContext *Context); void registerMatchers(ast_matchers::MatchFinder *Finder) override; void check(const ast_matchers::MatchFinder::MatchResult &Result) override; bool isLanguageVersionSupported(const LangOptions &LangOpts) const override { From c66668e825213c540c7e6d7de0eefcd283b2defd Mon Sep 17 00:00:00 2001 From: JJ Marr Date: Thu, 3 Jul 2025 22:40:12 -0400 Subject: [PATCH 07/83] Make matchers more specific --- ...dPlatformSpecificFundamentalTypesCheck.cpp | 99 +++++++++---------- 1 file changed, 49 insertions(+), 50 deletions(-) diff --git a/clang-tools-extra/clang-tidy/portability/AvoidPlatformSpecificFundamentalTypesCheck.cpp b/clang-tools-extra/clang-tidy/portability/AvoidPlatformSpecificFundamentalTypesCheck.cpp index 2c04e8020ff3a..b1b2dde523428 100644 --- a/clang-tools-extra/clang-tidy/portability/AvoidPlatformSpecificFundamentalTypesCheck.cpp +++ b/clang-tools-extra/clang-tidy/portability/AvoidPlatformSpecificFundamentalTypesCheck.cpp @@ -16,22 +16,6 @@ using namespace clang::ast_matchers; namespace clang::tidy::portability { -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 - AvoidPlatformSpecificFundamentalTypesCheck:: AvoidPlatformSpecificFundamentalTypesCheck(StringRef Name, ClangTidyContext *Context) @@ -89,22 +73,55 @@ bool AvoidPlatformSpecificFundamentalTypesCheck::isSemanticType( void AvoidPlatformSpecificFundamentalTypesCheck::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 to check their underlying types - Finder->addMatcher(typedefDecl().bind("typedef_decl"), this); - - Finder->addMatcher(typeAliasDecl().bind("alias_decl"), this); + // Create a matcher for platform-specific fundamental integer types + // This should only match direct uses of builtin types, not typedefs + auto PlatformSpecificFundamentalType = qualType( + allOf( + // Must be a builtin type directly (not through typedef) + builtinType(), + // Only match the specific fundamental integer types we care about + anyOf( + asString("int"), + asString("unsigned int"), + asString("short"), + asString("unsigned short"), + asString("long"), + asString("unsigned long"), + asString("long long"), + asString("unsigned long long") + ) + ) + ); + + // Match variable declarations with platform-specific fundamental integer types + Finder->addMatcher( + varDecl(hasType(PlatformSpecificFundamentalType)).bind("var_decl"), + this); + + // Match function declarations with platform-specific fundamental integer return types + Finder->addMatcher( + functionDecl(returns(PlatformSpecificFundamentalType)).bind("func_decl"), + this); + + // Match function parameters with platform-specific fundamental integer types + Finder->addMatcher( + parmVarDecl(hasType(PlatformSpecificFundamentalType)).bind("param_decl"), + this); + + // Match field declarations with platform-specific fundamental integer types + Finder->addMatcher( + fieldDecl(hasType(PlatformSpecificFundamentalType)).bind("field_decl"), + this); + + // Match typedef declarations with platform-specific fundamental underlying types + Finder->addMatcher( + typedefDecl(hasUnderlyingType(PlatformSpecificFundamentalType)).bind("typedef_decl"), + this); + + // Match type alias declarations with platform-specific fundamental underlying types + Finder->addMatcher( + typeAliasDecl(hasType(PlatformSpecificFundamentalType)).bind("alias_decl"), + this); } void AvoidPlatformSpecificFundamentalTypesCheck::check( @@ -148,24 +165,6 @@ void AvoidPlatformSpecificFundamentalTypesCheck::check( if (Loc.isInvalid() || QT.isNull()) return; - // Check if the type is already a typedef - if so, don't warn - // since the user is already using a typedef (which is what we want) - if (QT->getAs()) { - return; - } - - const Type *T = QT.getCanonicalType().getTypePtr(); - if (!T) - return; - - // Skip if not a fundamental integer type - if (!isFundamentalIntegerType(T)) - return; - - // Skip semantic types - if (isSemanticType(T)) - return; - // Get the type name for the diagnostic std::string TypeName = QT.getAsString(); From 1b314bbe3a6705e5e95cc2945a985416231f0568 Mon Sep 17 00:00:00 2001 From: JJ Marr Date: Thu, 3 Jul 2025 22:45:33 -0400 Subject: [PATCH 08/83] Remove dead code --- ...dPlatformSpecificFundamentalTypesCheck.cpp | 115 +++++------------- ...oidPlatformSpecificFundamentalTypesCheck.h | 4 - 2 files changed, 30 insertions(+), 89 deletions(-) diff --git a/clang-tools-extra/clang-tidy/portability/AvoidPlatformSpecificFundamentalTypesCheck.cpp b/clang-tools-extra/clang-tidy/portability/AvoidPlatformSpecificFundamentalTypesCheck.cpp index b1b2dde523428..e7efa2fde6564 100644 --- a/clang-tools-extra/clang-tidy/portability/AvoidPlatformSpecificFundamentalTypesCheck.cpp +++ b/clang-tools-extra/clang-tidy/portability/AvoidPlatformSpecificFundamentalTypesCheck.cpp @@ -21,84 +21,33 @@ AvoidPlatformSpecificFundamentalTypesCheck:: ClangTidyContext *Context) : ClangTidyCheck(Name, Context) {} -bool AvoidPlatformSpecificFundamentalTypesCheck::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 AvoidPlatformSpecificFundamentalTypesCheck::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 AvoidPlatformSpecificFundamentalTypesCheck::registerMatchers( MatchFinder *Finder) { // Create a matcher for platform-specific fundamental integer types // This should only match direct uses of builtin types, not typedefs - auto PlatformSpecificFundamentalType = qualType( - allOf( - // Must be a builtin type directly (not through typedef) - builtinType(), - // Only match the specific fundamental integer types we care about - anyOf( - asString("int"), - asString("unsigned int"), - asString("short"), - asString("unsigned short"), - asString("long"), - asString("unsigned long"), - asString("long long"), - asString("unsigned long long") - ) - ) - ); - - // Match variable declarations with platform-specific fundamental integer types + auto PlatformSpecificFundamentalType = qualType(allOf( + // Must be a builtin type directly (not through typedef) + builtinType(), + // Only match the specific fundamental integer types we care about + anyOf(asString("short"), asString("short int"), asString("signed short"), + asString("signed short int"), asString("unsigned short"), + asString("unsigned short int"), asString("int"), asString("signed"), + asString("signed int"), asString("unsigned"), + asString("unsigned int"), asString("long"), asString("long int"), + asString("signed long"), asString("signed long int"), + asString("unsigned long"), asString("unsigned long int"), + asString("long long"), asString("long long int"), + asString("signed long long"), asString("signed long long int"), + asString("unsigned long long"), + asString("unsigned long long int")))); + + // Match variable declarations with platform-specific fundamental integer + // types Finder->addMatcher( - varDecl(hasType(PlatformSpecificFundamentalType)).bind("var_decl"), - this); + varDecl(hasType(PlatformSpecificFundamentalType)).bind("var_decl"), this); - // Match function declarations with platform-specific fundamental integer return types + // Match function declarations with platform-specific fundamental integer + // return types Finder->addMatcher( functionDecl(returns(PlatformSpecificFundamentalType)).bind("func_decl"), this); @@ -113,51 +62,47 @@ void AvoidPlatformSpecificFundamentalTypesCheck::registerMatchers( fieldDecl(hasType(PlatformSpecificFundamentalType)).bind("field_decl"), this); - // Match typedef declarations with platform-specific fundamental underlying types + // Match typedef declarations with platform-specific fundamental underlying + // types Finder->addMatcher( - typedefDecl(hasUnderlyingType(PlatformSpecificFundamentalType)).bind("typedef_decl"), + typedefDecl(hasUnderlyingType(PlatformSpecificFundamentalType)) + .bind("typedef_decl"), this); - // Match type alias declarations with platform-specific fundamental underlying types - Finder->addMatcher( - typeAliasDecl(hasType(PlatformSpecificFundamentalType)).bind("alias_decl"), - this); + // Match type alias declarations with platform-specific fundamental underlying + // types + Finder->addMatcher(typeAliasDecl(hasType(PlatformSpecificFundamentalType)) + .bind("alias_decl"), + this); } void AvoidPlatformSpecificFundamentalTypesCheck::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"; } else if (const auto *FD = Result.Nodes.getNodeAs("func_decl")) { Loc = FD->getLocation(); QT = FD->getReturnType(); - DeclType = "function return type"; } else if (const auto *PD = Result.Nodes.getNodeAs("param_decl")) { Loc = PD->getLocation(); QT = PD->getType(); - DeclType = "function parameter"; } else if (const auto *FD = Result.Nodes.getNodeAs("field_decl")) { Loc = FD->getLocation(); QT = FD->getType(); - DeclType = "field"; } else if (const auto *TD = Result.Nodes.getNodeAs("typedef_decl")) { Loc = TD->getLocation(); QT = TD->getUnderlyingType(); - DeclType = "typedef"; } else if (const auto *AD = Result.Nodes.getNodeAs("alias_decl")) { Loc = AD->getLocation(); QT = AD->getUnderlyingType(); - DeclType = "type alias"; } else { return; } diff --git a/clang-tools-extra/clang-tidy/portability/AvoidPlatformSpecificFundamentalTypesCheck.h b/clang-tools-extra/clang-tidy/portability/AvoidPlatformSpecificFundamentalTypesCheck.h index 7c446328c8ea0..e0ae7c67fa310 100644 --- a/clang-tools-extra/clang-tidy/portability/AvoidPlatformSpecificFundamentalTypesCheck.h +++ b/clang-tools-extra/clang-tidy/portability/AvoidPlatformSpecificFundamentalTypesCheck.h @@ -36,10 +36,6 @@ class AvoidPlatformSpecificFundamentalTypesCheck : public ClangTidyCheck { std::optional getCheckTraversalKind() const override { return TK_IgnoreUnlessSpelledInSource; } - -private: - bool isFundamentalIntegerType(const Type *T) const; - bool isSemanticType(const Type *T) const; }; } // namespace clang::tidy::portability From 411d5987069dfba1861fc4ffc859b7324535db1d Mon Sep 17 00:00:00 2001 From: JJ Marr Date: Thu, 3 Jul 2025 22:48:57 -0400 Subject: [PATCH 09/83] Fix doc --- .../portability/avoid-platform-specific-fundamental-types.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clang-tools-extra/docs/clang-tidy/checks/portability/avoid-platform-specific-fundamental-types.rst b/clang-tools-extra/docs/clang-tidy/checks/portability/avoid-platform-specific-fundamental-types.rst index 3da0b19658343..2813b9ba385fd 100644 --- a/clang-tools-extra/docs/clang-tidy/checks/portability/avoid-platform-specific-fundamental-types.rst +++ b/clang-tools-extra/docs/clang-tidy/checks/portability/avoid-platform-specific-fundamental-types.rst @@ -1,7 +1,7 @@ .. 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. From b427df738990651cc0b95a3faa34e45c68da18c1 Mon Sep 17 00:00:00 2001 From: JJ Marr Date: Sat, 5 Jul 2025 15:20:19 -0400 Subject: [PATCH 10/83] Fix issue on MSVC --- .../avoid-platform-specific-fundamental-types.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/clang-tools-extra/test/clang-tidy/checkers/portability/avoid-platform-specific-fundamental-types.cpp b/clang-tools-extra/test/clang-tidy/checkers/portability/avoid-platform-specific-fundamental-types.cpp index 3eb2b3b8a3074..337166cdf3699 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/portability/avoid-platform-specific-fundamental-types.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/portability/avoid-platform-specific-fundamental-types.cpp @@ -8,8 +8,11 @@ typedef unsigned long long uint64_t; typedef long long int64_t; // Mock standard library semantic types -typedef unsigned long size_t; typedef long ptrdiff_t; +// MSVC defines size_t automatically +#ifndef _MSC_VER +typedef unsigned long size_t; +#endif // NOLINTEND(portability-avoid-platform-specific-fundamental-types) // Test fundamental integer types that should trigger warnings From 5dd5c722485d85022988f0948d955ed62680f2df Mon Sep 17 00:00:00 2001 From: JJ Marr Date: Sat, 5 Jul 2025 15:21:33 -0400 Subject: [PATCH 11/83] Merge comment with previous line --- .../portability/AvoidPlatformSpecificFundamentalTypesCheck.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/clang-tools-extra/clang-tidy/portability/AvoidPlatformSpecificFundamentalTypesCheck.cpp b/clang-tools-extra/clang-tidy/portability/AvoidPlatformSpecificFundamentalTypesCheck.cpp index e7efa2fde6564..286bbe420f260 100644 --- a/clang-tools-extra/clang-tidy/portability/AvoidPlatformSpecificFundamentalTypesCheck.cpp +++ b/clang-tools-extra/clang-tidy/portability/AvoidPlatformSpecificFundamentalTypesCheck.cpp @@ -1,5 +1,4 @@ -//===--- AvoidPlatformSpecificFundamentalTypesCheck.cpp - clang-tidy -//---------------===// +//===--- 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. From 7c2031bc94538d283fd03efb514f8ff93ae7aada Mon Sep 17 00:00:00 2001 From: JJ Marr Date: Sat, 5 Jul 2025 15:23:17 -0400 Subject: [PATCH 12/83] Add linter check to release notes --- clang-tools-extra/docs/ReleaseNotes.rst | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/clang-tools-extra/docs/ReleaseNotes.rst b/clang-tools-extra/docs/ReleaseNotes.rst index 198efee7754de..0815b7f844c0b 100644 --- a/clang-tools-extra/docs/ReleaseNotes.rst +++ b/clang-tools-extra/docs/ReleaseNotes.rst @@ -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 + or fixed-width types instead to improve portability across different platforms. + - New :doc:`portability-avoid-pragma-once ` check. From 475f1b2bc2c817206222490e64e9e61560a9ed76 Mon Sep 17 00:00:00 2001 From: JJ Marr Date: Sat, 5 Jul 2025 15:46:45 -0400 Subject: [PATCH 13/83] Update documentation --- ...id-platform-specific-fundamental-types.rst | 60 +++++++++++-------- 1 file changed, 36 insertions(+), 24 deletions(-) diff --git a/clang-tools-extra/docs/clang-tidy/checks/portability/avoid-platform-specific-fundamental-types.rst b/clang-tools-extra/docs/clang-tidy/checks/portability/avoid-platform-specific-fundamental-types.rst index 2813b9ba385fd..ef015f9c578fb 100644 --- a/clang-tools-extra/docs/clang-tidy/checks/portability/avoid-platform-specific-fundamental-types.rst +++ b/clang-tools-extra/docs/clang-tidy/checks/portability/avoid-platform-specific-fundamental-types.rst @@ -5,14 +5,15 @@ portability-avoid-platform-specific-fundamental-types Finds fundamental types and recommends using typedefs or fixed-width types instead. -This check detects fundamental integer types (``int``, ``short``, ``long``, ``long long``, and their -``unsigned`` 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 +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. +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 -------- @@ -61,7 +62,8 @@ Examples int64_t member_int64; }; -The check will also warn about typedef declarations that use fundamental types as their underlying type: +The check will also warn about typedef declarations that use fundamental types +as their underlying type: .. code-block:: c++ @@ -78,34 +80,44 @@ The check will also warn about typedef declarations that use fundamental types a Rationale --------- -Fundamental integer types have platform-dependent sizes and behavior: +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 +- ``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 - -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 that -communicates your intent. +- ``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: -- ``char``, ``signed char``, ``unsigned char`` (character types) - ``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 -``char`` is excluded because it is implementation-defined to always be 1 byte, regardless of the -platform's definition of a byte. - ``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. From 20e43d842f37928898080af62f74558eb5008198 Mon Sep 17 00:00:00 2001 From: JJ Marr Date: Sat, 5 Jul 2025 15:46:51 -0400 Subject: [PATCH 14/83] Fix redundant check --- .../portability/AvoidPlatformSpecificFundamentalTypesCheck.cpp | 3 --- 1 file changed, 3 deletions(-) diff --git a/clang-tools-extra/clang-tidy/portability/AvoidPlatformSpecificFundamentalTypesCheck.cpp b/clang-tools-extra/clang-tidy/portability/AvoidPlatformSpecificFundamentalTypesCheck.cpp index 286bbe420f260..a05d8b09ebd7c 100644 --- a/clang-tools-extra/clang-tidy/portability/AvoidPlatformSpecificFundamentalTypesCheck.cpp +++ b/clang-tools-extra/clang-tidy/portability/AvoidPlatformSpecificFundamentalTypesCheck.cpp @@ -106,9 +106,6 @@ void AvoidPlatformSpecificFundamentalTypesCheck::check( return; } - if (Loc.isInvalid() || QT.isNull()) - return; - // Get the type name for the diagnostic std::string TypeName = QT.getAsString(); From 20e9b32d647f6760e13d493fdf42865e93973730 Mon Sep 17 00:00:00 2001 From: JJ Marr Date: Sat, 5 Jul 2025 17:29:43 -0400 Subject: [PATCH 15/83] In progress work on float check --- ...dPlatformSpecificFundamentalTypesCheck.cpp | 179 +++++++++++++++--- ...oidPlatformSpecificFundamentalTypesCheck.h | 14 +- ...id-platform-specific-fundamental-types.rst | 34 ++++ ...form-specific-fundamental-types-floats.cpp | 100 ++++++++++ 4 files changed, 299 insertions(+), 28 deletions(-) create mode 100644 clang-tools-extra/test/clang-tidy/checkers/portability/avoid-platform-specific-fundamental-types-floats.cpp diff --git a/clang-tools-extra/clang-tidy/portability/AvoidPlatformSpecificFundamentalTypesCheck.cpp b/clang-tools-extra/clang-tidy/portability/AvoidPlatformSpecificFundamentalTypesCheck.cpp index a05d8b09ebd7c..f28507300e246 100644 --- a/clang-tools-extra/clang-tidy/portability/AvoidPlatformSpecificFundamentalTypesCheck.cpp +++ b/clang-tools-extra/clang-tidy/portability/AvoidPlatformSpecificFundamentalTypesCheck.cpp @@ -10,6 +10,7 @@ #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; @@ -18,45 +19,121 @@ namespace clang::tidy::portability { AvoidPlatformSpecificFundamentalTypesCheck:: AvoidPlatformSpecificFundamentalTypesCheck(StringRef Name, ClangTidyContext *Context) - : ClangTidyCheck(Name, 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) { - // Create a matcher for platform-specific fundamental integer types - // This should only match direct uses of builtin types, not typedefs + // 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(), - // Only match the specific fundamental integer types we care about - anyOf(asString("short"), asString("short int"), asString("signed short"), - asString("signed short int"), asString("unsigned short"), - asString("unsigned short int"), asString("int"), asString("signed"), - asString("signed int"), asString("unsigned"), - asString("unsigned int"), asString("long"), asString("long int"), - asString("signed long"), asString("signed long int"), - asString("unsigned long"), asString("unsigned long int"), - asString("long long"), asString("long long int"), - asString("signed long long"), asString("signed long long int"), - asString("unsigned long long"), - asString("unsigned long long int")))); - - // Match variable declarations with platform-specific fundamental integer - // types + // 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 with platform-specific fundamental integer - // return types + // Match function declarations with platform-specific fundamental return types Finder->addMatcher( functionDecl(returns(PlatformSpecificFundamentalType)).bind("func_decl"), this); - // Match function parameters with platform-specific fundamental integer types + // Match function parameters with platform-specific fundamental types Finder->addMatcher( parmVarDecl(hasType(PlatformSpecificFundamentalType)).bind("param_decl"), this); - // Match field declarations with platform-specific fundamental integer types + // Match field declarations with platform-specific fundamental types Finder->addMatcher( fieldDecl(hasType(PlatformSpecificFundamentalType)).bind("field_decl"), this); @@ -79,29 +156,48 @@ void AvoidPlatformSpecificFundamentalTypesCheck::check( const MatchFinder::MatchResult &Result) { SourceLocation Loc; QualType QT; + SourceRange TypeRange; if (const auto *VD = Result.Nodes.getNodeAs("var_decl")) { Loc = VD->getLocation(); QT = VD->getType(); + if (VD->getTypeSourceInfo()) { + TypeRange = VD->getTypeSourceInfo()->getTypeLoc().getSourceRange(); + } } else if (const auto *FD = Result.Nodes.getNodeAs("func_decl")) { Loc = FD->getLocation(); QT = FD->getReturnType(); + if (FD->getTypeSourceInfo()) { + TypeRange = FD->getTypeSourceInfo()->getTypeLoc().getSourceRange(); + } } else if (const auto *PD = Result.Nodes.getNodeAs("param_decl")) { Loc = PD->getLocation(); QT = PD->getType(); + if (PD->getTypeSourceInfo()) { + TypeRange = PD->getTypeSourceInfo()->getTypeLoc().getSourceRange(); + } } else if (const auto *FD = Result.Nodes.getNodeAs("field_decl")) { Loc = FD->getLocation(); QT = FD->getType(); + if (FD->getTypeSourceInfo()) { + TypeRange = FD->getTypeSourceInfo()->getTypeLoc().getSourceRange(); + } } else if (const auto *TD = Result.Nodes.getNodeAs("typedef_decl")) { Loc = TD->getLocation(); QT = TD->getUnderlyingType(); + if (TD->getTypeSourceInfo()) { + TypeRange = TD->getTypeSourceInfo()->getTypeLoc().getSourceRange(); + } } else if (const auto *AD = Result.Nodes.getNodeAs("alias_decl")) { Loc = AD->getLocation(); QT = AD->getUnderlyingType(); + if (AD->getTypeSourceInfo()) { + TypeRange = AD->getTypeSourceInfo()->getTypeLoc().getSourceRange(); + } } else { return; } @@ -109,9 +205,42 @@ void AvoidPlatformSpecificFundamentalTypesCheck::check( // Get the type name for the diagnostic std::string TypeName = QT.getAsString(); - diag(Loc, "avoid using platform-dependent fundamental integer type '%0'; " - "consider using a typedef or fixed-width type instead") - << TypeName; + // Check if this is a floating point type + const auto *BT = QT->getAs(); + bool IsFloatingPoint = BT && (BT->getKind() == BuiltinType::Half || + BT->getKind() == BuiltinType::BFloat16 || + BT->getKind() == BuiltinType::Float || + BT->getKind() == BuiltinType::Double || + BT->getKind() == BuiltinType::LongDouble); + + if (IsFloatingPoint) { + // Handle floating point types + std::string Replacement = getFloatReplacement(BT, *Result.Context); + if (!Replacement.empty()) { + auto Diag = + diag(Loc, "avoid using platform-dependent floating point type '%0'; " + "consider using '%1' instead") + << TypeName << Replacement; + + if (TypeRange.isValid()) { + Diag << FixItHint::CreateReplacement(TypeRange, Replacement); + } + + if (auto IncludeFixit = IncludeInserter.createIncludeInsertion( + Result.SourceManager->getFileID(Loc), "")) { + Diag << *IncludeFixit; + } + } else { + diag(Loc, "avoid using platform-dependent floating point type '%0'; " + "consider using a typedef or fixed-width type instead") + << TypeName; + } + } else { + // Handle integer types + diag(Loc, "avoid using platform-dependent fundamental integer type '%0'; " + "consider using a typedef or fixed-width type instead") + << TypeName; + } } } // namespace clang::tidy::portability diff --git a/clang-tools-extra/clang-tidy/portability/AvoidPlatformSpecificFundamentalTypesCheck.h b/clang-tools-extra/clang-tidy/portability/AvoidPlatformSpecificFundamentalTypesCheck.h index e0ae7c67fa310..4d59cae47c52b 100644 --- a/clang-tools-extra/clang-tidy/portability/AvoidPlatformSpecificFundamentalTypesCheck.h +++ b/clang-tools-extra/clang-tidy/portability/AvoidPlatformSpecificFundamentalTypesCheck.h @@ -1,16 +1,16 @@ -//===--- AvoidPlatformSpecificFundamentalTypesCheck.h - clang-tidy -------*- C++ -//-*-===// +//===--- 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 { @@ -28,14 +28,22 @@ 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; + utils::IncludeInserter IncludeInserter; + std::string getFloatReplacement(const BuiltinType *BT, ASTContext &Context) const; }; } // namespace clang::tidy::portability diff --git a/clang-tools-extra/docs/clang-tidy/checks/portability/avoid-platform-specific-fundamental-types.rst b/clang-tools-extra/docs/clang-tidy/checks/portability/avoid-platform-specific-fundamental-types.rst index ef015f9c578fb..54fba9dfaec25 100644 --- a/clang-tools-extra/docs/clang-tidy/checks/portability/avoid-platform-specific-fundamental-types.rst +++ b/clang-tools-extra/docs/clang-tidy/checks/portability/avoid-platform-specific-fundamental-types.rst @@ -121,3 +121,37 @@ The following types are intentionally not flagged: ``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. + + Example with ``WarnOnFloats`` enabled: + + .. code-block:: c++ + + // Bad: platform-dependent floating point types + float pi = 3.14f; + double e = 2.71828; + + .. code-block:: c++ + + // Good: use fixed-width floating point types + #include // C++23 + + float32_t pi = 3.14f; + float64_t e = 2.71828; diff --git a/clang-tools-extra/test/clang-tidy/checkers/portability/avoid-platform-specific-fundamental-types-floats.cpp b/clang-tools-extra/test/clang-tidy/checkers/portability/avoid-platform-specific-fundamental-types-floats.cpp new file mode 100644 index 0000000000000..22b3629731b66 --- /dev/null +++ b/clang-tools-extra/test/clang-tidy/checkers/portability/avoid-platform-specific-fundamental-types-floats.cpp @@ -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; + +double global_double = 3.14159; +// CHECK-MESSAGES: :[[@LINE-1]]:8: warning: avoid using platform-dependent floating point type 'double'; consider using 'float64_t' instead [portability-avoid-platform-specific-fundamental-types] +// CHECK-FIXES: float64_t global_double = 3.14159; + +// Test integer types that should still trigger warnings +int global_int = 42; +// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: avoid using platform-dependent fundamental integer type 'int'; consider using a typedef or fixed-width type instead [portability-avoid-platform-specific-fundamental-types] + +// Test function parameters with float types +void function_with_float_param(float param) { +// CHECK-MESSAGES: :[[@LINE-1]]:38: warning: avoid using platform-dependent floating point type 'float'; consider using 'float32_t' instead [portability-avoid-platform-specific-fundamental-types] +} + +void function_with_double_param(double param) { +// CHECK-MESSAGES: :[[@LINE-1]]:40: warning: avoid using platform-dependent floating point type 'double'; consider using 'float64_t' instead [portability-avoid-platform-specific-fundamental-types] +} + +// Test function return types with float types +float function_returning_float() { +// 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] + return 3.14f; +} + +double function_returning_double() { +// CHECK-MESSAGES: :[[@LINE-1]]:8: warning: avoid using platform-dependent floating point type 'double'; consider using 'float64_t' instead [portability-avoid-platform-specific-fundamental-types] + return 3.14159; +} + +// Test local variables with float types +void test_local_float_variables() { + float local_float = 2.71f; + // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: avoid using platform-dependent floating point type 'float'; consider using 'float32_t' instead [portability-avoid-platform-specific-fundamental-types] + + double local_double = 2.71828; + // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: avoid using platform-dependent floating point type 'double'; consider using 'float64_t' instead [portability-avoid-platform-specific-fundamental-types] + + // Fixed-width types should not trigger warnings + float32_t local_float32 = 3.14f; + float64_t local_float64 = 3.14159; +} + +// Test struct/class members with float types +struct TestFloatStruct { + float member_float; + // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: avoid using platform-dependent floating point type 'float'; consider using 'float32_t' instead [portability-avoid-platform-specific-fundamental-types] + + double member_double; + // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: avoid using platform-dependent floating point type 'double'; consider using 'float64_t' instead [portability-avoid-platform-specific-fundamental-types] + + // Fixed-width types should not trigger warnings + float32_t member_float32; + float64_t member_float64; +}; + +class TestFloatClass { +public: + float public_float_member; + // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: avoid using platform-dependent floating point type 'float'; consider using 'float32_t' instead [portability-avoid-platform-specific-fundamental-types] + +private: + double private_double_member; + // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: avoid using platform-dependent floating point type 'double'; consider using 'float64_t' instead [portability-avoid-platform-specific-fundamental-types] +}; + +// Test typedefs and type aliases with float types +typedef float MyFloat; +// CHECK-MESSAGES: :[[@LINE-1]]:15: warning: avoid using platform-dependent floating point type 'float'; consider using 'float32_t' instead [portability-avoid-platform-specific-fundamental-types] + +using MyDouble = double; +// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: avoid using platform-dependent floating point type 'double'; consider using 'float64_t' instead [portability-avoid-platform-specific-fundamental-types] + +// Test template specializations with float types +template +void template_function(T param) {} + +template<> +void template_function(float param) { +// CHECK-MESSAGES: :[[@LINE-1]]:37: warning: avoid using platform-dependent floating point type 'float'; consider using 'float32_t' instead [portability-avoid-platform-specific-fundamental-types] +} + +template<> +void template_function(double param) { +// CHECK-MESSAGES: :[[@LINE-1]]:39: warning: avoid using platform-dependent floating point type 'double'; consider using 'float64_t' instead [portability-avoid-platform-specific-fundamental-types] +} From f49a289fde746f4e011209a87c44fc2f6d58c806 Mon Sep 17 00:00:00 2001 From: JJ Marr <168750718+jj-marr@users.noreply.github.com> Date: Sat, 5 Jul 2025 17:51:14 -0400 Subject: [PATCH 16/83] Declare const Co-authored-by: EugeneZelenko --- .../portability/AvoidPlatformSpecificFundamentalTypesCheck.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clang-tools-extra/clang-tidy/portability/AvoidPlatformSpecificFundamentalTypesCheck.cpp b/clang-tools-extra/clang-tidy/portability/AvoidPlatformSpecificFundamentalTypesCheck.cpp index f28507300e246..6ea84516def42 100644 --- a/clang-tools-extra/clang-tidy/portability/AvoidPlatformSpecificFundamentalTypesCheck.cpp +++ b/clang-tools-extra/clang-tidy/portability/AvoidPlatformSpecificFundamentalTypesCheck.cpp @@ -203,7 +203,7 @@ void AvoidPlatformSpecificFundamentalTypesCheck::check( } // Get the type name for the diagnostic - std::string TypeName = QT.getAsString(); + const std::string TypeName = QT.getAsString(); // Check if this is a floating point type const auto *BT = QT->getAs(); From 143fcadfeaf23b78b4661be5ed432baabb4d6c40 Mon Sep 17 00:00:00 2001 From: JJ Marr Date: Sat, 5 Jul 2025 18:36:37 -0400 Subject: [PATCH 17/83] Synchronize with release notes --- .../portability/avoid-platform-specific-fundamental-types.rst | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/clang-tools-extra/docs/clang-tidy/checks/portability/avoid-platform-specific-fundamental-types.rst b/clang-tools-extra/docs/clang-tidy/checks/portability/avoid-platform-specific-fundamental-types.rst index 54fba9dfaec25..6f0835aba9c41 100644 --- a/clang-tools-extra/docs/clang-tidy/checks/portability/avoid-platform-specific-fundamental-types.rst +++ b/clang-tools-extra/docs/clang-tidy/checks/portability/avoid-platform-specific-fundamental-types.rst @@ -3,7 +3,8 @@ portability-avoid-platform-specific-fundamental-types ===================================================== -Finds fundamental types and recommends using typedefs or fixed-width types instead. +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 From 3c2ccd5fd336ebf007fcb22aab4f2f0c999b8f4f Mon Sep 17 00:00:00 2001 From: JJ Marr Date: Sat, 5 Jul 2025 18:44:55 -0400 Subject: [PATCH 18/83] Attempt to format --- .../AvoidPlatformSpecificFundamentalTypesCheck.h | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/clang-tools-extra/clang-tidy/portability/AvoidPlatformSpecificFundamentalTypesCheck.h b/clang-tools-extra/clang-tidy/portability/AvoidPlatformSpecificFundamentalTypesCheck.h index 4d59cae47c52b..da9e73660bace 100644 --- a/clang-tools-extra/clang-tidy/portability/AvoidPlatformSpecificFundamentalTypesCheck.h +++ b/clang-tools-extra/clang-tidy/portability/AvoidPlatformSpecificFundamentalTypesCheck.h @@ -1,10 +1,12 @@ -//===--- AvoidPlatformSpecificFundamentalTypesCheck.h - clang-tidy -------*- C++ -*-===// +// 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 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_PORTABILITY_AVOIDPLATFORMSPECIFICFUNDAMENTALTYPESCHECK_H #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_PORTABILITY_AVOIDPLATFORMSPECIFICFUNDAMENTALTYPESCHECK_H @@ -43,7 +45,8 @@ class AvoidPlatformSpecificFundamentalTypesCheck : public ClangTidyCheck { private: const bool WarnOnFloats; utils::IncludeInserter IncludeInserter; - std::string getFloatReplacement(const BuiltinType *BT, ASTContext &Context) const; + std::string getFloatReplacement(const BuiltinType *BT, + ASTContext &Context) const; }; } // namespace clang::tidy::portability From 40b8be31da0db152ac0c7ee2aff3cae29dc062d2 Mon Sep 17 00:00:00 2001 From: JJ Marr Date: Sun, 6 Jul 2025 01:10:01 -0400 Subject: [PATCH 19/83] Allow for int to not be warned --- ...dPlatformSpecificFundamentalTypesCheck.cpp | 70 +++++++++++-------- ...oidPlatformSpecificFundamentalTypesCheck.h | 1 + ...tform-specific-fundamental-types-ints.cpp} | 0 3 files changed, 43 insertions(+), 28 deletions(-) rename clang-tools-extra/test/clang-tidy/checkers/portability/{avoid-platform-specific-fundamental-types.cpp => avoid-platform-specific-fundamental-types-ints.cpp} (100%) diff --git a/clang-tools-extra/clang-tidy/portability/AvoidPlatformSpecificFundamentalTypesCheck.cpp b/clang-tools-extra/clang-tidy/portability/AvoidPlatformSpecificFundamentalTypesCheck.cpp index 6ea84516def42..c5f320c89dbb1 100644 --- a/clang-tools-extra/clang-tidy/portability/AvoidPlatformSpecificFundamentalTypesCheck.cpp +++ b/clang-tools-extra/clang-tidy/portability/AvoidPlatformSpecificFundamentalTypesCheck.cpp @@ -21,6 +21,7 @@ AvoidPlatformSpecificFundamentalTypesCheck:: ClangTidyContext *Context) : ClangTidyCheck(Name, Context), WarnOnFloats(Options.get("WarnOnFloats", false)), + WarnOnInts(Options.get("WarnOnInts", true)), IncludeInserter(Options.getLocalOrGlobal("IncludeStyle", utils::IncludeSorter::IS_LLVM), areDiagsSelfContained()) {} @@ -33,6 +34,7 @@ void AvoidPlatformSpecificFundamentalTypesCheck::registerPPCallbacks( void AvoidPlatformSpecificFundamentalTypesCheck::storeOptions( ClangTidyOptions::OptionMap &Opts) { Options.store(Opts, "WarnOnFloats", WarnOnFloats); + Options.store(Opts, "WarnOnInts", WarnOnInts); Options.store(Opts, "IncludeStyle", IncludeInserter.getStyle()); } @@ -74,37 +76,49 @@ std::string AvoidPlatformSpecificFundamentalTypesCheck::getFloatReplacement( 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"}; + 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.push_back("half"); - TypeStrings.push_back("__bf16"); - TypeStrings.push_back("float"); - TypeStrings.push_back("double"); - TypeStrings.push_back("long double"); + TypeStrings.insert(TypeStrings.end(), { + "half", + "__bf16", + "float", + "double", + "long double"}); + } + + // If no types are enabled, return early + if (TypeStrings.empty()) { + return; } // Create the matcher dynamically diff --git a/clang-tools-extra/clang-tidy/portability/AvoidPlatformSpecificFundamentalTypesCheck.h b/clang-tools-extra/clang-tidy/portability/AvoidPlatformSpecificFundamentalTypesCheck.h index da9e73660bace..c15660a9cf1f8 100644 --- a/clang-tools-extra/clang-tidy/portability/AvoidPlatformSpecificFundamentalTypesCheck.h +++ b/clang-tools-extra/clang-tidy/portability/AvoidPlatformSpecificFundamentalTypesCheck.h @@ -44,6 +44,7 @@ class AvoidPlatformSpecificFundamentalTypesCheck : public ClangTidyCheck { private: const bool WarnOnFloats; + const bool WarnOnInts; utils::IncludeInserter IncludeInserter; std::string getFloatReplacement(const BuiltinType *BT, ASTContext &Context) const; diff --git a/clang-tools-extra/test/clang-tidy/checkers/portability/avoid-platform-specific-fundamental-types.cpp b/clang-tools-extra/test/clang-tidy/checkers/portability/avoid-platform-specific-fundamental-types-ints.cpp similarity index 100% rename from clang-tools-extra/test/clang-tidy/checkers/portability/avoid-platform-specific-fundamental-types.cpp rename to clang-tools-extra/test/clang-tidy/checkers/portability/avoid-platform-specific-fundamental-types-ints.cpp From 93c8489cb193c786056cf12f11f7eadd109f9dcd Mon Sep 17 00:00:00 2001 From: JJ Marr Date: Sun, 6 Jul 2025 01:13:38 -0400 Subject: [PATCH 20/83] Reduce some duplication --- ...dPlatformSpecificFundamentalTypesCheck.cpp | 30 ++++++++----------- 1 file changed, 12 insertions(+), 18 deletions(-) diff --git a/clang-tools-extra/clang-tidy/portability/AvoidPlatformSpecificFundamentalTypesCheck.cpp b/clang-tools-extra/clang-tidy/portability/AvoidPlatformSpecificFundamentalTypesCheck.cpp index c5f320c89dbb1..3b783ccc2e764 100644 --- a/clang-tools-extra/clang-tidy/portability/AvoidPlatformSpecificFundamentalTypesCheck.cpp +++ b/clang-tools-extra/clang-tidy/portability/AvoidPlatformSpecificFundamentalTypesCheck.cpp @@ -172,46 +172,40 @@ void AvoidPlatformSpecificFundamentalTypesCheck::check( QualType QT; SourceRange TypeRange; + auto SetTypeRange = [&TypeRange](auto Decl){ + if(Decl->getTypeSourceInfo()) { + TypeRange = Decl->getTypeSourceInfo()->getTypeLoc().getSourceRange(); + } + }; + if (const auto *VD = Result.Nodes.getNodeAs("var_decl")) { Loc = VD->getLocation(); QT = VD->getType(); - if (VD->getTypeSourceInfo()) { - TypeRange = VD->getTypeSourceInfo()->getTypeLoc().getSourceRange(); - } + SetTypeRange(VD); } else if (const auto *FD = Result.Nodes.getNodeAs("func_decl")) { Loc = FD->getLocation(); QT = FD->getReturnType(); - if (FD->getTypeSourceInfo()) { - TypeRange = FD->getTypeSourceInfo()->getTypeLoc().getSourceRange(); - } + SetTypeRange(FD); } else if (const auto *PD = Result.Nodes.getNodeAs("param_decl")) { Loc = PD->getLocation(); QT = PD->getType(); - if (PD->getTypeSourceInfo()) { - TypeRange = PD->getTypeSourceInfo()->getTypeLoc().getSourceRange(); - } + SetTypeRange(PD); } else if (const auto *FD = Result.Nodes.getNodeAs("field_decl")) { Loc = FD->getLocation(); QT = FD->getType(); - if (FD->getTypeSourceInfo()) { - TypeRange = FD->getTypeSourceInfo()->getTypeLoc().getSourceRange(); - } + SetTypeRange(FD); } else if (const auto *TD = Result.Nodes.getNodeAs("typedef_decl")) { Loc = TD->getLocation(); QT = TD->getUnderlyingType(); - if (TD->getTypeSourceInfo()) { - TypeRange = TD->getTypeSourceInfo()->getTypeLoc().getSourceRange(); - } + SetTypeRange(TD); } else if (const auto *AD = Result.Nodes.getNodeAs("alias_decl")) { Loc = AD->getLocation(); QT = AD->getUnderlyingType(); - if (AD->getTypeSourceInfo()) { - TypeRange = AD->getTypeSourceInfo()->getTypeLoc().getSourceRange(); - } + SetTypeRange(AD); } else { return; } From 91eb7655fa848b9b8a60f4ad44f444b3e78b4346 Mon Sep 17 00:00:00 2001 From: JJ Marr Date: Sun, 6 Jul 2025 01:36:58 -0400 Subject: [PATCH 21/83] vibecoding: not even once --- .../AvoidPlatformSpecificFundamentalTypesCheck.cpp | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/clang-tools-extra/clang-tidy/portability/AvoidPlatformSpecificFundamentalTypesCheck.cpp b/clang-tools-extra/clang-tidy/portability/AvoidPlatformSpecificFundamentalTypesCheck.cpp index 3b783ccc2e764..b9ed6c6078e3b 100644 --- a/clang-tools-extra/clang-tidy/portability/AvoidPlatformSpecificFundamentalTypesCheck.cpp +++ b/clang-tools-extra/clang-tidy/portability/AvoidPlatformSpecificFundamentalTypesCheck.cpp @@ -215,13 +215,8 @@ void AvoidPlatformSpecificFundamentalTypesCheck::check( // Check if this is a floating point type const auto *BT = QT->getAs(); - bool IsFloatingPoint = BT && (BT->getKind() == BuiltinType::Half || - BT->getKind() == BuiltinType::BFloat16 || - BT->getKind() == BuiltinType::Float || - BT->getKind() == BuiltinType::Double || - BT->getKind() == BuiltinType::LongDouble); - if (IsFloatingPoint) { + if (BT->isFloatingPoint()) { // Handle floating point types std::string Replacement = getFloatReplacement(BT, *Result.Context); if (!Replacement.empty()) { From 723a76e716433cbc0675d675fb6e54aca70945d5 Mon Sep 17 00:00:00 2001 From: JJ Marr Date: Sun, 6 Jul 2025 01:39:18 -0400 Subject: [PATCH 22/83] For each loop --- .../AvoidPlatformSpecificFundamentalTypesCheck.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/clang-tools-extra/clang-tidy/portability/AvoidPlatformSpecificFundamentalTypesCheck.cpp b/clang-tools-extra/clang-tidy/portability/AvoidPlatformSpecificFundamentalTypesCheck.cpp index b9ed6c6078e3b..6621480b448ca 100644 --- a/clang-tools-extra/clang-tidy/portability/AvoidPlatformSpecificFundamentalTypesCheck.cpp +++ b/clang-tools-extra/clang-tidy/portability/AvoidPlatformSpecificFundamentalTypesCheck.cpp @@ -122,9 +122,9 @@ void AvoidPlatformSpecificFundamentalTypesCheck::registerMatchers( } // 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 TypeMatcher = asString(TypeStrings.front()); + for (const auto& TypeString : TypeStrings) { + TypeMatcher = anyOf(TypeMatcher, asString(TypeString)); } auto PlatformSpecificFundamentalType = qualType(allOf( From a30bedf1cec06544e6ba67bdb21e65ace08466ba Mon Sep 17 00:00:00 2001 From: JJ Marr Date: Sun, 6 Jul 2025 01:39:37 -0400 Subject: [PATCH 23/83] Format code --- .../AvoidPlatformSpecificFundamentalTypesCheck.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/clang-tools-extra/clang-tidy/portability/AvoidPlatformSpecificFundamentalTypesCheck.cpp b/clang-tools-extra/clang-tidy/portability/AvoidPlatformSpecificFundamentalTypesCheck.cpp index 6621480b448ca..bae2712134a53 100644 --- a/clang-tools-extra/clang-tidy/portability/AvoidPlatformSpecificFundamentalTypesCheck.cpp +++ b/clang-tools-extra/clang-tidy/portability/AvoidPlatformSpecificFundamentalTypesCheck.cpp @@ -123,7 +123,7 @@ void AvoidPlatformSpecificFundamentalTypesCheck::registerMatchers( // Create the matcher dynamically auto TypeMatcher = asString(TypeStrings.front()); - for (const auto& TypeString : TypeStrings) { + for (const auto &TypeString : TypeStrings) { TypeMatcher = anyOf(TypeMatcher, asString(TypeString)); } @@ -172,8 +172,8 @@ void AvoidPlatformSpecificFundamentalTypesCheck::check( QualType QT; SourceRange TypeRange; - auto SetTypeRange = [&TypeRange](auto Decl){ - if(Decl->getTypeSourceInfo()) { + auto SetTypeRange = [&TypeRange](auto Decl) { + if (Decl->getTypeSourceInfo()) { TypeRange = Decl->getTypeSourceInfo()->getTypeLoc().getSourceRange(); } }; From 76125bb2832a7db4ef0cba4b4884f1253d79d6a4 Mon Sep 17 00:00:00 2001 From: JJ Marr Date: Sun, 6 Jul 2025 01:54:30 -0400 Subject: [PATCH 24/83] Warn on chars --- ...dPlatformSpecificFundamentalTypesCheck.cpp | 20 +++++- ...oidPlatformSpecificFundamentalTypesCheck.h | 1 + ...id-platform-specific-fundamental-types.rst | 32 ++++++++++ ...tform-specific-fundamental-types-chars.cpp | 63 +++++++++++++++++++ 4 files changed, 115 insertions(+), 1 deletion(-) create mode 100644 clang-tools-extra/test/clang-tidy/checkers/portability/avoid-platform-specific-fundamental-types-chars.cpp diff --git a/clang-tools-extra/clang-tidy/portability/AvoidPlatformSpecificFundamentalTypesCheck.cpp b/clang-tools-extra/clang-tidy/portability/AvoidPlatformSpecificFundamentalTypesCheck.cpp index bae2712134a53..87ca48cdee46e 100644 --- a/clang-tools-extra/clang-tidy/portability/AvoidPlatformSpecificFundamentalTypesCheck.cpp +++ b/clang-tools-extra/clang-tidy/portability/AvoidPlatformSpecificFundamentalTypesCheck.cpp @@ -22,6 +22,7 @@ AvoidPlatformSpecificFundamentalTypesCheck:: : 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()) {} @@ -35,6 +36,7 @@ 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()); } @@ -116,6 +118,14 @@ void AvoidPlatformSpecificFundamentalTypesCheck::registerMatchers( "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; @@ -213,7 +223,7 @@ void AvoidPlatformSpecificFundamentalTypesCheck::check( // Get the type name for the diagnostic const std::string TypeName = QT.getAsString(); - // Check if this is a floating point type + // Check the type category const auto *BT = QT->getAs(); if (BT->isFloatingPoint()) { @@ -238,6 +248,14 @@ void AvoidPlatformSpecificFundamentalTypesCheck::check( "consider using a typedef or fixed-width type instead") << TypeName; } + } else if (BT->getKind() == BuiltinType::Char_S || + BT->getKind() == BuiltinType::Char_U || + BT->getKind() == BuiltinType::SChar || + BT->getKind() == BuiltinType::UChar) { + // Handle char types + diag(Loc, "avoid using platform-dependent character type '%0'; " + "consider using char8_t for text or std::byte for bytes") + << TypeName; } else { // Handle integer types diag(Loc, "avoid using platform-dependent fundamental integer type '%0'; " diff --git a/clang-tools-extra/clang-tidy/portability/AvoidPlatformSpecificFundamentalTypesCheck.h b/clang-tools-extra/clang-tidy/portability/AvoidPlatformSpecificFundamentalTypesCheck.h index c15660a9cf1f8..f4bea1e631953 100644 --- a/clang-tools-extra/clang-tidy/portability/AvoidPlatformSpecificFundamentalTypesCheck.h +++ b/clang-tools-extra/clang-tidy/portability/AvoidPlatformSpecificFundamentalTypesCheck.h @@ -45,6 +45,7 @@ class AvoidPlatformSpecificFundamentalTypesCheck : public ClangTidyCheck { private: const bool WarnOnFloats; const bool WarnOnInts; + const bool WarnOnChars; utils::IncludeInserter IncludeInserter; std::string getFloatReplacement(const BuiltinType *BT, ASTContext &Context) const; diff --git a/clang-tools-extra/docs/clang-tidy/checks/portability/avoid-platform-specific-fundamental-types.rst b/clang-tools-extra/docs/clang-tidy/checks/portability/avoid-platform-specific-fundamental-types.rst index 6f0835aba9c41..155006586f3bd 100644 --- a/clang-tools-extra/docs/clang-tidy/checks/portability/avoid-platform-specific-fundamental-types.rst +++ b/clang-tools-extra/docs/clang-tidy/checks/portability/avoid-platform-specific-fundamental-types.rst @@ -156,3 +156,35 @@ Options float32_t pi = 3.14f; float64_t e = 2.71828; + +.. option:: WarnOnChars + + When `true`, the check will warn about character types (``char``, ``signed char``, and ``unsigned char``). + When `false` (default), character types are not flagged. + + Character types can have platform-dependent behavior: + + - ``char`` can be either signed or unsigned depending on the platform (signed on ARM, unsigned on x86) + - The signedness of ``char`` affects comparisons and arithmetic operations + + When this option is enabled, the check will suggest using explicit signedness or typedefs + to make the intent clear and ensure consistent behavior across platforms. + + Example with ``WarnOnChars`` enabled: + + .. code-block:: c++ + + // Bad: platform-dependent character types + char buffer[256]; + signed char byte_value = -1; + unsigned char raw_byte = 255; + + .. code-block:: c++ + + // Good: use explicit types or typedefs + using byte_t = unsigned char; // For raw byte data + using text_char_t = char; // For text (when signedness doesn't matter) + + text_char_t buffer[256]; // For text storage + int8_t signed_byte = -1; // For signed 8-bit values + uint8_t raw_byte = 255; // For unsigned 8-bit values diff --git a/clang-tools-extra/test/clang-tidy/checkers/portability/avoid-platform-specific-fundamental-types-chars.cpp b/clang-tools-extra/test/clang-tidy/checkers/portability/avoid-platform-specific-fundamental-types-chars.cpp new file mode 100644 index 0000000000000..e7307823dc22d --- /dev/null +++ b/clang-tools-extra/test/clang-tidy/checkers/portability/avoid-platform-specific-fundamental-types-chars.cpp @@ -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 + +// 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] + +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] + +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] + +// 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] + +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] + +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] + +// 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] + +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] + +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-platform-specific-fundamental-types] + +// Struct fields +struct TestStruct { + char field_char; + // CHECK-MESSAGES: :[[@LINE-1]]:8: 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 field_signed_char; + // CHECK-MESSAGES: :[[@LINE-1]]:15: 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 field_unsigned_char; + // CHECK-MESSAGES: :[[@LINE-1]]:17: 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] +}; + +// Typedefs +typedef char char_typedef; +// CHECK-MESSAGES: :[[@LINE-1]]:14: 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] + +typedef signed char signed_char_typedef; +// CHECK-MESSAGES: :[[@LINE-1]]:21: 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] + +typedef unsigned char unsigned_char_typedef; +// CHECK-MESSAGES: :[[@LINE-1]]:23: 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] + +// Type aliases (C++11) +using char_alias = char; +// CHECK-MESSAGES: :[[@LINE-1]]:7: 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] + +using signed_char_alias = signed char; +// CHECK-MESSAGES: :[[@LINE-1]]:7: 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] + +using unsigned_char_alias = unsigned char; +// CHECK-MESSAGES: :[[@LINE-1]]:7: 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] From 8258324cb681363aff02c6dcbec884400af8f27a Mon Sep 17 00:00:00 2001 From: JJ Marr Date: Sun, 6 Jul 2025 01:59:41 -0400 Subject: [PATCH 25/83] Fix header doc --- .../AvoidPlatformSpecificFundamentalTypesCheck.h | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/clang-tools-extra/clang-tidy/portability/AvoidPlatformSpecificFundamentalTypesCheck.h b/clang-tools-extra/clang-tidy/portability/AvoidPlatformSpecificFundamentalTypesCheck.h index f4bea1e631953..dd7652c770d4c 100644 --- a/clang-tools-extra/clang-tidy/portability/AvoidPlatformSpecificFundamentalTypesCheck.h +++ b/clang-tools-extra/clang-tidy/portability/AvoidPlatformSpecificFundamentalTypesCheck.h @@ -16,13 +16,11 @@ namespace clang::tidy::portability { -/// Find fundamental integer types and recommend using typedefs or fixed-width -/// types. +/// Find fundamental platform-dependent 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. +/// 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 From 8dd606b33698a5595471051636fcf2da45b47e21 Mon Sep 17 00:00:00 2001 From: JJ Marr Date: Sun, 6 Jul 2025 02:03:44 -0400 Subject: [PATCH 26/83] Forgot to format --- ...dPlatformSpecificFundamentalTypesCheck.cpp | 61 ++++++++----------- ...oidPlatformSpecificFundamentalTypesCheck.h | 4 +- 2 files changed, 29 insertions(+), 36 deletions(-) diff --git a/clang-tools-extra/clang-tidy/portability/AvoidPlatformSpecificFundamentalTypesCheck.cpp b/clang-tools-extra/clang-tidy/portability/AvoidPlatformSpecificFundamentalTypesCheck.cpp index 87ca48cdee46e..e9d403540560f 100644 --- a/clang-tools-extra/clang-tidy/portability/AvoidPlatformSpecificFundamentalTypesCheck.cpp +++ b/clang-tools-extra/clang-tidy/portability/AvoidPlatformSpecificFundamentalTypesCheck.cpp @@ -82,48 +82,41 @@ void AvoidPlatformSpecificFundamentalTypesCheck::registerMatchers( // 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"}); + 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"}); + 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"}); + TypeStrings.insert(TypeStrings.end(), + {"char", "signed char", "unsigned char"}); } // If no types are enabled, return early diff --git a/clang-tools-extra/clang-tidy/portability/AvoidPlatformSpecificFundamentalTypesCheck.h b/clang-tools-extra/clang-tidy/portability/AvoidPlatformSpecificFundamentalTypesCheck.h index dd7652c770d4c..d7b1582cf8f41 100644 --- a/clang-tools-extra/clang-tidy/portability/AvoidPlatformSpecificFundamentalTypesCheck.h +++ b/clang-tools-extra/clang-tidy/portability/AvoidPlatformSpecificFundamentalTypesCheck.h @@ -16,10 +16,10 @@ namespace clang::tidy::portability { -/// Find fundamental platform-dependent types and recommend using typedefs or +/// Find fundamental platform-dependent types and recommend using typedefs or /// fixed-width types. /// -/// Detects fundamental types (int, short, long, long long, char, float, etc) +/// 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: From 90c98871c280500dac53ba1f0452359073a4027e Mon Sep 17 00:00:00 2001 From: JJ Marr Date: Sun, 6 Jul 2025 16:23:59 -0400 Subject: [PATCH 27/83] Fix typo --- .../avoid-platform-specific-fundamental-types.rst | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/clang-tools-extra/docs/clang-tidy/checks/portability/avoid-platform-specific-fundamental-types.rst b/clang-tools-extra/docs/clang-tidy/checks/portability/avoid-platform-specific-fundamental-types.rst index 155006586f3bd..289f10e4fdce9 100644 --- a/clang-tools-extra/docs/clang-tidy/checks/portability/avoid-platform-specific-fundamental-types.rst +++ b/clang-tools-extra/docs/clang-tidy/checks/portability/avoid-platform-specific-fundamental-types.rst @@ -92,11 +92,11 @@ Fundamental types have platform-dependent sizes and behavior: 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``. +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 From c487bf3176bb58c200caf1c93247e530ce6367a6 Mon Sep 17 00:00:00 2001 From: JJ Marr Date: Sun, 6 Jul 2025 16:25:36 -0400 Subject: [PATCH 28/83] Fix formatting --- .../AvoidPlatformSpecificFundamentalTypesCheck.h | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/clang-tools-extra/clang-tidy/portability/AvoidPlatformSpecificFundamentalTypesCheck.h b/clang-tools-extra/clang-tidy/portability/AvoidPlatformSpecificFundamentalTypesCheck.h index d7b1582cf8f41..6b214a546002f 100644 --- a/clang-tools-extra/clang-tidy/portability/AvoidPlatformSpecificFundamentalTypesCheck.h +++ b/clang-tools-extra/clang-tidy/portability/AvoidPlatformSpecificFundamentalTypesCheck.h @@ -1,12 +1,10 @@ -// clang-format off -//===--- AvoidPlatformSpecificFundamentalTypesCheck.h - clang-tidy -*- C++ -*-===// +//==-- 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 +//==------------------------------------------------------------------------==// #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_PORTABILITY_AVOIDPLATFORMSPECIFICFUNDAMENTALTYPESCHECK_H #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_PORTABILITY_AVOIDPLATFORMSPECIFICFUNDAMENTALTYPESCHECK_H From 09a762d881624871e54c84a6e9a2ec11a0338cf2 Mon Sep 17 00:00:00 2001 From: JJ Marr Date: Sun, 6 Jul 2025 16:27:27 -0400 Subject: [PATCH 29/83] Declare as const --- .../portability/AvoidPlatformSpecificFundamentalTypesCheck.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clang-tools-extra/clang-tidy/portability/AvoidPlatformSpecificFundamentalTypesCheck.cpp b/clang-tools-extra/clang-tidy/portability/AvoidPlatformSpecificFundamentalTypesCheck.cpp index e9d403540560f..74256ba34d7d4 100644 --- a/clang-tools-extra/clang-tidy/portability/AvoidPlatformSpecificFundamentalTypesCheck.cpp +++ b/clang-tools-extra/clang-tidy/portability/AvoidPlatformSpecificFundamentalTypesCheck.cpp @@ -221,7 +221,7 @@ void AvoidPlatformSpecificFundamentalTypesCheck::check( if (BT->isFloatingPoint()) { // Handle floating point types - std::string Replacement = getFloatReplacement(BT, *Result.Context); + const std::string Replacement = getFloatReplacement(BT, *Result.Context); if (!Replacement.empty()) { auto Diag = diag(Loc, "avoid using platform-dependent floating point type '%0'; " From a53b5bcf50975d98aa4377bd805f1f1552f045a9 Mon Sep 17 00:00:00 2001 From: JJ Marr Date: Sun, 6 Jul 2025 16:35:14 -0400 Subject: [PATCH 30/83] Add WarnOnInts documentation --- ...id-platform-specific-fundamental-types.rst | 37 +++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/clang-tools-extra/docs/clang-tidy/checks/portability/avoid-platform-specific-fundamental-types.rst b/clang-tools-extra/docs/clang-tidy/checks/portability/avoid-platform-specific-fundamental-types.rst index 289f10e4fdce9..3a74e7d9f6529 100644 --- a/clang-tools-extra/docs/clang-tidy/checks/portability/avoid-platform-specific-fundamental-types.rst +++ b/clang-tools-extra/docs/clang-tidy/checks/portability/avoid-platform-specific-fundamental-types.rst @@ -126,6 +126,43 @@ 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 need exactly 32 bits + int64_t timestamp = 12345L; // When you need exactly 64 bits + uint16_t port = 8080; // When you need exactly 16 unsigned bits + std::vector vec; + // A size_t is the maximum size of an object on a given platform + for(size_t i = 0U; i Date: Sun, 6 Jul 2025 16:39:27 -0400 Subject: [PATCH 31/83] Enable all checks by default --- ...AvoidPlatformSpecificFundamentalTypesCheck.cpp | 4 ++-- .../avoid-platform-specific-fundamental-types.rst | 8 ++++---- ...-platform-specific-fundamental-types-chars.cpp | 8 +++++++- ...platform-specific-fundamental-types-floats.cpp | 12 ++++++++---- ...d-platform-specific-fundamental-types-ints.cpp | 15 +++++++++------ 5 files changed, 30 insertions(+), 17 deletions(-) diff --git a/clang-tools-extra/clang-tidy/portability/AvoidPlatformSpecificFundamentalTypesCheck.cpp b/clang-tools-extra/clang-tidy/portability/AvoidPlatformSpecificFundamentalTypesCheck.cpp index 74256ba34d7d4..31cf10f3c2949 100644 --- a/clang-tools-extra/clang-tidy/portability/AvoidPlatformSpecificFundamentalTypesCheck.cpp +++ b/clang-tools-extra/clang-tidy/portability/AvoidPlatformSpecificFundamentalTypesCheck.cpp @@ -20,9 +20,9 @@ AvoidPlatformSpecificFundamentalTypesCheck:: AvoidPlatformSpecificFundamentalTypesCheck(StringRef Name, ClangTidyContext *Context) : ClangTidyCheck(Name, Context), - WarnOnFloats(Options.get("WarnOnFloats", false)), + WarnOnFloats(Options.get("WarnOnFloats", true)), WarnOnInts(Options.get("WarnOnInts", true)), - WarnOnChars(Options.get("WarnOnChars", false)), + WarnOnChars(Options.get("WarnOnChars", true)), IncludeInserter(Options.getLocalOrGlobal("IncludeStyle", utils::IncludeSorter::IS_LLVM), areDiagsSelfContained()) {} diff --git a/clang-tools-extra/docs/clang-tidy/checks/portability/avoid-platform-specific-fundamental-types.rst b/clang-tools-extra/docs/clang-tidy/checks/portability/avoid-platform-specific-fundamental-types.rst index 3a74e7d9f6529..28b29544724fd 100644 --- a/clang-tools-extra/docs/clang-tidy/checks/portability/avoid-platform-specific-fundamental-types.rst +++ b/clang-tools-extra/docs/clang-tidy/checks/portability/avoid-platform-specific-fundamental-types.rst @@ -165,8 +165,8 @@ 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. + When `true` (default), the check will warn about floating point types (``float`` and ``double``). + When `false`, floating point types are not flagged. Floating point types can have platform-dependent behavior: @@ -196,8 +196,8 @@ Options .. option:: WarnOnChars - When `true`, the check will warn about character types (``char``, ``signed char``, and ``unsigned char``). - When `false` (default), character types are not flagged. + When `true` (default), the check will warn about character types (``char``, ``signed char``, and ``unsigned char``). + When `false`, character types are not flagged. Character types can have platform-dependent behavior: diff --git a/clang-tools-extra/test/clang-tidy/checkers/portability/avoid-platform-specific-fundamental-types-chars.cpp b/clang-tools-extra/test/clang-tidy/checkers/portability/avoid-platform-specific-fundamental-types-chars.cpp index e7307823dc22d..59a0dbeefe840 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/portability/avoid-platform-specific-fundamental-types-chars.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/portability/avoid-platform-specific-fundamental-types-chars.cpp @@ -1,4 +1,4 @@ -// 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 +// 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 // Test character types that should trigger warnings when WarnOnChars is enabled char global_char = 'a'; @@ -61,3 +61,9 @@ using signed_char_alias = signed char; using unsigned_char_alias = unsigned char; // CHECK-MESSAGES: :[[@LINE-1]]:7: 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] + +// Test that integer and float types are NOT flagged when their options are disabled +int should_not_warn_int = 42; +long should_not_warn_long = 100L; +float should_not_warn_float = 3.14f; +double should_not_warn_double = 2.71828; diff --git a/clang-tools-extra/test/clang-tidy/checkers/portability/avoid-platform-specific-fundamental-types-floats.cpp b/clang-tools-extra/test/clang-tidy/checkers/portability/avoid-platform-specific-fundamental-types-floats.cpp index 22b3629731b66..4cea5fe84d4bb 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/portability/avoid-platform-specific-fundamental-types-floats.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/portability/avoid-platform-specific-fundamental-types-floats.cpp @@ -1,4 +1,4 @@ -// 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 +// 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 // Mock fixed-width float types // In reality, these types are aliases to "extended floating point types", and @@ -18,9 +18,6 @@ double global_double = 3.14159; // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: avoid using platform-dependent floating point type 'double'; consider using 'float64_t' instead [portability-avoid-platform-specific-fundamental-types] // CHECK-FIXES: float64_t global_double = 3.14159; -// Test integer types that should still trigger warnings -int global_int = 42; -// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: avoid using platform-dependent fundamental integer type 'int'; consider using a typedef or fixed-width type instead [portability-avoid-platform-specific-fundamental-types] // Test function parameters with float types void function_with_float_param(float param) { @@ -98,3 +95,10 @@ template<> void template_function(double param) { // CHECK-MESSAGES: :[[@LINE-1]]:39: warning: avoid using platform-dependent floating point type 'double'; consider using 'float64_t' instead [portability-avoid-platform-specific-fundamental-types] } + +// Test that integer and char types are NOT flagged when their options are disabled +int should_not_warn_int = 42; +long should_not_warn_long = 100L; +char should_not_warn_char = 'a'; +signed char should_not_warn_signed_char = 'b'; +unsigned char should_not_warn_unsigned_char = 'c'; diff --git a/clang-tools-extra/test/clang-tidy/checkers/portability/avoid-platform-specific-fundamental-types-ints.cpp b/clang-tools-extra/test/clang-tidy/checkers/portability/avoid-platform-specific-fundamental-types-ints.cpp index 337166cdf3699..c072fb8a52590 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/portability/avoid-platform-specific-fundamental-types-ints.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/portability/avoid-platform-specific-fundamental-types-ints.cpp @@ -1,4 +1,4 @@ -// RUN: %check_clang_tidy %s portability-avoid-platform-specific-fundamental-types %t +// 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 // Mock fixed-width integer types // NOLINTBEGIN(portability-avoid-platform-specific-fundamental-types) @@ -40,12 +40,15 @@ unsigned long global_unsigned_long = 100UL; unsigned long long global_unsigned_long_long = 1000ULL; // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: avoid using platform-dependent fundamental integer type 'unsigned long long'; consider using a typedef or fixed-width type instead [portability-avoid-platform-specific-fundamental-types] -// Test semantic types that should NOT trigger warnings -char global_char = 'a'; -signed char global_signed_char = 'b'; -unsigned char global_unsigned_char = 'c'; +// Test integer that should NEVER trigger warnings bool global_bool = true; -wchar_t global_wchar = L'w'; + +// Test that char and float types are NOT flagged when their options are disabled +float should_not_warn_float = 3.14f; +double should_not_warn_double = 2.71828; +char should_not_warn_char = 'a'; +signed char should_not_warn_signed_char = 'b'; +unsigned char should_not_warn_unsigned_char = 'c'; // Test fixed-width types that should NOT trigger warnings uint32_t global_uint32 = 42U; From de662e86a7a61ee8c67e6cfc41f5ef2974a6389d Mon Sep 17 00:00:00 2001 From: JJ Marr <168750718+jj-marr@users.noreply.github.com> Date: Sun, 6 Jul 2025 22:49:24 -0400 Subject: [PATCH 32/83] Update clang-tools-extra/clang-tidy/portability/AvoidPlatformSpecificFundamentalTypesCheck.cpp Co-authored-by: Baranov Victor --- .../portability/AvoidPlatformSpecificFundamentalTypesCheck.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/clang-tools-extra/clang-tidy/portability/AvoidPlatformSpecificFundamentalTypesCheck.cpp b/clang-tools-extra/clang-tidy/portability/AvoidPlatformSpecificFundamentalTypesCheck.cpp index 31cf10f3c2949..272c832be29ff 100644 --- a/clang-tools-extra/clang-tidy/portability/AvoidPlatformSpecificFundamentalTypesCheck.cpp +++ b/clang-tools-extra/clang-tidy/portability/AvoidPlatformSpecificFundamentalTypesCheck.cpp @@ -7,7 +7,6 @@ //===----------------------------------------------------------------------===// #include "AvoidPlatformSpecificFundamentalTypesCheck.h" -#include "clang/AST/ASTContext.h" #include "clang/ASTMatchers/ASTMatchFinder.h" #include "clang/ASTMatchers/ASTMatchers.h" #include "clang/Basic/TargetInfo.h" From d0012d364c4367eed28e1858249203517436dd43 Mon Sep 17 00:00:00 2001 From: JJ Marr Date: Thu, 10 Jul 2025 20:00:08 -0400 Subject: [PATCH 33/83] Fix formatting more --- .../AvoidPlatformSpecificFundamentalTypesCheck.cpp | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/clang-tools-extra/clang-tidy/portability/AvoidPlatformSpecificFundamentalTypesCheck.cpp b/clang-tools-extra/clang-tidy/portability/AvoidPlatformSpecificFundamentalTypesCheck.cpp index 272c832be29ff..abe8649b7593f 100644 --- a/clang-tools-extra/clang-tidy/portability/AvoidPlatformSpecificFundamentalTypesCheck.cpp +++ b/clang-tools-extra/clang-tidy/portability/AvoidPlatformSpecificFundamentalTypesCheck.cpp @@ -119,15 +119,13 @@ void AvoidPlatformSpecificFundamentalTypesCheck::registerMatchers( } // If no types are enabled, return early - if (TypeStrings.empty()) { + if (TypeStrings.empty()) return; - } // Create the matcher dynamically auto TypeMatcher = asString(TypeStrings.front()); - for (const auto &TypeString : TypeStrings) { + for (const auto &TypeString : TypeStrings) TypeMatcher = anyOf(TypeMatcher, asString(TypeString)); - } auto PlatformSpecificFundamentalType = qualType(allOf( // Must be a builtin type directly (not through typedef) @@ -175,9 +173,8 @@ void AvoidPlatformSpecificFundamentalTypesCheck::check( SourceRange TypeRange; auto SetTypeRange = [&TypeRange](auto Decl) { - if (Decl->getTypeSourceInfo()) { + if (Decl->getTypeSourceInfo()) TypeRange = Decl->getTypeSourceInfo()->getTypeLoc().getSourceRange(); - } }; if (const auto *VD = Result.Nodes.getNodeAs("var_decl")) { @@ -227,9 +224,8 @@ void AvoidPlatformSpecificFundamentalTypesCheck::check( "consider using '%1' instead") << TypeName << Replacement; - if (TypeRange.isValid()) { + if (TypeRange.isValid()) Diag << FixItHint::CreateReplacement(TypeRange, Replacement); - } if (auto IncludeFixit = IncludeInserter.createIncludeInsertion( Result.SourceManager->getFileID(Loc), "")) { From 304b7b0d446bdeeeae697be4562d5ce85af84f3d Mon Sep 17 00:00:00 2001 From: JJ Marr Date: Thu, 10 Jul 2025 20:10:30 -0400 Subject: [PATCH 34/83] Use or later standards --- .../avoid-platform-specific-fundamental-types-chars.cpp | 2 +- .../avoid-platform-specific-fundamental-types-floats.cpp | 2 +- .../avoid-platform-specific-fundamental-types-ints.cpp | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/clang-tools-extra/test/clang-tidy/checkers/portability/avoid-platform-specific-fundamental-types-chars.cpp b/clang-tools-extra/test/clang-tidy/checkers/portability/avoid-platform-specific-fundamental-types-chars.cpp index 59a0dbeefe840..d7cb01cf23b51 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/portability/avoid-platform-specific-fundamental-types-chars.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/portability/avoid-platform-specific-fundamental-types-chars.cpp @@ -1,4 +1,4 @@ -// 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 +// 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=.* // Test character types that should trigger warnings when WarnOnChars is enabled char global_char = 'a'; diff --git a/clang-tools-extra/test/clang-tidy/checkers/portability/avoid-platform-specific-fundamental-types-floats.cpp b/clang-tools-extra/test/clang-tidy/checkers/portability/avoid-platform-specific-fundamental-types-floats.cpp index 4cea5fe84d4bb..31d8839b6398b 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/portability/avoid-platform-specific-fundamental-types-floats.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/portability/avoid-platform-specific-fundamental-types-floats.cpp @@ -1,4 +1,4 @@ -// 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 +// 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=.* // Mock fixed-width float types // In reality, these types are aliases to "extended floating point types", and diff --git a/clang-tools-extra/test/clang-tidy/checkers/portability/avoid-platform-specific-fundamental-types-ints.cpp b/clang-tools-extra/test/clang-tidy/checkers/portability/avoid-platform-specific-fundamental-types-ints.cpp index c072fb8a52590..cef758c9bc7ea 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/portability/avoid-platform-specific-fundamental-types-ints.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/portability/avoid-platform-specific-fundamental-types-ints.cpp @@ -1,4 +1,4 @@ -// 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 +// 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=.* // Mock fixed-width integer types // NOLINTBEGIN(portability-avoid-platform-specific-fundamental-types) From e66cf7bbedf1c63b8c807c5b8dd306306c0a6694 Mon Sep 17 00:00:00 2001 From: JJ Marr Date: Thu, 10 Jul 2025 20:10:59 -0400 Subject: [PATCH 35/83] Remove header filters --- .../avoid-platform-specific-fundamental-types-chars.cpp | 2 +- .../avoid-platform-specific-fundamental-types-floats.cpp | 2 +- .../avoid-platform-specific-fundamental-types-ints.cpp | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/clang-tools-extra/test/clang-tidy/checkers/portability/avoid-platform-specific-fundamental-types-chars.cpp b/clang-tools-extra/test/clang-tidy/checkers/portability/avoid-platform-specific-fundamental-types-chars.cpp index d7cb01cf23b51..9648a84bf64cb 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/portability/avoid-platform-specific-fundamental-types-chars.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/portability/avoid-platform-specific-fundamental-types-chars.cpp @@ -1,4 +1,4 @@ -// 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=.* +// 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}]}" // Test character types that should trigger warnings when WarnOnChars is enabled char global_char = 'a'; diff --git a/clang-tools-extra/test/clang-tidy/checkers/portability/avoid-platform-specific-fundamental-types-floats.cpp b/clang-tools-extra/test/clang-tidy/checkers/portability/avoid-platform-specific-fundamental-types-floats.cpp index 31d8839b6398b..9e4605aacec67 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/portability/avoid-platform-specific-fundamental-types-floats.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/portability/avoid-platform-specific-fundamental-types-floats.cpp @@ -1,4 +1,4 @@ -// 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=.* +// 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}]}" // Mock fixed-width float types // In reality, these types are aliases to "extended floating point types", and diff --git a/clang-tools-extra/test/clang-tidy/checkers/portability/avoid-platform-specific-fundamental-types-ints.cpp b/clang-tools-extra/test/clang-tidy/checkers/portability/avoid-platform-specific-fundamental-types-ints.cpp index cef758c9bc7ea..a4b40595245ce 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/portability/avoid-platform-specific-fundamental-types-ints.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/portability/avoid-platform-specific-fundamental-types-ints.cpp @@ -1,4 +1,4 @@ -// 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=.* +// 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}]}" // Mock fixed-width integer types // NOLINTBEGIN(portability-avoid-platform-specific-fundamental-types) From c2f53d98e2f50a556cd598060db0695c961a4656 Mon Sep 17 00:00:00 2001 From: JJ Marr Date: Thu, 10 Jul 2025 20:57:44 -0400 Subject: [PATCH 36/83] Replace string matching --- ...dPlatformSpecificFundamentalTypesCheck.cpp | 117 ++++++++++-------- 1 file changed, 64 insertions(+), 53 deletions(-) diff --git a/clang-tools-extra/clang-tidy/portability/AvoidPlatformSpecificFundamentalTypesCheck.cpp b/clang-tools-extra/clang-tidy/portability/AvoidPlatformSpecificFundamentalTypesCheck.cpp index abe8649b7593f..5c6b0f6eb2a2d 100644 --- a/clang-tools-extra/clang-tidy/portability/AvoidPlatformSpecificFundamentalTypesCheck.cpp +++ b/clang-tools-extra/clang-tidy/portability/AvoidPlatformSpecificFundamentalTypesCheck.cpp @@ -7,12 +7,69 @@ //===----------------------------------------------------------------------===// #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; + + 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; + + switch (BT->getKind()) { + case clang::BuiltinType::Char_S: + case clang::BuiltinType::Char_U: + case clang::BuiltinType::SChar: + case clang::BuiltinType::UChar: + return true; + default: + return false; + } +} +} // namespace + namespace clang::tidy::portability { AvoidPlatformSpecificFundamentalTypesCheck:: @@ -76,63 +133,17 @@ std::string AvoidPlatformSpecificFundamentalTypesCheck::getFloatReplacement( 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"}); - } + // Create the type matcher using the three separate matchers + auto PlatformSpecificFundamentalType = qualType( + allOf(builtinType(), + anyOf(WarnOnInts ? isBuiltinInt() : unless(anything()), + WarnOnFloats ? isBuiltinFloat() : unless(anything()), + WarnOnChars ? isBuiltinChar() : unless(anything())))); // If no types are enabled, return early - if (TypeStrings.empty()) + if (!WarnOnInts && !WarnOnFloats && !WarnOnChars) return; - // Create the matcher dynamically - auto TypeMatcher = asString(TypeStrings.front()); - for (const auto &TypeString : TypeStrings) - TypeMatcher = anyOf(TypeMatcher, asString(TypeString)); - - 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); From 32343ae50742930f330ecb67ab1bf916723f8a9c Mon Sep 17 00:00:00 2001 From: JJ Marr Date: Thu, 10 Jul 2025 20:59:13 -0400 Subject: [PATCH 37/83] Remove useless comments --- ...AvoidPlatformSpecificFundamentalTypesCheck.cpp | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/clang-tools-extra/clang-tidy/portability/AvoidPlatformSpecificFundamentalTypesCheck.cpp b/clang-tools-extra/clang-tidy/portability/AvoidPlatformSpecificFundamentalTypesCheck.cpp index 5c6b0f6eb2a2d..410654b274a46 100644 --- a/clang-tools-extra/clang-tidy/portability/AvoidPlatformSpecificFundamentalTypesCheck.cpp +++ b/clang-tools-extra/clang-tidy/portability/AvoidPlatformSpecificFundamentalTypesCheck.cpp @@ -133,45 +133,35 @@ std::string AvoidPlatformSpecificFundamentalTypesCheck::getFloatReplacement( void AvoidPlatformSpecificFundamentalTypesCheck::registerMatchers( MatchFinder *Finder) { - // Create the type matcher using the three separate matchers auto PlatformSpecificFundamentalType = qualType( allOf(builtinType(), anyOf(WarnOnInts ? isBuiltinInt() : unless(anything()), WarnOnFloats ? isBuiltinFloat() : unless(anything()), WarnOnChars ? isBuiltinChar() : unless(anything())))); - // If no types are enabled, return early if (!WarnOnInts && !WarnOnFloats && !WarnOnChars) return; - // Match variable declarations with platform-specific fundamental types Finder->addMatcher( varDecl(hasType(PlatformSpecificFundamentalType)).bind("var_decl"), this); - // Match function declarations with platform-specific fundamental return types Finder->addMatcher( functionDecl(returns(PlatformSpecificFundamentalType)).bind("func_decl"), this); - // Match function parameters with platform-specific fundamental types Finder->addMatcher( parmVarDecl(hasType(PlatformSpecificFundamentalType)).bind("param_decl"), this); - // Match field declarations with platform-specific fundamental types Finder->addMatcher( fieldDecl(hasType(PlatformSpecificFundamentalType)).bind("field_decl"), this); - // Match typedef declarations with platform-specific fundamental underlying - // types Finder->addMatcher( typedefDecl(hasUnderlyingType(PlatformSpecificFundamentalType)) .bind("typedef_decl"), this); - // Match type alias declarations with platform-specific fundamental underlying - // types Finder->addMatcher(typeAliasDecl(hasType(PlatformSpecificFundamentalType)) .bind("alias_decl"), this); @@ -220,14 +210,11 @@ void AvoidPlatformSpecificFundamentalTypesCheck::check( return; } - // Get the type name for the diagnostic const std::string TypeName = QT.getAsString(); - // Check the type category const auto *BT = QT->getAs(); if (BT->isFloatingPoint()) { - // Handle floating point types const std::string Replacement = getFloatReplacement(BT, *Result.Context); if (!Replacement.empty()) { auto Diag = @@ -251,12 +238,10 @@ void AvoidPlatformSpecificFundamentalTypesCheck::check( BT->getKind() == BuiltinType::Char_U || BT->getKind() == BuiltinType::SChar || BT->getKind() == BuiltinType::UChar) { - // Handle char types diag(Loc, "avoid using platform-dependent character type '%0'; " "consider using char8_t for text or std::byte for bytes") << TypeName; } else { - // Handle integer types diag(Loc, "avoid using platform-dependent fundamental integer type '%0'; " "consider using a typedef or fixed-width type instead") << TypeName; From d37015e5f21708d7a64362c3e2e24a4c8a36361a Mon Sep 17 00:00:00 2001 From: JJ Marr Date: Thu, 10 Jul 2025 21:05:49 -0400 Subject: [PATCH 38/83] Add static helper functions --- ...dPlatformSpecificFundamentalTypesCheck.cpp | 33 ++++++++++--------- ...oidPlatformSpecificFundamentalTypesCheck.h | 2 -- 2 files changed, 18 insertions(+), 17 deletions(-) diff --git a/clang-tools-extra/clang-tidy/portability/AvoidPlatformSpecificFundamentalTypesCheck.cpp b/clang-tools-extra/clang-tidy/portability/AvoidPlatformSpecificFundamentalTypesCheck.cpp index 410654b274a46..3543abb5604f1 100644 --- a/clang-tools-extra/clang-tidy/portability/AvoidPlatformSpecificFundamentalTypesCheck.cpp +++ b/clang-tools-extra/clang-tidy/portability/AvoidPlatformSpecificFundamentalTypesCheck.cpp @@ -16,6 +16,20 @@ 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) @@ -58,15 +72,7 @@ AST_MATCHER(clang::QualType, isBuiltinChar) { if (!BT) return false; - switch (BT->getKind()) { - case clang::BuiltinType::Char_S: - case clang::BuiltinType::Char_U: - case clang::BuiltinType::SChar: - case clang::BuiltinType::UChar: - return true; - default: - return false; - } + return isCharType(BT); } } // namespace @@ -96,8 +102,8 @@ void AvoidPlatformSpecificFundamentalTypesCheck::storeOptions( Options.store(Opts, "IncludeStyle", IncludeInserter.getStyle()); } -std::string AvoidPlatformSpecificFundamentalTypesCheck::getFloatReplacement( - const BuiltinType *BT, ASTContext &Context) const { +static std::string getFloatReplacement(const BuiltinType *BT, + ASTContext &Context) { const TargetInfo &Target = Context.getTargetInfo(); auto GetReplacementType = [](unsigned Width) { @@ -234,10 +240,7 @@ void AvoidPlatformSpecificFundamentalTypesCheck::check( "consider using a typedef or fixed-width type instead") << TypeName; } - } else if (BT->getKind() == BuiltinType::Char_S || - BT->getKind() == BuiltinType::Char_U || - BT->getKind() == BuiltinType::SChar || - BT->getKind() == BuiltinType::UChar) { + } else if (isCharType(BT)) { diag(Loc, "avoid using platform-dependent character type '%0'; " "consider using char8_t for text or std::byte for bytes") << TypeName; diff --git a/clang-tools-extra/clang-tidy/portability/AvoidPlatformSpecificFundamentalTypesCheck.h b/clang-tools-extra/clang-tidy/portability/AvoidPlatformSpecificFundamentalTypesCheck.h index 6b214a546002f..95e62d983f65d 100644 --- a/clang-tools-extra/clang-tidy/portability/AvoidPlatformSpecificFundamentalTypesCheck.h +++ b/clang-tools-extra/clang-tidy/portability/AvoidPlatformSpecificFundamentalTypesCheck.h @@ -43,8 +43,6 @@ class AvoidPlatformSpecificFundamentalTypesCheck : public ClangTidyCheck { const bool WarnOnInts; const bool WarnOnChars; utils::IncludeInserter IncludeInserter; - std::string getFloatReplacement(const BuiltinType *BT, - ASTContext &Context) const; }; } // namespace clang::tidy::portability From 9d47d7a23ecad1ed59a13864d59b006f2cdb602e Mon Sep 17 00:00:00 2001 From: JJ Marr <168750718+jj-marr@users.noreply.github.com> Date: Sun, 3 Aug 2025 20:34:17 -0400 Subject: [PATCH 39/83] Apply suggestions from code review Co-authored-by: EugeneZelenko --- clang-tools-extra/docs/ReleaseNotes.rst | 2 +- .../avoid-platform-specific-fundamental-types.rst | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/clang-tools-extra/docs/ReleaseNotes.rst b/clang-tools-extra/docs/ReleaseNotes.rst index 0815b7f844c0b..826c5f9bed562 100644 --- a/clang-tools-extra/docs/ReleaseNotes.rst +++ b/clang-tools-extra/docs/ReleaseNotes.rst @@ -152,7 +152,7 @@ New checks ` check. - Finds fundamental types (e.g. `int`, `float`) and recommends using typedefs + Finds fundamental types (e.g. ``int``, ``float``) and recommends using typedefs or fixed-width types instead to improve portability across different platforms. - New :doc:`portability-avoid-pragma-once diff --git a/clang-tools-extra/docs/clang-tidy/checks/portability/avoid-platform-specific-fundamental-types.rst b/clang-tools-extra/docs/clang-tidy/checks/portability/avoid-platform-specific-fundamental-types.rst index 28b29544724fd..3676a1d82b382 100644 --- a/clang-tools-extra/docs/clang-tidy/checks/portability/avoid-platform-specific-fundamental-types.rst +++ b/clang-tools-extra/docs/clang-tidy/checks/portability/avoid-platform-specific-fundamental-types.rst @@ -3,7 +3,7 @@ portability-avoid-platform-specific-fundamental-types ===================================================== -Finds fundamental types (e.g. `int`, `float`) and recommends using typedefs +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``, @@ -131,7 +131,7 @@ Options 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): + Example with `WarnOnInts` enabled: .. code-block:: c++ @@ -207,7 +207,7 @@ Options When this option is enabled, the check will suggest using explicit signedness or typedefs to make the intent clear and ensure consistent behavior across platforms. - Example with ``WarnOnChars`` enabled: + Example with `WarnOnChars` enabled: .. code-block:: c++ From 1fed634397af18ff1c1de5782049fd9437f5afcc Mon Sep 17 00:00:00 2001 From: JJ Marr Date: Sun, 3 Aug 2025 20:42:48 -0400 Subject: [PATCH 40/83] Trim to 80 characters and reword --- ...id-platform-specific-fundamental-types.rst | 101 ++++++++++-------- 1 file changed, 55 insertions(+), 46 deletions(-) diff --git a/clang-tools-extra/docs/clang-tidy/checks/portability/avoid-platform-specific-fundamental-types.rst b/clang-tools-extra/docs/clang-tidy/checks/portability/avoid-platform-specific-fundamental-types.rst index 3676a1d82b382..229c40add03c1 100644 --- a/clang-tools-extra/docs/clang-tidy/checks/portability/avoid-platform-specific-fundamental-types.rst +++ b/clang-tools-extra/docs/clang-tidy/checks/portability/avoid-platform-specific-fundamental-types.rst @@ -3,17 +3,17 @@ 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. +Finds fundamental types (e.g. ``int``, ``float``) and recommends using typedefs +or fixed-width types 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 +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 +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 @@ -26,15 +26,15 @@ Examples 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; @@ -44,20 +44,20 @@ Examples // 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; @@ -90,17 +90,19 @@ Fundamental types have platform-dependent sizes and behavior: 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 +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 @@ -120,15 +122,18 @@ The following types are intentionally not flagged: - 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. +``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` (default), the check will warn about fundamental integer types (``short``, ``int``, ``long``, ``long long`` and their ``signed`` and ``unsigned`` variants). + 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: @@ -153,7 +158,7 @@ Options // Good: use fixed-width or descriptive types #include #include - + int32_t counter = 0; // When you need exactly 32 bits int64_t timestamp = 12345L; // When you need exactly 64 bits uint16_t port = 8080; // When you need exactly 16 unsigned bits @@ -165,18 +170,19 @@ Options .. option:: WarnOnFloats - When `true` (default), the check will warn about floating point types (``float`` and ``double``). + When `true` (default), the check will warn about floating point types + (``float`` and ``double``). When `false`, 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. + - ``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. Example with ``WarnOnFloats`` enabled: @@ -190,22 +196,25 @@ Options // Good: use fixed-width floating point types #include // C++23 - + float32_t pi = 3.14f; float64_t e = 2.71828; .. option:: WarnOnChars - When `true` (default), the check will warn about character types (``char``, ``signed char``, and ``unsigned char``). + When `true` (default), the check will warn about character types (``char``, + ``signed char``, and ``unsigned char``). When `false`, character types are not flagged. Character types can have platform-dependent behavior: - - - ``char`` can be either signed or unsigned depending on the platform (signed on ARM, unsigned on x86) + + - ``char`` can be either signed or unsigned depending on the platform (signed + on ARM, unsigned on x86) - The signedness of ``char`` affects comparisons and arithmetic operations - - When this option is enabled, the check will suggest using explicit signedness or typedefs - to make the intent clear and ensure consistent behavior across platforms. + + When this option is enabled, the check will suggest using explicit signedness + or typedefs to make the intent clear and ensure consistent behavior across + platforms. Example with `WarnOnChars` enabled: @@ -221,7 +230,7 @@ Options // Good: use explicit types or typedefs using byte_t = unsigned char; // For raw byte data using text_char_t = char; // For text (when signedness doesn't matter) - + text_char_t buffer[256]; // For text storage int8_t signed_byte = -1; // For signed 8-bit values uint8_t raw_byte = 255; // For unsigned 8-bit values From 110bb528cb0098b05a213a94702814acbaea95e1 Mon Sep 17 00:00:00 2001 From: JJ Marr Date: Sun, 3 Aug 2025 20:44:50 -0400 Subject: [PATCH 41/83] Fix changes from code review --- .../AvoidPlatformSpecificFundamentalTypesCheck.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/clang-tools-extra/clang-tidy/portability/AvoidPlatformSpecificFundamentalTypesCheck.cpp b/clang-tools-extra/clang-tidy/portability/AvoidPlatformSpecificFundamentalTypesCheck.cpp index 3543abb5604f1..c3099815dfce8 100644 --- a/clang-tools-extra/clang-tidy/portability/AvoidPlatformSpecificFundamentalTypesCheck.cpp +++ b/clang-tools-extra/clang-tidy/portability/AvoidPlatformSpecificFundamentalTypesCheck.cpp @@ -220,6 +220,7 @@ void AvoidPlatformSpecificFundamentalTypesCheck::check( const auto *BT = QT->getAs(); + assert(BT); if (BT->isFloatingPoint()) { const std::string Replacement = getFloatReplacement(BT, *Result.Context); if (!Replacement.empty()) { @@ -237,16 +238,16 @@ void AvoidPlatformSpecificFundamentalTypesCheck::check( } } else { diag(Loc, "avoid using platform-dependent floating point type '%0'; " - "consider using a typedef or fixed-width type instead") + "consider using a 'typedef' or fixed-width type instead") << TypeName; } } else if (isCharType(BT)) { diag(Loc, "avoid using platform-dependent character type '%0'; " - "consider using char8_t for text or std::byte for bytes") + "consider using 'char8_t' for text or 'std::byte' for bytes") << TypeName; } else { diag(Loc, "avoid using platform-dependent fundamental integer type '%0'; " - "consider using a typedef or fixed-width type instead") + "consider using a 'typedef' or fixed-width type instead") << TypeName; } } From 7c0003cf252cf2ad7827fe83e9098b22067aafd3 Mon Sep 17 00:00:00 2001 From: JJ Marr Date: Mon, 4 Aug 2025 01:24:11 -0400 Subject: [PATCH 42/83] Use existing checker --- ...dPlatformSpecificFundamentalTypesCheck.cpp | 35 ++----------------- 1 file changed, 3 insertions(+), 32 deletions(-) diff --git a/clang-tools-extra/clang-tidy/portability/AvoidPlatformSpecificFundamentalTypesCheck.cpp b/clang-tools-extra/clang-tidy/portability/AvoidPlatformSpecificFundamentalTypesCheck.cpp index c3099815dfce8..d6af70cf581a7 100644 --- a/clang-tools-extra/clang-tidy/portability/AvoidPlatformSpecificFundamentalTypesCheck.cpp +++ b/clang-tools-extra/clang-tidy/portability/AvoidPlatformSpecificFundamentalTypesCheck.cpp @@ -17,19 +17,6 @@ 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) @@ -55,25 +42,9 @@ AST_MATCHER(clang::QualType, isBuiltinFloat) { 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; - } + return BT->isFloatingPoint(); } -AST_MATCHER(clang::QualType, isBuiltinChar) { - const auto *BT = Node->getAs(); - if (!BT) - return false; - - return isCharType(BT); -} } // namespace namespace clang::tidy::portability { @@ -143,7 +114,7 @@ void AvoidPlatformSpecificFundamentalTypesCheck::registerMatchers( allOf(builtinType(), anyOf(WarnOnInts ? isBuiltinInt() : unless(anything()), WarnOnFloats ? isBuiltinFloat() : unless(anything()), - WarnOnChars ? isBuiltinChar() : unless(anything())))); + WarnOnChars ? isAnyCharacter() : unless(anything())))); if (!WarnOnInts && !WarnOnFloats && !WarnOnChars) return; @@ -241,7 +212,7 @@ void AvoidPlatformSpecificFundamentalTypesCheck::check( "consider using a 'typedef' or fixed-width type instead") << TypeName; } - } else if (isCharType(BT)) { + } else if (QT->isAnyCharacterType()) { diag(Loc, "avoid using platform-dependent character type '%0'; " "consider using 'char8_t' for text or 'std::byte' for bytes") << TypeName; From b3a206fc3dd9ebc0b67e1f0bd81c2f22cd8a488a Mon Sep 17 00:00:00 2001 From: JJ Marr <168750718+jj-marr@users.noreply.github.com> Date: Mon, 4 Aug 2025 01:25:08 -0400 Subject: [PATCH 43/83] Update clang-tools-extra/docs/clang-tidy/checks/portability/avoid-platform-specific-fundamental-types.rst Co-authored-by: EugeneZelenko --- .../portability/avoid-platform-specific-fundamental-types.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clang-tools-extra/docs/clang-tidy/checks/portability/avoid-platform-specific-fundamental-types.rst b/clang-tools-extra/docs/clang-tidy/checks/portability/avoid-platform-specific-fundamental-types.rst index 229c40add03c1..d33d7054f41c7 100644 --- a/clang-tools-extra/docs/clang-tidy/checks/portability/avoid-platform-specific-fundamental-types.rst +++ b/clang-tools-extra/docs/clang-tidy/checks/portability/avoid-platform-specific-fundamental-types.rst @@ -216,7 +216,7 @@ Options or typedefs to make the intent clear and ensure consistent behavior across platforms. - Example with `WarnOnChars` enabled: + Example with :option:`WarnOnChars` enabled: .. code-block:: c++ From 1361674ce37528e44929879f9f4c92f2fbe63e50 Mon Sep 17 00:00:00 2001 From: JJ Marr <168750718+jj-marr@users.noreply.github.com> Date: Sat, 9 Aug 2025 20:54:53 -0400 Subject: [PATCH 44/83] Update clang-tools-extra/docs/clang-tidy/checks/portability/avoid-platform-specific-fundamental-types.rst Co-authored-by: EugeneZelenko --- .../portability/avoid-platform-specific-fundamental-types.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clang-tools-extra/docs/clang-tidy/checks/portability/avoid-platform-specific-fundamental-types.rst b/clang-tools-extra/docs/clang-tidy/checks/portability/avoid-platform-specific-fundamental-types.rst index d33d7054f41c7..89f9029a652e7 100644 --- a/clang-tools-extra/docs/clang-tidy/checks/portability/avoid-platform-specific-fundamental-types.rst +++ b/clang-tools-extra/docs/clang-tidy/checks/portability/avoid-platform-specific-fundamental-types.rst @@ -184,7 +184,7 @@ Options ``float64_t`` instead of ``float`` and ``double`` respectively, when the target platform supports standard IEEE754 sizes. - Example with ``WarnOnFloats`` enabled: + Example with :option:`WarnOnFloats` enabled: .. code-block:: c++ From 4a1af0c64d780f066119519763f418ef89211a97 Mon Sep 17 00:00:00 2001 From: JJ Marr Date: Sat, 9 Aug 2025 20:55:34 -0400 Subject: [PATCH 45/83] Fix tests --- ...tform-specific-fundamental-types-chars.cpp | 36 +++++++-------- ...atform-specific-fundamental-types-ints.cpp | 46 +++++++++---------- 2 files changed, 41 insertions(+), 41 deletions(-) diff --git a/clang-tools-extra/test/clang-tidy/checkers/portability/avoid-platform-specific-fundamental-types-chars.cpp b/clang-tools-extra/test/clang-tidy/checkers/portability/avoid-platform-specific-fundamental-types-chars.cpp index 9648a84bf64cb..a798db04aa6ec 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/portability/avoid-platform-specific-fundamental-types-chars.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/portability/avoid-platform-specific-fundamental-types-chars.cpp @@ -2,65 +2,65 @@ // 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]]: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] 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]]: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] 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]]: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] // 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]]: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] 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]]: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] 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]]: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] // 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]]: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] 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]]: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] 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-platform-specific-fundamental-types] +// 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] // Struct fields struct TestStruct { char field_char; - // CHECK-MESSAGES: :[[@LINE-1]]:8: 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]]:8: 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 field_signed_char; - // CHECK-MESSAGES: :[[@LINE-1]]:15: 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]]:15: 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 field_unsigned_char; - // CHECK-MESSAGES: :[[@LINE-1]]:17: 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]]:17: 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] }; // Typedefs typedef char char_typedef; -// CHECK-MESSAGES: :[[@LINE-1]]:14: 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]]:14: 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] typedef signed char signed_char_typedef; -// CHECK-MESSAGES: :[[@LINE-1]]:21: 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]]:21: 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] typedef unsigned char unsigned_char_typedef; -// CHECK-MESSAGES: :[[@LINE-1]]:23: 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]]:23: 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] // Type aliases (C++11) using char_alias = char; -// CHECK-MESSAGES: :[[@LINE-1]]:7: 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]]:7: 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] using signed_char_alias = signed char; -// CHECK-MESSAGES: :[[@LINE-1]]:7: 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]]:7: 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] using unsigned_char_alias = unsigned char; -// CHECK-MESSAGES: :[[@LINE-1]]:7: 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]]:7: 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] // Test that integer and float types are NOT flagged when their options are disabled int should_not_warn_int = 42; diff --git a/clang-tools-extra/test/clang-tidy/checkers/portability/avoid-platform-specific-fundamental-types-ints.cpp b/clang-tools-extra/test/clang-tidy/checkers/portability/avoid-platform-specific-fundamental-types-ints.cpp index a4b40595245ce..26ec188ddd18c 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/portability/avoid-platform-specific-fundamental-types-ints.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/portability/avoid-platform-specific-fundamental-types-ints.cpp @@ -17,28 +17,28 @@ typedef unsigned long size_t; // Test fundamental integer types that should trigger warnings int global_int = 42; -// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: avoid using platform-dependent fundamental integer type 'int'; consider using a typedef or fixed-width type instead [portability-avoid-platform-specific-fundamental-types] +// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: avoid using platform-dependent fundamental integer type 'int'; consider using a 'typedef' or fixed-width type instead [portability-avoid-platform-specific-fundamental-types] short global_short = 10; -// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: avoid using platform-dependent fundamental integer type 'short'; consider using a typedef or fixed-width type instead [portability-avoid-platform-specific-fundamental-types] +// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: avoid using platform-dependent fundamental integer type 'short'; consider using a 'typedef' or fixed-width type instead [portability-avoid-platform-specific-fundamental-types] long global_long = 100L; -// CHECK-MESSAGES: :[[@LINE-1]]:6: warning: avoid using platform-dependent fundamental integer type 'long'; consider using a typedef or fixed-width type instead [portability-avoid-platform-specific-fundamental-types] +// CHECK-MESSAGES: :[[@LINE-1]]:6: warning: avoid using platform-dependent fundamental integer type 'long'; consider using a 'typedef' or fixed-width type instead [portability-avoid-platform-specific-fundamental-types] long long global_long_long = 1000LL; -// CHECK-MESSAGES: :[[@LINE-1]]:11: warning: avoid using platform-dependent fundamental integer type 'long long'; consider using a typedef or fixed-width type instead [portability-avoid-platform-specific-fundamental-types] +// CHECK-MESSAGES: :[[@LINE-1]]:11: warning: avoid using platform-dependent fundamental integer type 'long long'; consider using a 'typedef' or fixed-width type instead [portability-avoid-platform-specific-fundamental-types] unsigned int global_unsigned_int = 42U; -// CHECK-MESSAGES: :[[@LINE-1]]:14: warning: avoid using platform-dependent fundamental integer type 'unsigned int'; consider using a typedef or fixed-width type instead [portability-avoid-platform-specific-fundamental-types] +// CHECK-MESSAGES: :[[@LINE-1]]:14: warning: avoid using platform-dependent fundamental integer type 'unsigned int'; consider using a 'typedef' or fixed-width type instead [portability-avoid-platform-specific-fundamental-types] unsigned short global_unsigned_short = 10U; -// CHECK-MESSAGES: :[[@LINE-1]]:16: warning: avoid using platform-dependent fundamental integer type 'unsigned short'; consider using a typedef or fixed-width type instead [portability-avoid-platform-specific-fundamental-types] +// CHECK-MESSAGES: :[[@LINE-1]]:16: warning: avoid using platform-dependent fundamental integer type 'unsigned short'; consider using a 'typedef' or fixed-width type instead [portability-avoid-platform-specific-fundamental-types] unsigned long global_unsigned_long = 100UL; -// CHECK-MESSAGES: :[[@LINE-1]]:15: warning: avoid using platform-dependent fundamental integer type 'unsigned long'; consider using a typedef or fixed-width type instead [portability-avoid-platform-specific-fundamental-types] +// CHECK-MESSAGES: :[[@LINE-1]]:15: warning: avoid using platform-dependent fundamental integer type 'unsigned long'; consider using a 'typedef' or fixed-width type instead [portability-avoid-platform-specific-fundamental-types] unsigned long long global_unsigned_long_long = 1000ULL; -// CHECK-MESSAGES: :[[@LINE-1]]:20: warning: avoid using platform-dependent fundamental integer type 'unsigned long long'; consider using a typedef or fixed-width type instead [portability-avoid-platform-specific-fundamental-types] +// CHECK-MESSAGES: :[[@LINE-1]]:20: warning: avoid using platform-dependent fundamental integer type 'unsigned long long'; consider using a 'typedef' or fixed-width type instead [portability-avoid-platform-specific-fundamental-types] // Test integer that should NEVER trigger warnings bool global_bool = true; @@ -62,34 +62,34 @@ ptrdiff_t global_ptrdiff = 50; // Test function parameters void function_with_int_param(int param) { -// CHECK-MESSAGES: :[[@LINE-1]]:34: warning: avoid using platform-dependent fundamental integer type 'int'; consider using a typedef or fixed-width type instead [portability-avoid-platform-specific-fundamental-types] +// CHECK-MESSAGES: :[[@LINE-1]]:34: warning: avoid using platform-dependent fundamental integer type 'int'; consider using a 'typedef' or fixed-width type instead [portability-avoid-platform-specific-fundamental-types] } void function_with_short_param(short param) { -// CHECK-MESSAGES: :[[@LINE-1]]:38: warning: avoid using platform-dependent fundamental integer type 'short'; consider using a typedef or fixed-width type instead [portability-avoid-platform-specific-fundamental-types] +// CHECK-MESSAGES: :[[@LINE-1]]:38: warning: avoid using platform-dependent fundamental integer type 'short'; consider using a 'typedef' or fixed-width type instead [portability-avoid-platform-specific-fundamental-types] } // Test function return types int function_returning_int() { -// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: avoid using platform-dependent fundamental integer type 'int'; consider using a typedef or fixed-width type instead [portability-avoid-platform-specific-fundamental-types] +// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: avoid using platform-dependent fundamental integer type 'int'; consider using a 'typedef' or fixed-width type instead [portability-avoid-platform-specific-fundamental-types] return 42; } long function_returning_long() { -// CHECK-MESSAGES: :[[@LINE-1]]:6: warning: avoid using platform-dependent fundamental integer type 'long'; consider using a typedef or fixed-width type instead [portability-avoid-platform-specific-fundamental-types] +// CHECK-MESSAGES: :[[@LINE-1]]:6: warning: avoid using platform-dependent fundamental integer type 'long'; consider using a 'typedef' or fixed-width type instead [portability-avoid-platform-specific-fundamental-types] return 100L; } // Test local variables void test_local_variables() { int local_int = 10; - // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: avoid using platform-dependent fundamental integer type 'int'; consider using a typedef or fixed-width type instead [portability-avoid-platform-specific-fundamental-types] + // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: avoid using platform-dependent fundamental integer type 'int'; consider using a 'typedef' or fixed-width type instead [portability-avoid-platform-specific-fundamental-types] short local_short = 5; - // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: avoid using platform-dependent fundamental integer type 'short'; consider using a typedef or fixed-width type instead [portability-avoid-platform-specific-fundamental-types] + // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: avoid using platform-dependent fundamental integer type 'short'; consider using a 'typedef' or fixed-width type instead [portability-avoid-platform-specific-fundamental-types] unsigned long local_unsigned_long = 200UL; - // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: avoid using platform-dependent fundamental integer type 'unsigned long'; consider using a typedef or fixed-width type instead [portability-avoid-platform-specific-fundamental-types] + // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: avoid using platform-dependent fundamental integer type 'unsigned long'; consider using a 'typedef' or fixed-width type instead [portability-avoid-platform-specific-fundamental-types] // These should not trigger warnings char local_char = 'x'; @@ -107,10 +107,10 @@ void test_local_variables() { // Test struct/class members struct TestStruct { int member_int; - // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: avoid using platform-dependent fundamental integer type 'int'; consider using a typedef or fixed-width type instead [portability-avoid-platform-specific-fundamental-types] + // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: avoid using platform-dependent fundamental integer type 'int'; consider using a 'typedef' or fixed-width type instead [portability-avoid-platform-specific-fundamental-types] long member_long; - // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: avoid using platform-dependent fundamental integer type 'long'; consider using a typedef or fixed-width type instead [portability-avoid-platform-specific-fundamental-types] + // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: avoid using platform-dependent fundamental integer type 'long'; consider using a 'typedef' or fixed-width type instead [portability-avoid-platform-specific-fundamental-types] // These should not trigger warnings char member_char; @@ -120,22 +120,22 @@ struct TestStruct { class TestClass { public: unsigned int public_member; - // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: avoid using platform-dependent fundamental integer type 'unsigned int'; consider using a typedef or fixed-width type instead [portability-avoid-platform-specific-fundamental-types] + // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: avoid using platform-dependent fundamental integer type 'unsigned int'; consider using a 'typedef' or fixed-width type instead [portability-avoid-platform-specific-fundamental-types] private: short private_member; - // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: avoid using platform-dependent fundamental integer type 'short'; consider using a typedef or fixed-width type instead [portability-avoid-platform-specific-fundamental-types] + // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: avoid using platform-dependent fundamental integer type 'short'; consider using a 'typedef' or fixed-width type instead [portability-avoid-platform-specific-fundamental-types] }; // Test typedefs and type aliases typedef int MyInt; -// CHECK-MESSAGES: :[[@LINE-1]]:13: warning: avoid using platform-dependent fundamental integer type 'int'; consider using a typedef or fixed-width type instead [portability-avoid-platform-specific-fundamental-types] +// CHECK-MESSAGES: :[[@LINE-1]]:13: warning: avoid using platform-dependent fundamental integer type 'int'; consider using a 'typedef' or fixed-width type instead [portability-avoid-platform-specific-fundamental-types] using MyLong = long; -// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: avoid using platform-dependent fundamental integer type 'long'; consider using a typedef or fixed-width type instead [portability-avoid-platform-specific-fundamental-types] +// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: avoid using platform-dependent fundamental integer type 'long'; consider using a 'typedef' or fixed-width type instead [portability-avoid-platform-specific-fundamental-types] typedef long long customType; -// CHECK-MESSAGES: :[[@LINE-1]]:19: warning: avoid using platform-dependent fundamental integer type 'long long'; consider using a typedef or fixed-width type instead [portability-avoid-platform-specific-fundamental-types] +// CHECK-MESSAGES: :[[@LINE-1]]:19: warning: avoid using platform-dependent fundamental integer type 'long long'; consider using a 'typedef' or fixed-width type instead [portability-avoid-platform-specific-fundamental-types] // Test template parameters template @@ -143,5 +143,5 @@ void template_function(T param) {} template<> void template_function(int param) { -// CHECK-MESSAGES: :[[@LINE-1]]:33: warning: avoid using platform-dependent fundamental integer type 'int'; consider using a typedef or fixed-width type instead [portability-avoid-platform-specific-fundamental-types] +// CHECK-MESSAGES: :[[@LINE-1]]:33: warning: avoid using platform-dependent fundamental integer type 'int'; consider using a 'typedef' or fixed-width type instead [portability-avoid-platform-specific-fundamental-types] } From bdbccb368286794e7263b3d848897f8752ae3699 Mon Sep 17 00:00:00 2001 From: JJ Marr Date: Sat, 9 Aug 2025 20:59:04 -0400 Subject: [PATCH 46/83] link as option --- .../portability/avoid-platform-specific-fundamental-types.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clang-tools-extra/docs/clang-tidy/checks/portability/avoid-platform-specific-fundamental-types.rst b/clang-tools-extra/docs/clang-tidy/checks/portability/avoid-platform-specific-fundamental-types.rst index 89f9029a652e7..36c7d0fd36803 100644 --- a/clang-tools-extra/docs/clang-tidy/checks/portability/avoid-platform-specific-fundamental-types.rst +++ b/clang-tools-extra/docs/clang-tidy/checks/portability/avoid-platform-specific-fundamental-types.rst @@ -136,7 +136,7 @@ Options ``unsigned`` variants). When `false`, integer types are not flagged. - Example with `WarnOnInts` enabled: + Example with :option:`WarnOnInts` enabled: .. code-block:: c++ From 8c05d1f32e13295b20579f93df31ba389e5354f3 Mon Sep 17 00:00:00 2001 From: JJ Marr Date: Sat, 9 Aug 2025 21:05:19 -0400 Subject: [PATCH 47/83] Split run directives across multiple lines --- .../avoid-platform-specific-fundamental-types-chars.cpp | 8 +++++++- .../avoid-platform-specific-fundamental-types-floats.cpp | 8 +++++++- .../avoid-platform-specific-fundamental-types-ints.cpp | 8 +++++++- 3 files changed, 21 insertions(+), 3 deletions(-) diff --git a/clang-tools-extra/test/clang-tidy/checkers/portability/avoid-platform-specific-fundamental-types-chars.cpp b/clang-tools-extra/test/clang-tidy/checkers/portability/avoid-platform-specific-fundamental-types-chars.cpp index a798db04aa6ec..6aca575e2704c 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/portability/avoid-platform-specific-fundamental-types-chars.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/portability/avoid-platform-specific-fundamental-types-chars.cpp @@ -1,4 +1,10 @@ -// 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}]}" +// RUN: %check_clang_tidy -std=c++11-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}]}" // Test character types that should trigger warnings when WarnOnChars is enabled char global_char = 'a'; diff --git a/clang-tools-extra/test/clang-tidy/checkers/portability/avoid-platform-specific-fundamental-types-floats.cpp b/clang-tools-extra/test/clang-tidy/checkers/portability/avoid-platform-specific-fundamental-types-floats.cpp index 9e4605aacec67..19197479b0cb8 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/portability/avoid-platform-specific-fundamental-types-floats.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/portability/avoid-platform-specific-fundamental-types-floats.cpp @@ -1,4 +1,10 @@ -// 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}]}" +// RUN: %check_clang_tidy -std=c++23-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.WarnOnChars, \ +// RUN: value: false}]}" // Mock fixed-width float types // In reality, these types are aliases to "extended floating point types", and diff --git a/clang-tools-extra/test/clang-tidy/checkers/portability/avoid-platform-specific-fundamental-types-ints.cpp b/clang-tools-extra/test/clang-tidy/checkers/portability/avoid-platform-specific-fundamental-types-ints.cpp index 26ec188ddd18c..97cfe5301fff4 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/portability/avoid-platform-specific-fundamental-types-ints.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/portability/avoid-platform-specific-fundamental-types-ints.cpp @@ -1,4 +1,10 @@ -// 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}]}" +// RUN: %check_clang_tidy -std=c++11-or-later %s \ +// RUN: portability-avoid-platform-specific-fundamental-types %t -- \ +// RUN: -config="{CheckOptions: \ +// RUN: [{key: portability-avoid-platform-specific-fundamental-types.WarnOnChars, \ +// RUN: value: false}, \ +// RUN: {key: portability-avoid-platform-specific-fundamental-types.WarnOnFloats, \ +// RUN: value: false}]}" // Mock fixed-width integer types // NOLINTBEGIN(portability-avoid-platform-specific-fundamental-types) From 03f0dfe5f45954755d37bebb674fa7fc1c0c00b0 Mon Sep 17 00:00:00 2001 From: JJ Marr Date: Sat, 9 Aug 2025 21:07:30 -0400 Subject: [PATCH 48/83] Harmonize release notes with header --- .../portability/AvoidPlatformSpecificFundamentalTypesCheck.h | 3 --- clang-tools-extra/docs/ReleaseNotes.rst | 4 ++-- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/clang-tools-extra/clang-tidy/portability/AvoidPlatformSpecificFundamentalTypesCheck.h b/clang-tools-extra/clang-tidy/portability/AvoidPlatformSpecificFundamentalTypesCheck.h index 95e62d983f65d..edbdf9c061526 100644 --- a/clang-tools-extra/clang-tidy/portability/AvoidPlatformSpecificFundamentalTypesCheck.h +++ b/clang-tools-extra/clang-tidy/portability/AvoidPlatformSpecificFundamentalTypesCheck.h @@ -14,9 +14,6 @@ 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. /// diff --git a/clang-tools-extra/docs/ReleaseNotes.rst b/clang-tools-extra/docs/ReleaseNotes.rst index 826c5f9bed562..d4f1f18c983d2 100644 --- a/clang-tools-extra/docs/ReleaseNotes.rst +++ b/clang-tools-extra/docs/ReleaseNotes.rst @@ -152,8 +152,8 @@ New checks ` check. - Finds fundamental types (e.g. ``int``, ``float``) and recommends using typedefs - or fixed-width types instead to improve portability across different platforms. + Detects fundamental types (int, short, long, long long, char, float, etc) + and warns against their use due to platform-dependent behavior. - New :doc:`portability-avoid-pragma-once ` check. From ed7157d31065580bc9483c9953f7bb0d1e5b3500 Mon Sep 17 00:00:00 2001 From: JJ Marr Date: Sat, 9 Aug 2025 21:14:35 -0400 Subject: [PATCH 49/83] Make "default is true" the last sentence --- .../avoid-platform-specific-fundamental-types.rst | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/clang-tools-extra/docs/clang-tidy/checks/portability/avoid-platform-specific-fundamental-types.rst b/clang-tools-extra/docs/clang-tidy/checks/portability/avoid-platform-specific-fundamental-types.rst index 36c7d0fd36803..15ebe10ae7965 100644 --- a/clang-tools-extra/docs/clang-tidy/checks/portability/avoid-platform-specific-fundamental-types.rst +++ b/clang-tools-extra/docs/clang-tidy/checks/portability/avoid-platform-specific-fundamental-types.rst @@ -131,10 +131,10 @@ Options .. option:: WarnOnInts - When `true` (default), the check will warn about fundamental integer types + 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. + When `false`, integer types are not flagged. Default is `true` Example with :option:`WarnOnInts` enabled: @@ -170,7 +170,7 @@ Options .. option:: WarnOnFloats - When `true` (default), the check will warn about floating point types + When `true`, the check will warn about floating point types (``float`` and ``double``). When `false`, floating point types are not flagged. @@ -184,6 +184,8 @@ Options ``float64_t`` instead of ``float`` and ``double`` respectively, when the target platform supports standard IEEE754 sizes. + Default is `true` + Example with :option:`WarnOnFloats` enabled: .. code-block:: c++ @@ -202,7 +204,7 @@ Options .. option:: WarnOnChars - When `true` (default), the check will warn about character types (``char``, + When `true`, the check will warn about character types (``char``, ``signed char``, and ``unsigned char``). When `false`, character types are not flagged. @@ -216,6 +218,8 @@ Options or typedefs to make the intent clear and ensure consistent behavior across platforms. + Default is `true`. + Example with :option:`WarnOnChars` enabled: .. code-block:: c++ From d26bb9ebe374a52dbb5a42645394f2dba45e4871 Mon Sep 17 00:00:00 2001 From: JJ Marr Date: Sat, 9 Aug 2025 22:05:43 -0400 Subject: [PATCH 50/83] warn on bad config and other stuff --- .../AvoidPlatformSpecificFundamentalTypesCheck.cpp | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/clang-tools-extra/clang-tidy/portability/AvoidPlatformSpecificFundamentalTypesCheck.cpp b/clang-tools-extra/clang-tidy/portability/AvoidPlatformSpecificFundamentalTypesCheck.cpp index d6af70cf581a7..0e343368e5938 100644 --- a/clang-tools-extra/clang-tidy/portability/AvoidPlatformSpecificFundamentalTypesCheck.cpp +++ b/clang-tools-extra/clang-tidy/portability/AvoidPlatformSpecificFundamentalTypesCheck.cpp @@ -22,6 +22,7 @@ AST_MATCHER(clang::QualType, isBuiltinInt) { if (!BT) return false; + // BT->isInteger() would detect char and bool switch (BT->getKind()) { case clang::BuiltinType::Short: case clang::BuiltinType::UShort: @@ -58,7 +59,13 @@ AvoidPlatformSpecificFundamentalTypesCheck:: WarnOnChars(Options.get("WarnOnChars", true)), IncludeInserter(Options.getLocalOrGlobal("IncludeStyle", utils::IncludeSorter::IS_LLVM), - areDiagsSelfContained()) {} + 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) { From 9634a744be07ab5d8a01d28926891d4f9e439a35 Mon Sep 17 00:00:00 2001 From: JJ Marr Date: Sat, 9 Aug 2025 22:38:11 -0400 Subject: [PATCH 51/83] Refactor redundant code, works for int and float --- ...dPlatformSpecificFundamentalTypesCheck.cpp | 68 ++----------------- ...tform-specific-fundamental-types-chars.cpp | 36 +++++----- ...form-specific-fundamental-types-floats.cpp | 34 +++++----- ...atform-specific-fundamental-types-ints.cpp | 47 ++++++------- 4 files changed, 67 insertions(+), 118 deletions(-) diff --git a/clang-tools-extra/clang-tidy/portability/AvoidPlatformSpecificFundamentalTypesCheck.cpp b/clang-tools-extra/clang-tidy/portability/AvoidPlatformSpecificFundamentalTypesCheck.cpp index 0e343368e5938..5ecef7c126b50 100644 --- a/clang-tools-extra/clang-tidy/portability/AvoidPlatformSpecificFundamentalTypesCheck.cpp +++ b/clang-tools-extra/clang-tidy/portability/AvoidPlatformSpecificFundamentalTypesCheck.cpp @@ -126,73 +126,19 @@ void AvoidPlatformSpecificFundamentalTypesCheck::registerMatchers( 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(hasType(PlatformSpecificFundamentalType)).bind("field_decl"), - this); - - Finder->addMatcher( - typedefDecl(hasUnderlyingType(PlatformSpecificFundamentalType)) - .bind("typedef_decl"), - this); - - Finder->addMatcher(typeAliasDecl(hasType(PlatformSpecificFundamentalType)) - .bind("alias_decl"), + Finder->addMatcher(typeLoc(loc(PlatformSpecificFundamentalType)).bind("type"), this); } void AvoidPlatformSpecificFundamentalTypesCheck::check( const MatchFinder::MatchResult &Result) { - SourceLocation Loc; - QualType QT; - SourceRange TypeRange; - - auto SetTypeRange = [&TypeRange](auto Decl) { - if (Decl->getTypeSourceInfo()) - TypeRange = Decl->getTypeSourceInfo()->getTypeLoc().getSourceRange(); - }; - - if (const auto *VD = Result.Nodes.getNodeAs("var_decl")) { - Loc = VD->getLocation(); - QT = VD->getType(); - SetTypeRange(VD); - } else if (const auto *FD = - Result.Nodes.getNodeAs("func_decl")) { - Loc = FD->getLocation(); - QT = FD->getReturnType(); - SetTypeRange(FD); - } else if (const auto *PD = - Result.Nodes.getNodeAs("param_decl")) { - Loc = PD->getLocation(); - QT = PD->getType(); - SetTypeRange(PD); - } else if (const auto *FD = Result.Nodes.getNodeAs("field_decl")) { - Loc = FD->getLocation(); - QT = FD->getType(); - SetTypeRange(FD); - } else if (const auto *TD = - Result.Nodes.getNodeAs("typedef_decl")) { - Loc = TD->getLocation(); - QT = TD->getUnderlyingType(); - SetTypeRange(TD); - } else if (const auto *AD = - Result.Nodes.getNodeAs("alias_decl")) { - Loc = AD->getLocation(); - QT = AD->getUnderlyingType(); - SetTypeRange(AD); - } else { + const auto *TL = Result.Nodes.getNodeAs("type"); + if (!TL) return; - } + + SourceLocation Loc = TL->getBeginLoc(); + QualType QT = TL->getType(); + SourceRange TypeRange = TL->getSourceRange(); const std::string TypeName = QT.getAsString(); diff --git a/clang-tools-extra/test/clang-tidy/checkers/portability/avoid-platform-specific-fundamental-types-chars.cpp b/clang-tools-extra/test/clang-tidy/checkers/portability/avoid-platform-specific-fundamental-types-chars.cpp index 6aca575e2704c..3ce7c6b259af6 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/portability/avoid-platform-specific-fundamental-types-chars.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/portability/avoid-platform-specific-fundamental-types-chars.cpp @@ -8,65 +8,65 @@ // 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]]:28: 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]]:35: 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]]:37: 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-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] // Struct fields struct TestStruct { char field_char; - // CHECK-MESSAGES: :[[@LINE-1]]:8: 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]]:3: 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 field_signed_char; - // CHECK-MESSAGES: :[[@LINE-1]]:15: 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]]:3: 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 field_unsigned_char; - // CHECK-MESSAGES: :[[@LINE-1]]:17: 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]]:3: 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] }; // Typedefs typedef char char_typedef; -// CHECK-MESSAGES: :[[@LINE-1]]:14: 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]]:9: 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] typedef signed char signed_char_typedef; -// CHECK-MESSAGES: :[[@LINE-1]]:21: 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]]:9: 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] typedef unsigned char unsigned_char_typedef; -// CHECK-MESSAGES: :[[@LINE-1]]:23: 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]]:9: 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] // Type aliases (C++11) using char_alias = char; -// CHECK-MESSAGES: :[[@LINE-1]]:7: 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]]:20: 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] using signed_char_alias = signed char; -// CHECK-MESSAGES: :[[@LINE-1]]:7: 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]]:27: 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] using unsigned_char_alias = unsigned char; -// CHECK-MESSAGES: :[[@LINE-1]]:7: 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]]:29: 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] // Test that integer and float types are NOT flagged when their options are disabled int should_not_warn_int = 42; diff --git a/clang-tools-extra/test/clang-tidy/checkers/portability/avoid-platform-specific-fundamental-types-floats.cpp b/clang-tools-extra/test/clang-tidy/checkers/portability/avoid-platform-specific-fundamental-types-floats.cpp index 19197479b0cb8..c1d802fbacaff 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/portability/avoid-platform-specific-fundamental-types-floats.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/portability/avoid-platform-specific-fundamental-types-floats.cpp @@ -17,41 +17,41 @@ typedef double float64_t; // 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-MESSAGES: :[[@LINE-1]]:1: 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; double global_double = 3.14159; -// CHECK-MESSAGES: :[[@LINE-1]]:8: warning: avoid using platform-dependent floating point type 'double'; consider using 'float64_t' instead [portability-avoid-platform-specific-fundamental-types] +// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: avoid using platform-dependent floating point type 'double'; consider using 'float64_t' instead [portability-avoid-platform-specific-fundamental-types] // CHECK-FIXES: float64_t global_double = 3.14159; // Test function parameters with float types void function_with_float_param(float param) { -// CHECK-MESSAGES: :[[@LINE-1]]:38: warning: avoid using platform-dependent floating point type 'float'; consider using 'float32_t' instead [portability-avoid-platform-specific-fundamental-types] +// CHECK-MESSAGES: :[[@LINE-1]]:32: warning: avoid using platform-dependent floating point type 'float'; consider using 'float32_t' instead [portability-avoid-platform-specific-fundamental-types] } void function_with_double_param(double param) { -// CHECK-MESSAGES: :[[@LINE-1]]:40: warning: avoid using platform-dependent floating point type 'double'; consider using 'float64_t' instead [portability-avoid-platform-specific-fundamental-types] +// CHECK-MESSAGES: :[[@LINE-1]]:33: warning: avoid using platform-dependent floating point type 'double'; consider using 'float64_t' instead [portability-avoid-platform-specific-fundamental-types] } // Test function return types with float types float function_returning_float() { -// 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-MESSAGES: :[[@LINE-1]]:1: warning: avoid using platform-dependent floating point type 'float'; consider using 'float32_t' instead [portability-avoid-platform-specific-fundamental-types] return 3.14f; } double function_returning_double() { -// CHECK-MESSAGES: :[[@LINE-1]]:8: warning: avoid using platform-dependent floating point type 'double'; consider using 'float64_t' instead [portability-avoid-platform-specific-fundamental-types] +// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: avoid using platform-dependent floating point type 'double'; consider using 'float64_t' instead [portability-avoid-platform-specific-fundamental-types] return 3.14159; } // Test local variables with float types void test_local_float_variables() { float local_float = 2.71f; - // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: avoid using platform-dependent floating point type 'float'; consider using 'float32_t' instead [portability-avoid-platform-specific-fundamental-types] + // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: avoid using platform-dependent floating point type 'float'; consider using 'float32_t' instead [portability-avoid-platform-specific-fundamental-types] double local_double = 2.71828; - // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: avoid using platform-dependent floating point type 'double'; consider using 'float64_t' instead [portability-avoid-platform-specific-fundamental-types] + // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: avoid using platform-dependent floating point type 'double'; consider using 'float64_t' instead [portability-avoid-platform-specific-fundamental-types] // Fixed-width types should not trigger warnings float32_t local_float32 = 3.14f; @@ -61,10 +61,10 @@ void test_local_float_variables() { // Test struct/class members with float types struct TestFloatStruct { float member_float; - // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: avoid using platform-dependent floating point type 'float'; consider using 'float32_t' instead [portability-avoid-platform-specific-fundamental-types] + // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: avoid using platform-dependent floating point type 'float'; consider using 'float32_t' instead [portability-avoid-platform-specific-fundamental-types] double member_double; - // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: avoid using platform-dependent floating point type 'double'; consider using 'float64_t' instead [portability-avoid-platform-specific-fundamental-types] + // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: avoid using platform-dependent floating point type 'double'; consider using 'float64_t' instead [portability-avoid-platform-specific-fundamental-types] // Fixed-width types should not trigger warnings float32_t member_float32; @@ -74,19 +74,19 @@ struct TestFloatStruct { class TestFloatClass { public: float public_float_member; - // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: avoid using platform-dependent floating point type 'float'; consider using 'float32_t' instead [portability-avoid-platform-specific-fundamental-types] + // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: avoid using platform-dependent floating point type 'float'; consider using 'float32_t' instead [portability-avoid-platform-specific-fundamental-types] private: double private_double_member; - // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: avoid using platform-dependent floating point type 'double'; consider using 'float64_t' instead [portability-avoid-platform-specific-fundamental-types] + // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: avoid using platform-dependent floating point type 'double'; consider using 'float64_t' instead [portability-avoid-platform-specific-fundamental-types] }; // Test typedefs and type aliases with float types typedef float MyFloat; -// CHECK-MESSAGES: :[[@LINE-1]]:15: warning: avoid using platform-dependent floating point type 'float'; consider using 'float32_t' instead [portability-avoid-platform-specific-fundamental-types] +// CHECK-MESSAGES: :[[@LINE-1]]:9: warning: avoid using platform-dependent floating point type 'float'; consider using 'float32_t' instead [portability-avoid-platform-specific-fundamental-types] using MyDouble = double; -// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: avoid using platform-dependent floating point type 'double'; consider using 'float64_t' instead [portability-avoid-platform-specific-fundamental-types] +// CHECK-MESSAGES: :[[@LINE-1]]:18: warning: avoid using platform-dependent floating point type 'double'; consider using 'float64_t' instead [portability-avoid-platform-specific-fundamental-types] // Test template specializations with float types template @@ -94,12 +94,14 @@ void template_function(T param) {} template<> void template_function(float param) { -// CHECK-MESSAGES: :[[@LINE-1]]:37: warning: avoid using platform-dependent floating point type 'float'; consider using 'float32_t' instead [portability-avoid-platform-specific-fundamental-types] +// CHECK-MESSAGES: :[[@LINE-1]]:24: warning: avoid using platform-dependent floating point type 'float'; consider using 'float32_t' instead [portability-avoid-platform-specific-fundamental-types] +// CHECK-MESSAGES: :[[@LINE-2]]:31: warning: avoid using platform-dependent floating point type 'float'; consider using 'float32_t' instead [portability-avoid-platform-specific-fundamental-types] } template<> void template_function(double param) { -// CHECK-MESSAGES: :[[@LINE-1]]:39: warning: avoid using platform-dependent floating point type 'double'; consider using 'float64_t' instead [portability-avoid-platform-specific-fundamental-types] +// CHECK-MESSAGES: :[[@LINE-1]]:24: warning: avoid using platform-dependent floating point type 'double'; consider using 'float64_t' instead [portability-avoid-platform-specific-fundamental-types] +// CHECK-MESSAGES: :[[@LINE-2]]:32: warning: avoid using platform-dependent floating point type 'double'; consider using 'float64_t' instead [portability-avoid-platform-specific-fundamental-types] } // Test that integer and char types are NOT flagged when their options are disabled diff --git a/clang-tools-extra/test/clang-tidy/checkers/portability/avoid-platform-specific-fundamental-types-ints.cpp b/clang-tools-extra/test/clang-tidy/checkers/portability/avoid-platform-specific-fundamental-types-ints.cpp index 97cfe5301fff4..fef9d6373531e 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/portability/avoid-platform-specific-fundamental-types-ints.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/portability/avoid-platform-specific-fundamental-types-ints.cpp @@ -23,28 +23,28 @@ typedef unsigned long size_t; // Test fundamental integer types that should trigger warnings int global_int = 42; -// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: avoid using platform-dependent fundamental integer type 'int'; consider using a 'typedef' or fixed-width type instead [portability-avoid-platform-specific-fundamental-types] +// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: avoid using platform-dependent fundamental integer type 'int'; consider using a 'typedef' or fixed-width type instead [portability-avoid-platform-specific-fundamental-types] short global_short = 10; -// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: avoid using platform-dependent fundamental integer type 'short'; consider using a 'typedef' or fixed-width type instead [portability-avoid-platform-specific-fundamental-types] +// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: avoid using platform-dependent fundamental integer type 'short'; consider using a 'typedef' or fixed-width type instead [portability-avoid-platform-specific-fundamental-types] long global_long = 100L; -// CHECK-MESSAGES: :[[@LINE-1]]:6: warning: avoid using platform-dependent fundamental integer type 'long'; consider using a 'typedef' or fixed-width type instead [portability-avoid-platform-specific-fundamental-types] +// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: avoid using platform-dependent fundamental integer type 'long'; consider using a 'typedef' or fixed-width type instead [portability-avoid-platform-specific-fundamental-types] long long global_long_long = 1000LL; -// CHECK-MESSAGES: :[[@LINE-1]]:11: warning: avoid using platform-dependent fundamental integer type 'long long'; consider using a 'typedef' or fixed-width type instead [portability-avoid-platform-specific-fundamental-types] +// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: avoid using platform-dependent fundamental integer type 'long long'; consider using a 'typedef' or fixed-width type instead [portability-avoid-platform-specific-fundamental-types] unsigned int global_unsigned_int = 42U; -// CHECK-MESSAGES: :[[@LINE-1]]:14: warning: avoid using platform-dependent fundamental integer type 'unsigned int'; consider using a 'typedef' or fixed-width type instead [portability-avoid-platform-specific-fundamental-types] +// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: avoid using platform-dependent fundamental integer type 'unsigned int'; consider using a 'typedef' or fixed-width type instead [portability-avoid-platform-specific-fundamental-types] unsigned short global_unsigned_short = 10U; -// CHECK-MESSAGES: :[[@LINE-1]]:16: warning: avoid using platform-dependent fundamental integer type 'unsigned short'; consider using a 'typedef' or fixed-width type instead [portability-avoid-platform-specific-fundamental-types] +// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: avoid using platform-dependent fundamental integer type 'unsigned short'; consider using a 'typedef' or fixed-width type instead [portability-avoid-platform-specific-fundamental-types] unsigned long global_unsigned_long = 100UL; -// CHECK-MESSAGES: :[[@LINE-1]]:15: warning: avoid using platform-dependent fundamental integer type 'unsigned long'; consider using a 'typedef' or fixed-width type instead [portability-avoid-platform-specific-fundamental-types] +// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: avoid using platform-dependent fundamental integer type 'unsigned long'; consider using a 'typedef' or fixed-width type instead [portability-avoid-platform-specific-fundamental-types] unsigned long long global_unsigned_long_long = 1000ULL; -// CHECK-MESSAGES: :[[@LINE-1]]:20: warning: avoid using platform-dependent fundamental integer type 'unsigned long long'; consider using a 'typedef' or fixed-width type instead [portability-avoid-platform-specific-fundamental-types] +// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: avoid using platform-dependent fundamental integer type 'unsigned long long'; consider using a 'typedef' or fixed-width type instead [portability-avoid-platform-specific-fundamental-types] // Test integer that should NEVER trigger warnings bool global_bool = true; @@ -68,34 +68,34 @@ ptrdiff_t global_ptrdiff = 50; // Test function parameters void function_with_int_param(int param) { -// CHECK-MESSAGES: :[[@LINE-1]]:34: warning: avoid using platform-dependent fundamental integer type 'int'; consider using a 'typedef' or fixed-width type instead [portability-avoid-platform-specific-fundamental-types] +// CHECK-MESSAGES: :[[@LINE-1]]:30: warning: avoid using platform-dependent fundamental integer type 'int'; consider using a 'typedef' or fixed-width type instead [portability-avoid-platform-specific-fundamental-types] } void function_with_short_param(short param) { -// CHECK-MESSAGES: :[[@LINE-1]]:38: warning: avoid using platform-dependent fundamental integer type 'short'; consider using a 'typedef' or fixed-width type instead [portability-avoid-platform-specific-fundamental-types] +// CHECK-MESSAGES: :[[@LINE-1]]:32: warning: avoid using platform-dependent fundamental integer type 'short'; consider using a 'typedef' or fixed-width type instead [portability-avoid-platform-specific-fundamental-types] } // Test function return types int function_returning_int() { -// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: avoid using platform-dependent fundamental integer type 'int'; consider using a 'typedef' or fixed-width type instead [portability-avoid-platform-specific-fundamental-types] +// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: avoid using platform-dependent fundamental integer type 'int'; consider using a 'typedef' or fixed-width type instead [portability-avoid-platform-specific-fundamental-types] return 42; } long function_returning_long() { -// CHECK-MESSAGES: :[[@LINE-1]]:6: warning: avoid using platform-dependent fundamental integer type 'long'; consider using a 'typedef' or fixed-width type instead [portability-avoid-platform-specific-fundamental-types] +// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: avoid using platform-dependent fundamental integer type 'long'; consider using a 'typedef' or fixed-width type instead [portability-avoid-platform-specific-fundamental-types] return 100L; } // Test local variables void test_local_variables() { int local_int = 10; - // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: avoid using platform-dependent fundamental integer type 'int'; consider using a 'typedef' or fixed-width type instead [portability-avoid-platform-specific-fundamental-types] + // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: avoid using platform-dependent fundamental integer type 'int'; consider using a 'typedef' or fixed-width type instead [portability-avoid-platform-specific-fundamental-types] short local_short = 5; - // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: avoid using platform-dependent fundamental integer type 'short'; consider using a 'typedef' or fixed-width type instead [portability-avoid-platform-specific-fundamental-types] + // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: avoid using platform-dependent fundamental integer type 'short'; consider using a 'typedef' or fixed-width type instead [portability-avoid-platform-specific-fundamental-types] unsigned long local_unsigned_long = 200UL; - // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: avoid using platform-dependent fundamental integer type 'unsigned long'; consider using a 'typedef' or fixed-width type instead [portability-avoid-platform-specific-fundamental-types] + // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: avoid using platform-dependent fundamental integer type 'unsigned long'; consider using a 'typedef' or fixed-width type instead [portability-avoid-platform-specific-fundamental-types] // These should not trigger warnings char local_char = 'x'; @@ -113,10 +113,10 @@ void test_local_variables() { // Test struct/class members struct TestStruct { int member_int; - // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: avoid using platform-dependent fundamental integer type 'int'; consider using a 'typedef' or fixed-width type instead [portability-avoid-platform-specific-fundamental-types] + // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: avoid using platform-dependent fundamental integer type 'int'; consider using a 'typedef' or fixed-width type instead [portability-avoid-platform-specific-fundamental-types] long member_long; - // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: avoid using platform-dependent fundamental integer type 'long'; consider using a 'typedef' or fixed-width type instead [portability-avoid-platform-specific-fundamental-types] + // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: avoid using platform-dependent fundamental integer type 'long'; consider using a 'typedef' or fixed-width type instead [portability-avoid-platform-specific-fundamental-types] // These should not trigger warnings char member_char; @@ -126,22 +126,22 @@ struct TestStruct { class TestClass { public: unsigned int public_member; - // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: avoid using platform-dependent fundamental integer type 'unsigned int'; consider using a 'typedef' or fixed-width type instead [portability-avoid-platform-specific-fundamental-types] + // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: avoid using platform-dependent fundamental integer type 'unsigned int'; consider using a 'typedef' or fixed-width type instead [portability-avoid-platform-specific-fundamental-types] private: short private_member; - // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: avoid using platform-dependent fundamental integer type 'short'; consider using a 'typedef' or fixed-width type instead [portability-avoid-platform-specific-fundamental-types] + // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: avoid using platform-dependent fundamental integer type 'short'; consider using a 'typedef' or fixed-width type instead [portability-avoid-platform-specific-fundamental-types] }; // Test typedefs and type aliases typedef int MyInt; -// CHECK-MESSAGES: :[[@LINE-1]]:13: warning: avoid using platform-dependent fundamental integer type 'int'; consider using a 'typedef' or fixed-width type instead [portability-avoid-platform-specific-fundamental-types] +// CHECK-MESSAGES: :[[@LINE-1]]:9: warning: avoid using platform-dependent fundamental integer type 'int'; consider using a 'typedef' or fixed-width type instead [portability-avoid-platform-specific-fundamental-types] using MyLong = long; -// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: avoid using platform-dependent fundamental integer type 'long'; consider using a 'typedef' or fixed-width type instead [portability-avoid-platform-specific-fundamental-types] +// CHECK-MESSAGES: :[[@LINE-1]]:16: warning: avoid using platform-dependent fundamental integer type 'long'; consider using a 'typedef' or fixed-width type instead [portability-avoid-platform-specific-fundamental-types] typedef long long customType; -// CHECK-MESSAGES: :[[@LINE-1]]:19: warning: avoid using platform-dependent fundamental integer type 'long long'; consider using a 'typedef' or fixed-width type instead [portability-avoid-platform-specific-fundamental-types] +// CHECK-MESSAGES: :[[@LINE-1]]:9: warning: avoid using platform-dependent fundamental integer type 'long long'; consider using a 'typedef' or fixed-width type instead [portability-avoid-platform-specific-fundamental-types] // Test template parameters template @@ -149,5 +149,6 @@ void template_function(T param) {} template<> void template_function(int param) { -// CHECK-MESSAGES: :[[@LINE-1]]:33: warning: avoid using platform-dependent fundamental integer type 'int'; consider using a 'typedef' or fixed-width type instead [portability-avoid-platform-specific-fundamental-types] +// CHECK-MESSAGES: :[[@LINE-1]]:24: warning: avoid using platform-dependent fundamental integer type 'int'; consider using a 'typedef' or fixed-width type instead [portability-avoid-platform-specific-fundamental-types] +// CHECK-MESSAGES: :[[@LINE-2]]:29: warning: avoid using platform-dependent fundamental integer type 'int'; consider using a 'typedef' or fixed-width type instead [portability-avoid-platform-specific-fundamental-types] } From 89d44899af017783708f23bc68e03696e78a3c78 Mon Sep 17 00:00:00 2001 From: JJ Marr Date: Sat, 9 Aug 2025 23:08:49 -0400 Subject: [PATCH 52/83] Fix for char --- ...dPlatformSpecificFundamentalTypesCheck.cpp | 9 ++++- ...tform-specific-fundamental-types-chars.cpp | 6 +-- clang/include/clang/ASTMatchers/ASTMatchers.h | 37 +++++++++++++++++-- 3 files changed, 44 insertions(+), 8 deletions(-) diff --git a/clang-tools-extra/clang-tidy/portability/AvoidPlatformSpecificFundamentalTypesCheck.cpp b/clang-tools-extra/clang-tidy/portability/AvoidPlatformSpecificFundamentalTypesCheck.cpp index 5ecef7c126b50..29d7228cfdf28 100644 --- a/clang-tools-extra/clang-tidy/portability/AvoidPlatformSpecificFundamentalTypesCheck.cpp +++ b/clang-tools-extra/clang-tidy/portability/AvoidPlatformSpecificFundamentalTypesCheck.cpp @@ -121,7 +121,8 @@ void AvoidPlatformSpecificFundamentalTypesCheck::registerMatchers( allOf(builtinType(), anyOf(WarnOnInts ? isBuiltinInt() : unless(anything()), WarnOnFloats ? isBuiltinFloat() : unless(anything()), - WarnOnChars ? isAnyCharacter() : unless(anything())))); + WarnOnChars ? isChar() : unless(anything()), + WarnOnChars ? isWideChar() : unless(anything())))); if (!WarnOnInts && !WarnOnFloats && !WarnOnChars) return; @@ -140,6 +141,10 @@ void AvoidPlatformSpecificFundamentalTypesCheck::check( 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.getAsString(); const auto *BT = QT->getAs(); @@ -165,7 +170,7 @@ void AvoidPlatformSpecificFundamentalTypesCheck::check( "consider using a 'typedef' or fixed-width type instead") << TypeName; } - } else if (QT->isAnyCharacterType()) { + } else if (QT->isCharType() || QT->isWideCharType()) { diag(Loc, "avoid using platform-dependent character type '%0'; " "consider using 'char8_t' for text or 'std::byte' for bytes") << TypeName; diff --git a/clang-tools-extra/test/clang-tidy/checkers/portability/avoid-platform-specific-fundamental-types-chars.cpp b/clang-tools-extra/test/clang-tidy/checkers/portability/avoid-platform-specific-fundamental-types-chars.cpp index 3ce7c6b259af6..734ceb4ff3ee9 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/portability/avoid-platform-specific-fundamental-types-chars.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/portability/avoid-platform-specific-fundamental-types-chars.cpp @@ -18,13 +18,13 @@ unsigned char global_unsigned_char = 'c'; // Function parameters void func_with_char_param(char param) {} -// CHECK-MESSAGES: :[[@LINE-1]]:28: 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]]:35: 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]]:37: 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'; } diff --git a/clang/include/clang/ASTMatchers/ASTMatchers.h b/clang/include/clang/ASTMatchers/ASTMatchers.h index e4d605d165324..99eeafdcb0aed 100644 --- a/clang/include/clang/ASTMatchers/ASTMatchers.h +++ b/clang/include/clang/ASTMatchers/ASTMatchers.h @@ -6556,16 +6556,47 @@ AST_MATCHER(QualType, isSignedInteger) { return Node->isSignedIntegerType(); } -/// Matches QualType nodes that are of character type. +/// Matches QualType nodes that are of char type. /// /// Given /// \code /// void a(char); /// void b(wchar_t); -/// void c(double); +/// void c(char8_t); +/// void d(double); +/// \endcode +/// functionDecl(hasAnyParameter(hasType(isChar()))) +/// matches "a(char)", but not "b(wchar_t)", "c(char8_t)", or "d(double)" +AST_MATCHER(QualType, isChar) { + return Node->isCharType(); +} + +/// Matches QualType nodes that are of wide char type. +/// +/// Given +/// \code +/// void a(char); +/// void b(wchar_t); +/// void c(char8_t); +/// void d(double); +/// \endcode +/// functionDecl(hasAnyParameter(hasType(isChar()))) +/// matches "b(wchar_t)", but not "a(char)", "c(char8_t)", or "d(double)" +AST_MATCHER(QualType, isWideChar) { + return Node->isWideCharType(); +} + +/// Matches QualType nodes that are of any character type. +/// +/// Given +/// \code +/// void a(char); +/// void b(wchar_t); +/// void c(char8_t); +/// void d(double); /// \endcode /// functionDecl(hasAnyParameter(hasType(isAnyCharacter()))) -/// matches "a(char)", "b(wchar_t)", but not "c(double)". +/// matches "a(char)", "b(wchar_t)", "c(char8_t)", but not "d(double)". AST_MATCHER(QualType, isAnyCharacter) { return Node->isAnyCharacterType(); } From 4669797843e294b96ce36c683fa9036dbf6eb3c0 Mon Sep 17 00:00:00 2001 From: JJ Marr Date: Sat, 9 Aug 2025 23:16:04 -0400 Subject: [PATCH 53/83] Avoid flagging unicode characters --- ...d-platform-specific-fundamental-types-chars.cpp | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/clang-tools-extra/test/clang-tidy/checkers/portability/avoid-platform-specific-fundamental-types-chars.cpp b/clang-tools-extra/test/clang-tidy/checkers/portability/avoid-platform-specific-fundamental-types-chars.cpp index 734ceb4ff3ee9..28acce64cd235 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/portability/avoid-platform-specific-fundamental-types-chars.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/portability/avoid-platform-specific-fundamental-types-chars.cpp @@ -1,4 +1,4 @@ -// 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, \ @@ -6,6 +6,13 @@ // 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]]: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] @@ -73,3 +80,8 @@ int should_not_warn_int = 42; long should_not_warn_long = 100L; float should_not_warn_float = 3.14f; double should_not_warn_double = 2.71828; + +// Test that unicode characters are not flagged +char8_t utf8 = u8'a'; +char16_t utf16 = u'a'; +char32_t utf32 = U'a'; From a59542164a14f3b903feb5f625b13e52b5afad04 Mon Sep 17 00:00:00 2001 From: JJ Marr Date: Sat, 9 Aug 2025 23:19:58 -0400 Subject: [PATCH 54/83] Fix typo --- clang/include/clang/ASTMatchers/ASTMatchers.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clang/include/clang/ASTMatchers/ASTMatchers.h b/clang/include/clang/ASTMatchers/ASTMatchers.h index 99eeafdcb0aed..9a385a57d021d 100644 --- a/clang/include/clang/ASTMatchers/ASTMatchers.h +++ b/clang/include/clang/ASTMatchers/ASTMatchers.h @@ -6580,7 +6580,7 @@ AST_MATCHER(QualType, isChar) { /// void c(char8_t); /// void d(double); /// \endcode -/// functionDecl(hasAnyParameter(hasType(isChar()))) +/// functionDecl(hasAnyParameter(hasType(isWideChar()))) /// matches "b(wchar_t)", but not "a(char)", "c(char8_t)", or "d(double)" AST_MATCHER(QualType, isWideChar) { return Node->isWideCharType(); From 69e4f38439d953c834fe40e571ba45b939cbf66b Mon Sep 17 00:00:00 2001 From: JJ Marr Date: Sat, 9 Aug 2025 23:20:51 -0400 Subject: [PATCH 55/83] add std::byte test case --- .../avoid-platform-specific-fundamental-types-chars.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/clang-tools-extra/test/clang-tidy/checkers/portability/avoid-platform-specific-fundamental-types-chars.cpp b/clang-tools-extra/test/clang-tidy/checkers/portability/avoid-platform-specific-fundamental-types-chars.cpp index 28acce64cd235..7303c70fe2298 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/portability/avoid-platform-specific-fundamental-types-chars.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/portability/avoid-platform-specific-fundamental-types-chars.cpp @@ -85,3 +85,4 @@ double should_not_warn_double = 2.71828; char8_t utf8 = u8'a'; char16_t utf16 = u'a'; char32_t utf32 = U'a'; +std::byte null{0}; From 950513db256ca95eea3adb737ca83eecf4dc752b Mon Sep 17 00:00:00 2001 From: JJ Marr Date: Sat, 9 Aug 2025 23:39:41 -0400 Subject: [PATCH 56/83] also add to rst --- clang-tools-extra/docs/ReleaseNotes.rst | 5 +++-- .../avoid-platform-specific-fundamental-types.rst | 4 ++-- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/clang-tools-extra/docs/ReleaseNotes.rst b/clang-tools-extra/docs/ReleaseNotes.rst index d4f1f18c983d2..23907b34941c3 100644 --- a/clang-tools-extra/docs/ReleaseNotes.rst +++ b/clang-tools-extra/docs/ReleaseNotes.rst @@ -152,8 +152,9 @@ New checks ` check. - Detects fundamental types (int, short, long, long long, char, float, etc) - and warns against their use due to platform-dependent behavior. + Detects fundamental types (``int``, ``short``, ``long``, ``long long``, + ``char``, ``float``, etc) and warns against their use due to + platform-dependent behavior. - New :doc:`portability-avoid-pragma-once ` check. diff --git a/clang-tools-extra/docs/clang-tidy/checks/portability/avoid-platform-specific-fundamental-types.rst b/clang-tools-extra/docs/clang-tidy/checks/portability/avoid-platform-specific-fundamental-types.rst index 15ebe10ae7965..2ea382620ca35 100644 --- a/clang-tools-extra/docs/clang-tidy/checks/portability/avoid-platform-specific-fundamental-types.rst +++ b/clang-tools-extra/docs/clang-tidy/checks/portability/avoid-platform-specific-fundamental-types.rst @@ -3,8 +3,8 @@ portability-avoid-platform-specific-fundamental-types ===================================================== -Finds fundamental types (e.g. ``int``, ``float``) and recommends using typedefs -or fixed-width types to improve portability across different platforms. +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 From 66939407e1e20ad453a307cd27c6e523133027d9 Mon Sep 17 00:00:00 2001 From: JJ Marr Date: Sat, 9 Aug 2025 23:40:24 -0400 Subject: [PATCH 57/83] remove CV qualifier when reporting issue --- ...dPlatformSpecificFundamentalTypesCheck.cpp | 2 +- ...tform-specific-fundamental-types-chars.cpp | 95 +++++++++++++++++++ 2 files changed, 96 insertions(+), 1 deletion(-) diff --git a/clang-tools-extra/clang-tidy/portability/AvoidPlatformSpecificFundamentalTypesCheck.cpp b/clang-tools-extra/clang-tidy/portability/AvoidPlatformSpecificFundamentalTypesCheck.cpp index 29d7228cfdf28..f0f54f7ddbc7d 100644 --- a/clang-tools-extra/clang-tidy/portability/AvoidPlatformSpecificFundamentalTypesCheck.cpp +++ b/clang-tools-extra/clang-tidy/portability/AvoidPlatformSpecificFundamentalTypesCheck.cpp @@ -145,7 +145,7 @@ void AvoidPlatformSpecificFundamentalTypesCheck::check( if (!Loc.isValid() || !TypeRange.isValid()) return; - const std::string TypeName = QT.getAsString(); + const std::string TypeName = QT.getUnqualifiedType().getAsString(); const auto *BT = QT->getAs(); diff --git a/clang-tools-extra/test/clang-tidy/checkers/portability/avoid-platform-specific-fundamental-types-chars.cpp b/clang-tools-extra/test/clang-tidy/checkers/portability/avoid-platform-specific-fundamental-types-chars.cpp index 7303c70fe2298..0ceb75456e198 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/portability/avoid-platform-specific-fundamental-types-chars.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/portability/avoid-platform-specific-fundamental-types-chars.cpp @@ -75,6 +75,101 @@ using signed_char_alias = signed char; using unsigned_char_alias = unsigned char; // CHECK-MESSAGES: :[[@LINE-1]]:29: 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] +// Test const and reference parameters +void func_const_char_ref_param(const char ¶m) {} +// CHECK-MESSAGES: :[[@LINE-1]]:38: 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_const_signed_char_ref_param(const signed char ¶m) {} +// CHECK-MESSAGES: :[[@LINE-1]]:45: 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_const_unsigned_char_ref_param(const unsigned char ¶m) {} +// CHECK-MESSAGES: :[[@LINE-1]]:47: 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] + +// Test template declarations +template struct TemplateStruct { + typedef char char_type; + // CHECK-MESSAGES: :[[@LINE-1]]:11: 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] + + char template_field; + // CHECK-MESSAGES: :[[@LINE-1]]:3: 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] + + char create_char() { return char('x'); } + // CHECK-MESSAGES: :[[@LINE-1]]:3: 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-2]]:31: 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] +}; + +// Test namespace usage +namespace ns_chars { + char ns_char; + // CHECK-MESSAGES: :[[@LINE-1]]:3: 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 test_comprehensive_cases() { + // Test with spacing + char spaced_char; + // CHECK-MESSAGES: :[[@LINE-1]]:3: 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 spaced_signed_char; + // CHECK-MESSAGES: :[[@LINE-1]]:3: 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] + + // Test pointers + char *char_ptr; + // CHECK-MESSAGES: :[[@LINE-1]]:3: 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] + + unsigned char *unsigned_char_ptr; + // CHECK-MESSAGES: :[[@LINE-1]]:3: 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] + + // Test static declarations + static char static_char; + // CHECK-MESSAGES: :[[@LINE-1]]:10: 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] + + // Test cv-qualifiers + const char const_char = 'a'; + // CHECK-MESSAGES: :[[@LINE-1]]:9: 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] + + volatile char volatile_char; + // CHECK-MESSAGES: :[[@LINE-1]]:12: 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] + + const volatile char const_volatile_char = '\0'; + // CHECK-MESSAGES: :[[@LINE-1]]:18: 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] + + // Test auto with initializer + auto auto_char = char{'x'}; + // CHECK-MESSAGES: :[[@LINE-1]]:20: 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] + + char brace_init_char{}; + // CHECK-MESSAGES: :[[@LINE-1]]:3: 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] + + // Test arrays + char char_array[10]; + // CHECK-MESSAGES: :[[@LINE-1]]:3: 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] + + unsigned char unsigned_char_array[] = {'a', 'b', 'c'}; + // CHECK-MESSAGES: :[[@LINE-1]]:3: 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] + + // Test multiple declarations + char multi_char1, multi_char2, multi_char3; + // CHECK-MESSAGES: :[[@LINE-1]]:3: 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] +} + +// Test class with character type members +class CharacterClass { +public: + char &get_char_ref(); + // CHECK-MESSAGES: :[[@LINE-1]]:3: 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] + +private: + char private_char; + // CHECK-MESSAGES: :[[@LINE-1]]:3: 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] +}; + +// Test template instantiation +void test_template_instantiation() { + TemplateStruct template_instance; + char template_test = template_instance.create_char(); + // CHECK-MESSAGES: :[[@LINE-1]]:3: 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] +} + // Test that integer and float types are NOT flagged when their options are disabled int should_not_warn_int = 42; long should_not_warn_long = 100L; From 082a5ada8bdc4f6f6eb7ba133a4a8e9e4bc59a03 Mon Sep 17 00:00:00 2001 From: JJ Marr Date: Sat, 9 Aug 2025 23:42:41 -0400 Subject: [PATCH 58/83] fix indent --- clang-tools-extra/docs/ReleaseNotes.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/clang-tools-extra/docs/ReleaseNotes.rst b/clang-tools-extra/docs/ReleaseNotes.rst index d2389522778ee..a52300830659b 100644 --- a/clang-tools-extra/docs/ReleaseNotes.rst +++ b/clang-tools-extra/docs/ReleaseNotes.rst @@ -128,9 +128,9 @@ New checks ` check. - Detects fundamental types (``int``, ``short``, ``long``, ``long long``, - ``char``, ``float``, etc) and warns against their use due to - platform-dependent behavior. + Detects fundamental types (``int``, ``short``, ``long``, ``long long``, + ``char``, ``float``, etc) and warns against their use due to + platform-dependent behavior. New check aliases ^^^^^^^^^^^^^^^^^ From 88bbef03cbea2b92e116f382b964c6447bf864ba Mon Sep 17 00:00:00 2001 From: JJ Marr Date: Sat, 9 Aug 2025 23:54:40 -0400 Subject: [PATCH 59/83] Fix doc --- .../avoid-platform-specific-fundamental-types.rst | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/clang-tools-extra/docs/clang-tidy/checks/portability/avoid-platform-specific-fundamental-types.rst b/clang-tools-extra/docs/clang-tidy/checks/portability/avoid-platform-specific-fundamental-types.rst index 2ea382620ca35..e8ac160190d7f 100644 --- a/clang-tools-extra/docs/clang-tidy/checks/portability/avoid-platform-specific-fundamental-types.rst +++ b/clang-tools-extra/docs/clang-tidy/checks/portability/avoid-platform-specific-fundamental-types.rst @@ -4,7 +4,8 @@ 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. +, ``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 @@ -176,8 +177,8 @@ Options 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 + - ``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 From 485022d530aa4ac8cdfa311ad89fdc8786a0c16f Mon Sep 17 00:00:00 2001 From: JJ Marr Date: Sat, 9 Aug 2025 23:58:21 -0400 Subject: [PATCH 60/83] Fix formatting --- .../AvoidPlatformSpecificFundamentalTypesCheck.cpp | 11 +++++------ clang/include/clang/ASTMatchers/ASTMatchers.h | 8 ++------ 2 files changed, 7 insertions(+), 12 deletions(-) diff --git a/clang-tools-extra/clang-tidy/portability/AvoidPlatformSpecificFundamentalTypesCheck.cpp b/clang-tools-extra/clang-tidy/portability/AvoidPlatformSpecificFundamentalTypesCheck.cpp index f0f54f7ddbc7d..080cb2023ecc3 100644 --- a/clang-tools-extra/clang-tidy/portability/AvoidPlatformSpecificFundamentalTypesCheck.cpp +++ b/clang-tools-extra/clang-tidy/portability/AvoidPlatformSpecificFundamentalTypesCheck.cpp @@ -117,12 +117,11 @@ static std::string getFloatReplacement(const BuiltinType *BT, 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())))); + 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; diff --git a/clang/include/clang/ASTMatchers/ASTMatchers.h b/clang/include/clang/ASTMatchers/ASTMatchers.h index 62a991b869e0d..2d0937000300a 100644 --- a/clang/include/clang/ASTMatchers/ASTMatchers.h +++ b/clang/include/clang/ASTMatchers/ASTMatchers.h @@ -6608,9 +6608,7 @@ AST_MATCHER(QualType, isSignedInteger) { /// \endcode /// functionDecl(hasAnyParameter(hasType(isChar()))) /// matches "a(char)", but not "b(wchar_t)", "c(char8_t)", or "d(double)" -AST_MATCHER(QualType, isChar) { - return Node->isCharType(); -} +AST_MATCHER(QualType, isChar) { return Node->isCharType(); } /// Matches QualType nodes that are of wide char type. /// @@ -6623,9 +6621,7 @@ AST_MATCHER(QualType, isChar) { /// \endcode /// functionDecl(hasAnyParameter(hasType(isWideChar()))) /// matches "b(wchar_t)", but not "a(char)", "c(char8_t)", or "d(double)" -AST_MATCHER(QualType, isWideChar) { - return Node->isWideCharType(); -} +AST_MATCHER(QualType, isWideChar) { return Node->isWideCharType(); } /// Matches QualType nodes that are of any character type. /// From 9a01bc0f3bb48228add9cc9be1eee6c40a247925 Mon Sep 17 00:00:00 2001 From: JJ Marr <168750718+jj-marr@users.noreply.github.com> Date: Sun, 24 Aug 2025 16:18:48 -0400 Subject: [PATCH 61/83] Apply suggestions from code review Co-authored-by: EugeneZelenko --- .../portability/AvoidPlatformSpecificFundamentalTypesCheck.cpp | 2 +- .../portability/AvoidPlatformSpecificFundamentalTypesCheck.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/clang-tools-extra/clang-tidy/portability/AvoidPlatformSpecificFundamentalTypesCheck.cpp b/clang-tools-extra/clang-tidy/portability/AvoidPlatformSpecificFundamentalTypesCheck.cpp index 080cb2023ecc3..2031b54f640f1 100644 --- a/clang-tools-extra/clang-tidy/portability/AvoidPlatformSpecificFundamentalTypesCheck.cpp +++ b/clang-tools-extra/clang-tidy/portability/AvoidPlatformSpecificFundamentalTypesCheck.cpp @@ -1,4 +1,4 @@ -//===--- 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. diff --git a/clang-tools-extra/clang-tidy/portability/AvoidPlatformSpecificFundamentalTypesCheck.h b/clang-tools-extra/clang-tidy/portability/AvoidPlatformSpecificFundamentalTypesCheck.h index edbdf9c061526..6fe6ffef1e9f9 100644 --- a/clang-tools-extra/clang-tidy/portability/AvoidPlatformSpecificFundamentalTypesCheck.h +++ b/clang-tools-extra/clang-tidy/portability/AvoidPlatformSpecificFundamentalTypesCheck.h @@ -1,4 +1,4 @@ -//==-- 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. From 2db38a1bce995731cac3dd5fc69c6d8985835481 Mon Sep 17 00:00:00 2001 From: JJ Marr <168750718+jj-marr@users.noreply.github.com> Date: Sun, 24 Aug 2025 16:20:30 -0400 Subject: [PATCH 62/83] Apply suggestions from code review Co-authored-by: Baranov Victor --- .../portability/AvoidPlatformSpecificFundamentalTypesCheck.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clang-tools-extra/clang-tidy/portability/AvoidPlatformSpecificFundamentalTypesCheck.cpp b/clang-tools-extra/clang-tidy/portability/AvoidPlatformSpecificFundamentalTypesCheck.cpp index 2031b54f640f1..5b4f0c855970f 100644 --- a/clang-tools-extra/clang-tidy/portability/AvoidPlatformSpecificFundamentalTypesCheck.cpp +++ b/clang-tools-extra/clang-tidy/portability/AvoidPlatformSpecificFundamentalTypesCheck.cpp @@ -166,7 +166,7 @@ void AvoidPlatformSpecificFundamentalTypesCheck::check( } } else { diag(Loc, "avoid using platform-dependent floating point type '%0'; " - "consider using a 'typedef' or fixed-width type instead") + "consider using a type alias or fixed-width type instead") << TypeName; } } else if (QT->isCharType() || QT->isWideCharType()) { From a5d4073a714542fab955ccfd89fb667a393a847f Mon Sep 17 00:00:00 2001 From: JJ Marr <168750718+jj-marr@users.noreply.github.com> Date: Sun, 24 Aug 2025 16:21:02 -0400 Subject: [PATCH 63/83] Apply suggestions from code review Co-authored-by: Baranov Victor --- .../avoid-platform-specific-fundamental-types.rst | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/clang-tools-extra/docs/clang-tidy/checks/portability/avoid-platform-specific-fundamental-types.rst b/clang-tools-extra/docs/clang-tidy/checks/portability/avoid-platform-specific-fundamental-types.rst index e8ac160190d7f..9819438f8dd62 100644 --- a/clang-tools-extra/docs/clang-tidy/checks/portability/avoid-platform-specific-fundamental-types.rst +++ b/clang-tools-extra/docs/clang-tidy/checks/portability/avoid-platform-specific-fundamental-types.rst @@ -28,18 +28,6 @@ Examples 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++ From 9864a96cbace470d10f79ed6b0a3beb002b71f5e Mon Sep 17 00:00:00 2001 From: JJ Marr <168750718+jj-marr@users.noreply.github.com> Date: Sun, 24 Aug 2025 16:21:13 -0400 Subject: [PATCH 64/83] Update clang-tools-extra/docs/clang-tidy/checks/portability/avoid-platform-specific-fundamental-types.rst Co-authored-by: Baranov Victor --- .../avoid-platform-specific-fundamental-types.rst | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/clang-tools-extra/docs/clang-tidy/checks/portability/avoid-platform-specific-fundamental-types.rst b/clang-tools-extra/docs/clang-tidy/checks/portability/avoid-platform-specific-fundamental-types.rst index 9819438f8dd62..ec92c3bde767b 100644 --- a/clang-tools-extra/docs/clang-tidy/checks/portability/avoid-platform-specific-fundamental-types.rst +++ b/clang-tools-extra/docs/clang-tidy/checks/portability/avoid-platform-specific-fundamental-types.rst @@ -39,18 +39,6 @@ Examples 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: From 09158b034604fe4f0cd62d1e20df83ae9773d0a0 Mon Sep 17 00:00:00 2001 From: JJ Marr <168750718+jj-marr@users.noreply.github.com> Date: Sun, 24 Aug 2025 16:21:23 -0400 Subject: [PATCH 65/83] Update clang-tools-extra/docs/clang-tidy/checks/portability/avoid-platform-specific-fundamental-types.rst Co-authored-by: Baranov Victor --- .../portability/avoid-platform-specific-fundamental-types.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clang-tools-extra/docs/clang-tidy/checks/portability/avoid-platform-specific-fundamental-types.rst b/clang-tools-extra/docs/clang-tidy/checks/portability/avoid-platform-specific-fundamental-types.rst index ec92c3bde767b..6fd0512b05ac6 100644 --- a/clang-tools-extra/docs/clang-tidy/checks/portability/avoid-platform-specific-fundamental-types.rst +++ b/clang-tools-extra/docs/clang-tidy/checks/portability/avoid-platform-specific-fundamental-types.rst @@ -111,7 +111,7 @@ Options 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` + When `false`, integer types are not flagged. Default is `true`. Example with :option:`WarnOnInts` enabled: From 6c4803ab8b4dffdc6a62c1702a3ec40dd02b5226 Mon Sep 17 00:00:00 2001 From: JJ Marr Date: Sun, 24 Aug 2025 16:27:52 -0400 Subject: [PATCH 66/83] Fix char documentation (which isn't even correct) --- ...id-platform-specific-fundamental-types.rst | 42 +------------------ 1 file changed, 2 insertions(+), 40 deletions(-) diff --git a/clang-tools-extra/docs/clang-tidy/checks/portability/avoid-platform-specific-fundamental-types.rst b/clang-tools-extra/docs/clang-tidy/checks/portability/avoid-platform-specific-fundamental-types.rst index 6fd0512b05ac6..8591cb2084edd 100644 --- a/clang-tools-extra/docs/clang-tidy/checks/portability/avoid-platform-specific-fundamental-types.rst +++ b/clang-tools-extra/docs/clang-tidy/checks/portability/avoid-platform-specific-fundamental-types.rst @@ -163,22 +163,6 @@ Options Default is `true` - Example with :option:`WarnOnFloats` enabled: - - .. code-block:: c++ - - // Bad: platform-dependent floating point types - float pi = 3.14f; - double e = 2.71828; - - .. code-block:: c++ - - // Good: use fixed-width floating point types - #include // C++23 - - float32_t pi = 3.14f; - float64_t e = 2.71828; - .. option:: WarnOnChars When `true`, the check will warn about character types (``char``, @@ -191,27 +175,5 @@ Options on ARM, unsigned on x86) - The signedness of ``char`` affects comparisons and arithmetic operations - When this option is enabled, the check will suggest using explicit signedness - or typedefs to make the intent clear and ensure consistent behavior across - platforms. - - Default is `true`. - - Example with :option:`WarnOnChars` enabled: - - .. code-block:: c++ - - // Bad: platform-dependent character types - char buffer[256]; - signed char byte_value = -1; - unsigned char raw_byte = 255; - - .. code-block:: c++ - - // Good: use explicit types or typedefs - using byte_t = unsigned char; // For raw byte data - using text_char_t = char; // For text (when signedness doesn't matter) - - text_char_t buffer[256]; // For text storage - int8_t signed_byte = -1; // For signed 8-bit values - uint8_t raw_byte = 255; // For unsigned 8-bit values + When this option is enabled, the check will suggest using ``std::byte`` or a + Unicode character type instead of character types. From 568990ba24d3c6d99f6aef67841881ec060bdc0a Mon Sep 17 00:00:00 2001 From: JJ Marr Date: Sun, 24 Aug 2025 16:29:05 -0400 Subject: [PATCH 67/83] remove typedef examples --- ...avoid-platform-specific-fundamental-types.rst | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/clang-tools-extra/docs/clang-tidy/checks/portability/avoid-platform-specific-fundamental-types.rst b/clang-tools-extra/docs/clang-tidy/checks/portability/avoid-platform-specific-fundamental-types.rst index 8591cb2084edd..354dc059de8fa 100644 --- a/clang-tools-extra/docs/clang-tidy/checks/portability/avoid-platform-specific-fundamental-types.rst +++ b/clang-tools-extra/docs/clang-tidy/checks/portability/avoid-platform-specific-fundamental-types.rst @@ -39,22 +39,6 @@ Examples int64_t global_int64 = 100L; uint64_t global_uint64 = 100UL; - -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 --------- From a71bb2e08cf012c1cb01fa33cf0654fea6c75441 Mon Sep 17 00:00:00 2001 From: JJ Marr Date: Sun, 24 Aug 2025 17:05:10 -0400 Subject: [PATCH 68/83] Revise documentation --- ...id-platform-specific-fundamental-types.rst | 58 +++++++------------ 1 file changed, 21 insertions(+), 37 deletions(-) diff --git a/clang-tools-extra/docs/clang-tidy/checks/portability/avoid-platform-specific-fundamental-types.rst b/clang-tools-extra/docs/clang-tidy/checks/portability/avoid-platform-specific-fundamental-types.rst index 354dc059de8fa..a849abfa639ad 100644 --- a/clang-tools-extra/docs/clang-tidy/checks/portability/avoid-platform-specific-fundamental-types.rst +++ b/clang-tools-extra/docs/clang-tidy/checks/portability/avoid-platform-specific-fundamental-types.rst @@ -25,9 +25,18 @@ Examples // Bad: platform-dependent fundamental types int global_int = 42; short global_short = 10; - long global_long = 100L; - unsigned long global_unsigned_long = 100UL; - + // 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. + std::vector slowVec; + // This could overflow and cause undefined behaviour if slowVec is too big. + for(int i = 0U; i int32_t global_int32 = 42; - int16_t global_int16 = 10; - int64_t global_int64 = 100L; uint64_t global_uint64 = 100UL; + // On a 64-bit system, int_fast32_t will probably be 64 bits in size, + // potentially allowing faster accesses. + std::vector fastVec; + // A size_t can hold any index into an array or vector on a given platform, + // because it can hold the maximum size of any theoretical object, so we will + // never overflow fastVec's size. + for(size_t i = 0U; i - - 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 exactly 32 bits - int64_t timestamp = 12345L; // When you need exactly 64 bits - uint16_t port = 8080; // When you need exactly 16 unsigned bits - std::vector vec; - // A size_t is the maximum size of an object on a given platform - for(size_t i = 0U; i Date: Wed, 17 Sep 2025 18:54:39 -0400 Subject: [PATCH 69/83] further documentation edits --- ...id-platform-specific-fundamental-types.rst | 29 ++++--------------- 1 file changed, 6 insertions(+), 23 deletions(-) diff --git a/clang-tools-extra/docs/clang-tidy/checks/portability/avoid-platform-specific-fundamental-types.rst b/clang-tools-extra/docs/clang-tidy/checks/portability/avoid-platform-specific-fundamental-types.rst index a849abfa639ad..76af009636264 100644 --- a/clang-tools-extra/docs/clang-tidy/checks/portability/avoid-platform-specific-fundamental-types.rst +++ b/clang-tools-extra/docs/clang-tidy/checks/portability/avoid-platform-specific-fundamental-types.rst @@ -68,7 +68,7 @@ Fundamental types have platform-dependent sizes and behavior: - ``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 +the size, representation, and purpose 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 @@ -88,16 +88,18 @@ 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. +is an appropriate replacement. ``char`` can be either signed or unsigned +depending on the platform (unsigned on ARM, signed on x86), while ``char8_t`` +and ``std::byte`` are guaranteed to be implemented as unsigned. Types Not Flagged ----------------- The following types are intentionally not flagged: -- ``bool`` (boolean type) +- ``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 +- 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 @@ -119,16 +121,6 @@ Options (``float`` and ``double``). When `false`, 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. - Default is `true` .. option:: WarnOnChars @@ -136,12 +128,3 @@ Options When `true`, the check will warn about character types (``char``, ``signed char``, and ``unsigned char``). When `false`, character types are not flagged. - - Character types can have platform-dependent behavior: - - - ``char`` can be either signed or unsigned depending on the platform (signed - on ARM, unsigned on x86) - - The signedness of ``char`` affects comparisons and arithmetic operations - - When this option is enabled, the check will suggest using ``std::byte`` or a - Unicode character type instead of character types. From 87fbe9df80a03ae6c42cc5aba54dc065a66fdc2a Mon Sep 17 00:00:00 2001 From: JJ Marr Date: Wed, 17 Sep 2025 19:06:42 -0400 Subject: [PATCH 70/83] further edits --- ...id-platform-specific-fundamental-types.rst | 36 +++++++++---------- 1 file changed, 17 insertions(+), 19 deletions(-) diff --git a/clang-tools-extra/docs/clang-tidy/checks/portability/avoid-platform-specific-fundamental-types.rst b/clang-tools-extra/docs/clang-tidy/checks/portability/avoid-platform-specific-fundamental-types.rst index 76af009636264..cca88e5123f63 100644 --- a/clang-tools-extra/docs/clang-tidy/checks/portability/avoid-platform-specific-fundamental-types.rst +++ b/clang-tools-extra/docs/clang-tidy/checks/portability/avoid-platform-specific-fundamental-types.rst @@ -5,13 +5,8 @@ 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. +behaviour. 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 @@ -58,7 +53,7 @@ Examples Rationale --------- -Fundamental types have platform-dependent sizes and behavior: +Examples of platform-dependent behaviour: - ``int`` is typically 32 bits on modern platforms but is only guaranteed to be 16 bits by the spec @@ -78,19 +73,18 @@ 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. +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. +``float64_t`` which, if they exist, are guaranteed to be standard IEEE754 floats +of the 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. ``char`` can be either signed or unsigned -depending on the platform (unsigned on ARM, signed on x86), while ``char8_t`` -and ``std::byte`` are guaranteed to be implemented as unsigned. +is the correct replacement. ``char8_t`` and ``std::byte`` are guaranteed to be +implemented with similar behaviour to unsigned char. Types Not Flagged ----------------- @@ -102,8 +96,8 @@ The following types are intentionally not flagged: - 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. +vulnerable to overflow or narrowing issues that occur as a result of it being an +implementation-defined size. Options ------- @@ -113,7 +107,9 @@ Options 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`. + When `false`, integer types are not flagged. + + Default is `true`. .. option:: WarnOnFloats @@ -128,3 +124,5 @@ Options When `true`, the check will warn about character types (``char``, ``signed char``, and ``unsigned char``). When `false`, character types are not flagged. + + Default is `true` From e4f9a80018ce1af6f235e5983bf2ebc0691690f0 Mon Sep 17 00:00:00 2001 From: JJ Marr <168750718+jj-marr@users.noreply.github.com> Date: Wed, 17 Sep 2025 19:07:21 -0400 Subject: [PATCH 71/83] Apply suggestions from code review Co-authored-by: Baranov Victor Co-authored-by: EugeneZelenko --- .../AvoidPlatformSpecificFundamentalTypesCheck.cpp | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/clang-tools-extra/clang-tidy/portability/AvoidPlatformSpecificFundamentalTypesCheck.cpp b/clang-tools-extra/clang-tidy/portability/AvoidPlatformSpecificFundamentalTypesCheck.cpp index 5b4f0c855970f..8c96119e1103d 100644 --- a/clang-tools-extra/clang-tidy/portability/AvoidPlatformSpecificFundamentalTypesCheck.cpp +++ b/clang-tools-extra/clang-tidy/portability/AvoidPlatformSpecificFundamentalTypesCheck.cpp @@ -133,12 +133,11 @@ void AvoidPlatformSpecificFundamentalTypesCheck::registerMatchers( void AvoidPlatformSpecificFundamentalTypesCheck::check( const MatchFinder::MatchResult &Result) { const auto *TL = Result.Nodes.getNodeAs("type"); - if (!TL) - return; + assert(TL); - SourceLocation Loc = TL->getBeginLoc(); - QualType QT = TL->getType(); - SourceRange TypeRange = TL->getSourceRange(); + const SourceLocation Loc = TL->getBeginLoc(); + const QualType QT = TL->getType(); + const SourceRange TypeRange = TL->getSourceRange(); // Skip implicit type locations, such as literals if (!Loc.isValid() || !TypeRange.isValid()) @@ -175,7 +174,7 @@ void AvoidPlatformSpecificFundamentalTypesCheck::check( << TypeName; } else { diag(Loc, "avoid using platform-dependent fundamental integer type '%0'; " - "consider using a 'typedef' or fixed-width type instead") + "consider using a type alias or fixed-width type instead") << TypeName; } } From c868336b3eab5b326f86fcd10a022c395466327c Mon Sep 17 00:00:00 2001 From: JJ Marr Date: Wed, 17 Sep 2025 19:14:06 -0400 Subject: [PATCH 72/83] another test case --- .../avoid-platform-specific-fundamental-types-chars.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/clang-tools-extra/test/clang-tidy/checkers/portability/avoid-platform-specific-fundamental-types-chars.cpp b/clang-tools-extra/test/clang-tidy/checkers/portability/avoid-platform-specific-fundamental-types-chars.cpp index 0ceb75456e198..5dc8552c6e6f9 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/portability/avoid-platform-specific-fundamental-types-chars.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/portability/avoid-platform-specific-fundamental-types-chars.cpp @@ -136,6 +136,9 @@ void test_comprehensive_cases() { // Test auto with initializer auto auto_char = char{'x'}; // CHECK-MESSAGES: :[[@LINE-1]]:20: 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] + + // Verify auto without initializer isn't flagged + auto auto_nonexplicit_char = 'x'; char brace_init_char{}; // CHECK-MESSAGES: :[[@LINE-1]]:3: 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] From 5dc7c47c65d1bd5ddbe657370cdab927d37ac127 Mon Sep 17 00:00:00 2001 From: JJ Marr Date: Wed, 17 Sep 2025 19:17:37 -0400 Subject: [PATCH 73/83] replace more matcher if statements with assertions --- .../AvoidPlatformSpecificFundamentalTypesCheck.cpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/clang-tools-extra/clang-tidy/portability/AvoidPlatformSpecificFundamentalTypesCheck.cpp b/clang-tools-extra/clang-tidy/portability/AvoidPlatformSpecificFundamentalTypesCheck.cpp index 8c96119e1103d..0bf6dfc81e7bf 100644 --- a/clang-tools-extra/clang-tidy/portability/AvoidPlatformSpecificFundamentalTypesCheck.cpp +++ b/clang-tools-extra/clang-tidy/portability/AvoidPlatformSpecificFundamentalTypesCheck.cpp @@ -19,8 +19,7 @@ namespace { AST_MATCHER(clang::QualType, isBuiltinInt) { const auto *BT = Node->getAs(); - if (!BT) - return false; + assert(BT); // BT->isInteger() would detect char and bool switch (BT->getKind()) { @@ -40,8 +39,7 @@ AST_MATCHER(clang::QualType, isBuiltinInt) { AST_MATCHER(clang::QualType, isBuiltinFloat) { const auto *BT = Node->getAs(); - if (!BT) - return false; + assert(BT); return BT->isFloatingPoint(); } From 2a6222daf8e70c4404d9a0afec87fb919ba7b8d9 Mon Sep 17 00:00:00 2001 From: JJ Marr Date: Wed, 17 Sep 2025 19:23:32 -0400 Subject: [PATCH 74/83] use std::optional instead of empty string --- ...idPlatformSpecificFundamentalTypesCheck.cpp | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/clang-tools-extra/clang-tidy/portability/AvoidPlatformSpecificFundamentalTypesCheck.cpp b/clang-tools-extra/clang-tidy/portability/AvoidPlatformSpecificFundamentalTypesCheck.cpp index 0bf6dfc81e7bf..f8c1b8638405c 100644 --- a/clang-tools-extra/clang-tidy/portability/AvoidPlatformSpecificFundamentalTypesCheck.cpp +++ b/clang-tools-extra/clang-tidy/portability/AvoidPlatformSpecificFundamentalTypesCheck.cpp @@ -78,15 +78,15 @@ void AvoidPlatformSpecificFundamentalTypesCheck::storeOptions( Options.store(Opts, "IncludeStyle", IncludeInserter.getStyle()); } -static std::string getFloatReplacement(const BuiltinType *BT, - ASTContext &Context) { +static std::optional getFloatReplacement(const BuiltinType *BT, + ASTContext &Context) { const TargetInfo &Target = Context.getTargetInfo(); - auto GetReplacementType = [](unsigned Width) { + auto GetReplacementType = [](unsigned Width) -> std::optional { switch (Width) { // This is ambiguous by default since it could be bfloat16 or float16 case 16U: - return ""; + return std::nullopt; case 32U: return "float32_t"; case 64U: @@ -94,7 +94,7 @@ static std::string getFloatReplacement(const BuiltinType *BT, case 128U: return "float128_t"; default: - return ""; + return std::nullopt; } }; @@ -109,7 +109,7 @@ static std::string getFloatReplacement(const BuiltinType *BT, case BuiltinType::Double: return GetReplacementType(Target.getDoubleWidth()); default: - return ""; + return std::nullopt; } } @@ -147,15 +147,15 @@ void AvoidPlatformSpecificFundamentalTypesCheck::check( assert(BT); if (BT->isFloatingPoint()) { - const std::string Replacement = getFloatReplacement(BT, *Result.Context); - if (!Replacement.empty()) { + const auto Replacement = getFloatReplacement(BT, *Result.Context); + if (Replacement.has_value()) { auto Diag = diag(Loc, "avoid using platform-dependent floating point type '%0'; " "consider using '%1' instead") << TypeName << Replacement; if (TypeRange.isValid()) - Diag << FixItHint::CreateReplacement(TypeRange, Replacement); + Diag << FixItHint::CreateReplacement(TypeRange, Replacement.value()); if (auto IncludeFixit = IncludeInserter.createIncludeInsertion( Result.SourceManager->getFileID(Loc), "")) { From 10a3a2efe34307b4bc7d38bc179efb156af5af6a Mon Sep 17 00:00:00 2001 From: JJ Marr Date: Wed, 17 Sep 2025 19:27:13 -0400 Subject: [PATCH 75/83] Use early return Co-authored-by: Baranov Victor --- ...dPlatformSpecificFundamentalTypesCheck.cpp | 29 ++++++++++--------- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/clang-tools-extra/clang-tidy/portability/AvoidPlatformSpecificFundamentalTypesCheck.cpp b/clang-tools-extra/clang-tidy/portability/AvoidPlatformSpecificFundamentalTypesCheck.cpp index f8c1b8638405c..ee193229cd309 100644 --- a/clang-tools-extra/clang-tidy/portability/AvoidPlatformSpecificFundamentalTypesCheck.cpp +++ b/clang-tools-extra/clang-tidy/portability/AvoidPlatformSpecificFundamentalTypesCheck.cpp @@ -148,24 +148,25 @@ void AvoidPlatformSpecificFundamentalTypesCheck::check( assert(BT); if (BT->isFloatingPoint()) { const auto Replacement = getFloatReplacement(BT, *Result.Context); - if (Replacement.has_value()) { - auto Diag = - diag(Loc, "avoid using platform-dependent floating point type '%0'; " - "consider using '%1' instead") - << TypeName << Replacement; - - if (TypeRange.isValid()) - Diag << FixItHint::CreateReplacement(TypeRange, Replacement.value()); - - if (auto IncludeFixit = IncludeInserter.createIncludeInsertion( - Result.SourceManager->getFileID(Loc), "")) { - Diag << *IncludeFixit; - } - } else { + + if (!Replacement.has_value()) { diag(Loc, "avoid using platform-dependent floating point type '%0'; " "consider using a type alias or fixed-width type instead") << TypeName; } + + auto Diag = + diag(Loc, "avoid using platform-dependent floating point type '%0'; " + "consider using '%1' instead") + << TypeName << Replacement; + + if (TypeRange.isValid()) + Diag << FixItHint::CreateReplacement(TypeRange, Replacement.value()); + + if (auto IncludeFixit = IncludeInserter.createIncludeInsertion( + Result.SourceManager->getFileID(Loc), "")) { + Diag << *IncludeFixit; + } } else if (QT->isCharType() || QT->isWideCharType()) { diag(Loc, "avoid using platform-dependent character type '%0'; " "consider using 'char8_t' for text or 'std::byte' for bytes") From c7c28c95cfdc6bafb1057de159a3b0ee05ee91a4 Mon Sep 17 00:00:00 2001 From: JJ Marr Date: Wed, 17 Sep 2025 19:39:51 -0400 Subject: [PATCH 76/83] add more floating point types to the switch statement --- .../AvoidPlatformSpecificFundamentalTypesCheck.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/clang-tools-extra/clang-tidy/portability/AvoidPlatformSpecificFundamentalTypesCheck.cpp b/clang-tools-extra/clang-tidy/portability/AvoidPlatformSpecificFundamentalTypesCheck.cpp index ee193229cd309..c2ba856939ae5 100644 --- a/clang-tools-extra/clang-tidy/portability/AvoidPlatformSpecificFundamentalTypesCheck.cpp +++ b/clang-tools-extra/clang-tidy/portability/AvoidPlatformSpecificFundamentalTypesCheck.cpp @@ -108,6 +108,10 @@ static std::optional getFloatReplacement(const BuiltinType *BT, return GetReplacementType(Target.getFloatWidth()); case BuiltinType::Double: return GetReplacementType(Target.getDoubleWidth()); + case BuiltinType::LongDouble: + return GetReplacementType(Target.getLongDoubleWidth()); + case BuiltinType::Float128: + return "float128_t"; default: return std::nullopt; } From 21049529342a32b095069a2f1ddcf4d6385db4a0 Mon Sep 17 00:00:00 2001 From: JJ Marr Date: Sat, 20 Sep 2025 17:38:59 -0400 Subject: [PATCH 77/83] fix use of optional --- .../portability/AvoidPlatformSpecificFundamentalTypesCheck.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/clang-tools-extra/clang-tidy/portability/AvoidPlatformSpecificFundamentalTypesCheck.cpp b/clang-tools-extra/clang-tidy/portability/AvoidPlatformSpecificFundamentalTypesCheck.cpp index c2ba856939ae5..2a21c2ef4aa73 100644 --- a/clang-tools-extra/clang-tidy/portability/AvoidPlatformSpecificFundamentalTypesCheck.cpp +++ b/clang-tools-extra/clang-tidy/portability/AvoidPlatformSpecificFundamentalTypesCheck.cpp @@ -157,12 +157,13 @@ void AvoidPlatformSpecificFundamentalTypesCheck::check( diag(Loc, "avoid using platform-dependent floating point type '%0'; " "consider using a type alias or fixed-width type instead") << TypeName; + return; } auto Diag = diag(Loc, "avoid using platform-dependent floating point type '%0'; " "consider using '%1' instead") - << TypeName << Replacement; + << TypeName << Replacement.value(); if (TypeRange.isValid()) Diag << FixItHint::CreateReplacement(TypeRange, Replacement.value()); From c72530127b86eebd058dd0c3593274be58fe00d5 Mon Sep 17 00:00:00 2001 From: JJ Marr Date: Sat, 20 Sep 2025 17:46:04 -0400 Subject: [PATCH 78/83] fix unit tests to match new warning message --- ...atform-specific-fundamental-types-ints.cpp | 48 +++++++++---------- 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/clang-tools-extra/test/clang-tidy/checkers/portability/avoid-platform-specific-fundamental-types-ints.cpp b/clang-tools-extra/test/clang-tidy/checkers/portability/avoid-platform-specific-fundamental-types-ints.cpp index fef9d6373531e..b4f3079c50304 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/portability/avoid-platform-specific-fundamental-types-ints.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/portability/avoid-platform-specific-fundamental-types-ints.cpp @@ -23,28 +23,28 @@ typedef unsigned long size_t; // Test fundamental integer types that should trigger warnings int global_int = 42; -// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: avoid using platform-dependent fundamental integer type 'int'; consider using a 'typedef' or fixed-width type instead [portability-avoid-platform-specific-fundamental-types] +// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: avoid using platform-dependent fundamental integer type 'int'; consider using a type alias or fixed-width type instead [portability-avoid-platform-specific-fundamental-types] short global_short = 10; -// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: avoid using platform-dependent fundamental integer type 'short'; consider using a 'typedef' or fixed-width type instead [portability-avoid-platform-specific-fundamental-types] +// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: avoid using platform-dependent fundamental integer type 'short'; consider using a type alias or fixed-width type instead [portability-avoid-platform-specific-fundamental-types] long global_long = 100L; -// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: avoid using platform-dependent fundamental integer type 'long'; consider using a 'typedef' or fixed-width type instead [portability-avoid-platform-specific-fundamental-types] +// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: avoid using platform-dependent fundamental integer type 'long'; consider using a type alias or fixed-width type instead [portability-avoid-platform-specific-fundamental-types] long long global_long_long = 1000LL; -// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: avoid using platform-dependent fundamental integer type 'long long'; consider using a 'typedef' or fixed-width type instead [portability-avoid-platform-specific-fundamental-types] +// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: avoid using platform-dependent fundamental integer type 'long long'; consider using a type alias or fixed-width type instead [portability-avoid-platform-specific-fundamental-types] unsigned int global_unsigned_int = 42U; -// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: avoid using platform-dependent fundamental integer type 'unsigned int'; consider using a 'typedef' or fixed-width type instead [portability-avoid-platform-specific-fundamental-types] +// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: avoid using platform-dependent fundamental integer type 'unsigned int'; consider using a type alias or fixed-width type instead [portability-avoid-platform-specific-fundamental-types] unsigned short global_unsigned_short = 10U; -// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: avoid using platform-dependent fundamental integer type 'unsigned short'; consider using a 'typedef' or fixed-width type instead [portability-avoid-platform-specific-fundamental-types] +// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: avoid using platform-dependent fundamental integer type 'unsigned short'; consider using a type alias or fixed-width type instead [portability-avoid-platform-specific-fundamental-types] unsigned long global_unsigned_long = 100UL; -// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: avoid using platform-dependent fundamental integer type 'unsigned long'; consider using a 'typedef' or fixed-width type instead [portability-avoid-platform-specific-fundamental-types] +// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: avoid using platform-dependent fundamental integer type 'unsigned long'; consider using a type alias or fixed-width type instead [portability-avoid-platform-specific-fundamental-types] unsigned long long global_unsigned_long_long = 1000ULL; -// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: avoid using platform-dependent fundamental integer type 'unsigned long long'; consider using a 'typedef' or fixed-width type instead [portability-avoid-platform-specific-fundamental-types] +// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: avoid using platform-dependent fundamental integer type 'unsigned long long'; consider using a type alias or fixed-width type instead [portability-avoid-platform-specific-fundamental-types] // Test integer that should NEVER trigger warnings bool global_bool = true; @@ -68,34 +68,34 @@ ptrdiff_t global_ptrdiff = 50; // Test function parameters void function_with_int_param(int param) { -// CHECK-MESSAGES: :[[@LINE-1]]:30: warning: avoid using platform-dependent fundamental integer type 'int'; consider using a 'typedef' or fixed-width type instead [portability-avoid-platform-specific-fundamental-types] +// CHECK-MESSAGES: :[[@LINE-1]]:30: warning: avoid using platform-dependent fundamental integer type 'int'; consider using a type alias or fixed-width type instead [portability-avoid-platform-specific-fundamental-types] } void function_with_short_param(short param) { -// CHECK-MESSAGES: :[[@LINE-1]]:32: warning: avoid using platform-dependent fundamental integer type 'short'; consider using a 'typedef' or fixed-width type instead [portability-avoid-platform-specific-fundamental-types] +// CHECK-MESSAGES: :[[@LINE-1]]:32: warning: avoid using platform-dependent fundamental integer type 'short'; consider using a type alias or fixed-width type instead [portability-avoid-platform-specific-fundamental-types] } // Test function return types int function_returning_int() { -// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: avoid using platform-dependent fundamental integer type 'int'; consider using a 'typedef' or fixed-width type instead [portability-avoid-platform-specific-fundamental-types] +// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: avoid using platform-dependent fundamental integer type 'int'; consider using a type alias or fixed-width type instead [portability-avoid-platform-specific-fundamental-types] return 42; } long function_returning_long() { -// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: avoid using platform-dependent fundamental integer type 'long'; consider using a 'typedef' or fixed-width type instead [portability-avoid-platform-specific-fundamental-types] +// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: avoid using platform-dependent fundamental integer type 'long'; consider using a type alias or fixed-width type instead [portability-avoid-platform-specific-fundamental-types] return 100L; } // Test local variables void test_local_variables() { int local_int = 10; - // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: avoid using platform-dependent fundamental integer type 'int'; consider using a 'typedef' or fixed-width type instead [portability-avoid-platform-specific-fundamental-types] + // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: avoid using platform-dependent fundamental integer type 'int'; consider using a type alias or fixed-width type instead [portability-avoid-platform-specific-fundamental-types] short local_short = 5; - // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: avoid using platform-dependent fundamental integer type 'short'; consider using a 'typedef' or fixed-width type instead [portability-avoid-platform-specific-fundamental-types] + // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: avoid using platform-dependent fundamental integer type 'short'; consider using a type alias or fixed-width type instead [portability-avoid-platform-specific-fundamental-types] unsigned long local_unsigned_long = 200UL; - // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: avoid using platform-dependent fundamental integer type 'unsigned long'; consider using a 'typedef' or fixed-width type instead [portability-avoid-platform-specific-fundamental-types] + // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: avoid using platform-dependent fundamental integer type 'unsigned long'; consider using a type alias or fixed-width type instead [portability-avoid-platform-specific-fundamental-types] // These should not trigger warnings char local_char = 'x'; @@ -113,10 +113,10 @@ void test_local_variables() { // Test struct/class members struct TestStruct { int member_int; - // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: avoid using platform-dependent fundamental integer type 'int'; consider using a 'typedef' or fixed-width type instead [portability-avoid-platform-specific-fundamental-types] + // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: avoid using platform-dependent fundamental integer type 'int'; consider using a type alias or fixed-width type instead [portability-avoid-platform-specific-fundamental-types] long member_long; - // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: avoid using platform-dependent fundamental integer type 'long'; consider using a 'typedef' or fixed-width type instead [portability-avoid-platform-specific-fundamental-types] + // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: avoid using platform-dependent fundamental integer type 'long'; consider using a type alias or fixed-width type instead [portability-avoid-platform-specific-fundamental-types] // These should not trigger warnings char member_char; @@ -126,22 +126,22 @@ struct TestStruct { class TestClass { public: unsigned int public_member; - // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: avoid using platform-dependent fundamental integer type 'unsigned int'; consider using a 'typedef' or fixed-width type instead [portability-avoid-platform-specific-fundamental-types] + // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: avoid using platform-dependent fundamental integer type 'unsigned int'; consider using a type alias or fixed-width type instead [portability-avoid-platform-specific-fundamental-types] private: short private_member; - // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: avoid using platform-dependent fundamental integer type 'short'; consider using a 'typedef' or fixed-width type instead [portability-avoid-platform-specific-fundamental-types] + // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: avoid using platform-dependent fundamental integer type 'short'; consider using a type alias or fixed-width type instead [portability-avoid-platform-specific-fundamental-types] }; // Test typedefs and type aliases typedef int MyInt; -// CHECK-MESSAGES: :[[@LINE-1]]:9: warning: avoid using platform-dependent fundamental integer type 'int'; consider using a 'typedef' or fixed-width type instead [portability-avoid-platform-specific-fundamental-types] +// CHECK-MESSAGES: :[[@LINE-1]]:9: warning: avoid using platform-dependent fundamental integer type 'int'; consider using a type alias or fixed-width type instead [portability-avoid-platform-specific-fundamental-types] using MyLong = long; -// CHECK-MESSAGES: :[[@LINE-1]]:16: warning: avoid using platform-dependent fundamental integer type 'long'; consider using a 'typedef' or fixed-width type instead [portability-avoid-platform-specific-fundamental-types] +// CHECK-MESSAGES: :[[@LINE-1]]:16: warning: avoid using platform-dependent fundamental integer type 'long'; consider using a type alias or fixed-width type instead [portability-avoid-platform-specific-fundamental-types] typedef long long customType; -// CHECK-MESSAGES: :[[@LINE-1]]:9: warning: avoid using platform-dependent fundamental integer type 'long long'; consider using a 'typedef' or fixed-width type instead [portability-avoid-platform-specific-fundamental-types] +// CHECK-MESSAGES: :[[@LINE-1]]:9: warning: avoid using platform-dependent fundamental integer type 'long long'; consider using a type alias or fixed-width type instead [portability-avoid-platform-specific-fundamental-types] // Test template parameters template @@ -149,6 +149,6 @@ void template_function(T param) {} template<> void template_function(int param) { -// CHECK-MESSAGES: :[[@LINE-1]]:24: warning: avoid using platform-dependent fundamental integer type 'int'; consider using a 'typedef' or fixed-width type instead [portability-avoid-platform-specific-fundamental-types] -// CHECK-MESSAGES: :[[@LINE-2]]:29: warning: avoid using platform-dependent fundamental integer type 'int'; consider using a 'typedef' or fixed-width type instead [portability-avoid-platform-specific-fundamental-types] +// CHECK-MESSAGES: :[[@LINE-1]]:24: warning: avoid using platform-dependent fundamental integer type 'int'; consider using a type alias or fixed-width type instead [portability-avoid-platform-specific-fundamental-types] +// CHECK-MESSAGES: :[[@LINE-2]]:29: warning: avoid using platform-dependent fundamental integer type 'int'; consider using a type alias or fixed-width type instead [portability-avoid-platform-specific-fundamental-types] } From 57e3e3909945244dcb26e9541d9b194fddb69ce0 Mon Sep 17 00:00:00 2001 From: JJ Marr Date: Sat, 20 Sep 2025 22:58:21 -0400 Subject: [PATCH 79/83] test char type template specialization --- ...avoid-platform-specific-fundamental-types-chars.cpp | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/clang-tools-extra/test/clang-tidy/checkers/portability/avoid-platform-specific-fundamental-types-chars.cpp b/clang-tools-extra/test/clang-tidy/checkers/portability/avoid-platform-specific-fundamental-types-chars.cpp index 5dc8552c6e6f9..393fb0ce961b6 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/portability/avoid-platform-specific-fundamental-types-chars.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/portability/avoid-platform-specific-fundamental-types-chars.cpp @@ -173,6 +173,16 @@ void test_template_instantiation() { // CHECK-MESSAGES: :[[@LINE-1]]:3: 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] } +// Test template specializations with char types +template +void template_function(T param) {} + +template<> +void template_function(char param) { +// CHECK-MESSAGES: :[[@LINE-1]]:24: warning: avoid using platform-dependent character type 'char'; consider using 'char8_t' for text or 'std::byte' for bytes +// CHECK-MESSAGES: :[[@LINE-2]]:30: warning: avoid using platform-dependent character type 'char'; consider using 'char8_t' for text or 'std::byte' for bytes +} + // Test that integer and float types are NOT flagged when their options are disabled int should_not_warn_int = 42; long should_not_warn_long = 100L; From 466133f9d82b54706a666fec1868829f899df9d9 Mon Sep 17 00:00:00 2001 From: JJ Marr <168750718+jj-marr@users.noreply.github.com> Date: Sat, 27 Sep 2025 19:01:44 -0400 Subject: [PATCH 80/83] Update clang-tools-extra/clang-tidy/portability/AvoidPlatformSpecificFundamentalTypesCheck.h Co-authored-by: EugeneZelenko --- .../portability/AvoidPlatformSpecificFundamentalTypesCheck.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clang-tools-extra/clang-tidy/portability/AvoidPlatformSpecificFundamentalTypesCheck.h b/clang-tools-extra/clang-tidy/portability/AvoidPlatformSpecificFundamentalTypesCheck.h index 6fe6ffef1e9f9..a7c1520f35068 100644 --- a/clang-tools-extra/clang-tidy/portability/AvoidPlatformSpecificFundamentalTypesCheck.h +++ b/clang-tools-extra/clang-tidy/portability/AvoidPlatformSpecificFundamentalTypesCheck.h @@ -18,7 +18,7 @@ namespace clang::tidy::portability { /// 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 +/// https://clang.llvm.org/extra/clang-tidy/checks/portability/avoid-platform-specific-fundamental-types.html class AvoidPlatformSpecificFundamentalTypesCheck : public ClangTidyCheck { public: AvoidPlatformSpecificFundamentalTypesCheck(StringRef Name, From 813894507a0b20e9ada0c5c37993bb93b8d8fc03 Mon Sep 17 00:00:00 2001 From: JJ Marr Date: Sun, 5 Oct 2025 16:04:05 -0400 Subject: [PATCH 81/83] trim contents of char check --- ...tform-specific-fundamental-types-chars.cpp | 84 +++++++++---------- 1 file changed, 42 insertions(+), 42 deletions(-) diff --git a/clang-tools-extra/test/clang-tidy/checkers/portability/avoid-platform-specific-fundamental-types-chars.cpp b/clang-tools-extra/test/clang-tidy/checkers/portability/avoid-platform-specific-fundamental-types-chars.cpp index 393fb0ce961b6..74c6f4a40972e 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/portability/avoid-platform-specific-fundamental-types-chars.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/portability/avoid-platform-specific-fundamental-types-chars.cpp @@ -15,162 +15,162 @@ enum class byte : unsigned char {}; // Test character types that should trigger warnings when WarnOnChars is enabled char global_char = 'a'; -// 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] +// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: avoid using platform-dependent character type 'char'; signed char global_signed_char = 'b'; -// 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] +// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: avoid using platform-dependent character type 'signed char'; unsigned char global_unsigned_char = 'c'; -// 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] +// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: avoid using platform-dependent character type 'unsigned char'; // Function parameters void func_with_char_param(char param) {} -// 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] +// CHECK-MESSAGES: :[[@LINE-1]]:27: warning: avoid using platform-dependent character type 'char'; void func_with_signed_char_param(signed char param) {} -// 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] +// CHECK-MESSAGES: :[[@LINE-1]]:34: warning: avoid using platform-dependent character type 'signed char'; void func_with_unsigned_char_param(unsigned char param) {} -// 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] +// CHECK-MESSAGES: :[[@LINE-1]]:36: warning: avoid using platform-dependent character type 'unsigned char'; // Function return types char func_returning_char() { return 'a'; } -// 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] +// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: avoid using platform-dependent character type 'char'; signed char func_returning_signed_char() { return 'b'; } -// 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] +// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: avoid using platform-dependent character type 'signed char'; unsigned char func_returning_unsigned_char() { return 'c'; } -// 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] +// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: avoid using platform-dependent character type 'unsigned char'; // Struct fields struct TestStruct { char field_char; - // CHECK-MESSAGES: :[[@LINE-1]]:3: 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]]:3: warning: avoid using platform-dependent character type 'char'; signed char field_signed_char; - // CHECK-MESSAGES: :[[@LINE-1]]:3: 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]]:3: warning: avoid using platform-dependent character type 'signed char'; unsigned char field_unsigned_char; - // CHECK-MESSAGES: :[[@LINE-1]]:3: 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]]:3: warning: avoid using platform-dependent character type 'unsigned char'; }; // Typedefs typedef char char_typedef; -// CHECK-MESSAGES: :[[@LINE-1]]:9: 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]]:9: warning: avoid using platform-dependent character type 'char'; typedef signed char signed_char_typedef; -// CHECK-MESSAGES: :[[@LINE-1]]:9: 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]]:9: warning: avoid using platform-dependent character type 'signed char'; typedef unsigned char unsigned_char_typedef; -// CHECK-MESSAGES: :[[@LINE-1]]:9: 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]]:9: warning: avoid using platform-dependent character type 'unsigned char'; // Type aliases (C++11) using char_alias = char; -// CHECK-MESSAGES: :[[@LINE-1]]:20: 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]]:20: warning: avoid using platform-dependent character type 'char'; using signed_char_alias = signed char; -// CHECK-MESSAGES: :[[@LINE-1]]:27: 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]]:27: warning: avoid using platform-dependent character type 'signed char'; using unsigned_char_alias = unsigned char; -// CHECK-MESSAGES: :[[@LINE-1]]:29: 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]]:29: warning: avoid using platform-dependent character type 'unsigned char'; // Test const and reference parameters void func_const_char_ref_param(const char ¶m) {} -// CHECK-MESSAGES: :[[@LINE-1]]:38: 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]]:38: warning: avoid using platform-dependent character type 'char'; void func_const_signed_char_ref_param(const signed char ¶m) {} -// CHECK-MESSAGES: :[[@LINE-1]]:45: 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]]:45: warning: avoid using platform-dependent character type 'signed char'; void func_const_unsigned_char_ref_param(const unsigned char ¶m) {} -// CHECK-MESSAGES: :[[@LINE-1]]:47: 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]]:47: warning: avoid using platform-dependent character type 'unsigned char'; // Test template declarations template struct TemplateStruct { typedef char char_type; - // CHECK-MESSAGES: :[[@LINE-1]]:11: 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]]:11: warning: avoid using platform-dependent character type 'char'; char template_field; - // CHECK-MESSAGES: :[[@LINE-1]]:3: 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]]:3: warning: avoid using platform-dependent character type 'char'; char create_char() { return char('x'); } - // CHECK-MESSAGES: :[[@LINE-1]]:3: 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-2]]:31: 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]]:3: warning: avoid using platform-dependent character type 'char'; + // CHECK-MESSAGES: :[[@LINE-2]]:31: warning: avoid using platform-dependent character type 'char'; }; // Test namespace usage namespace ns_chars { char ns_char; - // CHECK-MESSAGES: :[[@LINE-1]]:3: 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]]:3: warning: avoid using platform-dependent character type 'char'; } void test_comprehensive_cases() { // Test with spacing char spaced_char; - // CHECK-MESSAGES: :[[@LINE-1]]:3: 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]]:3: warning: avoid using platform-dependent character type 'char'; signed char spaced_signed_char; - // CHECK-MESSAGES: :[[@LINE-1]]:3: 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]]:3: warning: avoid using platform-dependent character type 'signed char'; // Test pointers char *char_ptr; - // CHECK-MESSAGES: :[[@LINE-1]]:3: 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]]:3: warning: avoid using platform-dependent character type 'char'; unsigned char *unsigned_char_ptr; - // CHECK-MESSAGES: :[[@LINE-1]]:3: 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]]:3: warning: avoid using platform-dependent character type 'unsigned char'; // Test static declarations static char static_char; - // CHECK-MESSAGES: :[[@LINE-1]]:10: 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]]:10: warning: avoid using platform-dependent character type 'char'; // Test cv-qualifiers const char const_char = 'a'; - // CHECK-MESSAGES: :[[@LINE-1]]:9: 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]]:9: warning: avoid using platform-dependent character type 'char'; volatile char volatile_char; - // CHECK-MESSAGES: :[[@LINE-1]]:12: 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]]:12: warning: avoid using platform-dependent character type 'char'; const volatile char const_volatile_char = '\0'; - // CHECK-MESSAGES: :[[@LINE-1]]:18: 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]]:18: warning: avoid using platform-dependent character type 'char'; // Test auto with initializer auto auto_char = char{'x'}; - // CHECK-MESSAGES: :[[@LINE-1]]:20: 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]]:20: warning: avoid using platform-dependent character type 'char'; // Verify auto without initializer isn't flagged auto auto_nonexplicit_char = 'x'; char brace_init_char{}; - // CHECK-MESSAGES: :[[@LINE-1]]:3: 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]]:3: warning: avoid using platform-dependent character type 'char'; // Test arrays char char_array[10]; - // CHECK-MESSAGES: :[[@LINE-1]]:3: 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]]:3: warning: avoid using platform-dependent character type 'char'; unsigned char unsigned_char_array[] = {'a', 'b', 'c'}; - // CHECK-MESSAGES: :[[@LINE-1]]:3: 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]]:3: warning: avoid using platform-dependent character type 'unsigned char'; // Test multiple declarations char multi_char1, multi_char2, multi_char3; - // CHECK-MESSAGES: :[[@LINE-1]]:3: 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]]:3: warning: avoid using platform-dependent character type 'char'; } // Test class with character type members class CharacterClass { public: char &get_char_ref(); - // CHECK-MESSAGES: :[[@LINE-1]]:3: 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]]:3: warning: avoid using platform-dependent character type 'char'; private: char private_char; - // CHECK-MESSAGES: :[[@LINE-1]]:3: 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]]:3: warning: avoid using platform-dependent character type 'char'; }; // Test template instantiation void test_template_instantiation() { TemplateStruct template_instance; char template_test = template_instance.create_char(); - // CHECK-MESSAGES: :[[@LINE-1]]:3: 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]]:3: warning: avoid using platform-dependent character type 'char'; } // Test template specializations with char types From b02eccc79cd32c4576f32c5209a59403867cf471 Mon Sep 17 00:00:00 2001 From: JJ Marr Date: Sun, 5 Oct 2025 16:18:42 -0400 Subject: [PATCH 82/83] vibe coded replacement suggestion --- ...dPlatformSpecificFundamentalTypesCheck.cpp | 85 ++++++++++++++++++- ...oidPlatformSpecificFundamentalTypesCheck.h | 1 + ...-specific-fundamental-types-ints-exact.cpp | 77 +++++++++++++++++ ...m-specific-fundamental-types-ints-fast.cpp | 77 +++++++++++++++++ ...-specific-fundamental-types-ints-least.cpp | 77 +++++++++++++++++ ...atform-specific-fundamental-types-ints.cpp | 71 ++++++++++------ 6 files changed, 361 insertions(+), 27 deletions(-) create mode 100644 clang-tools-extra/test/clang-tidy/checkers/portability/avoid-platform-specific-fundamental-types-ints-exact.cpp create mode 100644 clang-tools-extra/test/clang-tidy/checkers/portability/avoid-platform-specific-fundamental-types-ints-fast.cpp create mode 100644 clang-tools-extra/test/clang-tidy/checkers/portability/avoid-platform-specific-fundamental-types-ints-least.cpp diff --git a/clang-tools-extra/clang-tidy/portability/AvoidPlatformSpecificFundamentalTypesCheck.cpp b/clang-tools-extra/clang-tidy/portability/AvoidPlatformSpecificFundamentalTypesCheck.cpp index 2a21c2ef4aa73..fb31952205c52 100644 --- a/clang-tools-extra/clang-tidy/portability/AvoidPlatformSpecificFundamentalTypesCheck.cpp +++ b/clang-tools-extra/clang-tidy/portability/AvoidPlatformSpecificFundamentalTypesCheck.cpp @@ -55,6 +55,7 @@ AvoidPlatformSpecificFundamentalTypesCheck:: WarnOnFloats(Options.get("WarnOnFloats", true)), WarnOnInts(Options.get("WarnOnInts", true)), WarnOnChars(Options.get("WarnOnChars", true)), + IntegerReplacementStyle(Options.get("IntegerReplacementStyle", "Exact")), IncludeInserter(Options.getLocalOrGlobal("IncludeStyle", utils::IncludeSorter::IS_LLVM), areDiagsSelfContained()) { @@ -75,6 +76,7 @@ void AvoidPlatformSpecificFundamentalTypesCheck::storeOptions( Options.store(Opts, "WarnOnFloats", WarnOnFloats); Options.store(Opts, "WarnOnInts", WarnOnInts); Options.store(Opts, "WarnOnChars", WarnOnChars); + Options.store(Opts, "IntegerReplacementStyle", IntegerReplacementStyle); Options.store(Opts, "IncludeStyle", IncludeInserter.getStyle()); } @@ -117,6 +119,64 @@ static std::optional getFloatReplacement(const BuiltinType *BT, } } +static std::optional getIntegerReplacement(const BuiltinType *BT, + ASTContext &Context, + StringRef Style) { + const TargetInfo &Target = Context.getTargetInfo(); + + auto GetReplacementType = [&Style](unsigned Width, bool IsSigned) -> std::optional { + std::string Prefix; + std::string Suffix; + + if (Style == "Exact") { + Prefix = IsSigned ? "int" : "uint"; + Suffix = "_t"; + } else if (Style == "Fast") { + Prefix = IsSigned ? "int_fast" : "uint_fast"; + Suffix = "_t"; + } else if (Style == "Least") { + Prefix = IsSigned ? "int_least" : "uint_least"; + Suffix = "_t"; + } else { + return std::nullopt; + } + + switch (Width) { + case 8U: + return Prefix + "8" + Suffix; + case 16U: + return Prefix + "16" + Suffix; + case 32U: + return Prefix + "32" + Suffix; + case 64U: + return Prefix + "64" + Suffix; + default: + return std::nullopt; + } + }; + + switch (BT->getKind()) { + case BuiltinType::Short: + return GetReplacementType(Target.getShortWidth(), true); + case BuiltinType::UShort: + return GetReplacementType(Target.getShortWidth(), false); + case BuiltinType::Int: + return GetReplacementType(Target.getIntWidth(), true); + case BuiltinType::UInt: + return GetReplacementType(Target.getIntWidth(), false); + case BuiltinType::Long: + return GetReplacementType(Target.getLongWidth(), true); + case BuiltinType::ULong: + return GetReplacementType(Target.getLongWidth(), false); + case BuiltinType::LongLong: + return GetReplacementType(Target.getLongLongWidth(), true); + case BuiltinType::ULongLong: + return GetReplacementType(Target.getLongLongWidth(), false); + default: + return std::nullopt; + } +} + void AvoidPlatformSpecificFundamentalTypesCheck::registerMatchers( MatchFinder *Finder) { auto PlatformSpecificFundamentalType = qualType(allOf( @@ -177,9 +237,28 @@ void AvoidPlatformSpecificFundamentalTypesCheck::check( "consider using 'char8_t' for text or 'std::byte' for bytes") << TypeName; } else { - diag(Loc, "avoid using platform-dependent fundamental integer type '%0'; " - "consider using a type alias or fixed-width type instead") - << TypeName; + // Handle integer types + const auto Replacement = getIntegerReplacement(BT, *Result.Context, IntegerReplacementStyle); + + if (!Replacement.has_value()) { + diag(Loc, "avoid using platform-dependent fundamental integer type '%0'; " + "consider using a type alias or fixed-width type instead") + << TypeName; + return; + } + + auto Diag = + diag(Loc, "avoid using platform-dependent fundamental integer type '%0'; " + "consider using '%1' instead") + << TypeName << Replacement.value(); + + if (TypeRange.isValid()) + Diag << FixItHint::CreateReplacement(TypeRange, Replacement.value()); + + if (auto IncludeFixit = IncludeInserter.createIncludeInsertion( + Result.SourceManager->getFileID(Loc), "")) { + Diag << *IncludeFixit; + } } } diff --git a/clang-tools-extra/clang-tidy/portability/AvoidPlatformSpecificFundamentalTypesCheck.h b/clang-tools-extra/clang-tidy/portability/AvoidPlatformSpecificFundamentalTypesCheck.h index a7c1520f35068..97344d25b88b2 100644 --- a/clang-tools-extra/clang-tidy/portability/AvoidPlatformSpecificFundamentalTypesCheck.h +++ b/clang-tools-extra/clang-tidy/portability/AvoidPlatformSpecificFundamentalTypesCheck.h @@ -39,6 +39,7 @@ class AvoidPlatformSpecificFundamentalTypesCheck : public ClangTidyCheck { const bool WarnOnFloats; const bool WarnOnInts; const bool WarnOnChars; + const std::string IntegerReplacementStyle; utils::IncludeInserter IncludeInserter; }; diff --git a/clang-tools-extra/test/clang-tidy/checkers/portability/avoid-platform-specific-fundamental-types-ints-exact.cpp b/clang-tools-extra/test/clang-tidy/checkers/portability/avoid-platform-specific-fundamental-types-ints-exact.cpp new file mode 100644 index 0000000000000..b4bbbc233c2f5 --- /dev/null +++ b/clang-tools-extra/test/clang-tidy/checkers/portability/avoid-platform-specific-fundamental-types-ints-exact.cpp @@ -0,0 +1,77 @@ +// RUN: %check_clang_tidy -std=c++11-or-later %s \ +// RUN: portability-avoid-platform-specific-fundamental-types %t -- \ +// RUN: -config="{CheckOptions: \ +// RUN: [{key: portability-avoid-platform-specific-fundamental-types.WarnOnChars, \ +// RUN: value: false}, \ +// RUN: {key: portability-avoid-platform-specific-fundamental-types.WarnOnFloats, \ +// RUN: value: false}, \ +// RUN: {key: portability-avoid-platform-specific-fundamental-types.IntegerReplacementStyle, \ +// RUN: value: Exact}]}" + +// Test "Exact" replacement style (default) +int global_int = 42; +// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: avoid using platform-dependent fundamental integer type 'int'; consider using 'int32_t' instead [portability-avoid-platform-specific-fundamental-types] +// CHECK-FIXES: int32_t global_int = 42; + +unsigned int global_unsigned_int = 42U; +// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: avoid using platform-dependent fundamental integer type 'unsigned int'; consider using 'uint32_t' instead [portability-avoid-platform-specific-fundamental-types] +// CHECK-FIXES: uint32_t global_unsigned_int = 42U; + +short global_short = 10; +// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: avoid using platform-dependent fundamental integer type 'short'; consider using 'int16_t' instead [portability-avoid-platform-specific-fundamental-types] +// CHECK-FIXES: int16_t global_short = 10; + +unsigned short global_unsigned_short = 10U; +// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: avoid using platform-dependent fundamental integer type 'unsigned short'; consider using 'uint16_t' instead [portability-avoid-platform-specific-fundamental-types] +// CHECK-FIXES: uint16_t global_unsigned_short = 10U; + +long global_long = 100L; +// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: avoid using platform-dependent fundamental integer type 'long'; consider using 'int{{(32|64)}}_t' instead [portability-avoid-platform-specific-fundamental-types] +// CHECK-FIXES: int{{(32|64)}}_t global_long = 100L; + +unsigned long global_unsigned_long = 100UL; +// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: avoid using platform-dependent fundamental integer type 'unsigned long'; consider using 'uint{{(32|64)}}_t' instead [portability-avoid-platform-specific-fundamental-types] +// CHECK-FIXES: uint{{(32|64)}}_t global_unsigned_long = 100UL; + +long long global_long_long = 1000LL; +// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: avoid using platform-dependent fundamental integer type 'long long'; consider using 'int64_t' instead [portability-avoid-platform-specific-fundamental-types] +// CHECK-FIXES: int64_t global_long_long = 1000LL; + +unsigned long long global_unsigned_long_long = 1000ULL; +// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: avoid using platform-dependent fundamental integer type 'unsigned long long'; consider using 'uint64_t' instead [portability-avoid-platform-specific-fundamental-types] +// CHECK-FIXES: uint64_t global_unsigned_long_long = 1000ULL; + +// Test function parameters +void function_with_int_param(int param) { +// CHECK-MESSAGES: :[[@LINE-1]]:30: warning: avoid using platform-dependent fundamental integer type 'int'; consider using 'int32_t' instead [portability-avoid-platform-specific-fundamental-types] +// CHECK-FIXES: void function_with_int_param(int32_t param) { +} + +// Test function return types +int function_returning_int() { +// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: avoid using platform-dependent fundamental integer type 'int'; consider using 'int32_t' instead [portability-avoid-platform-specific-fundamental-types] +// CHECK-FIXES: int32_t function_returning_int() { + return 42; +} + +// Test local variables +void test_local_variables() { + int local_int = 10; + // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: avoid using platform-dependent fundamental integer type 'int'; consider using 'int32_t' instead [portability-avoid-platform-specific-fundamental-types] + // CHECK-FIXES: int32_t local_int = 10; + + short local_short = 5; + // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: avoid using platform-dependent fundamental integer type 'short'; consider using 'int16_t' instead [portability-avoid-platform-specific-fundamental-types] + // CHECK-FIXES: int16_t local_short = 5; +} + +// Test struct members +struct TestStruct { + int member_int; + // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: avoid using platform-dependent fundamental integer type 'int'; consider using 'int32_t' instead [portability-avoid-platform-specific-fundamental-types] + // CHECK-FIXES: int32_t member_int; + + long member_long; + // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: avoid using platform-dependent fundamental integer type 'long'; consider using 'int{{(32|64)}}_t' instead [portability-avoid-platform-specific-fundamental-types] + // CHECK-FIXES: int{{(32|64)}}_t member_long; +}; diff --git a/clang-tools-extra/test/clang-tidy/checkers/portability/avoid-platform-specific-fundamental-types-ints-fast.cpp b/clang-tools-extra/test/clang-tidy/checkers/portability/avoid-platform-specific-fundamental-types-ints-fast.cpp new file mode 100644 index 0000000000000..7b5d3b8e8aed2 --- /dev/null +++ b/clang-tools-extra/test/clang-tidy/checkers/portability/avoid-platform-specific-fundamental-types-ints-fast.cpp @@ -0,0 +1,77 @@ +// RUN: %check_clang_tidy -std=c++11-or-later %s \ +// RUN: portability-avoid-platform-specific-fundamental-types %t -- \ +// RUN: -config="{CheckOptions: \ +// RUN: [{key: portability-avoid-platform-specific-fundamental-types.WarnOnChars, \ +// RUN: value: false}, \ +// RUN: {key: portability-avoid-platform-specific-fundamental-types.WarnOnFloats, \ +// RUN: value: false}, \ +// RUN: {key: portability-avoid-platform-specific-fundamental-types.IntegerReplacementStyle, \ +// RUN: value: Fast}]}" + +// Test "Fast" replacement style +int global_int = 42; +// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: avoid using platform-dependent fundamental integer type 'int'; consider using 'int_fast32_t' instead [portability-avoid-platform-specific-fundamental-types] +// CHECK-FIXES: int_fast32_t global_int = 42; + +unsigned int global_unsigned_int = 42U; +// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: avoid using platform-dependent fundamental integer type 'unsigned int'; consider using 'uint_fast32_t' instead [portability-avoid-platform-specific-fundamental-types] +// CHECK-FIXES: uint_fast32_t global_unsigned_int = 42U; + +short global_short = 10; +// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: avoid using platform-dependent fundamental integer type 'short'; consider using 'int_fast16_t' instead [portability-avoid-platform-specific-fundamental-types] +// CHECK-FIXES: int_fast16_t global_short = 10; + +unsigned short global_unsigned_short = 10U; +// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: avoid using platform-dependent fundamental integer type 'unsigned short'; consider using 'uint_fast16_t' instead [portability-avoid-platform-specific-fundamental-types] +// CHECK-FIXES: uint_fast16_t global_unsigned_short = 10U; + +long global_long = 100L; +// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: avoid using platform-dependent fundamental integer type 'long'; consider using '{{u?}}int_fast{{(32|64)}}_t' instead [portability-avoid-platform-specific-fundamental-types] +// CHECK-FIXES: {{u?}}int_fast{{(32|64)}}_t global_long = 100L; + +unsigned long global_unsigned_long = 100UL; +// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: avoid using platform-dependent fundamental integer type 'unsigned long'; consider using 'uint_fast{{(32|64)}}_t' instead [portability-avoid-platform-specific-fundamental-types] +// CHECK-FIXES: uint_fast{{(32|64)}}_t global_unsigned_long = 100UL; + +long long global_long_long = 1000LL; +// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: avoid using platform-dependent fundamental integer type 'long long'; consider using 'int_fast64_t' instead [portability-avoid-platform-specific-fundamental-types] +// CHECK-FIXES: int_fast64_t global_long_long = 1000LL; + +unsigned long long global_unsigned_long_long = 1000ULL; +// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: avoid using platform-dependent fundamental integer type 'unsigned long long'; consider using 'uint_fast64_t' instead [portability-avoid-platform-specific-fundamental-types] +// CHECK-FIXES: uint_fast64_t global_unsigned_long_long = 1000ULL; + +// Test function parameters +void function_with_int_param(int param) { +// CHECK-MESSAGES: :[[@LINE-1]]:30: warning: avoid using platform-dependent fundamental integer type 'int'; consider using 'int_fast32_t' instead [portability-avoid-platform-specific-fundamental-types] +// CHECK-FIXES: void function_with_int_param(int_fast32_t param) { +} + +// Test function return types +int function_returning_int() { +// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: avoid using platform-dependent fundamental integer type 'int'; consider using 'int_fast32_t' instead [portability-avoid-platform-specific-fundamental-types] +// CHECK-FIXES: int_fast32_t function_returning_int() { + return 42; +} + +// Test local variables +void test_local_variables() { + int local_int = 10; + // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: avoid using platform-dependent fundamental integer type 'int'; consider using 'int_fast32_t' instead [portability-avoid-platform-specific-fundamental-types] + // CHECK-FIXES: int_fast32_t local_int = 10; + + short local_short = 5; + // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: avoid using platform-dependent fundamental integer type 'short'; consider using 'int_fast16_t' instead [portability-avoid-platform-specific-fundamental-types] + // CHECK-FIXES: int_fast16_t local_short = 5; +} + +// Test struct members +struct TestStruct { + int member_int; + // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: avoid using platform-dependent fundamental integer type 'int'; consider using 'int_fast32_t' instead [portability-avoid-platform-specific-fundamental-types] + // CHECK-FIXES: int_fast32_t member_int; + + long member_long; + // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: avoid using platform-dependent fundamental integer type 'long'; consider using '{{u?}}int_fast{{(32|64)}}_t' instead [portability-avoid-platform-specific-fundamental-types] + // CHECK-FIXES: {{u?}}int_fast{{(32|64)}}_t member_long; +}; diff --git a/clang-tools-extra/test/clang-tidy/checkers/portability/avoid-platform-specific-fundamental-types-ints-least.cpp b/clang-tools-extra/test/clang-tidy/checkers/portability/avoid-platform-specific-fundamental-types-ints-least.cpp new file mode 100644 index 0000000000000..f4706ce59aa29 --- /dev/null +++ b/clang-tools-extra/test/clang-tidy/checkers/portability/avoid-platform-specific-fundamental-types-ints-least.cpp @@ -0,0 +1,77 @@ +// RUN: %check_clang_tidy -std=c++11-or-later %s \ +// RUN: portability-avoid-platform-specific-fundamental-types %t -- \ +// RUN: -config="{CheckOptions: \ +// RUN: [{key: portability-avoid-platform-specific-fundamental-types.WarnOnChars, \ +// RUN: value: false}, \ +// RUN: {key: portability-avoid-platform-specific-fundamental-types.WarnOnFloats, \ +// RUN: value: false}, \ +// RUN: {key: portability-avoid-platform-specific-fundamental-types.IntegerReplacementStyle, \ +// RUN: value: Least}]}" + +// Test "Least" replacement style +int global_int = 42; +// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: avoid using platform-dependent fundamental integer type 'int'; consider using 'int_least32_t' instead [portability-avoid-platform-specific-fundamental-types] +// CHECK-FIXES: int_least32_t global_int = 42; + +unsigned int global_unsigned_int = 42U; +// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: avoid using platform-dependent fundamental integer type 'unsigned int'; consider using 'uint_least32_t' instead [portability-avoid-platform-specific-fundamental-types] +// CHECK-FIXES: uint_least32_t global_unsigned_int = 42U; + +short global_short = 10; +// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: avoid using platform-dependent fundamental integer type 'short'; consider using 'int_least16_t' instead [portability-avoid-platform-specific-fundamental-types] +// CHECK-FIXES: int_least16_t global_short = 10; + +unsigned short global_unsigned_short = 10U; +// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: avoid using platform-dependent fundamental integer type 'unsigned short'; consider using 'uint_least16_t' instead [portability-avoid-platform-specific-fundamental-types] +// CHECK-FIXES: uint_least16_t global_unsigned_short = 10U; + +long global_long = 100L; +// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: avoid using platform-dependent fundamental integer type 'long'; consider using '{{u?}}int_least{{(32|64)}}_t' instead [portability-avoid-platform-specific-fundamental-types] +// CHECK-FIXES: {{u?}}int_least{{(32|64)}}_t global_long = 100L; + +unsigned long global_unsigned_long = 100UL; +// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: avoid using platform-dependent fundamental integer type 'unsigned long'; consider using 'uint_least{{(32|64)}}_t' instead [portability-avoid-platform-specific-fundamental-types] +// CHECK-FIXES: uint_least{{(32|64)}}_t global_unsigned_long = 100UL; + +long long global_long_long = 1000LL; +// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: avoid using platform-dependent fundamental integer type 'long long'; consider using 'int_least64_t' instead [portability-avoid-platform-specific-fundamental-types] +// CHECK-FIXES: int_least64_t global_long_long = 1000LL; + +unsigned long long global_unsigned_long_long = 1000ULL; +// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: avoid using platform-dependent fundamental integer type 'unsigned long long'; consider using 'uint_least64_t' instead [portability-avoid-platform-specific-fundamental-types] +// CHECK-FIXES: uint_least64_t global_unsigned_long_long = 1000ULL; + +// Test function parameters +void function_with_int_param(int param) { +// CHECK-MESSAGES: :[[@LINE-1]]:30: warning: avoid using platform-dependent fundamental integer type 'int'; consider using 'int_least32_t' instead [portability-avoid-platform-specific-fundamental-types] +// CHECK-FIXES: void function_with_int_param(int_least32_t param) { +} + +// Test function return types +int function_returning_int() { +// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: avoid using platform-dependent fundamental integer type 'int'; consider using 'int_least32_t' instead [portability-avoid-platform-specific-fundamental-types] +// CHECK-FIXES: int_least32_t function_returning_int() { + return 42; +} + +// Test local variables +void test_local_variables() { + int local_int = 10; + // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: avoid using platform-dependent fundamental integer type 'int'; consider using 'int_least32_t' instead [portability-avoid-platform-specific-fundamental-types] + // CHECK-FIXES: int_least32_t local_int = 10; + + short local_short = 5; + // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: avoid using platform-dependent fundamental integer type 'short'; consider using 'int_least16_t' instead [portability-avoid-platform-specific-fundamental-types] + // CHECK-FIXES: int_least16_t local_short = 5; +} + +// Test struct members +struct TestStruct { + int member_int; + // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: avoid using platform-dependent fundamental integer type 'int'; consider using 'int_least32_t' instead [portability-avoid-platform-specific-fundamental-types] + // CHECK-FIXES: int_least32_t member_int; + + long member_long; + // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: avoid using platform-dependent fundamental integer type 'long'; consider using '{{u?}}int_least{{(32|64)}}_t' instead [portability-avoid-platform-specific-fundamental-types] + // CHECK-FIXES: {{u?}}int_least{{(32|64)}}_t member_long; +}; diff --git a/clang-tools-extra/test/clang-tidy/checkers/portability/avoid-platform-specific-fundamental-types-ints.cpp b/clang-tools-extra/test/clang-tidy/checkers/portability/avoid-platform-specific-fundamental-types-ints.cpp index b4f3079c50304..072160225a224 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/portability/avoid-platform-specific-fundamental-types-ints.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/portability/avoid-platform-specific-fundamental-types-ints.cpp @@ -23,28 +23,36 @@ typedef unsigned long size_t; // Test fundamental integer types that should trigger warnings int global_int = 42; -// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: avoid using platform-dependent fundamental integer type 'int'; consider using a type alias or fixed-width type instead [portability-avoid-platform-specific-fundamental-types] +// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: avoid using platform-dependent fundamental integer type 'int'; consider using 'int32_t' instead [portability-avoid-platform-specific-fundamental-types] +// CHECK-FIXES: int32_t global_int = 42; short global_short = 10; -// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: avoid using platform-dependent fundamental integer type 'short'; consider using a type alias or fixed-width type instead [portability-avoid-platform-specific-fundamental-types] +// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: avoid using platform-dependent fundamental integer type 'short'; consider using 'int16_t' instead [portability-avoid-platform-specific-fundamental-types] +// CHECK-FIXES: int16_t global_short = 10; long global_long = 100L; -// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: avoid using platform-dependent fundamental integer type 'long'; consider using a type alias or fixed-width type instead [portability-avoid-platform-specific-fundamental-types] +// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: avoid using platform-dependent fundamental integer type 'long'; consider using 'int{{(32|64)}}_t' instead [portability-avoid-platform-specific-fundamental-types] +// CHECK-FIXES: int{{(32|64)}}_t global_long = 100L; long long global_long_long = 1000LL; -// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: avoid using platform-dependent fundamental integer type 'long long'; consider using a type alias or fixed-width type instead [portability-avoid-platform-specific-fundamental-types] +// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: avoid using platform-dependent fundamental integer type 'long long'; consider using 'int64_t' instead [portability-avoid-platform-specific-fundamental-types] +// CHECK-FIXES: int64_t global_long_long = 1000LL; unsigned int global_unsigned_int = 42U; -// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: avoid using platform-dependent fundamental integer type 'unsigned int'; consider using a type alias or fixed-width type instead [portability-avoid-platform-specific-fundamental-types] +// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: avoid using platform-dependent fundamental integer type 'unsigned int'; consider using 'uint32_t' instead [portability-avoid-platform-specific-fundamental-types] +// CHECK-FIXES: uint32_t global_unsigned_int = 42U; unsigned short global_unsigned_short = 10U; -// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: avoid using platform-dependent fundamental integer type 'unsigned short'; consider using a type alias or fixed-width type instead [portability-avoid-platform-specific-fundamental-types] +// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: avoid using platform-dependent fundamental integer type 'unsigned short'; consider using 'uint16_t' instead [portability-avoid-platform-specific-fundamental-types] +// CHECK-FIXES: uint16_t global_unsigned_short = 10U; unsigned long global_unsigned_long = 100UL; -// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: avoid using platform-dependent fundamental integer type 'unsigned long'; consider using a type alias or fixed-width type instead [portability-avoid-platform-specific-fundamental-types] +// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: avoid using platform-dependent fundamental integer type 'unsigned long'; consider using 'uint{{(32|64)}}_t' instead [portability-avoid-platform-specific-fundamental-types] +// CHECK-FIXES: uint{{(32|64)}}_t global_unsigned_long = 100UL; unsigned long long global_unsigned_long_long = 1000ULL; -// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: avoid using platform-dependent fundamental integer type 'unsigned long long'; consider using a type alias or fixed-width type instead [portability-avoid-platform-specific-fundamental-types] +// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: avoid using platform-dependent fundamental integer type 'unsigned long long'; consider using 'uint64_t' instead [portability-avoid-platform-specific-fundamental-types] +// CHECK-FIXES: uint64_t global_unsigned_long_long = 1000ULL; // Test integer that should NEVER trigger warnings bool global_bool = true; @@ -68,34 +76,41 @@ ptrdiff_t global_ptrdiff = 50; // Test function parameters void function_with_int_param(int param) { -// CHECK-MESSAGES: :[[@LINE-1]]:30: warning: avoid using platform-dependent fundamental integer type 'int'; consider using a type alias or fixed-width type instead [portability-avoid-platform-specific-fundamental-types] +// CHECK-MESSAGES: :[[@LINE-1]]:30: warning: avoid using platform-dependent fundamental integer type 'int'; consider using 'int32_t' instead [portability-avoid-platform-specific-fundamental-types] +// CHECK-FIXES: void function_with_int_param(int32_t param) { } void function_with_short_param(short param) { -// CHECK-MESSAGES: :[[@LINE-1]]:32: warning: avoid using platform-dependent fundamental integer type 'short'; consider using a type alias or fixed-width type instead [portability-avoid-platform-specific-fundamental-types] +// CHECK-MESSAGES: :[[@LINE-1]]:32: warning: avoid using platform-dependent fundamental integer type 'short'; consider using 'int16_t' instead [portability-avoid-platform-specific-fundamental-types] +// CHECK-FIXES: void function_with_short_param(int16_t param) { } // Test function return types int function_returning_int() { -// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: avoid using platform-dependent fundamental integer type 'int'; consider using a type alias or fixed-width type instead [portability-avoid-platform-specific-fundamental-types] +// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: avoid using platform-dependent fundamental integer type 'int'; consider using 'int32_t' instead [portability-avoid-platform-specific-fundamental-types] +// CHECK-FIXES: int32_t function_returning_int() { return 42; } long function_returning_long() { -// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: avoid using platform-dependent fundamental integer type 'long'; consider using a type alias or fixed-width type instead [portability-avoid-platform-specific-fundamental-types] +// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: avoid using platform-dependent fundamental integer type 'long'; consider using 'int{{(32|64)}}_t' instead [portability-avoid-platform-specific-fundamental-types] +// CHECK-FIXES: int{{(32|64)}}_t function_returning_long() { return 100L; } // Test local variables void test_local_variables() { int local_int = 10; - // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: avoid using platform-dependent fundamental integer type 'int'; consider using a type alias or fixed-width type instead [portability-avoid-platform-specific-fundamental-types] + // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: avoid using platform-dependent fundamental integer type 'int'; consider using 'int32_t' instead [portability-avoid-platform-specific-fundamental-types] + // CHECK-FIXES: int32_t local_int = 10; short local_short = 5; - // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: avoid using platform-dependent fundamental integer type 'short'; consider using a type alias or fixed-width type instead [portability-avoid-platform-specific-fundamental-types] + // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: avoid using platform-dependent fundamental integer type 'short'; consider using 'int16_t' instead [portability-avoid-platform-specific-fundamental-types] + // CHECK-FIXES: int16_t local_short = 5; unsigned long local_unsigned_long = 200UL; - // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: avoid using platform-dependent fundamental integer type 'unsigned long'; consider using a type alias or fixed-width type instead [portability-avoid-platform-specific-fundamental-types] + // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: avoid using platform-dependent fundamental integer type 'unsigned long'; consider using 'uint{{(32|64)}}_t' instead [portability-avoid-platform-specific-fundamental-types] + // CHECK-FIXES: uint{{(32|64)}}_t local_unsigned_long = 200UL; // These should not trigger warnings char local_char = 'x'; @@ -113,10 +128,12 @@ void test_local_variables() { // Test struct/class members struct TestStruct { int member_int; - // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: avoid using platform-dependent fundamental integer type 'int'; consider using a type alias or fixed-width type instead [portability-avoid-platform-specific-fundamental-types] + // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: avoid using platform-dependent fundamental integer type 'int'; consider using 'int32_t' instead [portability-avoid-platform-specific-fundamental-types] + // CHECK-FIXES: int32_t member_int; long member_long; - // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: avoid using platform-dependent fundamental integer type 'long'; consider using a type alias or fixed-width type instead [portability-avoid-platform-specific-fundamental-types] + // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: avoid using platform-dependent fundamental integer type 'long'; consider using 'int{{(32|64)}}_t' instead [portability-avoid-platform-specific-fundamental-types] + // CHECK-FIXES: int{{(32|64)}}_t member_long; // These should not trigger warnings char member_char; @@ -126,22 +143,27 @@ struct TestStruct { class TestClass { public: unsigned int public_member; - // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: avoid using platform-dependent fundamental integer type 'unsigned int'; consider using a type alias or fixed-width type instead [portability-avoid-platform-specific-fundamental-types] + // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: avoid using platform-dependent fundamental integer type 'unsigned int'; consider using 'uint32_t' instead [portability-avoid-platform-specific-fundamental-types] + // CHECK-FIXES: uint32_t public_member; private: short private_member; - // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: avoid using platform-dependent fundamental integer type 'short'; consider using a type alias or fixed-width type instead [portability-avoid-platform-specific-fundamental-types] + // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: avoid using platform-dependent fundamental integer type 'short'; consider using 'int16_t' instead [portability-avoid-platform-specific-fundamental-types] + // CHECK-FIXES: int16_t private_member; }; // Test typedefs and type aliases typedef int MyInt; -// CHECK-MESSAGES: :[[@LINE-1]]:9: warning: avoid using platform-dependent fundamental integer type 'int'; consider using a type alias or fixed-width type instead [portability-avoid-platform-specific-fundamental-types] +// CHECK-MESSAGES: :[[@LINE-1]]:9: warning: avoid using platform-dependent fundamental integer type 'int'; consider using 'int32_t' instead [portability-avoid-platform-specific-fundamental-types] +// CHECK-FIXES: typedef int32_t MyInt; using MyLong = long; -// CHECK-MESSAGES: :[[@LINE-1]]:16: warning: avoid using platform-dependent fundamental integer type 'long'; consider using a type alias or fixed-width type instead [portability-avoid-platform-specific-fundamental-types] +// CHECK-MESSAGES: :[[@LINE-1]]:16: warning: avoid using platform-dependent fundamental integer type 'long'; consider using 'int{{(32|64)}}_t' instead [portability-avoid-platform-specific-fundamental-types] +// CHECK-FIXES: using MyLong = int{{(32|64)}}_t; typedef long long customType; -// CHECK-MESSAGES: :[[@LINE-1]]:9: warning: avoid using platform-dependent fundamental integer type 'long long'; consider using a type alias or fixed-width type instead [portability-avoid-platform-specific-fundamental-types] +// CHECK-MESSAGES: :[[@LINE-1]]:9: warning: avoid using platform-dependent fundamental integer type 'long long'; consider using 'int64_t' instead [portability-avoid-platform-specific-fundamental-types] +// CHECK-FIXES: typedef int64_t customType; // Test template parameters template @@ -149,6 +171,7 @@ void template_function(T param) {} template<> void template_function(int param) { -// CHECK-MESSAGES: :[[@LINE-1]]:24: warning: avoid using platform-dependent fundamental integer type 'int'; consider using a type alias or fixed-width type instead [portability-avoid-platform-specific-fundamental-types] -// CHECK-MESSAGES: :[[@LINE-2]]:29: warning: avoid using platform-dependent fundamental integer type 'int'; consider using a type alias or fixed-width type instead [portability-avoid-platform-specific-fundamental-types] +// CHECK-MESSAGES: :[[@LINE-1]]:24: warning: avoid using platform-dependent fundamental integer type 'int'; consider using 'int32_t' instead [portability-avoid-platform-specific-fundamental-types] +// CHECK-MESSAGES: :[[@LINE-2]]:29: warning: avoid using platform-dependent fundamental integer type 'int'; consider using 'int32_t' instead [portability-avoid-platform-specific-fundamental-types] +// CHECK-FIXES: void template_function(int32_t param) { } From 388fe0c460b419ec964e4744cada6638748a9c58 Mon Sep 17 00:00:00 2001 From: JJ Marr Date: Sun, 5 Oct 2025 21:37:05 -0400 Subject: [PATCH 83/83] Touch up suggestion code --- ...dPlatformSpecificFundamentalTypesCheck.cpp | 65 ++++++++++++------- ...oidPlatformSpecificFundamentalTypesCheck.h | 8 ++- ...id-platform-specific-fundamental-types.rst | 24 +++---- 3 files changed, 60 insertions(+), 37 deletions(-) diff --git a/clang-tools-extra/clang-tidy/portability/AvoidPlatformSpecificFundamentalTypesCheck.cpp b/clang-tools-extra/clang-tidy/portability/AvoidPlatformSpecificFundamentalTypesCheck.cpp index fb31952205c52..8b1ef50877b1e 100644 --- a/clang-tools-extra/clang-tidy/portability/AvoidPlatformSpecificFundamentalTypesCheck.cpp +++ b/clang-tools-extra/clang-tidy/portability/AvoidPlatformSpecificFundamentalTypesCheck.cpp @@ -12,6 +12,7 @@ #include "clang/ASTMatchers/ASTMatchFinder.h" #include "clang/ASTMatchers/ASTMatchers.h" #include "clang/Basic/TargetInfo.h" +#include "llvm/Support/ErrorHandling.h" using namespace clang::ast_matchers; @@ -46,6 +47,22 @@ AST_MATCHER(clang::QualType, isBuiltinFloat) { } // namespace +template <> +struct clang::tidy::OptionEnumMapping { + static llvm::ArrayRef< + std::pair> + getEnumMapping() { + static constexpr std::pair + Mapping[] = { + {portability::AvoidPlatformSpecificFundamentalTypesCheck::IntegerReplacementStyle::Exact, "Exact"}, + {portability::AvoidPlatformSpecificFundamentalTypesCheck::IntegerReplacementStyle::Fast, "Fast"}, + {portability::AvoidPlatformSpecificFundamentalTypesCheck::IntegerReplacementStyle::Least, "Least"}, + }; + return {Mapping}; + } +}; + namespace clang::tidy::portability { AvoidPlatformSpecificFundamentalTypesCheck:: @@ -55,7 +72,7 @@ AvoidPlatformSpecificFundamentalTypesCheck:: WarnOnFloats(Options.get("WarnOnFloats", true)), WarnOnInts(Options.get("WarnOnInts", true)), WarnOnChars(Options.get("WarnOnChars", true)), - IntegerReplacementStyle(Options.get("IntegerReplacementStyle", "Exact")), + IntegerReplacementStyleValue(Options.get("IntegerReplacementStyle", IntegerReplacementStyle::Exact)), IncludeInserter(Options.getLocalOrGlobal("IncludeStyle", utils::IncludeSorter::IS_LLVM), areDiagsSelfContained()) { @@ -76,7 +93,7 @@ void AvoidPlatformSpecificFundamentalTypesCheck::storeOptions( Options.store(Opts, "WarnOnFloats", WarnOnFloats); Options.store(Opts, "WarnOnInts", WarnOnInts); Options.store(Opts, "WarnOnChars", WarnOnChars); - Options.store(Opts, "IntegerReplacementStyle", IntegerReplacementStyle); + Options.store(Opts, "IntegerReplacementStyle", IntegerReplacementStyleValue); Options.store(Opts, "IncludeStyle", IncludeInserter.getStyle()); } @@ -119,37 +136,35 @@ static std::optional getFloatReplacement(const BuiltinType *BT, } } -static std::optional getIntegerReplacement(const BuiltinType *BT, - ASTContext &Context, - StringRef Style) { +static std::optional getIntegerReplacement( + const BuiltinType *BT, ASTContext &Context, + AvoidPlatformSpecificFundamentalTypesCheck::IntegerReplacementStyle Style) { const TargetInfo &Target = Context.getTargetInfo(); - auto GetReplacementType = [&Style](unsigned Width, bool IsSigned) -> std::optional { - std::string Prefix; - std::string Suffix; - - if (Style == "Exact") { - Prefix = IsSigned ? "int" : "uint"; - Suffix = "_t"; - } else if (Style == "Fast") { - Prefix = IsSigned ? "int_fast" : "uint_fast"; - Suffix = "_t"; - } else if (Style == "Least") { - Prefix = IsSigned ? "int_least" : "uint_least"; - Suffix = "_t"; - } else { - return std::nullopt; + auto GetReplacementType = [Style](unsigned Width, bool IsSigned) -> std::optional { + std::string Prefix = [Style, IsSigned](){ + std::string SignedPrefix = IsSigned ? "int" : "uint"; + switch (Style) { + case AvoidPlatformSpecificFundamentalTypesCheck::IntegerReplacementStyle::Exact: + return SignedPrefix; + case AvoidPlatformSpecificFundamentalTypesCheck::IntegerReplacementStyle::Fast: + return SignedPrefix + "_fast"; + case AvoidPlatformSpecificFundamentalTypesCheck::IntegerReplacementStyle::Least: + return SignedPrefix + "_least"; + default: + llvm_unreachable("Invalid integer replacement style"); } + }(); switch (Width) { case 8U: - return Prefix + "8" + Suffix; + return Prefix + "8_t"; case 16U: - return Prefix + "16" + Suffix; + return Prefix + "16_t"; case 32U: - return Prefix + "32" + Suffix; + return Prefix + "32_t"; case 64U: - return Prefix + "64" + Suffix; + return Prefix + "64_t"; default: return std::nullopt; } @@ -238,7 +253,7 @@ void AvoidPlatformSpecificFundamentalTypesCheck::check( << TypeName; } else { // Handle integer types - const auto Replacement = getIntegerReplacement(BT, *Result.Context, IntegerReplacementStyle); + const auto Replacement = getIntegerReplacement(BT, *Result.Context, IntegerReplacementStyleValue); if (!Replacement.has_value()) { diag(Loc, "avoid using platform-dependent fundamental integer type '%0'; " diff --git a/clang-tools-extra/clang-tidy/portability/AvoidPlatformSpecificFundamentalTypesCheck.h b/clang-tools-extra/clang-tidy/portability/AvoidPlatformSpecificFundamentalTypesCheck.h index 97344d25b88b2..711d5d8f3b7d3 100644 --- a/clang-tools-extra/clang-tidy/portability/AvoidPlatformSpecificFundamentalTypesCheck.h +++ b/clang-tools-extra/clang-tidy/portability/AvoidPlatformSpecificFundamentalTypesCheck.h @@ -21,6 +21,12 @@ namespace clang::tidy::portability { /// https://clang.llvm.org/extra/clang-tidy/checks/portability/avoid-platform-specific-fundamental-types.html class AvoidPlatformSpecificFundamentalTypesCheck : public ClangTidyCheck { public: + enum class IntegerReplacementStyle { + Exact, // int32_t, uint32_t, etc. + Fast, // int_fast32_t, uint_fast32_t, etc. + Least // int_least32_t, uint_least32_t, etc. + }; + AvoidPlatformSpecificFundamentalTypesCheck(StringRef Name, ClangTidyContext *Context); void registerPPCallbacks(const SourceManager &SM, Preprocessor *PP, @@ -39,7 +45,7 @@ class AvoidPlatformSpecificFundamentalTypesCheck : public ClangTidyCheck { const bool WarnOnFloats; const bool WarnOnInts; const bool WarnOnChars; - const std::string IntegerReplacementStyle; + const IntegerReplacementStyle IntegerReplacementStyleValue; utils::IncludeInserter IncludeInserter; }; diff --git a/clang-tools-extra/docs/clang-tidy/checks/portability/avoid-platform-specific-fundamental-types.rst b/clang-tools-extra/docs/clang-tidy/checks/portability/avoid-platform-specific-fundamental-types.rst index cca88e5123f63..3d71e2ba87169 100644 --- a/clang-tools-extra/docs/clang-tidy/checks/portability/avoid-platform-specific-fundamental-types.rst +++ b/clang-tools-extra/docs/clang-tidy/checks/portability/avoid-platform-specific-fundamental-types.rst @@ -106,23 +106,25 @@ Options 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`. + ``unsigned`` variants). Default is `true`. .. option:: WarnOnFloats When `true`, the check will warn about floating point types - (``float`` and ``double``). - When `false`, floating point types are not flagged. - - Default is `true` + (``float`` and ``double``). Default is `true`. .. option:: WarnOnChars When `true`, the check will warn about character types (``char``, - ``signed char``, and ``unsigned char``). - When `false`, character types are not flagged. + ``signed char``, and ``unsigned char``). Default is `true`. + +.. option:: IntegerReplacementStyle + + Specifies the style of integer type replacements when ``WarnOnInts`` is + enabled. Default is `exact`. + + The possible values, and replacements for ``int`` when ``int`` is 32-bits: - Default is `true` + - ``"Exact"``: Replace with exact-width types (e.g., ``int`` → ``int32_t``) + - ``"Fast"``: Replace with fast minimum-width types (e.g., ``int`` → ``int_fast32_t``) + - ``"Least"``: Replace with least minimum-width types (e.g., ``int`` → ``int_least32_t``)