Skip to content

Commit f41310d

Browse files
committed
[clang-tidy] Fix cppcoreguidelines-pro-type-member-init check
1 parent a83e09a commit f41310d

File tree

3 files changed

+71
-2
lines changed

3 files changed

+71
-2
lines changed

clang-tools-extra/clang-tidy/cppcoreguidelines/ProTypeMemberInitCheck.cpp

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -361,7 +361,8 @@ void ProTypeMemberInitCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) {
361361
}
362362

363363
// FIXME: Copied from clang/lib/Sema/SemaDeclCXX.cpp.
364-
static bool isIncompleteOrZeroLengthArrayType(ASTContext &Context, QualType T) {
364+
static bool isIncompleteOrZeroLengthArrayType(const ASTContext &Context,
365+
QualType T) {
365366
if (T->isIncompleteArrayType())
366367
return true;
367368

@@ -375,7 +376,7 @@ static bool isIncompleteOrZeroLengthArrayType(ASTContext &Context, QualType T) {
375376
return false;
376377
}
377378

378-
static bool isEmpty(ASTContext &Context, const QualType &Type) {
379+
static bool isEmpty(const ASTContext &Context, const QualType &Type) {
379380
if (const CXXRecordDecl *ClassDecl = Type->getAsCXXRecordDecl()) {
380381
return ClassDecl->isEmpty();
381382
}
@@ -582,6 +583,33 @@ void ProTypeMemberInitCheck::checkMissingBaseClassInitializer(
582583

583584
void ProTypeMemberInitCheck::checkUninitializedTrivialType(
584585
const ASTContext &Context, const VarDecl *Var) {
586+
// Verify that the record actually needs initialization
587+
const CXXRecordDecl *Record = Var->getType()->getAsCXXRecordDecl();
588+
if (!Record)
589+
return;
590+
591+
SmallPtrSet<const FieldDecl *, 16> FieldsToInit;
592+
bool AnyMemberHasInitPerUnion = false;
593+
forEachFieldWithFilter(
594+
*Record, Record->fields(), AnyMemberHasInitPerUnion,
595+
[&](const FieldDecl *F) {
596+
if (IgnoreArrays && F->getType()->isArrayType())
597+
return;
598+
if (F->hasInClassInitializer() && F->getParent()->isUnion()) {
599+
AnyMemberHasInitPerUnion = true;
600+
removeFieldInitialized(F, FieldsToInit);
601+
}
602+
if (!F->hasInClassInitializer() &&
603+
utils::type_traits::isTriviallyDefaultConstructible(F->getType(),
604+
Context) &&
605+
!isEmpty(Context, F->getType()) && !F->isUnnamedBitField() &&
606+
!AnyMemberHasInitPerUnion)
607+
FieldsToInit.insert(F);
608+
});
609+
610+
if (FieldsToInit.empty())
611+
return;
612+
585613
const DiagnosticBuilder Diag =
586614
diag(Var->getBeginLoc(), "uninitialized record type: %0") << Var;
587615

clang-tools-extra/docs/ReleaseNotes.rst

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -424,6 +424,11 @@ Changes in existing checks
424424
adding an option to allow pointer arithmetic via prefix/postfix increment or
425425
decrement operators.
426426

427+
- Improved :doc:`cppcoreguidelines-pro-type-member-init
428+
<clang-tidy/checks/cppcoreguidelines/pro-type-member-init>` check to
429+
correctly ignore ``std::array`` and other containers when ``IgnoreArrays``
430+
option is set to ``true``.
431+
427432
- Improved :doc:`google-readability-casting
428433
<clang-tidy/checks/google/readability-casting>` check by adding fix-it
429434
notes for downcasts and casts to void pointer.

clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/pro-type-member-init.ignorearrays.cpp

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,3 +14,39 @@ struct HasArrayMember {
1414
int RawArray[4];
1515
int Number;
1616
};
17+
18+
namespace std {
19+
template <typename T, int N>
20+
struct array {
21+
T _Elems[N];
22+
void fill(const T &);
23+
};
24+
}
25+
26+
void test_local_std_array() {
27+
std::array<int, 4> a;
28+
}
29+
30+
struct OnlyArray {
31+
int a[4];
32+
};
33+
34+
void test_local_only_array() {
35+
OnlyArray a;
36+
}
37+
38+
struct Mixed {
39+
int a[4];
40+
int b;
41+
};
42+
43+
void test_local_mixed() {
44+
Mixed m;
45+
// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: uninitialized record type: 'm'
46+
}
47+
48+
void test_std_array_fill() {
49+
std::array<char, 10> someArray;
50+
// CHECK-MESSAGES-NOT: warning: uninitialized record type: 'someArray'
51+
someArray.fill('n');
52+
}

0 commit comments

Comments
 (0)