@@ -11293,9 +11293,16 @@ static bool AnalyzeBitFieldAssignment(Sema &S, FieldDecl *Bitfield, Expr *Init,
11293
11293
// The RHS is not constant. If the RHS has an enum type, make sure the
11294
11294
// bitfield is wide enough to hold all the values of the enum without
11295
11295
// truncation.
11296
- if (const auto *EnumTy = OriginalInit->getType()->getAs<EnumType>()) {
11296
+ const auto *EnumTy = OriginalInit->getType()->getAs<EnumType>();
11297
+ const PreferredTypeAttr *PTAttr = nullptr;
11298
+ if (!EnumTy) {
11299
+ PTAttr = Bitfield->getAttr<PreferredTypeAttr>();
11300
+ if (PTAttr)
11301
+ EnumTy = PTAttr->getType()->getAs<EnumType>();
11302
+ }
11303
+ if (EnumTy) {
11297
11304
EnumDecl *ED = EnumTy->getDecl();
11298
- bool SignedBitfield = BitfieldType->isSignedIntegerType ();
11305
+ bool SignedBitfield = BitfieldType->isSignedIntegerOrEnumerationType ();
11299
11306
11300
11307
// Enum types are implicitly signed on Windows, so check if there are any
11301
11308
// negative enumerators to see if the enum was intended to be signed or
@@ -11309,19 +11316,28 @@ static bool AnalyzeBitFieldAssignment(Sema &S, FieldDecl *Bitfield, Expr *Init,
11309
11316
// on Windows where unfixed enums always use an underlying type of 'int'.
11310
11317
unsigned DiagID = 0;
11311
11318
if (SignedEnum && !SignedBitfield) {
11312
- DiagID = diag::warn_unsigned_bitfield_assigned_signed_enum;
11319
+ DiagID =
11320
+ PTAttr == nullptr
11321
+ ? diag::warn_unsigned_bitfield_assigned_signed_enum
11322
+ : diag::
11323
+ warn_preferred_type_unsigned_bitfield_assigned_signed_enum;
11313
11324
} else if (SignedBitfield && !SignedEnum &&
11314
11325
ED->getNumPositiveBits() == FieldWidth) {
11315
- DiagID = diag::warn_signed_bitfield_enum_conversion;
11326
+ DiagID =
11327
+ PTAttr == nullptr
11328
+ ? diag::warn_signed_bitfield_enum_conversion
11329
+ : diag::warn_preferred_type_signed_bitfield_enum_conversion;
11316
11330
}
11317
-
11318
11331
if (DiagID) {
11319
11332
S.Diag(InitLoc, DiagID) << Bitfield << ED;
11320
11333
TypeSourceInfo *TSI = Bitfield->getTypeSourceInfo();
11321
11334
SourceRange TypeRange =
11322
11335
TSI ? TSI->getTypeLoc().getSourceRange() : SourceRange();
11323
11336
S.Diag(Bitfield->getTypeSpecStartLoc(), diag::note_change_bitfield_sign)
11324
11337
<< SignedEnum << TypeRange;
11338
+ if (PTAttr)
11339
+ S.Diag(PTAttr->getLocation(), diag::note_bitfield_preferred_type)
11340
+ << ED;
11325
11341
}
11326
11342
11327
11343
// Compute the required bitwidth. If the enum has negative values, we need
@@ -11334,10 +11350,16 @@ static bool AnalyzeBitFieldAssignment(Sema &S, FieldDecl *Bitfield, Expr *Init,
11334
11350
// Check the bitwidth.
11335
11351
if (BitsNeeded > FieldWidth) {
11336
11352
Expr *WidthExpr = Bitfield->getBitWidth();
11337
- S.Diag(InitLoc, diag::warn_bitfield_too_small_for_enum)
11338
- << Bitfield << ED;
11353
+ auto DiagID =
11354
+ PTAttr == nullptr
11355
+ ? diag::warn_bitfield_too_small_for_enum
11356
+ : diag::warn_preferred_type_bitfield_too_small_for_enum;
11357
+ S.Diag(InitLoc, DiagID) << Bitfield << ED;
11339
11358
S.Diag(WidthExpr->getExprLoc(), diag::note_widen_bitfield)
11340
11359
<< BitsNeeded << ED << WidthExpr->getSourceRange();
11360
+ if (PTAttr)
11361
+ S.Diag(PTAttr->getLocation(), diag::note_bitfield_preferred_type)
11362
+ << ED;
11341
11363
}
11342
11364
}
11343
11365
0 commit comments