Skip to content

Conversation

@zeyi2
Copy link
Member

@zeyi2 zeyi2 commented Nov 27, 2025

Closes #169677

@llvmbot
Copy link
Member

llvmbot commented Nov 27, 2025

@llvm/pr-subscribers-clang-tools-extra

@llvm/pr-subscribers-clang-tidy

Author: mitchell (zeyi2)

Changes

Closes #169677


Full diff: https://github.com/llvm/llvm-project/pull/169832.diff

3 Files Affected:

  • (modified) clang-tools-extra/clang-tidy/cppcoreguidelines/ProTypeMemberInitCheck.cpp (+30-2)
  • (modified) clang-tools-extra/docs/ReleaseNotes.rst (+5)
  • (modified) clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/pro-type-member-init.ignorearrays.cpp (+36)
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');
+}

Co-authored-by: EugeneZelenko <eugene.zelenko@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[clang-tidy] cppcoreguidelines-pro-type-member-init check flags local variables of std::array<> type

3 participants