https://github.com/zeyi2 created https://github.com/llvm/llvm-project/pull/169832
Closes [#169677](https://github.com/llvm/llvm-project/issues/169677) >From f41310dcb601075d980c4d7163d8db1d5dee7913 Mon Sep 17 00:00:00 2001 From: mtx <[email protected]> Date: Thu, 27 Nov 2025 23:50:47 +0800 Subject: [PATCH] [clang-tidy] Fix `cppcoreguidelines-pro-type-member-init` check --- .../ProTypeMemberInitCheck.cpp | 32 +++++++++++++++-- clang-tools-extra/docs/ReleaseNotes.rst | 5 +++ .../pro-type-member-init.ignorearrays.cpp | 36 +++++++++++++++++++ 3 files changed, 71 insertions(+), 2 deletions(-) diff --git a/clang-tools-extra/clang-tidy/cppcoreguidelines/ProTypeMemberInitCheck.cpp b/clang-tools-extra/clang-tidy/cppcoreguidelines/ProTypeMemberInitCheck.cpp index 66508da89f0dd..f8c096b4b4c66 100644 --- a/clang-tools-extra/clang-tidy/cppcoreguidelines/ProTypeMemberInitCheck.cpp +++ b/clang-tools-extra/clang-tidy/cppcoreguidelines/ProTypeMemberInitCheck.cpp @@ -361,7 +361,8 @@ void ProTypeMemberInitCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) { } // FIXME: Copied from clang/lib/Sema/SemaDeclCXX.cpp. -static bool isIncompleteOrZeroLengthArrayType(ASTContext &Context, QualType T) { +static bool isIncompleteOrZeroLengthArrayType(const ASTContext &Context, + QualType T) { if (T->isIncompleteArrayType()) return true; @@ -375,7 +376,7 @@ static bool isIncompleteOrZeroLengthArrayType(ASTContext &Context, QualType T) { return false; } -static bool isEmpty(ASTContext &Context, const QualType &Type) { +static bool isEmpty(const ASTContext &Context, const QualType &Type) { if (const CXXRecordDecl *ClassDecl = Type->getAsCXXRecordDecl()) { return ClassDecl->isEmpty(); } @@ -582,6 +583,33 @@ void ProTypeMemberInitCheck::checkMissingBaseClassInitializer( void ProTypeMemberInitCheck::checkUninitializedTrivialType( const ASTContext &Context, const VarDecl *Var) { + // Verify that the record actually needs initialization + const CXXRecordDecl *Record = Var->getType()->getAsCXXRecordDecl(); + if (!Record) + return; + + SmallPtrSet<const FieldDecl *, 16> FieldsToInit; + bool AnyMemberHasInitPerUnion = false; + forEachFieldWithFilter( + *Record, Record->fields(), AnyMemberHasInitPerUnion, + [&](const FieldDecl *F) { + if (IgnoreArrays && F->getType()->isArrayType()) + return; + if (F->hasInClassInitializer() && F->getParent()->isUnion()) { + AnyMemberHasInitPerUnion = true; + removeFieldInitialized(F, FieldsToInit); + } + if (!F->hasInClassInitializer() && + utils::type_traits::isTriviallyDefaultConstructible(F->getType(), + Context) && + !isEmpty(Context, F->getType()) && !F->isUnnamedBitField() && + !AnyMemberHasInitPerUnion) + FieldsToInit.insert(F); + }); + + if (FieldsToInit.empty()) + return; + const DiagnosticBuilder Diag = diag(Var->getBeginLoc(), "uninitialized record type: %0") << Var; diff --git a/clang-tools-extra/docs/ReleaseNotes.rst b/clang-tools-extra/docs/ReleaseNotes.rst index a6f80e3721db1..3ad2ffc07da5c 100644 --- a/clang-tools-extra/docs/ReleaseNotes.rst +++ b/clang-tools-extra/docs/ReleaseNotes.rst @@ -424,6 +424,11 @@ Changes in existing checks adding an option to allow pointer arithmetic via prefix/postfix increment or decrement operators. +- Improved :doc:`cppcoreguidelines-pro-type-member-init + <clang-tidy/checks/cppcoreguidelines/pro-type-member-init>` check to + correctly ignore ``std::array`` and other containers when ``IgnoreArrays`` + option is set to ``true``. + - Improved :doc:`google-readability-casting <clang-tidy/checks/google/readability-casting>` check by adding fix-it notes for downcasts and casts to void pointer. diff --git a/clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/pro-type-member-init.ignorearrays.cpp b/clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/pro-type-member-init.ignorearrays.cpp index 01859b3ad98f4..e4cfe679cfce9 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/pro-type-member-init.ignorearrays.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/pro-type-member-init.ignorearrays.cpp @@ -14,3 +14,39 @@ struct HasArrayMember { int RawArray[4]; int Number; }; + +namespace std { +template <typename T, int N> +struct array { + T _Elems[N]; + void fill(const T &); +}; +} + +void test_local_std_array() { + std::array<int, 4> a; +} + +struct OnlyArray { + int a[4]; +}; + +void test_local_only_array() { + OnlyArray a; +} + +struct Mixed { + int a[4]; + int b; +}; + +void test_local_mixed() { + Mixed m; + // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: uninitialized record type: 'm' +} + +void test_std_array_fill() { + std::array<char, 10> someArray; + // CHECK-MESSAGES-NOT: warning: uninitialized record type: 'someArray' + someArray.fill('n'); +} _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
