[clang-tidy] Don't use assignment for value-initialized enums

Summary:
The modernize-use-default-member-init check crashes when trying to
create an assignment value for a value-initialized enum because it isn't a
BuiltinType.
An enum cannot be initialized by assigning 0 to it unless a cast is added.
It could be initialized with an enumerator with the value 0, but there might not
be one.
Avoid these issues by ignoring the UseAssignment setting for value-initialized
enums.

Fixes PR35050.

Reviewers: aaron.ballman, alexfh, JonasToth

Reviewed By: JonasToth

Subscribers: xazax.hun, cfe-commits

Tags: #clang

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

llvm-svn: 353554
This commit is contained in:
Malcolm Parsons 2019-02-08 19:44:42 +00:00
parent 01e818a97d
commit 297b6a2b6e
3 changed files with 22 additions and 3 deletions

View File

@ -255,17 +255,20 @@ void UseDefaultMemberInitCheck::checkDefaultInit(
CharSourceRange InitRange =
CharSourceRange::getCharRange(LParenEnd, Init->getRParenLoc());
bool ValueInit = isa<ImplicitValueInitExpr>(Init->getInit());
bool CanAssign = UseAssignment && (!ValueInit || !Init->getInit()->getType()->isEnumeralType());
auto Diag =
diag(Field->getLocation(), "use default member initializer for %0")
<< Field
<< FixItHint::CreateInsertion(FieldEnd, UseAssignment ? " = " : "{")
<< FixItHint::CreateInsertion(FieldEnd, CanAssign ? " = " : "{")
<< FixItHint::CreateInsertionFromRange(FieldEnd, InitRange);
if (UseAssignment && isa<ImplicitValueInitExpr>(Init->getInit()))
if (CanAssign && ValueInit)
Diag << FixItHint::CreateInsertion(
FieldEnd, getValueOfValueInit(Init->getInit()->getType()));
if (!UseAssignment)
if (!CanAssign)
Diag << FixItHint::CreateInsertion(FieldEnd, "}");
Diag << FixItHint::CreateRemoval(Init->getSourceRange());

View File

@ -166,6 +166,14 @@ struct PositiveEnum {
// CHECK-FIXES: Enum e = Foo;
};
struct PositiveValueEnum {
PositiveValueEnum() : e() {}
// CHECK-FIXES: PositiveValueEnum() {}
Enum e;
// CHECK-MESSAGES: :[[@LINE-1]]:8: warning: use default member initializer for 'e'
// CHECK-FIXES: Enum e{};
};
struct PositiveString {
PositiveString() : s("foo") {}
// CHECK-FIXES: PositiveString() {}

View File

@ -165,6 +165,14 @@ struct PositiveEnum {
// CHECK-FIXES: Enum e{Foo};
};
struct PositiveValueEnum {
PositiveValueEnum() : e() {}
// CHECK-FIXES: PositiveValueEnum() {}
Enum e;
// CHECK-MESSAGES: :[[@LINE-1]]:8: warning: use default member initializer for 'e'
// CHECK-FIXES: Enum e{};
};
struct PositiveString {
PositiveString() : s("foo") {}
// CHECK-FIXES: PositiveString() {}