@@ -11293,9 +11293,16 @@ static bool AnalyzeBitFieldAssignment(Sema &S, FieldDecl *Bitfield, Expr *Init,
1129311293 // The RHS is not constant. If the RHS has an enum type, make sure the
1129411294 // bitfield is wide enough to hold all the values of the enum without
1129511295 // 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) {
1129711304 EnumDecl *ED = EnumTy->getDecl();
11298- bool SignedBitfield = BitfieldType->isSignedIntegerType ();
11305+ bool SignedBitfield = BitfieldType->isSignedIntegerOrEnumerationType ();
1129911306
1130011307 // Enum types are implicitly signed on Windows, so check if there are any
1130111308 // 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,
1130911316 // on Windows where unfixed enums always use an underlying type of 'int'.
1131011317 unsigned DiagID = 0;
1131111318 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;
1131311324 } else if (SignedBitfield && !SignedEnum &&
1131411325 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;
1131611330 }
11317-
1131811331 if (DiagID) {
1131911332 S.Diag(InitLoc, DiagID) << Bitfield << ED;
1132011333 TypeSourceInfo *TSI = Bitfield->getTypeSourceInfo();
1132111334 SourceRange TypeRange =
1132211335 TSI ? TSI->getTypeLoc().getSourceRange() : SourceRange();
1132311336 S.Diag(Bitfield->getTypeSpecStartLoc(), diag::note_change_bitfield_sign)
1132411337 << SignedEnum << TypeRange;
11338+ if (PTAttr)
11339+ S.Diag(PTAttr->getLocation(), diag::note_bitfield_preferred_type)
11340+ << ED;
1132511341 }
1132611342
1132711343 // 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,
1133411350 // Check the bitwidth.
1133511351 if (BitsNeeded > FieldWidth) {
1133611352 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;
1133911358 S.Diag(WidthExpr->getExprLoc(), diag::note_widen_bitfield)
1134011359 << BitsNeeded << ED << WidthExpr->getSourceRange();
11360+ if (PTAttr)
11361+ S.Diag(PTAttr->getLocation(), diag::note_bitfield_preferred_type)
11362+ << ED;
1134111363 }
1134211364 }
1134311365
0 commit comments