[clang-tidy] Ignore empty members and bases in cppcoreguidelines-pro-type-member-init

Summary: Empty/incomplete variables/members/bases don't need to be initialized

Reviewers: mgehre, aaron.ballman, alexfh

Subscribers: nemanjai, cfe-commits

Differential Revision: https://reviews.llvm.org/D25238

llvm-svn: 283886
This commit is contained in:
Malcolm Parsons 2016-10-11 14:49:24 +00:00
parent 38a42e4bfa
commit 66b7014092
2 changed files with 51 additions and 1 deletions

View File

@ -317,6 +317,28 @@ void ProTypeMemberInitCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) {
Options.store(Opts, "IgnoreArrays", IgnoreArrays);
}
// FIXME: Copied from clang/lib/Sema/SemaDeclCXX.cpp.
static bool isIncompleteOrZeroLengthArrayType(ASTContext &Context, QualType T) {
if (T->isIncompleteArrayType())
return true;
while (const ConstantArrayType *ArrayT = Context.getAsConstantArrayType(T)) {
if (!ArrayT->getSize())
return true;
T = ArrayT->getElementType();
}
return false;
}
static bool isEmpty(ASTContext &Context, const QualType &Type) {
if (const CXXRecordDecl *ClassDecl = Type->getAsCXXRecordDecl()) {
return ClassDecl->isEmpty();
}
return isIncompleteOrZeroLengthArrayType(Context, Type);
}
void ProTypeMemberInitCheck::checkMissingMemberInitializer(
ASTContext &Context, const CXXRecordDecl &ClassDecl,
const CXXConstructorDecl *Ctor) {
@ -330,7 +352,8 @@ void ProTypeMemberInitCheck::checkMissingMemberInitializer(
forEachField(ClassDecl, ClassDecl.fields(), false, [&](const FieldDecl *F) {
if (!F->hasInClassInitializer() &&
utils::type_traits::isTriviallyDefaultConstructible(F->getType(),
Context))
Context) &&
!isEmpty(Context, F->getType()))
FieldsToInit.insert(F);
});
if (FieldsToInit.empty())

View File

@ -423,3 +423,30 @@ UNINITIALIZED_FIELD_IN_MACRO_BODY_VIRTUAL(F);
// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: constructor does not initialize these fields: F
UNINITIALIZED_FIELD_IN_MACRO_BODY_VIRTUAL(G);
// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: constructor does not initialize these fields: G
struct NegativeEmpty {
};
static void NegativeEmptyVar() {
NegativeEmpty e;
(void)e;
}
struct NegativeEmptyMember {
NegativeEmptyMember() {}
NegativeEmpty e;
};
struct NegativeEmptyBase : NegativeEmpty {
NegativeEmptyBase() {}
};
struct NegativeEmptyArrayMember {
NegativeEmptyArrayMember() {}
char e[0];
};
struct NegativeIncompleteArrayMember {
NegativeIncompleteArrayMember() {}
char e[];
};