[clang] [Clang] Consider preferred_type in bitfield warnings (#116760) (PR #116785)

Oliver Hunt via cfe-commits cfe-commits at lists.llvm.org
Sat Apr 12 23:30:03 PDT 2025


https://github.com/ojhunt updated https://github.com/llvm/llvm-project/pull/116785

>From 5f260726253e78a00d2dff02c22837ce02b49075 Mon Sep 17 00:00:00 2001
From: Oliver Hunt <oliver at apple.com>
Date: Tue, 19 Nov 2024 11:55:11 +0100
Subject: [PATCH 1/9] [Clang] Consider preferred_type in bitfield warnings
 (#116760)

Very simply extends the bitfield sema checks for assignment to fields
with a preferred type specified to consider the preferred type if the
decl storage type is not explicitly an enum type.

This does mean that if the preferred and explicit types have different
storage requirements we may not warn in all possible cases, but that's
a scenario for which the warnings are much more complex and confusing.
---
 .../clang/Basic/DiagnosticSemaKinds.td        |   9 +-
 clang/lib/Sema/SemaChecking.cpp               |  23 +-
 .../Sema/bitfield-preferred-type-sizing.c     | 108 +++++
 .../bitfield-preferred-type-sizing.cpp        | 413 ++++++++++++++++++
 4 files changed, 546 insertions(+), 7 deletions(-)
 create mode 100644 clang/test/Sema/bitfield-preferred-type-sizing.c
 create mode 100644 clang/test/SemaCXX/bitfield-preferred-type-sizing.cpp

diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 3caf471d3037f..226b52f58d88d 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -6404,20 +6404,23 @@ def warn_bitfield_width_exceeds_type_width: Warning<
 def err_bitfield_too_wide : Error<
   "%select{bit-field %1|anonymous bit-field}0 is too wide (%2 bits)">;
 def warn_bitfield_too_small_for_enum : Warning<
-  "bit-field %0 is not wide enough to store all enumerators of %1">,
+  "bit-field %0 is not wide enough to store all enumerators of %select{|preferred type }1%2">,
   InGroup<BitFieldEnumConversion>, DefaultIgnore;
 def note_widen_bitfield : Note<
   "widen this field to %0 bits to store all values of %1">;
 def warn_unsigned_bitfield_assigned_signed_enum : Warning<
-  "assigning value of signed enum type %1 to unsigned bit-field %0; "
+  "assigning value of %select{|preferred }1signed enum type %2 to unsigned bit-field %0; "
   "negative enumerators of enum %1 will be converted to positive values">,
   InGroup<BitFieldEnumConversion>, DefaultIgnore;
 def warn_signed_bitfield_enum_conversion : Warning<
   "signed bit-field %0 needs an extra bit to represent the largest positive "
-  "enumerators of %1">,
+  "enumerators of %select{|preferred type }1%2">,
   InGroup<BitFieldEnumConversion>, DefaultIgnore;
 def note_change_bitfield_sign : Note<
   "consider making the bitfield type %select{unsigned|signed}0">;
+def note_bitfield_preferred_type : Note<
+  "preferred type for bitfield %0 specified here"
+>;
 
 def warn_missing_braces : Warning<
   "suggest braces around initialization of subobject">,
diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp
index 2d4a7cd287b70..254284e950c7e 100644
--- a/clang/lib/Sema/SemaChecking.cpp
+++ b/clang/lib/Sema/SemaChecking.cpp
@@ -10488,7 +10488,14 @@ static bool AnalyzeBitFieldAssignment(Sema &S, FieldDecl *Bitfield, Expr *Init,
     // The RHS is not constant.  If the RHS has an enum type, make sure the
     // bitfield is wide enough to hold all the values of the enum without
     // truncation.
-    if (const auto *EnumTy = OriginalInit->getType()->getAs<EnumType>()) {
+    const auto *EnumTy = OriginalInit->getType()->getAs<EnumType>();
+    const PreferredTypeAttr *PTAttr = nullptr;
+    if (!EnumTy) {
+      PTAttr = Bitfield->getAttr<PreferredTypeAttr>();
+      if (PTAttr)
+        EnumTy = PTAttr->getType()->getAs<EnumType>();
+    }
+    if (EnumTy) {
       EnumDecl *ED = EnumTy->getDecl();
       bool SignedBitfield = BitfieldType->isSignedIntegerType();
 
@@ -10509,14 +10516,18 @@ static bool AnalyzeBitFieldAssignment(Sema &S, FieldDecl *Bitfield, Expr *Init,
                  ED->getNumPositiveBits() == FieldWidth) {
         DiagID = diag::warn_signed_bitfield_enum_conversion;
       }
-
+      unsigned PreferredTypeDiagIndex = PTAttr != nullptr;
       if (DiagID) {
-        S.Diag(InitLoc, DiagID) << Bitfield << ED;
+        S.Diag(InitLoc, DiagID) << Bitfield << PreferredTypeDiagIndex << ED;
         TypeSourceInfo *TSI = Bitfield->getTypeSourceInfo();
         SourceRange TypeRange =
             TSI ? TSI->getTypeLoc().getSourceRange() : SourceRange();
         S.Diag(Bitfield->getTypeSpecStartLoc(), diag::note_change_bitfield_sign)
             << SignedEnum << TypeRange;
+        if (PTAttr) {
+          S.Diag(PTAttr->getLocation(), diag::note_bitfield_preferred_type)
+              << ED;
+        }
       }
 
       // Compute the required bitwidth. If the enum has negative values, we need
@@ -10530,9 +10541,13 @@ static bool AnalyzeBitFieldAssignment(Sema &S, FieldDecl *Bitfield, Expr *Init,
       if (BitsNeeded > FieldWidth) {
         Expr *WidthExpr = Bitfield->getBitWidth();
         S.Diag(InitLoc, diag::warn_bitfield_too_small_for_enum)
-            << Bitfield << ED;
+            << Bitfield << PreferredTypeDiagIndex << ED;
         S.Diag(WidthExpr->getExprLoc(), diag::note_widen_bitfield)
             << BitsNeeded << ED << WidthExpr->getSourceRange();
+        if (PTAttr) {
+          S.Diag(PTAttr->getLocation(), diag::note_bitfield_preferred_type)
+              << ED;
+        }
       }
     }
 
diff --git a/clang/test/Sema/bitfield-preferred-type-sizing.c b/clang/test/Sema/bitfield-preferred-type-sizing.c
new file mode 100644
index 0000000000000..16d48bc0692df
--- /dev/null
+++ b/clang/test/Sema/bitfield-preferred-type-sizing.c
@@ -0,0 +1,108 @@
+// RUN: %clang_cc1 %s -fsyntax-only -verify -std=c11 -Wno-unused-value -Wno-unused-but-set-variable -Wbitfield-width -Wbitfield-enum-conversion
+
+enum A {
+  A_a,
+  A_b,
+  A_c,
+  A_d
+};
+
+struct S {
+  enum A a1 : 1; // #1
+  enum A a2 : 2;
+  enum A a3 : 8;
+  __attribute__((preferred_type(enum A))) // #preferred_a4
+  unsigned a4 : 1; // #2
+  __attribute__((preferred_type(enum A)))
+  unsigned a5 : 2;
+  __attribute__((preferred_type(enum A)))
+  unsigned a6 : 8;
+  __attribute__((preferred_type(enum A)))  // #preferred_a7
+  int a7 : 1; // #3
+  __attribute__((preferred_type(enum A))) // #preferred_a8
+  int a8 : 2; // #4
+  __attribute__((preferred_type(enum A)))
+  int a9 : 8;
+};
+
+void read_enum(struct S *s) {
+  enum A x;
+  x = s->a1;
+  x = s->a2;
+  x = s->a3;
+  x = s->a4;
+  x = s->a5;
+  x = s->a6;
+  x = s->a7;
+  x = s->a8;
+  x = s->a9;
+}
+
+void write_enum(struct S *s, enum A x) {
+  s->a1 = x;
+  // expected-warning at -1 {{bit-field 'a1' is not wide enough to store all enumerators of 'A'}}
+  // expected-note@#1 {{widen this field to 2 bits to store all values of 'A'}}
+  s->a2 = x;
+  s->a3 = x;
+  s->a4 = x;
+  // expected-warning at -1 {{bit-field 'a4' is not wide enough to store all enumerators of 'A'}}
+  // expected-note@#2 {{widen this field to 2 bits to store all values of 'A'}}
+  s->a5 = x;
+  s->a6 = x;
+  s->a7 = x;
+  // expected-warning at -1 {{bit-field 'a7' is not wide enough to store all enumerators of 'A'}}
+  // expected-note@#3 {{widen this field to 2 bits to store all values of 'A'}}
+  s->a8 = x;
+  // expected-warning at -1 {{signed bit-field 'a8' needs an extra bit to represent the largest positive enumerators of 'A'}}
+  // expected-note@#4 {{consider making the bitfield type unsigned}}
+  s->a9 = x;
+}
+
+void write_enum_int(struct S *s, int x) {
+  s->a1 = x;
+  s->a2 = x;
+  s->a3 = x;
+  s->a4 = x;
+  // expected-warning at -1 {{bit-field 'a4' is not wide enough to store all enumerators of preferred type 'A'}}
+  // expected-note@#2 {{widen this field to 2 bits to store all values of 'A'}}
+  // expected-note@#preferred_a4 {{preferred type for bitfield 'A' specified here}}
+  s->a5 = x;
+  s->a6 = x;
+  s->a7 = x;
+  // expected-warning at -1 {{bit-field 'a7' is not wide enough to store all enumerators of preferred type 'A'}}
+  // expected-note@#3 {{widen this field to 2 bits to store all values of 'A'}}
+  // expected-note@#preferred_a7 {{preferred type for bitfield 'A' specified here}}
+  s->a8 = x;
+  // expected-warning at -1 {{signed bit-field 'a8' needs an extra bit to represent the largest positive enumerators of preferred type 'A'}}
+  // expected-note@#4 {{consider making the bitfield type unsigned}}
+  // expected-note@#preferred_a8 {{preferred type for bitfield 'A' specified here}}
+  s->a9 = x;
+}
+
+void write_low_constant(struct S *s) {
+  s->a1 = A_a;
+  s->a2 = A_a;
+  s->a3 = A_a;
+  s->a4 = A_a;
+  s->a5 = A_a;
+  s->a6 = A_a;
+  s->a7 = A_a;
+  s->a8 = A_a;
+  s->a9 = A_a;
+};
+
+void write_high_constant(struct S *s) {
+  s->a1 = A_d;
+  // expected-warning at -1 {{implicit truncation from 'int' to bit-field changes value from 3 to 1}}
+  s->a2 = A_d;
+  s->a3 = A_d;
+  s->a4 = A_d;
+  // expected-warning at -1 {{implicit truncation from 'int' to bit-field changes value from 3 to 1}}
+  s->a5 = A_d;
+  s->a6 = A_d;
+  s->a7 = A_d;
+  // expected-warning at -1 {{implicit truncation from 'int' to bit-field changes value from 3 to -1}}
+  s->a8 = A_d;
+  // expected-warning at -1 {{implicit truncation from 'int' to bit-field changes value from 3 to -1}}
+  s->a9 = A_d;
+};
diff --git a/clang/test/SemaCXX/bitfield-preferred-type-sizing.cpp b/clang/test/SemaCXX/bitfield-preferred-type-sizing.cpp
new file mode 100644
index 0000000000000..5e39d2ac2ba32
--- /dev/null
+++ b/clang/test/SemaCXX/bitfield-preferred-type-sizing.cpp
@@ -0,0 +1,413 @@
+// RUN: %clang_cc1 %s -fsyntax-only -verify -std=c++23 -Wno-unused-value -Wno-unused-but-set-variable -Wbitfield-width -Wbitfield-enum-conversion
+
+// This is more complex than the C version because the user can specify the
+// storage type 
+
+enum A {
+  A_a,
+  A_b,
+  A_c,
+  A_d
+};
+
+enum class B : int {
+  a,
+  b,
+  c,
+  d
+};
+
+enum class C : unsigned {
+  a,
+  b,
+  c,
+  d
+};
+
+enum class Derp : unsigned {
+  a,
+  b
+};
+
+// Not using templates here so we can more easily distinguish the responsible
+// party for each warning
+
+struct S_A {
+  A field1 : 1; // #S_A_field1
+  A field2 : 2; // #S_A_field2
+  A field3 : 8; // #S_A_field3
+  __attribute__((preferred_type(A))) // #preferred_S_A_field4
+  unsigned field4 : 1; // #S_A_field4
+  __attribute__((preferred_type(A)))
+  unsigned field5 : 2; // #S_A_field5
+  __attribute__((preferred_type(A)))
+  unsigned field6 : 8; // #S_A_field6
+  __attribute__((preferred_type(A))) // #preferred_S_A_field7
+  int field7 : 1; // #S_A_field7
+  __attribute__((preferred_type(A))) // #preferred_S_A_field8
+  int field8 : 2; // #S_A_field8
+  __attribute__((preferred_type(A)))
+  int field9 : 8; // #S_A_field9
+  __attribute__((preferred_type(A)))
+  Derp field10 : 1; // #S_A_field10
+  __attribute__((preferred_type(A))) // #preferred_S_A_field11
+  Derp field11 : 2; // #S_A_field11
+  __attribute__((preferred_type(A)))
+  Derp field12 : 8; // #S_A_field12
+};
+
+struct S_B {
+  B field1 : 1; // #S_B_field1
+  B field2 : 2; // #S_B_field2
+  B field3 : 8; // #S_B_field3
+  __attribute__((preferred_type(B))) // #preferred_S_B_field4
+  unsigned field4 : 1; // #S_B_field4
+  __attribute__((preferred_type(B)))
+  unsigned field5 : 2; // #S_B_field5
+  __attribute__((preferred_type(B)))
+  unsigned field6 : 8; // #S_B_field6
+  __attribute__((preferred_type(B))) // #preferred_S_B_field7
+  int field7 : 1; // #S_B_field7
+  __attribute__((preferred_type(B))) // #preferred_S_B_field8
+  int field8 : 2; // #S_B_field8
+  __attribute__((preferred_type(B)))
+  int field9 : 8; // #S_B_field9
+  __attribute__((preferred_type(B)))
+  Derp field10 : 1; // #S_B_field10
+  __attribute__((preferred_type(B))) // #preferred_S_B_field11
+  Derp field11 : 2; // #S_B_field11
+  __attribute__((preferred_type(B)))
+  Derp field12 : 8; // #S_B_field12
+};
+
+struct S_C {
+  C field1 : 1; // #S_C_field1
+  C field2 : 2; // #S_C_field2
+  C field3 : 8; // #S_C_field3
+  __attribute__((preferred_type(C))) // #preferred_S_C_field4
+  unsigned field4 : 1; // #S_C_field4
+  __attribute__((preferred_type(C)))
+  unsigned field5 : 2; // #S_C_field5
+  __attribute__((preferred_type(C)))
+  unsigned field6 : 8; // #S_C_field6
+  __attribute__((preferred_type(C))) // #preferred_S_C_field7
+  int field7 : 1; // #S_C_field7
+  __attribute__((preferred_type(C))) // #preferred_S_C_field8
+  int field8 : 2; // #S_C_field8
+  __attribute__((preferred_type(C)))
+  int field9 : 8; // #S_C_field9
+  __attribute__((preferred_type(C)))
+  Derp field10 : 1; // #S_C_field10
+  __attribute__((preferred_type(C))) // #preferred_S_C_field11
+  Derp field11 : 2; // #S_C_field11
+  __attribute__((preferred_type(C)))
+  Derp field12 : 8; // #S_C_field12
+};
+
+void read_enum(S_A *s) {
+  using EnumType = A;
+  EnumType x;
+  x = s->field1;
+  x = s->field2;
+  x = s->field3;
+  x = (EnumType)s->field4;
+  x = (EnumType)s->field5;
+  x = (EnumType)s->field6;
+  x = (EnumType)s->field7;
+  x = (EnumType)s->field8;
+  x = (EnumType)s->field9;
+  x = (EnumType)s->field10;
+  x = (EnumType)s->field11;
+  x = (EnumType)s->field12;
+}
+
+void read_enum(S_B *s) {
+  using EnumType = B;
+  EnumType x;
+  x = s->field1;
+  x = s->field2;
+  x = s->field3;
+  x = (EnumType)s->field4;
+  x = (EnumType)s->field5;
+  x = (EnumType)s->field6;
+  x = (EnumType)s->field7;
+  x = (EnumType)s->field8;
+  x = (EnumType)s->field9;
+  x = (EnumType)s->field10;
+  x = (EnumType)s->field11;
+  x = (EnumType)s->field12;
+}
+
+void read_enum(S_C *s) {
+  using EnumType = C;
+  EnumType x;
+  x = s->field1;
+  x = s->field2;
+  x = s->field3;
+  x = (EnumType)s->field4;
+  x = (EnumType)s->field5;
+  x = (EnumType)s->field6;
+  x = (EnumType)s->field7;
+  x = (EnumType)s->field8;
+  x = (EnumType)s->field9;
+  x = (EnumType)s->field10;
+  x = (EnumType)s->field11;
+  x = (EnumType)s->field12;
+}
+
+void write_enum(S_A *s, A x) {
+  s->field1 = x;
+  // expected-warning at -1 {{bit-field 'field1' is not wide enough to store all enumerators of 'A'}}
+  // expected-note@#S_A_field1 {{widen this field to 2 bits to store all values of 'A'}}
+  s->field2 = x;
+  s->field3 = x;
+  s->field4 = x;
+  // expected-warning at -1 {{bit-field 'field4' is not wide enough to store all enumerators of 'A'}}
+  // expected-note@#S_A_field4 {{widen this field to 2 bits to store all values of 'A'}}
+  s->field5 = x;
+  s->field6 = x;
+  s->field7 = x;
+  // expected-warning at -1 {{bit-field 'field7' is not wide enough to store all enumerators of 'A'}}
+  // expected-note@#S_A_field7 {{widen this field to 2 bits to store all values of 'A'}}
+  s->field8 = x;
+  // expected-warning at -1 {{signed bit-field 'field8' needs an extra bit to represent the largest positive enumerators of 'A'}}
+  // expected-note@#S_A_field8 {{consider making the bitfield type unsigned}}
+  s->field9 = x;
+  s->field10 = (Derp)x;
+  s->field11 = (Derp)x;
+  s->field12 = (Derp)x;
+}
+
+void write_enum(S_B *s, B x) {
+  s->field1 = x;
+  // expected-warning at -1 {{bit-field 'field1' is not wide enough to store all enumerators of 'B'}}
+  // expected-note@#S_B_field1 {{widen this field to 2 bits to store all values of 'B'}}
+  s->field2 = x;
+  s->field3 = x;
+  s->field4 = (unsigned)x;
+  // expected-warning at -1 {{bit-field 'field4' is not wide enough to store all enumerators of preferred type 'B'}}
+  // expected-note@#S_B_field4 {{widen this field to 2 bits to store all values of 'B'}}
+  // expected-note@#preferred_S_B_field4 {{preferred type for bitfield 'B' specified here}}
+  s->field5 = (unsigned)x;
+  s->field6 = (unsigned)x;
+  s->field7 = (int)x;
+  // expected-warning at -1 {{bit-field 'field7' is not wide enough to store all enumerators of preferred type 'B'}}
+  // expected-note@#S_B_field7 {{widen this field to 2 bits to store all values of 'B'}}
+  // expected-note@#preferred_S_B_field7 {{preferred type for bitfield 'B' specified here}}
+  s->field8 = (int)x;
+  // expected-warning at -1 {{signed bit-field 'field8' needs an extra bit to represent the largest positive enumerators of preferred type 'B'}}
+  // expected-note@#S_B_field8 {{consider making the bitfield type unsigned}}
+  // expected-note@#preferred_S_B_field8 {{preferred type for bitfield 'B' specified here}}
+  s->field9 = (int)x;
+  s->field10 = (Derp)x;
+  s->field11 = (Derp)x;
+  s->field12 = (Derp)x;
+}
+void write_enum(S_C *s, C x) {
+  s->field1 = x;
+  // expected-warning at -1 {{bit-field 'field1' is not wide enough to store all enumerators of 'C'}}
+  // expected-note@#S_C_field1 {{widen this field to 2 bits to store all values of 'C'}}
+  s->field2 = x;
+  s->field3 = x;
+  s->field4 = (unsigned)x;
+  // expected-warning at -1 {{bit-field 'field4' is not wide enough to store all enumerators of preferred type 'C'}}
+  // expected-note@#S_C_field4 {{widen this field to 2 bits to store all values of 'C'}}
+  // expected-note@#preferred_S_C_field4 {{preferred type for bitfield 'C' specified here}}
+  s->field5 = (unsigned)x;
+  s->field6 = (unsigned)x;
+  s->field7 = (int)x;
+  // expected-warning at -1 {{bit-field 'field7' is not wide enough to store all enumerators of preferred type 'C'}}
+  // expected-note@#S_C_field7 {{widen this field to 2 bits to store all values of 'C'}}
+  // expected-note@#preferred_S_C_field7 {{preferred type for bitfield 'C' specified here}}
+  s->field8 = (int)x;
+  // expected-warning at -1 {{signed bit-field 'field8' needs an extra bit to represent the largest positive enumerators of preferred type 'C'}}
+  // expected-note@#S_C_field8 {{consider making the bitfield type unsigned}}
+  // expected-note@#preferred_S_C_field8 {{preferred type for bitfield 'C' specified here}}
+  s->field9 = (int)x;
+  s->field10 = (Derp)x;
+  s->field11 = (Derp)x;
+  s->field12 = (Derp)x;
+}
+
+void write_enum_int(struct S_A *s, int x) {
+  using EnumType = A;
+  s->field1 = (EnumType)x;
+  // expected-warning at -1 {{bit-field 'field1' is not wide enough to store all enumerators of 'A'}}
+  // expected-note@#S_A_field1 {{widen this field to 2 bits to store all values of 'A'}}
+  s->field2 = (EnumType)x;
+  s->field3 = (EnumType)x;
+  s->field4 = x;
+  // expected-warning at -1 {{bit-field 'field4' is not wide enough to store all enumerators of preferred type 'A'}}
+  // expected-note@#S_A_field4 {{widen this field to 2 bits to store all values of 'A'}}
+  // expected-note@#preferred_S_A_field4 {{preferred type for bitfield 'A' specified here}}
+  s->field5 = x;
+  s->field6 = x;
+  s->field7 = x;
+  // expected-warning at -1 {{bit-field 'field7' is not wide enough to store all enumerators of preferred type 'A'}}
+  // expected-note@#S_A_field7 {{widen this field to 2 bits to store all values of 'A'}}
+  // expected-note@#preferred_S_A_field7 {{preferred type for bitfield 'A' specified here}}
+  s->field8 = x;
+  // expected-warning at -1 {{signed bit-field 'field8' needs an extra bit to represent the largest positive enumerators of preferred type 'A'}}
+  // expected-note@#S_A_field8 {{consider making the bitfield type unsigned}}
+  // expected-note@#preferred_S_A_field8 {{preferred type for bitfield 'A' specified here}}
+  s->field9 = x;
+  s->field10 = (Derp)x;
+  s->field11 = (Derp)x;
+  s->field12 = (Derp)x;
+}
+
+void write_enum_int(struct S_B *s, int x) {
+  using EnumType = B;
+  s->field1 = (EnumType)x;
+  // expected-warning at -1 {{bit-field 'field1' is not wide enough to store all enumerators of 'B'}}
+  // expected-note@#S_B_field1 {{widen this field to 2 bits to store all values of 'B'}}
+  s->field2 = (EnumType)x;
+  s->field3 = (EnumType)x;
+  s->field4 = x;
+  // expected-warning at -1 {{bit-field 'field4' is not wide enough to store all enumerators of preferred type 'B'}}
+  // expected-note@#S_B_field4 {{widen this field to 2 bits to store all values of 'B'}}
+  // expected-note@#preferred_S_B_field4 {{preferred type for bitfield 'B' specified here}}
+  s->field5 = x;
+  s->field6 = x;
+  s->field7 = x;
+  // expected-warning at -1 {{bit-field 'field7' is not wide enough to store all enumerators of preferred type 'B'}}
+  // expected-note@#S_B_field7 {{widen this field to 2 bits to store all values of 'B'}}
+  // expected-note@#preferred_S_B_field7 {{preferred type for bitfield 'B' specified here}}
+  s->field8 = x;
+  // expected-warning at -1 {{signed bit-field 'field8' needs an extra bit to represent the largest positive enumerators of preferred type 'B'}}
+  // expected-note@#S_B_field8 {{consider making the bitfield type unsigned}}
+  // expected-note@#preferred_S_B_field8 {{preferred type for bitfield 'B' specified here}}
+  s->field9 = x;
+  s->field10 = (Derp)x;
+  s->field11 = (Derp)x;
+  s->field12 = (Derp)x;
+}
+
+void write_enum_int(struct S_C *s, int x) {
+  using EnumType = C;
+  s->field1 = (EnumType)x;
+  // expected-warning at -1 {{bit-field 'field1' is not wide enough to store all enumerators of 'C'}}
+  // expected-note@#S_C_field1 {{widen this field to 2 bits to store all values of 'C'}}
+  s->field2 = (EnumType)x;
+  s->field3 = (EnumType)x;
+  s->field4 = x;
+  // expected-warning at -1 {{bit-field 'field4' is not wide enough to store all enumerators of preferred type 'C'}}
+  // expected-note@#S_C_field4 {{widen this field to 2 bits to store all values of 'C'}}
+  // expected-note@#preferred_S_C_field4 {{preferred type for bitfield 'C' specified here}}
+  s->field5 = x;
+  s->field6 = x;
+  s->field7 = x;
+  // expected-warning at -1 {{bit-field 'field7' is not wide enough to store all enumerators of preferred type 'C'}}
+  // expected-note@#S_C_field7 {{widen this field to 2 bits to store all values of 'C'}}
+  // expected-note@#preferred_S_C_field7 {{preferred type for bitfield 'C' specified here}}
+  s->field8 = x;
+  // expected-warning at -1 {{signed bit-field 'field8' needs an extra bit to represent the largest positive enumerators of preferred type 'C'}}
+  // expected-note@#S_C_field8 {{consider making the bitfield type unsigned}}
+  // expected-note@#preferred_S_C_field8 {{preferred type for bitfield 'C' specified here}}
+  s->field9 = x;
+  s->field10 = (Derp)x;
+  s->field11 = (Derp)x;
+  s->field12 = (Derp)x;
+}
+
+void write_low_constant(S_A *s) {
+  s->field1 = A_a;
+  s->field2 = A_a;
+  s->field3 = A_a;
+  s->field4 = A_a;
+  s->field5 = A_a;
+  s->field6 = A_a;
+  s->field7 = A_a;
+  s->field8 = A_a;
+  s->field9 = A_a;
+  s->field10 = (Derp)A_a;
+  s->field11 = (Derp)A_a;
+  s->field12 = (Derp)A_a;
+};
+
+void write_low_constant(S_B *s) {
+  using EnumType = B;
+  s->field1 = EnumType::a;
+  s->field2 = EnumType::a;
+  s->field3 = EnumType::a;
+  s->field4 = (unsigned)EnumType::a;
+  s->field5 = (unsigned)EnumType::a;
+  s->field6 = (unsigned)EnumType::a;
+  s->field7 = (int)EnumType::a;
+  s->field8 = (int)EnumType::a;
+  s->field9 = (int)EnumType::a;
+  s->field10 = (Derp)EnumType::a;
+  s->field11 = (Derp)EnumType::a;
+  s->field12 = (Derp)EnumType::a;
+};
+
+void write_low_constant(S_C *s) {
+  using EnumType = C;
+  s->field1 = EnumType::a;
+  s->field2 = EnumType::a;
+  s->field3 = EnumType::a;
+  s->field4 = (unsigned)EnumType::a;
+  s->field5 = (unsigned)EnumType::a;
+  s->field6 = (unsigned)EnumType::a;
+  s->field7 = (int)EnumType::a;
+  s->field8 = (int)EnumType::a;
+  s->field9 = (int)EnumType::a;
+  s->field10 = (Derp)EnumType::a;
+  s->field11 = (Derp)EnumType::a;
+  s->field12 = (Derp)EnumType::a;
+};
+
+void write_high_constant(S_A *s) {
+  s->field1 = A_d;
+  // expected-warning at -1 {{implicit truncation from 'A' to bit-field changes value from 3 to 1}}
+  s->field2 = A_d;
+  s->field3 = A_d;
+  s->field4 = A_d;
+  // expected-warning at -1 {{implicit truncation from 'A' to bit-field changes value from 3 to 1}}
+  s->field5 = A_d;
+  s->field6 = A_d;
+  s->field7 = A_d;
+  // expected-warning at -1 {{implicit truncation from 'A' to bit-field changes value from 3 to -1}}
+  s->field8 = A_d;
+  // expected-warning at -1 {{implicit truncation from 'A' to bit-field changes value from 3 to -1}}
+  s->field9 = A_d;
+  s->field10 = (Derp)A_d;
+  // expected-warning at -1 {{implicit truncation from 'Derp' to bit-field changes value from 3 to 1}}
+  s->field11 = (Derp)A_d;
+  s->field12 = (Derp)A_d;
+};
+
+void write_high_constant(S_B *s) {
+  using EnumType = B;
+  s->field1 = EnumType::d;
+  // expected-warning at -1 {{implicit truncation from 'B' to bit-field changes value from 3 to 1}}
+  s->field2 = EnumType::d;
+  s->field3 = EnumType::d;
+  s->field4 = (unsigned)EnumType::d;
+  // expected-warning at -1 {{implicit truncation from 'unsigned int' to bit-field changes value from 3 to 1}}
+  s->field5 = (unsigned)EnumType::d;
+  s->field6 = (unsigned)EnumType::d;
+  s->field7 = (int)EnumType::d;
+  // expected-warning at -1 {{implicit truncation from 'int' to bit-field changes value from 3 to -1}}
+  s->field8 = (int)EnumType::d;
+  // expected-warning at -1 {{implicit truncation from 'int' to bit-field changes value from 3 to -1}}
+  s->field9 = (int)EnumType::d;
+};
+
+
+void write_high_constant(S_C *s) {
+  using EnumType = C;
+  s->field1 = EnumType::d;
+  // expected-warning at -1 {{implicit truncation from 'C' to bit-field changes value from 3 to 1}}
+  s->field2 = EnumType::d;
+  s->field3 = EnumType::d;
+  s->field4 = (unsigned)EnumType::d;
+  // expected-warning at -1 {{implicit truncation from 'unsigned int' to bit-field changes value from 3 to 1}}
+  s->field5 = (unsigned)EnumType::d;
+  s->field6 = (unsigned)EnumType::d;
+  s->field7 = (int)EnumType::d;
+  // expected-warning at -1 {{implicit truncation from 'int' to bit-field changes value from 3 to -1}}
+  s->field8 = (int)EnumType::d;
+  // expected-warning at -1 {{implicit truncation from 'int' to bit-field changes value from 3 to -1}}
+  s->field9 = (int)EnumType::d;
+};

>From e9aa6125ee71927ac5a4c0a0524bc1194e7ceb4c Mon Sep 17 00:00:00 2001
From: Oliver Hunt <oliver at apple.com>
Date: Tue, 19 Nov 2024 13:14:40 +0100
Subject: [PATCH 2/9] Attempt to appease the windows bot

---
 clang/test/Sema/bitfield-preferred-type-sizing.c      | 2 +-
 clang/test/SemaCXX/bitfield-preferred-type-sizing.cpp | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/clang/test/Sema/bitfield-preferred-type-sizing.c b/clang/test/Sema/bitfield-preferred-type-sizing.c
index 16d48bc0692df..a8d207d94a797 100644
--- a/clang/test/Sema/bitfield-preferred-type-sizing.c
+++ b/clang/test/Sema/bitfield-preferred-type-sizing.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 %s -fsyntax-only -verify -std=c11 -Wno-unused-value -Wno-unused-but-set-variable -Wbitfield-width -Wbitfield-enum-conversion
+// RUN: %clang_cc1 %s -triple=x86_64-apple-darwin10 -fsyntax-only -verify -std=c11 -Wno-unused-value -Wno-unused-but-set-variable -Wbitfield-width -Wbitfield-enum-conversion
 
 enum A {
   A_a,
diff --git a/clang/test/SemaCXX/bitfield-preferred-type-sizing.cpp b/clang/test/SemaCXX/bitfield-preferred-type-sizing.cpp
index 5e39d2ac2ba32..7dfbbdae031d1 100644
--- a/clang/test/SemaCXX/bitfield-preferred-type-sizing.cpp
+++ b/clang/test/SemaCXX/bitfield-preferred-type-sizing.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 %s -fsyntax-only -verify -std=c++23 -Wno-unused-value -Wno-unused-but-set-variable -Wbitfield-width -Wbitfield-enum-conversion
+// RUN: %clang_cc1 %s -triple=x86_64-apple-darwin10 -fsyntax-only -verify -std=c++23 -Wno-unused-value -Wno-unused-but-set-variable -Wbitfield-width -Wbitfield-enum-conversion
 
 // This is more complex than the C version because the user can specify the
 // storage type 

>From 55e70a443b36f6bd6bd1389d4048fd8d500b404d Mon Sep 17 00:00:00 2001
From: Oliver Hunt <oliver at apple.com>
Date: Tue, 19 Nov 2024 14:53:04 +0100
Subject: [PATCH 3/9] Tidy up test cases

---
 .../Sema/bitfield-preferred-type-sizing.c     | 34 +++++++++----------
 1 file changed, 17 insertions(+), 17 deletions(-)

diff --git a/clang/test/Sema/bitfield-preferred-type-sizing.c b/clang/test/Sema/bitfield-preferred-type-sizing.c
index a8d207d94a797..af04f431ba046 100644
--- a/clang/test/Sema/bitfield-preferred-type-sizing.c
+++ b/clang/test/Sema/bitfield-preferred-type-sizing.c
@@ -8,19 +8,19 @@ enum A {
 };
 
 struct S {
-  enum A a1 : 1; // #1
+  enum A a1 : 1; // #S_a1_decl
   enum A a2 : 2;
   enum A a3 : 8;
-  __attribute__((preferred_type(enum A))) // #preferred_a4
-  unsigned a4 : 1; // #2
+  __attribute__((preferred_type(enum A))) // #preferred_S_a4
+  unsigned a4 : 1; // #S_a4_decl
   __attribute__((preferred_type(enum A)))
   unsigned a5 : 2;
   __attribute__((preferred_type(enum A)))
   unsigned a6 : 8;
-  __attribute__((preferred_type(enum A)))  // #preferred_a7
-  int a7 : 1; // #3
-  __attribute__((preferred_type(enum A))) // #preferred_a8
-  int a8 : 2; // #4
+  __attribute__((preferred_type(enum A)))  // #preferred_S_a7
+  int a7 : 1; // #S_a7_decl
+  __attribute__((preferred_type(enum A))) // #preferred_S_a8
+  int a8 : 2; // #S_a8_decl
   __attribute__((preferred_type(enum A)))
   int a9 : 8;
 };
@@ -41,20 +41,20 @@ void read_enum(struct S *s) {
 void write_enum(struct S *s, enum A x) {
   s->a1 = x;
   // expected-warning at -1 {{bit-field 'a1' is not wide enough to store all enumerators of 'A'}}
-  // expected-note@#1 {{widen this field to 2 bits to store all values of 'A'}}
+  // expected-note@#S_a1_decl {{widen this field to 2 bits to store all values of 'A'}}
   s->a2 = x;
   s->a3 = x;
   s->a4 = x;
   // expected-warning at -1 {{bit-field 'a4' is not wide enough to store all enumerators of 'A'}}
-  // expected-note@#2 {{widen this field to 2 bits to store all values of 'A'}}
+  // expected-note@#S_a4_decl {{widen this field to 2 bits to store all values of 'A'}}
   s->a5 = x;
   s->a6 = x;
   s->a7 = x;
   // expected-warning at -1 {{bit-field 'a7' is not wide enough to store all enumerators of 'A'}}
-  // expected-note@#3 {{widen this field to 2 bits to store all values of 'A'}}
+  // expected-note@#S_a7_decl {{widen this field to 2 bits to store all values of 'A'}}
   s->a8 = x;
   // expected-warning at -1 {{signed bit-field 'a8' needs an extra bit to represent the largest positive enumerators of 'A'}}
-  // expected-note@#4 {{consider making the bitfield type unsigned}}
+  // expected-note@#S_a8_decl {{consider making the bitfield type unsigned}}
   s->a9 = x;
 }
 
@@ -64,18 +64,18 @@ void write_enum_int(struct S *s, int x) {
   s->a3 = x;
   s->a4 = x;
   // expected-warning at -1 {{bit-field 'a4' is not wide enough to store all enumerators of preferred type 'A'}}
-  // expected-note@#2 {{widen this field to 2 bits to store all values of 'A'}}
-  // expected-note@#preferred_a4 {{preferred type for bitfield 'A' specified here}}
+  // expected-note@#S_a4_decl {{widen this field to 2 bits to store all values of 'A'}}
+  // expected-note@#preferred_S_a4 {{preferred type for bitfield 'A' specified here}}
   s->a5 = x;
   s->a6 = x;
   s->a7 = x;
   // expected-warning at -1 {{bit-field 'a7' is not wide enough to store all enumerators of preferred type 'A'}}
-  // expected-note@#3 {{widen this field to 2 bits to store all values of 'A'}}
-  // expected-note@#preferred_a7 {{preferred type for bitfield 'A' specified here}}
+  // expected-note@#S_a7_decl {{widen this field to 2 bits to store all values of 'A'}}
+  // expected-note@#preferred_S_a7 {{preferred type for bitfield 'A' specified here}}
   s->a8 = x;
   // expected-warning at -1 {{signed bit-field 'a8' needs an extra bit to represent the largest positive enumerators of preferred type 'A'}}
-  // expected-note@#4 {{consider making the bitfield type unsigned}}
-  // expected-note@#preferred_a8 {{preferred type for bitfield 'A' specified here}}
+  // expected-note@#S_a8_decl {{consider making the bitfield type unsigned}}
+  // expected-note@#preferred_S_a8 {{preferred type for bitfield 'A' specified here}}
   s->a9 = x;
 }
 

>From fe3d82439d427b818ebba6536054f08f2deac560 Mon Sep 17 00:00:00 2001
From: Oliver Hunt <oliver at apple.com>
Date: Mon, 2 Dec 2024 12:55:01 -0800
Subject: [PATCH 4/9] Code style

---
 clang/lib/Sema/SemaChecking.cpp | 6 ++----
 1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp
index 5ead1b9242953..e01994f7dc454 100644
--- a/clang/lib/Sema/SemaChecking.cpp
+++ b/clang/lib/Sema/SemaChecking.cpp
@@ -10612,10 +10612,9 @@ static bool AnalyzeBitFieldAssignment(Sema &S, FieldDecl *Bitfield, Expr *Init,
             TSI ? TSI->getTypeLoc().getSourceRange() : SourceRange();
         S.Diag(Bitfield->getTypeSpecStartLoc(), diag::note_change_bitfield_sign)
             << SignedEnum << TypeRange;
-        if (PTAttr) {
+        if (PTAttr)
           S.Diag(PTAttr->getLocation(), diag::note_bitfield_preferred_type)
               << ED;
-        }
       }
 
       // Compute the required bitwidth. If the enum has negative values, we need
@@ -10632,10 +10631,9 @@ static bool AnalyzeBitFieldAssignment(Sema &S, FieldDecl *Bitfield, Expr *Init,
             << Bitfield << PreferredTypeDiagIndex << ED;
         S.Diag(WidthExpr->getExprLoc(), diag::note_widen_bitfield)
             << BitsNeeded << ED << WidthExpr->getSourceRange();
-        if (PTAttr) {
+        if (PTAttr)
           S.Diag(PTAttr->getLocation(), diag::note_bitfield_preferred_type)
               << ED;
-        }
       }
     }
 

>From 0cd5127f8e840de59dd5a02a01c10e168d7aaa1c Mon Sep 17 00:00:00 2001
From: Oliver Hunt <oliver at apple.com>
Date: Mon, 30 Dec 2024 19:07:32 -0800
Subject: [PATCH 5/9] Redoing diagnostics to make this an error by default

---
 clang/include/clang/Basic/DiagnosticGroups.td |   6 +-
 .../clang/Basic/DiagnosticSemaKinds.td        |  20 +++-
 clang/lib/Sema/SemaChecking.cpp               |  21 +++-
 .../Sema/bitfield-preferred-type-sizing.c     |  49 ++++----
 .../bitfield-preferred-type-sizing.cpp        | 109 +++++++++---------
 5 files changed, 117 insertions(+), 88 deletions(-)

diff --git a/clang/include/clang/Basic/DiagnosticGroups.td b/clang/include/clang/Basic/DiagnosticGroups.td
index 3ac490d30371b..55e82c905e843 100644
--- a/clang/include/clang/Basic/DiagnosticGroups.td
+++ b/clang/include/clang/Basic/DiagnosticGroups.td
@@ -49,6 +49,8 @@ def SingleBitBitFieldConstantConversion :
   DiagGroup<"single-bit-bitfield-constant-conversion">;
 def BitFieldConstantConversion : DiagGroup<"bitfield-constant-conversion",
                                            [SingleBitBitFieldConstantConversion]>;
+def PreferredTypeBitFieldEnumConversion : DiagGroup<"preferred-type-bitfield-enum-conversion">;
+def PreferredTypeBitFieldWidth : DiagGroup<"preferred-type-bitfield-width">;
 def BitFieldEnumConversion : DiagGroup<"bitfield-enum-conversion">;
 def BitFieldWidth : DiagGroup<"bitfield-width">;
 def CompoundTokenSplitByMacro : DiagGroup<"compound-token-split-by-macro">;
@@ -1114,7 +1116,9 @@ def Most : DiagGroup<"most", [
     PrivateExtern,
     SelTypeCast,
     ExternCCompat,
-    UserDefinedWarnings
+    UserDefinedWarnings,
+    PreferredTypeBitFieldEnumConversion,
+    PreferredTypeBitFieldWidth 
  ]>;
 
 // Thread Safety warnings
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 6a97cc1ac15f5..8f5e4c3c7a65f 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -6423,24 +6423,34 @@ def warn_bitfield_width_exceeds_type_width: Warning<
 def err_bitfield_too_wide : Error<
   "%select{bit-field %1|anonymous bit-field}0 is too wide (%2 bits)">;
 def warn_bitfield_too_small_for_enum : Warning<
-  "bit-field %0 is not wide enough to store all enumerators of %select{|preferred type }1%2">,
+  "bit-field %0 is not wide enough to store all enumerators of %1">,
   InGroup<BitFieldEnumConversion>, DefaultIgnore;
 def note_widen_bitfield : Note<
   "widen this field to %0 bits to store all values of %1">;
 def warn_unsigned_bitfield_assigned_signed_enum : Warning<
-  "assigning value of %select{|preferred }1signed enum type %2 to unsigned bit-field %0; "
+  "assigning value of signed enum type %1 to unsigned bit-field %0; "
   "negative enumerators of enum %1 will be converted to positive values">,
   InGroup<BitFieldEnumConversion>, DefaultIgnore;
 def warn_signed_bitfield_enum_conversion : Warning<
   "signed bit-field %0 needs an extra bit to represent the largest positive "
-  "enumerators of %select{|preferred type }1%2">,
+  "enumerators of %1">,
   InGroup<BitFieldEnumConversion>, DefaultIgnore;
+def warn_preferred_type_bitfield_too_small_for_enum : Warning<
+  "bit-field %0 is not wide enough to store all enumerators of preferred type %1">,
+  InGroup<PreferredTypeBitFieldEnumConversion>, DefaultError;
+def warn_preferred_type_unsigned_bitfield_assigned_signed_enum : Warning<
+  "assigning value of preferred signed enum type %1 to unsigned bit-field %0; "
+  "negative enumerators of enum %1 will be converted to positive values">,
+  InGroup<PreferredTypeBitFieldEnumConversion>, DefaultIgnore;
+def warn_preferred_type_signed_bitfield_enum_conversion : Warning<
+  "signed bit-field %0 needs an extra bit to represent the largest positive "
+  "enumerators of preferred type %1">,
+  InGroup<PreferredTypeBitFieldEnumConversion>, DefaultError;
 def note_change_bitfield_sign : Note<
   "consider making the bit-field type %select{unsigned|signed}0">;
 def note_bitfield_preferred_type : Note<
-  "preferred type for bitfield %0 specified here"
+  "preferred type for bit-field %0 specified here"
 >;
-  "consider making the bit-field type %select{unsigned|signed}0">;
 
 def warn_missing_braces : Warning<
   "suggest braces around initialization of subobject">,
diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp
index b74c51cca6cb6..2eabd14acc23f 100644
--- a/clang/lib/Sema/SemaChecking.cpp
+++ b/clang/lib/Sema/SemaChecking.cpp
@@ -10608,14 +10608,20 @@ static bool AnalyzeBitFieldAssignment(Sema &S, FieldDecl *Bitfield, Expr *Init,
       // on Windows where unfixed enums always use an underlying type of 'int'.
       unsigned DiagID = 0;
       if (SignedEnum && !SignedBitfield) {
-        DiagID = diag::warn_unsigned_bitfield_assigned_signed_enum;
+        DiagID =
+            PTAttr == nullptr
+                ? diag::warn_unsigned_bitfield_assigned_signed_enum
+                : diag::
+                      warn_preferred_type_unsigned_bitfield_assigned_signed_enum;
       } else if (SignedBitfield && !SignedEnum &&
                  ED->getNumPositiveBits() == FieldWidth) {
-        DiagID = diag::warn_signed_bitfield_enum_conversion;
+        DiagID =
+            PTAttr == nullptr
+                ? diag::warn_signed_bitfield_enum_conversion
+                : diag::warn_preferred_type_signed_bitfield_enum_conversion;
       }
-      unsigned PreferredTypeDiagIndex = PTAttr != nullptr;
       if (DiagID) {
-        S.Diag(InitLoc, DiagID) << Bitfield << PreferredTypeDiagIndex << ED;
+        S.Diag(InitLoc, DiagID) << Bitfield << ED;
         TypeSourceInfo *TSI = Bitfield->getTypeSourceInfo();
         SourceRange TypeRange =
             TSI ? TSI->getTypeLoc().getSourceRange() : SourceRange();
@@ -10636,8 +10642,11 @@ static bool AnalyzeBitFieldAssignment(Sema &S, FieldDecl *Bitfield, Expr *Init,
       // Check the bitwidth.
       if (BitsNeeded > FieldWidth) {
         Expr *WidthExpr = Bitfield->getBitWidth();
-        S.Diag(InitLoc, diag::warn_bitfield_too_small_for_enum)
-            << Bitfield << PreferredTypeDiagIndex << ED;
+        auto DiagID =
+            PTAttr == nullptr
+                ? diag::warn_bitfield_too_small_for_enum
+                : diag::warn_preferred_type_bitfield_too_small_for_enum;
+        S.Diag(InitLoc, DiagID) << Bitfield << ED;
         S.Diag(WidthExpr->getExprLoc(), diag::note_widen_bitfield)
             << BitsNeeded << ED << WidthExpr->getSourceRange();
         if (PTAttr)
diff --git a/clang/test/Sema/bitfield-preferred-type-sizing.c b/clang/test/Sema/bitfield-preferred-type-sizing.c
index af04f431ba046..ab8c98dc35400 100644
--- a/clang/test/Sema/bitfield-preferred-type-sizing.c
+++ b/clang/test/Sema/bitfield-preferred-type-sizing.c
@@ -1,4 +1,6 @@
-// RUN: %clang_cc1 %s -triple=x86_64-apple-darwin10 -fsyntax-only -verify -std=c11 -Wno-unused-value -Wno-unused-but-set-variable -Wbitfield-width -Wbitfield-enum-conversion
+// RUN: %clang_cc1 %s -triple=x86_64-apple-darwin10 -fsyntax-only -verify=expected,preferrednotes -std=c11 -Wno-unused-value -Wno-unused-but-set-variable
+// RUN: %clang_cc1 %s -triple=x86_64-apple-darwin10 -fsyntax-only -verify=expected,bitfieldwarning,preferrednotes -std=c11 -Wno-unused-value -Wno-unused-but-set-variable -Wbitfield-width -Wbitfield-enum-conversion
+// RUN: %clang_cc1 %s -triple=x86_64-apple-darwin10 -fsyntax-only -verify=noerror,preferrednotes -std=c11 -Wno-unused-value -Wno-unused-but-set-variable -Wno-error=preferred-type-bitfield-enum-conversion -Wno-error=preferred-type-bitfield-width
 
 enum A {
   A_a,
@@ -40,21 +42,21 @@ void read_enum(struct S *s) {
 
 void write_enum(struct S *s, enum A x) {
   s->a1 = x;
-  // expected-warning at -1 {{bit-field 'a1' is not wide enough to store all enumerators of 'A'}}
-  // expected-note@#S_a1_decl {{widen this field to 2 bits to store all values of 'A'}}
+  // bitfieldwarning-warning at -1 {{bit-field 'a1' is not wide enough to store all enumerators of 'A'}}
+  // bitfieldwarning-note@#S_a1_decl {{widen this field to 2 bits to store all values of 'A'}}
   s->a2 = x;
   s->a3 = x;
   s->a4 = x;
-  // expected-warning at -1 {{bit-field 'a4' is not wide enough to store all enumerators of 'A'}}
-  // expected-note@#S_a4_decl {{widen this field to 2 bits to store all values of 'A'}}
+  // bitfieldwarning-warning at -1 {{bit-field 'a4' is not wide enough to store all enumerators of 'A'}}
+  // bitfieldwarning-note@#S_a4_decl {{widen this field to 2 bits to store all values of 'A'}}
   s->a5 = x;
   s->a6 = x;
   s->a7 = x;
-  // expected-warning at -1 {{bit-field 'a7' is not wide enough to store all enumerators of 'A'}}
-  // expected-note@#S_a7_decl {{widen this field to 2 bits to store all values of 'A'}}
+  // bitfieldwarning-warning at -1 {{bit-field 'a7' is not wide enough to store all enumerators of 'A'}}
+  // bitfieldwarning-note@#S_a7_decl {{widen this field to 2 bits to store all values of 'A'}}
   s->a8 = x;
-  // expected-warning at -1 {{signed bit-field 'a8' needs an extra bit to represent the largest positive enumerators of 'A'}}
-  // expected-note@#S_a8_decl {{consider making the bitfield type unsigned}}
+  // bitfieldwarning-warning at -1 {{signed bit-field 'a8' needs an extra bit to represent the largest positive enumerators of 'A'}}
+  // bitfieldwarning-note@#S_a8_decl {{consider making the bit-field type unsigned}}
   s->a9 = x;
 }
 
@@ -63,19 +65,22 @@ void write_enum_int(struct S *s, int x) {
   s->a2 = x;
   s->a3 = x;
   s->a4 = x;
-  // expected-warning at -1 {{bit-field 'a4' is not wide enough to store all enumerators of preferred type 'A'}}
-  // expected-note@#S_a4_decl {{widen this field to 2 bits to store all values of 'A'}}
-  // expected-note@#preferred_S_a4 {{preferred type for bitfield 'A' specified here}}
+  // expected-error at -1 {{bit-field 'a4' is not wide enough to store all enumerators of preferred type 'A'}}
+  // noerror-warning at -2 {{bit-field 'a4' is not wide enough to store all enumerators of preferred type 'A'}}
+  // preferrednotes-note@#S_a4_decl {{widen this field to 2 bits to store all values of 'A'}}
+  // preferrednotes-note@#preferred_S_a4 {{preferred type for bit-field 'A' specified here}}
   s->a5 = x;
   s->a6 = x;
   s->a7 = x;
-  // expected-warning at -1 {{bit-field 'a7' is not wide enough to store all enumerators of preferred type 'A'}}
-  // expected-note@#S_a7_decl {{widen this field to 2 bits to store all values of 'A'}}
-  // expected-note@#preferred_S_a7 {{preferred type for bitfield 'A' specified here}}
+  // expected-error at -1 {{bit-field 'a7' is not wide enough to store all enumerators of preferred type 'A'}}
+  // noerror-warning at -2 {{bit-field 'a7' is not wide enough to store all enumerators of preferred type 'A'}}
+  // preferrednotes-note@#S_a7_decl {{widen this field to 2 bits to store all values of 'A'}}
+  // preferrednotes-note@#preferred_S_a7 {{preferred type for bit-field 'A' specified here}}
   s->a8 = x;
-  // expected-warning at -1 {{signed bit-field 'a8' needs an extra bit to represent the largest positive enumerators of preferred type 'A'}}
-  // expected-note@#S_a8_decl {{consider making the bitfield type unsigned}}
-  // expected-note@#preferred_S_a8 {{preferred type for bitfield 'A' specified here}}
+  // expected-error at -1 {{signed bit-field 'a8' needs an extra bit to represent the largest positive enumerators of preferred type 'A'}}
+  // noerror-warning at -2 {{signed bit-field 'a8' needs an extra bit to represent the largest positive enumerators of preferred type 'A'}}
+  // preferrednotes-note@#S_a8_decl {{consider making the bit-field type unsigned}}
+  // preferrednotes-note@#preferred_S_a8 {{preferred type for bit-field 'A' specified here}}
   s->a9 = x;
 }
 
@@ -93,16 +98,16 @@ void write_low_constant(struct S *s) {
 
 void write_high_constant(struct S *s) {
   s->a1 = A_d;
-  // expected-warning at -1 {{implicit truncation from 'int' to bit-field changes value from 3 to 1}}
+  // preferrednotes-warning at -1 {{implicit truncation from 'int' to bit-field changes value from 3 to 1}}
   s->a2 = A_d;
   s->a3 = A_d;
   s->a4 = A_d;
-  // expected-warning at -1 {{implicit truncation from 'int' to bit-field changes value from 3 to 1}}
+  // preferrednotes-warning at -1 {{implicit truncation from 'int' to bit-field changes value from 3 to 1}}
   s->a5 = A_d;
   s->a6 = A_d;
   s->a7 = A_d;
-  // expected-warning at -1 {{implicit truncation from 'int' to bit-field changes value from 3 to -1}}
+  // preferrednotes-warning at -1 {{implicit truncation from 'int' to bit-field changes value from 3 to -1}}
   s->a8 = A_d;
-  // expected-warning at -1 {{implicit truncation from 'int' to bit-field changes value from 3 to -1}}
+  // preferrednotes-warning at -1 {{implicit truncation from 'int' to bit-field changes value from 3 to -1}}
   s->a9 = A_d;
 };
diff --git a/clang/test/SemaCXX/bitfield-preferred-type-sizing.cpp b/clang/test/SemaCXX/bitfield-preferred-type-sizing.cpp
index 7dfbbdae031d1..442463c5f23b8 100644
--- a/clang/test/SemaCXX/bitfield-preferred-type-sizing.cpp
+++ b/clang/test/SemaCXX/bitfield-preferred-type-sizing.cpp
@@ -1,4 +1,5 @@
-// RUN: %clang_cc1 %s -triple=x86_64-apple-darwin10 -fsyntax-only -verify -std=c++23 -Wno-unused-value -Wno-unused-but-set-variable -Wbitfield-width -Wbitfield-enum-conversion
+// RUN: %clang_cc1 %s -triple=x86_64-apple-darwin10 -fsyntax-only -verify -std=c++23 -Wno-unused-value -Wno-unused-but-set-variable
+// RUN: %clang_cc1 %s -triple=x86_64-apple-darwin10 -fsyntax-only -verify=expected,bitfieldwarnings -std=c++23 -Wno-unused-value -Wno-unused-but-set-variable -Wbitfield-width -Wbitfield-enum-conversion
 
 // This is more complex than the C version because the user can specify the
 // storage type 
@@ -157,21 +158,21 @@ void read_enum(S_C *s) {
 
 void write_enum(S_A *s, A x) {
   s->field1 = x;
-  // expected-warning at -1 {{bit-field 'field1' is not wide enough to store all enumerators of 'A'}}
-  // expected-note@#S_A_field1 {{widen this field to 2 bits to store all values of 'A'}}
+  // bitfieldwarnings-warning at -1 {{bit-field 'field1' is not wide enough to store all enumerators of 'A'}}
+  // bitfieldwarnings-note@#S_A_field1 {{widen this field to 2 bits to store all values of 'A'}}
   s->field2 = x;
   s->field3 = x;
   s->field4 = x;
-  // expected-warning at -1 {{bit-field 'field4' is not wide enough to store all enumerators of 'A'}}
-  // expected-note@#S_A_field4 {{widen this field to 2 bits to store all values of 'A'}}
+  // bitfieldwarnings-warning at -1 {{bit-field 'field4' is not wide enough to store all enumerators of 'A'}}
+  // bitfieldwarnings-note@#S_A_field4 {{widen this field to 2 bits to store all values of 'A'}}
   s->field5 = x;
   s->field6 = x;
   s->field7 = x;
-  // expected-warning at -1 {{bit-field 'field7' is not wide enough to store all enumerators of 'A'}}
-  // expected-note@#S_A_field7 {{widen this field to 2 bits to store all values of 'A'}}
+  // bitfieldwarnings-warning at -1 {{bit-field 'field7' is not wide enough to store all enumerators of 'A'}}
+  // bitfieldwarnings-note@#S_A_field7 {{widen this field to 2 bits to store all values of 'A'}}
   s->field8 = x;
-  // expected-warning at -1 {{signed bit-field 'field8' needs an extra bit to represent the largest positive enumerators of 'A'}}
-  // expected-note@#S_A_field8 {{consider making the bitfield type unsigned}}
+  // bitfieldwarnings-warning at -1 {{signed bit-field 'field8' needs an extra bit to represent the largest positive enumerators of 'A'}}
+  // bitfieldwarnings-note@#S_A_field8 {{consider making the bit-field type unsigned}}
   s->field9 = x;
   s->field10 = (Derp)x;
   s->field11 = (Derp)x;
@@ -180,24 +181,24 @@ void write_enum(S_A *s, A x) {
 
 void write_enum(S_B *s, B x) {
   s->field1 = x;
-  // expected-warning at -1 {{bit-field 'field1' is not wide enough to store all enumerators of 'B'}}
-  // expected-note@#S_B_field1 {{widen this field to 2 bits to store all values of 'B'}}
+  // bitfieldwarnings-warning at -1 {{bit-field 'field1' is not wide enough to store all enumerators of 'B'}}
+  // bitfieldwarnings-note@#S_B_field1 {{widen this field to 2 bits to store all values of 'B'}}
   s->field2 = x;
   s->field3 = x;
   s->field4 = (unsigned)x;
-  // expected-warning at -1 {{bit-field 'field4' is not wide enough to store all enumerators of preferred type 'B'}}
+  // expected-error at -1 {{bit-field 'field4' is not wide enough to store all enumerators of preferred type 'B'}}
   // expected-note@#S_B_field4 {{widen this field to 2 bits to store all values of 'B'}}
-  // expected-note@#preferred_S_B_field4 {{preferred type for bitfield 'B' specified here}}
+  // expected-note@#preferred_S_B_field4 {{preferred type for bit-field 'B' specified here}}
   s->field5 = (unsigned)x;
   s->field6 = (unsigned)x;
   s->field7 = (int)x;
-  // expected-warning at -1 {{bit-field 'field7' is not wide enough to store all enumerators of preferred type 'B'}}
+  // expected-error at -1 {{bit-field 'field7' is not wide enough to store all enumerators of preferred type 'B'}}
   // expected-note@#S_B_field7 {{widen this field to 2 bits to store all values of 'B'}}
-  // expected-note@#preferred_S_B_field7 {{preferred type for bitfield 'B' specified here}}
+  // expected-note@#preferred_S_B_field7 {{preferred type for bit-field 'B' specified here}}
   s->field8 = (int)x;
-  // expected-warning at -1 {{signed bit-field 'field8' needs an extra bit to represent the largest positive enumerators of preferred type 'B'}}
-  // expected-note@#S_B_field8 {{consider making the bitfield type unsigned}}
-  // expected-note@#preferred_S_B_field8 {{preferred type for bitfield 'B' specified here}}
+  // expected-error at -1 {{signed bit-field 'field8' needs an extra bit to represent the largest positive enumerators of preferred type 'B'}}
+  // expected-note@#S_B_field8 {{consider making the bit-field type unsigned}}
+  // expected-note@#preferred_S_B_field8 {{preferred type for bit-field 'B' specified here}}
   s->field9 = (int)x;
   s->field10 = (Derp)x;
   s->field11 = (Derp)x;
@@ -205,24 +206,24 @@ void write_enum(S_B *s, B x) {
 }
 void write_enum(S_C *s, C x) {
   s->field1 = x;
-  // expected-warning at -1 {{bit-field 'field1' is not wide enough to store all enumerators of 'C'}}
-  // expected-note@#S_C_field1 {{widen this field to 2 bits to store all values of 'C'}}
+  // bitfieldwarnings-warning at -1 {{bit-field 'field1' is not wide enough to store all enumerators of 'C'}}
+  // bitfieldwarnings-note@#S_C_field1 {{widen this field to 2 bits to store all values of 'C'}}
   s->field2 = x;
   s->field3 = x;
   s->field4 = (unsigned)x;
-  // expected-warning at -1 {{bit-field 'field4' is not wide enough to store all enumerators of preferred type 'C'}}
+  // expected-error at -1 {{bit-field 'field4' is not wide enough to store all enumerators of preferred type 'C'}}
   // expected-note@#S_C_field4 {{widen this field to 2 bits to store all values of 'C'}}
-  // expected-note@#preferred_S_C_field4 {{preferred type for bitfield 'C' specified here}}
+  // expected-note@#preferred_S_C_field4 {{preferred type for bit-field 'C' specified here}}
   s->field5 = (unsigned)x;
   s->field6 = (unsigned)x;
   s->field7 = (int)x;
-  // expected-warning at -1 {{bit-field 'field7' is not wide enough to store all enumerators of preferred type 'C'}}
+  // expected-error at -1 {{bit-field 'field7' is not wide enough to store all enumerators of preferred type 'C'}}
   // expected-note@#S_C_field7 {{widen this field to 2 bits to store all values of 'C'}}
-  // expected-note@#preferred_S_C_field7 {{preferred type for bitfield 'C' specified here}}
+  // expected-note@#preferred_S_C_field7 {{preferred type for bit-field 'C' specified here}}
   s->field8 = (int)x;
-  // expected-warning at -1 {{signed bit-field 'field8' needs an extra bit to represent the largest positive enumerators of preferred type 'C'}}
-  // expected-note@#S_C_field8 {{consider making the bitfield type unsigned}}
-  // expected-note@#preferred_S_C_field8 {{preferred type for bitfield 'C' specified here}}
+  // expected-error at -1 {{signed bit-field 'field8' needs an extra bit to represent the largest positive enumerators of preferred type 'C'}}
+  // expected-note@#S_C_field8 {{consider making the bit-field type unsigned}}
+  // expected-note@#preferred_S_C_field8 {{preferred type for bit-field 'C' specified here}}
   s->field9 = (int)x;
   s->field10 = (Derp)x;
   s->field11 = (Derp)x;
@@ -232,24 +233,24 @@ void write_enum(S_C *s, C x) {
 void write_enum_int(struct S_A *s, int x) {
   using EnumType = A;
   s->field1 = (EnumType)x;
-  // expected-warning at -1 {{bit-field 'field1' is not wide enough to store all enumerators of 'A'}}
-  // expected-note@#S_A_field1 {{widen this field to 2 bits to store all values of 'A'}}
+  // bitfieldwarnings-warning at -1 {{bit-field 'field1' is not wide enough to store all enumerators of 'A'}}
+  // bitfieldwarnings-note@#S_A_field1 {{widen this field to 2 bits to store all values of 'A'}}
   s->field2 = (EnumType)x;
   s->field3 = (EnumType)x;
   s->field4 = x;
-  // expected-warning at -1 {{bit-field 'field4' is not wide enough to store all enumerators of preferred type 'A'}}
+  // expected-error at -1 {{bit-field 'field4' is not wide enough to store all enumerators of preferred type 'A'}}
   // expected-note@#S_A_field4 {{widen this field to 2 bits to store all values of 'A'}}
-  // expected-note@#preferred_S_A_field4 {{preferred type for bitfield 'A' specified here}}
+  // expected-note@#preferred_S_A_field4 {{preferred type for bit-field 'A' specified here}}
   s->field5 = x;
   s->field6 = x;
   s->field7 = x;
-  // expected-warning at -1 {{bit-field 'field7' is not wide enough to store all enumerators of preferred type 'A'}}
+  // expected-error at -1 {{bit-field 'field7' is not wide enough to store all enumerators of preferred type 'A'}}
   // expected-note@#S_A_field7 {{widen this field to 2 bits to store all values of 'A'}}
-  // expected-note@#preferred_S_A_field7 {{preferred type for bitfield 'A' specified here}}
+  // expected-note@#preferred_S_A_field7 {{preferred type for bit-field 'A' specified here}}
   s->field8 = x;
-  // expected-warning at -1 {{signed bit-field 'field8' needs an extra bit to represent the largest positive enumerators of preferred type 'A'}}
-  // expected-note@#S_A_field8 {{consider making the bitfield type unsigned}}
-  // expected-note@#preferred_S_A_field8 {{preferred type for bitfield 'A' specified here}}
+  // expected-error at -1 {{signed bit-field 'field8' needs an extra bit to represent the largest positive enumerators of preferred type 'A'}}
+  // expected-note@#S_A_field8 {{consider making the bit-field type unsigned}}
+  // expected-note@#preferred_S_A_field8 {{preferred type for bit-field 'A' specified here}}
   s->field9 = x;
   s->field10 = (Derp)x;
   s->field11 = (Derp)x;
@@ -259,24 +260,24 @@ void write_enum_int(struct S_A *s, int x) {
 void write_enum_int(struct S_B *s, int x) {
   using EnumType = B;
   s->field1 = (EnumType)x;
-  // expected-warning at -1 {{bit-field 'field1' is not wide enough to store all enumerators of 'B'}}
-  // expected-note@#S_B_field1 {{widen this field to 2 bits to store all values of 'B'}}
+  // bitfieldwarnings-warning at -1 {{bit-field 'field1' is not wide enough to store all enumerators of 'B'}}
+  // bitfieldwarnings-note@#S_B_field1 {{widen this field to 2 bits to store all values of 'B'}}
   s->field2 = (EnumType)x;
   s->field3 = (EnumType)x;
   s->field4 = x;
-  // expected-warning at -1 {{bit-field 'field4' is not wide enough to store all enumerators of preferred type 'B'}}
+  // expected-error at -1 {{bit-field 'field4' is not wide enough to store all enumerators of preferred type 'B'}}
   // expected-note@#S_B_field4 {{widen this field to 2 bits to store all values of 'B'}}
-  // expected-note@#preferred_S_B_field4 {{preferred type for bitfield 'B' specified here}}
+  // expected-note@#preferred_S_B_field4 {{preferred type for bit-field 'B' specified here}}
   s->field5 = x;
   s->field6 = x;
   s->field7 = x;
-  // expected-warning at -1 {{bit-field 'field7' is not wide enough to store all enumerators of preferred type 'B'}}
+  // expected-error at -1 {{bit-field 'field7' is not wide enough to store all enumerators of preferred type 'B'}}
   // expected-note@#S_B_field7 {{widen this field to 2 bits to store all values of 'B'}}
-  // expected-note@#preferred_S_B_field7 {{preferred type for bitfield 'B' specified here}}
+  // expected-note@#preferred_S_B_field7 {{preferred type for bit-field 'B' specified here}}
   s->field8 = x;
-  // expected-warning at -1 {{signed bit-field 'field8' needs an extra bit to represent the largest positive enumerators of preferred type 'B'}}
-  // expected-note@#S_B_field8 {{consider making the bitfield type unsigned}}
-  // expected-note@#preferred_S_B_field8 {{preferred type for bitfield 'B' specified here}}
+  // expected-error at -1 {{signed bit-field 'field8' needs an extra bit to represent the largest positive enumerators of preferred type 'B'}}
+  // expected-note@#S_B_field8 {{consider making the bit-field type unsigned}}
+  // expected-note@#preferred_S_B_field8 {{preferred type for bit-field 'B' specified here}}
   s->field9 = x;
   s->field10 = (Derp)x;
   s->field11 = (Derp)x;
@@ -286,24 +287,24 @@ void write_enum_int(struct S_B *s, int x) {
 void write_enum_int(struct S_C *s, int x) {
   using EnumType = C;
   s->field1 = (EnumType)x;
-  // expected-warning at -1 {{bit-field 'field1' is not wide enough to store all enumerators of 'C'}}
-  // expected-note@#S_C_field1 {{widen this field to 2 bits to store all values of 'C'}}
+  // bitfieldwarnings-warning at -1 {{bit-field 'field1' is not wide enough to store all enumerators of 'C'}}
+  // bitfieldwarnings-note@#S_C_field1 {{widen this field to 2 bits to store all values of 'C'}}
   s->field2 = (EnumType)x;
   s->field3 = (EnumType)x;
   s->field4 = x;
-  // expected-warning at -1 {{bit-field 'field4' is not wide enough to store all enumerators of preferred type 'C'}}
+  // expected-error at -1 {{bit-field 'field4' is not wide enough to store all enumerators of preferred type 'C'}}
   // expected-note@#S_C_field4 {{widen this field to 2 bits to store all values of 'C'}}
-  // expected-note@#preferred_S_C_field4 {{preferred type for bitfield 'C' specified here}}
+  // expected-note@#preferred_S_C_field4 {{preferred type for bit-field 'C' specified here}}
   s->field5 = x;
   s->field6 = x;
   s->field7 = x;
-  // expected-warning at -1 {{bit-field 'field7' is not wide enough to store all enumerators of preferred type 'C'}}
+  // expected-error at -1 {{bit-field 'field7' is not wide enough to store all enumerators of preferred type 'C'}}
   // expected-note@#S_C_field7 {{widen this field to 2 bits to store all values of 'C'}}
-  // expected-note@#preferred_S_C_field7 {{preferred type for bitfield 'C' specified here}}
+  // expected-note@#preferred_S_C_field7 {{preferred type for bit-field 'C' specified here}}
   s->field8 = x;
-  // expected-warning at -1 {{signed bit-field 'field8' needs an extra bit to represent the largest positive enumerators of preferred type 'C'}}
-  // expected-note@#S_C_field8 {{consider making the bitfield type unsigned}}
-  // expected-note@#preferred_S_C_field8 {{preferred type for bitfield 'C' specified here}}
+  // expected-error at -1 {{signed bit-field 'field8' needs an extra bit to represent the largest positive enumerators of preferred type 'C'}}
+  // expected-note@#S_C_field8 {{consider making the bit-field type unsigned}}
+  // expected-note@#preferred_S_C_field8 {{preferred type for bit-field 'C' specified here}}
   s->field9 = x;
   s->field10 = (Derp)x;
   s->field11 = (Derp)x;

>From cbb6a203a17fb497c485587a7ac6006f81c2694a Mon Sep 17 00:00:00 2001
From: Oliver Hunt <oliver at apple.com>
Date: Sat, 4 Jan 2025 10:22:29 -0800
Subject: [PATCH 6/9] Sigh, i realised this change was not necessary but had
 not added it to the commit

---
 clang/include/clang/Basic/DiagnosticGroups.td | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/clang/include/clang/Basic/DiagnosticGroups.td b/clang/include/clang/Basic/DiagnosticGroups.td
index 55e82c905e843..318f2df11ca08 100644
--- a/clang/include/clang/Basic/DiagnosticGroups.td
+++ b/clang/include/clang/Basic/DiagnosticGroups.td
@@ -1116,9 +1116,7 @@ def Most : DiagGroup<"most", [
     PrivateExtern,
     SelTypeCast,
     ExternCCompat,
-    UserDefinedWarnings,
-    PreferredTypeBitFieldEnumConversion,
-    PreferredTypeBitFieldWidth 
+    UserDefinedWarnings
  ]>;
 
 // Thread Safety warnings

>From f45ff2c3aa1e46ec6e855399c7715548043d4e09 Mon Sep 17 00:00:00 2001
From: Oliver Hunt <oliver at apple.com>
Date: Sat, 12 Apr 2025 15:40:26 -0700
Subject: [PATCH 7/9] Addressing feedback

---
 .../clang/Basic/DiagnosticSemaKinds.td        |   2 +-
 clang/lib/Sema/SemaChecking.cpp               |   2 +-
 .../Sema/bitfield-preferred-type-sizing.c     |   4 +-
 .../bitfield-preferred-type-sizing.cpp        | 347 +++++++++---------
 4 files changed, 176 insertions(+), 179 deletions(-)

diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 326c248e2d493..790038249376d 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -6472,7 +6472,7 @@ def warn_preferred_type_bitfield_too_small_for_enum : Warning<
 def warn_preferred_type_unsigned_bitfield_assigned_signed_enum : Warning<
   "assigning value of preferred signed enum type %1 to unsigned bit-field %0; "
   "negative enumerators of enum %1 will be converted to positive values">,
-  InGroup<PreferredTypeBitFieldEnumConversion>, DefaultIgnore;
+  InGroup<PreferredTypeBitFieldEnumConversion>, DefaultError;
 def warn_preferred_type_signed_bitfield_enum_conversion : Warning<
   "signed bit-field %0 needs an extra bit to represent the largest positive "
   "enumerators of preferred type %1">,
diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp
index 29b68da7a2eb0..b95fe019dec23 100644
--- a/clang/lib/Sema/SemaChecking.cpp
+++ b/clang/lib/Sema/SemaChecking.cpp
@@ -11243,7 +11243,7 @@ static bool AnalyzeBitFieldAssignment(Sema &S, FieldDecl *Bitfield, Expr *Init,
     }
     if (EnumTy) {
       EnumDecl *ED = EnumTy->getDecl();
-      bool SignedBitfield = BitfieldType->isSignedIntegerType();
+      bool SignedBitfield = BitfieldType->hasSignedIntegerRepresentation();
 
       // Enum types are implicitly signed on Windows, so check if there are any
       // negative enumerators to see if the enum was intended to be signed or
diff --git a/clang/test/Sema/bitfield-preferred-type-sizing.c b/clang/test/Sema/bitfield-preferred-type-sizing.c
index ab8c98dc35400..28f51529abc5e 100644
--- a/clang/test/Sema/bitfield-preferred-type-sizing.c
+++ b/clang/test/Sema/bitfield-preferred-type-sizing.c
@@ -1,6 +1,6 @@
-// RUN: %clang_cc1 %s -triple=x86_64-apple-darwin10 -fsyntax-only -verify=expected,preferrednotes -std=c11 -Wno-unused-value -Wno-unused-but-set-variable
+// RUN: %clang_cc1 %s -triple=x86_64-apple-darwin10 -fsyntax-only -verify=expected,preferrednotes -std=c23 -Wno-unused-value -Wno-unused-but-set-variable
 // RUN: %clang_cc1 %s -triple=x86_64-apple-darwin10 -fsyntax-only -verify=expected,bitfieldwarning,preferrednotes -std=c11 -Wno-unused-value -Wno-unused-but-set-variable -Wbitfield-width -Wbitfield-enum-conversion
-// RUN: %clang_cc1 %s -triple=x86_64-apple-darwin10 -fsyntax-only -verify=noerror,preferrednotes -std=c11 -Wno-unused-value -Wno-unused-but-set-variable -Wno-error=preferred-type-bitfield-enum-conversion -Wno-error=preferred-type-bitfield-width
+// RUN: %clang_cc1 %s -triple=x86_64-apple-darwin10 -fsyntax-only -verify=noerror,preferrednotes -std=c23 -Wno-unused-value -Wno-unused-but-set-variable -Wno-error=preferred-type-bitfield-enum-conversion -Wno-error=preferred-type-bitfield-width
 
 enum A {
   A_a,
diff --git a/clang/test/SemaCXX/bitfield-preferred-type-sizing.cpp b/clang/test/SemaCXX/bitfield-preferred-type-sizing.cpp
index 442463c5f23b8..c0ea3d1c503ec 100644
--- a/clang/test/SemaCXX/bitfield-preferred-type-sizing.cpp
+++ b/clang/test/SemaCXX/bitfield-preferred-type-sizing.cpp
@@ -1,39 +1,33 @@
-// RUN: %clang_cc1 %s -triple=x86_64-apple-darwin10 -fsyntax-only -verify -std=c++23 -Wno-unused-value -Wno-unused-but-set-variable
-// RUN: %clang_cc1 %s -triple=x86_64-apple-darwin10 -fsyntax-only -verify=expected,bitfieldwarnings -std=c++23 -Wno-unused-value -Wno-unused-but-set-variable -Wbitfield-width -Wbitfield-enum-conversion
+// RUN: %clang_cc1 %s      -std=c++23 -triple=x86_64-apple-darwin10 -fsyntax-only -verify=expected,bitfieldwarnings,cpp -Wno-unused-value -Wno-unused-but-set-variable -Wbitfield-width -Wbitfield-enum-conversion
+// RUN: %clang_cc1 %s      -std=c++23 -triple=x86_64-apple-darwin10 -fsyntax-only -verify=expected,cpp -Wno-unused-value -Wno-unused-but-set-variable
 
-// This is more complex than the C version because the user can specify the
-// storage type 
+// RUN: %clang_cc1 %s -x c -std=c23   -triple=x86_64-apple-darwin10 -fsyntax-only -verify=expected,c -Wno-unused-value -Wno-unused-but-set-variable
+// RUN: %clang_cc1 %s -x c -std=c23   -triple=x86_64-apple-darwin10 -fsyntax-only -verify=expected,bitfieldwarnings,c -Wno-unused-value -Wno-unused-but-set-variable -Wbitfield-width -Wbitfield-enum-conversion
 
-enum A {
+
+typedef enum A {
   A_a,
   A_b,
   A_c,
   A_d
-};
+} A;
 
-enum class B : int {
-  a,
-  b,
-  c,
-  d
-};
+#ifdef __cplusplus
+#define DEFINE_ENUM(_Name, _Type, ...) enum class _Name : _Type { __VA_ARGS__ } ;
+#define ENUM_CLASS_REF(_Name, _Enum) _Name::_Enum
+#else
+#define DEFINE_ENUM(_Name, _Type, ...) typedef enum _Name : _Type { __VA_ARGS__ } _Name;
+#define ENUM_CLASS_REF(_Name, _Enum) _Enum
+#endif
 
-enum class C : unsigned {
-  a,
-  b,
-  c,
-  d
-};
-
-enum class Derp : unsigned {
-  a,
-  b
-};
+DEFINE_ENUM(B, int, B_a, B_b, B_c, B_d );
+DEFINE_ENUM(C, unsigned, C_a, C_b, C_c, C_d );
+DEFINE_ENUM(D, unsigned, D_a, D_b);
 
 // Not using templates here so we can more easily distinguish the responsible
 // party for each warning
 
-struct S_A {
+typedef struct S_A {
   A field1 : 1; // #S_A_field1
   A field2 : 2; // #S_A_field2
   A field3 : 8; // #S_A_field3
@@ -50,14 +44,14 @@ struct S_A {
   __attribute__((preferred_type(A)))
   int field9 : 8; // #S_A_field9
   __attribute__((preferred_type(A)))
-  Derp field10 : 1; // #S_A_field10
+  D field10 : 1; // #S_A_field10
   __attribute__((preferred_type(A))) // #preferred_S_A_field11
-  Derp field11 : 2; // #S_A_field11
+  D field11 : 2; // #S_A_field11
   __attribute__((preferred_type(A)))
-  Derp field12 : 8; // #S_A_field12
-};
+  D field12 : 8; // #S_A_field12
+} S_A;
 
-struct S_B {
+typedef struct S_B {
   B field1 : 1; // #S_B_field1
   B field2 : 2; // #S_B_field2
   B field3 : 8; // #S_B_field3
@@ -74,14 +68,14 @@ struct S_B {
   __attribute__((preferred_type(B)))
   int field9 : 8; // #S_B_field9
   __attribute__((preferred_type(B)))
-  Derp field10 : 1; // #S_B_field10
+  D field10 : 1; // #S_B_field10
   __attribute__((preferred_type(B))) // #preferred_S_B_field11
-  Derp field11 : 2; // #S_B_field11
+  D field11 : 2; // #S_B_field11
   __attribute__((preferred_type(B)))
-  Derp field12 : 8; // #S_B_field12
-};
+  D field12 : 8; // #S_B_field12
+} S_B;
 
-struct S_C {
+typedef struct S_C {
   C field1 : 1; // #S_C_field1
   C field2 : 2; // #S_C_field2
   C field3 : 8; // #S_C_field3
@@ -98,65 +92,62 @@ struct S_C {
   __attribute__((preferred_type(C)))
   int field9 : 8; // #S_C_field9
   __attribute__((preferred_type(C)))
-  Derp field10 : 1; // #S_C_field10
+  D field10 : 1; // #S_C_field10
   __attribute__((preferred_type(C))) // #preferred_S_C_field11
-  Derp field11 : 2; // #S_C_field11
+  D field11 : 2; // #S_C_field11
   __attribute__((preferred_type(C)))
-  Derp field12 : 8; // #S_C_field12
-};
+  D field12 : 8; // #S_C_field12
+} S_C;
 
-void read_enum(S_A *s) {
-  using EnumType = A;
-  EnumType x;
+void read_enumA(S_A *s) {
+  A x;
   x = s->field1;
   x = s->field2;
   x = s->field3;
-  x = (EnumType)s->field4;
-  x = (EnumType)s->field5;
-  x = (EnumType)s->field6;
-  x = (EnumType)s->field7;
-  x = (EnumType)s->field8;
-  x = (EnumType)s->field9;
-  x = (EnumType)s->field10;
-  x = (EnumType)s->field11;
-  x = (EnumType)s->field12;
+  x = (A)s->field4;
+  x = (A)s->field5;
+  x = (A)s->field6;
+  x = (A)s->field7;
+  x = (A)s->field8;
+  x = (A)s->field9;
+  x = (A)s->field10;
+  x = (A)s->field11;
+  x = (A)s->field12;
 }
 
-void read_enum(S_B *s) {
-  using EnumType = B;
-  EnumType x;
+void read_enumB(S_B *s) {
+  B x;
   x = s->field1;
   x = s->field2;
   x = s->field3;
-  x = (EnumType)s->field4;
-  x = (EnumType)s->field5;
-  x = (EnumType)s->field6;
-  x = (EnumType)s->field7;
-  x = (EnumType)s->field8;
-  x = (EnumType)s->field9;
-  x = (EnumType)s->field10;
-  x = (EnumType)s->field11;
-  x = (EnumType)s->field12;
+  x = (B)s->field4;
+  x = (B)s->field5;
+  x = (B)s->field6;
+  x = (B)s->field7;
+  x = (B)s->field8;
+  x = (B)s->field9;
+  x = (B)s->field10;
+  x = (B)s->field11;
+  x = (B)s->field12;
 }
 
-void read_enum(S_C *s) {
-  using EnumType = C;
-  EnumType x;
+void read_enumC(S_C *s) {
+  C x;
   x = s->field1;
   x = s->field2;
   x = s->field3;
-  x = (EnumType)s->field4;
-  x = (EnumType)s->field5;
-  x = (EnumType)s->field6;
-  x = (EnumType)s->field7;
-  x = (EnumType)s->field8;
-  x = (EnumType)s->field9;
-  x = (EnumType)s->field10;
-  x = (EnumType)s->field11;
-  x = (EnumType)s->field12;
+  x = (C)s->field4;
+  x = (C)s->field5;
+  x = (C)s->field6;
+  x = (C)s->field7;
+  x = (C)s->field8;
+  x = (C)s->field9;
+  x = (C)s->field10;
+  x = (C)s->field11;
+  x = (C)s->field12;
 }
 
-void write_enum(S_A *s, A x) {
+void write_enumA(S_A *s, A x) {
   s->field1 = x;
   // bitfieldwarnings-warning at -1 {{bit-field 'field1' is not wide enough to store all enumerators of 'A'}}
   // bitfieldwarnings-note@#S_A_field1 {{widen this field to 2 bits to store all values of 'A'}}
@@ -174,16 +165,19 @@ void write_enum(S_A *s, A x) {
   // bitfieldwarnings-warning at -1 {{signed bit-field 'field8' needs an extra bit to represent the largest positive enumerators of 'A'}}
   // bitfieldwarnings-note@#S_A_field8 {{consider making the bit-field type unsigned}}
   s->field9 = x;
-  s->field10 = (Derp)x;
-  s->field11 = (Derp)x;
-  s->field12 = (Derp)x;
+  s->field10 = (D)x;
+  s->field11 = (D)x;
+  s->field12 = (D)x;
 }
 
-void write_enum(S_B *s, B x) {
+void write_enumB(S_B *s, B x) {
   s->field1 = x;
   // bitfieldwarnings-warning at -1 {{bit-field 'field1' is not wide enough to store all enumerators of 'B'}}
   // bitfieldwarnings-note@#S_B_field1 {{widen this field to 2 bits to store all values of 'B'}}
   s->field2 = x;
+  // bitfieldwarnings-warning at -1 {{signed bit-field 'field2' needs an extra bit to represent the largest positive enumerators of 'B'}}
+  // bitfieldwarnings-note@#S_B_field2 {{consider making the bit-field type unsigned}}
+  
   s->field3 = x;
   s->field4 = (unsigned)x;
   // expected-error at -1 {{bit-field 'field4' is not wide enough to store all enumerators of preferred type 'B'}}
@@ -200,11 +194,11 @@ void write_enum(S_B *s, B x) {
   // expected-note@#S_B_field8 {{consider making the bit-field type unsigned}}
   // expected-note@#preferred_S_B_field8 {{preferred type for bit-field 'B' specified here}}
   s->field9 = (int)x;
-  s->field10 = (Derp)x;
-  s->field11 = (Derp)x;
-  s->field12 = (Derp)x;
+  s->field10 = (D)x;
+  s->field11 = (D)x;
+  s->field12 = (D)x;
 }
-void write_enum(S_C *s, C x) {
+void write_enumC(S_C *s, C x) {
   s->field1 = x;
   // bitfieldwarnings-warning at -1 {{bit-field 'field1' is not wide enough to store all enumerators of 'C'}}
   // bitfieldwarnings-note@#S_C_field1 {{widen this field to 2 bits to store all values of 'C'}}
@@ -225,18 +219,17 @@ void write_enum(S_C *s, C x) {
   // expected-note@#S_C_field8 {{consider making the bit-field type unsigned}}
   // expected-note@#preferred_S_C_field8 {{preferred type for bit-field 'C' specified here}}
   s->field9 = (int)x;
-  s->field10 = (Derp)x;
-  s->field11 = (Derp)x;
-  s->field12 = (Derp)x;
+  s->field10 = (D)x;
+  s->field11 = (D)x;
+  s->field12 = (D)x;
 }
 
-void write_enum_int(struct S_A *s, int x) {
-  using EnumType = A;
-  s->field1 = (EnumType)x;
+void write_enum_intA(struct S_A *s, int x) {
+  s->field1 = (A)x;
   // bitfieldwarnings-warning at -1 {{bit-field 'field1' is not wide enough to store all enumerators of 'A'}}
   // bitfieldwarnings-note@#S_A_field1 {{widen this field to 2 bits to store all values of 'A'}}
-  s->field2 = (EnumType)x;
-  s->field3 = (EnumType)x;
+  s->field2 = (A)x;
+  s->field3 = (A)x;
   s->field4 = x;
   // expected-error at -1 {{bit-field 'field4' is not wide enough to store all enumerators of preferred type 'A'}}
   // expected-note@#S_A_field4 {{widen this field to 2 bits to store all values of 'A'}}
@@ -252,18 +245,19 @@ void write_enum_int(struct S_A *s, int x) {
   // expected-note@#S_A_field8 {{consider making the bit-field type unsigned}}
   // expected-note@#preferred_S_A_field8 {{preferred type for bit-field 'A' specified here}}
   s->field9 = x;
-  s->field10 = (Derp)x;
-  s->field11 = (Derp)x;
-  s->field12 = (Derp)x;
+  s->field10 = (D)x;
+  s->field11 = (D)x;
+  s->field12 = (D)x;
 }
 
-void write_enum_int(struct S_B *s, int x) {
-  using EnumType = B;
-  s->field1 = (EnumType)x;
+void write_enum_intB(struct S_B *s, int x) {
+  s->field1 = (B)x;
   // bitfieldwarnings-warning at -1 {{bit-field 'field1' is not wide enough to store all enumerators of 'B'}}
   // bitfieldwarnings-note@#S_B_field1 {{widen this field to 2 bits to store all values of 'B'}}
-  s->field2 = (EnumType)x;
-  s->field3 = (EnumType)x;
+  s->field2 = (B)x;
+  // bitfieldwarnings-warning at -1 {{signed bit-field 'field2' needs an extra bit to represent the largest positive enumerators of 'B'}}
+  // bitfieldwarnings-note@#S_B_field2 {{consider making the bit-field type unsigned}}
+  s->field3 = (B)x;
   s->field4 = x;
   // expected-error at -1 {{bit-field 'field4' is not wide enough to store all enumerators of preferred type 'B'}}
   // expected-note@#S_B_field4 {{widen this field to 2 bits to store all values of 'B'}}
@@ -279,18 +273,17 @@ void write_enum_int(struct S_B *s, int x) {
   // expected-note@#S_B_field8 {{consider making the bit-field type unsigned}}
   // expected-note@#preferred_S_B_field8 {{preferred type for bit-field 'B' specified here}}
   s->field9 = x;
-  s->field10 = (Derp)x;
-  s->field11 = (Derp)x;
-  s->field12 = (Derp)x;
+  s->field10 = (D)x;
+  s->field11 = (D)x;
+  s->field12 = (D)x;
 }
 
-void write_enum_int(struct S_C *s, int x) {
-  using EnumType = C;
-  s->field1 = (EnumType)x;
+void write_enum_intC(struct S_C *s, int x) {
+  s->field1 = (C)x;
   // bitfieldwarnings-warning at -1 {{bit-field 'field1' is not wide enough to store all enumerators of 'C'}}
   // bitfieldwarnings-note@#S_C_field1 {{widen this field to 2 bits to store all values of 'C'}}
-  s->field2 = (EnumType)x;
-  s->field3 = (EnumType)x;
+  s->field2 = (C)x;
+  s->field3 = (C)x;
   s->field4 = x;
   // expected-error at -1 {{bit-field 'field4' is not wide enough to store all enumerators of preferred type 'C'}}
   // expected-note@#S_C_field4 {{widen this field to 2 bits to store all values of 'C'}}
@@ -306,12 +299,12 @@ void write_enum_int(struct S_C *s, int x) {
   // expected-note@#S_C_field8 {{consider making the bit-field type unsigned}}
   // expected-note@#preferred_S_C_field8 {{preferred type for bit-field 'C' specified here}}
   s->field9 = x;
-  s->field10 = (Derp)x;
-  s->field11 = (Derp)x;
-  s->field12 = (Derp)x;
+  s->field10 = (D)x;
+  s->field11 = (D)x;
+  s->field12 = (D)x;
 }
 
-void write_low_constant(S_A *s) {
+void write_low_constantA(S_A *s) {
   s->field1 = A_a;
   s->field2 = A_a;
   s->field3 = A_a;
@@ -321,94 +314,98 @@ void write_low_constant(S_A *s) {
   s->field7 = A_a;
   s->field8 = A_a;
   s->field9 = A_a;
-  s->field10 = (Derp)A_a;
-  s->field11 = (Derp)A_a;
-  s->field12 = (Derp)A_a;
+  s->field10 = (D)A_a;
+  s->field11 = (D)A_a;
+  s->field12 = (D)A_a;
 };
 
-void write_low_constant(S_B *s) {
-  using EnumType = B;
-  s->field1 = EnumType::a;
-  s->field2 = EnumType::a;
-  s->field3 = EnumType::a;
-  s->field4 = (unsigned)EnumType::a;
-  s->field5 = (unsigned)EnumType::a;
-  s->field6 = (unsigned)EnumType::a;
-  s->field7 = (int)EnumType::a;
-  s->field8 = (int)EnumType::a;
-  s->field9 = (int)EnumType::a;
-  s->field10 = (Derp)EnumType::a;
-  s->field11 = (Derp)EnumType::a;
-  s->field12 = (Derp)EnumType::a;
+void write_low_constantB(S_B *s) {
+  s->field1 = ENUM_CLASS_REF(B, B_a);
+  s->field2 = ENUM_CLASS_REF(B, B_a);
+  s->field3 = ENUM_CLASS_REF(B, B_a);
+  s->field4 = (unsigned)ENUM_CLASS_REF(B, B_a);
+  s->field5 = (unsigned)ENUM_CLASS_REF(B, B_a);
+  s->field6 = (unsigned)ENUM_CLASS_REF(B, B_a);
+  s->field7 = (int)ENUM_CLASS_REF(B, B_a);
+  s->field8 = (int)ENUM_CLASS_REF(B, B_a);
+  s->field9 = (int)ENUM_CLASS_REF(B, B_a);
+  s->field10 = (D)ENUM_CLASS_REF(B, B_a);
+  s->field11 = (D)ENUM_CLASS_REF(B, B_a);
+  s->field12 = (D)ENUM_CLASS_REF(B, B_a);
 };
 
-void write_low_constant(S_C *s) {
-  using EnumType = C;
-  s->field1 = EnumType::a;
-  s->field2 = EnumType::a;
-  s->field3 = EnumType::a;
-  s->field4 = (unsigned)EnumType::a;
-  s->field5 = (unsigned)EnumType::a;
-  s->field6 = (unsigned)EnumType::a;
-  s->field7 = (int)EnumType::a;
-  s->field8 = (int)EnumType::a;
-  s->field9 = (int)EnumType::a;
-  s->field10 = (Derp)EnumType::a;
-  s->field11 = (Derp)EnumType::a;
-  s->field12 = (Derp)EnumType::a;
+void write_low_constantC(S_C *s) {
+  s->field1 = ENUM_CLASS_REF(C, C_a);
+  s->field2 = ENUM_CLASS_REF(C, C_a);
+  s->field3 = ENUM_CLASS_REF(C, C_a);
+  s->field4 = (unsigned)ENUM_CLASS_REF(C, C_a);
+  s->field5 = (unsigned)ENUM_CLASS_REF(C, C_a);
+  s->field6 = (unsigned)ENUM_CLASS_REF(C, C_a);
+  s->field7 = (int)ENUM_CLASS_REF(C, C_a);
+  s->field8 = (int)ENUM_CLASS_REF(C, C_a);
+  s->field9 = (int)ENUM_CLASS_REF(C, C_a);
+  s->field10 = (D)ENUM_CLASS_REF(C, C_a);
+  s->field11 = (D)ENUM_CLASS_REF(C, C_a);
+  s->field12 = (D)ENUM_CLASS_REF(C, C_a);
 };
 
-void write_high_constant(S_A *s) {
+void write_high_constantA(S_A *s) {
   s->field1 = A_d;
-  // expected-warning at -1 {{implicit truncation from 'A' to bit-field changes value from 3 to 1}}
+  // cpp-warning at -1 {{implicit truncation from 'A' to bit-field changes value from 3 to 1}}
+  // c-warning at -2 {{implicit truncation from 'int' to bit-field changes value from 3 to 1}}
   s->field2 = A_d;
   s->field3 = A_d;
   s->field4 = A_d;
-  // expected-warning at -1 {{implicit truncation from 'A' to bit-field changes value from 3 to 1}}
+  // cpp-warning at -1 {{implicit truncation from 'A' to bit-field changes value from 3 to 1}}
+  // c-warning at -2 {{implicit truncation from 'int' to bit-field changes value from 3 to 1}}
   s->field5 = A_d;
   s->field6 = A_d;
   s->field7 = A_d;
-  // expected-warning at -1 {{implicit truncation from 'A' to bit-field changes value from 3 to -1}}
+  // cpp-warning at -1 {{implicit truncation from 'A' to bit-field changes value from 3 to -1}}
+  // c-warning at -2 {{implicit truncation from 'int' to bit-field changes value from 3 to -1}}
   s->field8 = A_d;
-  // expected-warning at -1 {{implicit truncation from 'A' to bit-field changes value from 3 to -1}}
+  // cpp-warning at -1 {{implicit truncation from 'A' to bit-field changes value from 3 to -1}}
+  // c-warning at -2 {{implicit truncation from 'int' to bit-field changes value from 3 to -1}}
   s->field9 = A_d;
-  s->field10 = (Derp)A_d;
-  // expected-warning at -1 {{implicit truncation from 'Derp' to bit-field changes value from 3 to 1}}
-  s->field11 = (Derp)A_d;
-  s->field12 = (Derp)A_d;
+  s->field10 = (D)A_d;
+  // cpp-warning at -1 {{implicit truncation from 'D' to bit-field changes value from 3 to 1}}
+  // c-warning at -2 {{implicit truncation from 'D' (aka 'enum D') to bit-field changes value from 3 to 1}}
+  s->field11 = (D)A_d;
+  s->field12 = (D)A_d;
 };
 
-void write_high_constant(S_B *s) {
-  using EnumType = B;
-  s->field1 = EnumType::d;
-  // expected-warning at -1 {{implicit truncation from 'B' to bit-field changes value from 3 to 1}}
-  s->field2 = EnumType::d;
-  s->field3 = EnumType::d;
-  s->field4 = (unsigned)EnumType::d;
+void write_high_constantB(S_B *s) {
+  s->field1 = ENUM_CLASS_REF(B, B_d);
+  // cpp-warning at -1 {{implicit truncation from 'B' to bit-field changes value from 3 to 1}}
+  // c-warning at -2 {{implicit truncation from 'int' to bit-field changes value from 3 to -1}}
+  s->field2 = ENUM_CLASS_REF(B, B_d);
+  // c-warning at -1 {{implicit truncation from 'int' to bit-field changes value from 3 to -1}}
+  s->field3 = ENUM_CLASS_REF(B, B_d);
+  s->field4 = (unsigned)ENUM_CLASS_REF(B, B_d);
   // expected-warning at -1 {{implicit truncation from 'unsigned int' to bit-field changes value from 3 to 1}}
-  s->field5 = (unsigned)EnumType::d;
-  s->field6 = (unsigned)EnumType::d;
-  s->field7 = (int)EnumType::d;
+  s->field5 = (unsigned)ENUM_CLASS_REF(B, B_d);
+  s->field6 = (unsigned)ENUM_CLASS_REF(B, B_d);
+  s->field7 = (int)ENUM_CLASS_REF(B, B_d);
   // expected-warning at -1 {{implicit truncation from 'int' to bit-field changes value from 3 to -1}}
-  s->field8 = (int)EnumType::d;
+  s->field8 = (int)ENUM_CLASS_REF(B, B_d);
   // expected-warning at -1 {{implicit truncation from 'int' to bit-field changes value from 3 to -1}}
-  s->field9 = (int)EnumType::d;
+  s->field9 = (int)ENUM_CLASS_REF(B, B_d);
 };
 
 
-void write_high_constant(S_C *s) {
-  using EnumType = C;
-  s->field1 = EnumType::d;
-  // expected-warning at -1 {{implicit truncation from 'C' to bit-field changes value from 3 to 1}}
-  s->field2 = EnumType::d;
-  s->field3 = EnumType::d;
-  s->field4 = (unsigned)EnumType::d;
+void write_high_constantC(S_C *s) {
+  s->field1 = ENUM_CLASS_REF(C, C_d);
+  // cpp-warning at -1 {{implicit truncation from 'C' to bit-field changes value from 3 to 1}}
+  // c-warning at -2 {{implicit truncation from 'unsigned int' to bit-field changes value from 3 to 1}}
+  s->field2 = ENUM_CLASS_REF(C, C_d);
+  s->field3 = ENUM_CLASS_REF(C, C_d);
+  s->field4 = (unsigned)ENUM_CLASS_REF(C, C_d);
   // expected-warning at -1 {{implicit truncation from 'unsigned int' to bit-field changes value from 3 to 1}}
-  s->field5 = (unsigned)EnumType::d;
-  s->field6 = (unsigned)EnumType::d;
-  s->field7 = (int)EnumType::d;
+  s->field5 = (unsigned)ENUM_CLASS_REF(C, C_d);
+  s->field6 = (unsigned)ENUM_CLASS_REF(C, C_d);
+  s->field7 = (int)ENUM_CLASS_REF(C, C_d);
   // expected-warning at -1 {{implicit truncation from 'int' to bit-field changes value from 3 to -1}}
-  s->field8 = (int)EnumType::d;
+  s->field8 = (int)ENUM_CLASS_REF(C, C_d);
   // expected-warning at -1 {{implicit truncation from 'int' to bit-field changes value from 3 to -1}}
-  s->field9 = (int)EnumType::d;
+  s->field9 = (int)ENUM_CLASS_REF(C, C_d);
 };

>From e131e4ff4dcdad8ba6f3c6ed43a97307db608f58 Mon Sep 17 00:00:00 2001
From: Oliver Hunt <oliver at apple.com>
Date: Sat, 12 Apr 2025 23:21:38 -0700
Subject: [PATCH 8/9] Updated release notes, made the diagnostics default on,
 not default error

---
 clang/docs/ReleaseNotes.rst                   |   8 ++
 .../clang/Basic/DiagnosticSemaKinds.td        |   6 +-
 clang/lib/Sema/SemaChecking.cpp               |   2 +-
 .../Sema/bitfield-preferred-type-sizing.c     | 113 ------------------
 .../bitfield-preferred-type-sizing.cpp        |  32 ++---
 5 files changed, 28 insertions(+), 133 deletions(-)
 delete mode 100644 clang/test/Sema/bitfield-preferred-type-sizing.c

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 9c45965dc4d82..9cfc0952cc98c 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -350,6 +350,14 @@ Improvements to Clang's diagnostics
 - Now correctly diagnose a tentative definition of an array with static
   storage duration in pedantic mode in C. (#GH50661)
 
+- Improved bit-field diagnostics to consider the type specified by the
+  ``preferred_type`` attribute. These diagnostics are controlled by the flags
+  ``-Wpreferred-type-bitfield-enum-conversion`` and
+  ``-Wpreferred-type-bitfield-width``. These warnings are on by default as they
+  they're only triggered if the authors are already making the choice to use
+  ``preferred_type`` attribute.
+
+
 Improvements to Clang's time-trace
 ----------------------------------
 
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 790038249376d..1d6d6691c0b76 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -6468,15 +6468,15 @@ def warn_signed_bitfield_enum_conversion : Warning<
   InGroup<BitFieldEnumConversion>, DefaultIgnore;
 def warn_preferred_type_bitfield_too_small_for_enum : Warning<
   "bit-field %0 is not wide enough to store all enumerators of preferred type %1">,
-  InGroup<PreferredTypeBitFieldEnumConversion>, DefaultError;
+  InGroup<PreferredTypeBitFieldEnumConversion>;
 def warn_preferred_type_unsigned_bitfield_assigned_signed_enum : Warning<
   "assigning value of preferred signed enum type %1 to unsigned bit-field %0; "
   "negative enumerators of enum %1 will be converted to positive values">,
-  InGroup<PreferredTypeBitFieldEnumConversion>, DefaultError;
+  InGroup<PreferredTypeBitFieldEnumConversion>;
 def warn_preferred_type_signed_bitfield_enum_conversion : Warning<
   "signed bit-field %0 needs an extra bit to represent the largest positive "
   "enumerators of preferred type %1">,
-  InGroup<PreferredTypeBitFieldEnumConversion>, DefaultError;
+  InGroup<PreferredTypeBitFieldEnumConversion>;
 def note_change_bitfield_sign : Note<
   "consider making the bit-field type %select{unsigned|signed}0">;
 def note_bitfield_preferred_type : Note<
diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp
index b95fe019dec23..a43680e8fbeef 100644
--- a/clang/lib/Sema/SemaChecking.cpp
+++ b/clang/lib/Sema/SemaChecking.cpp
@@ -11243,7 +11243,7 @@ static bool AnalyzeBitFieldAssignment(Sema &S, FieldDecl *Bitfield, Expr *Init,
     }
     if (EnumTy) {
       EnumDecl *ED = EnumTy->getDecl();
-      bool SignedBitfield = BitfieldType->hasSignedIntegerRepresentation();
+      bool SignedBitfield = BitfieldType->isSignedIntegerOrEnumerationType();
 
       // Enum types are implicitly signed on Windows, so check if there are any
       // negative enumerators to see if the enum was intended to be signed or
diff --git a/clang/test/Sema/bitfield-preferred-type-sizing.c b/clang/test/Sema/bitfield-preferred-type-sizing.c
deleted file mode 100644
index 28f51529abc5e..0000000000000
--- a/clang/test/Sema/bitfield-preferred-type-sizing.c
+++ /dev/null
@@ -1,113 +0,0 @@
-// RUN: %clang_cc1 %s -triple=x86_64-apple-darwin10 -fsyntax-only -verify=expected,preferrednotes -std=c23 -Wno-unused-value -Wno-unused-but-set-variable
-// RUN: %clang_cc1 %s -triple=x86_64-apple-darwin10 -fsyntax-only -verify=expected,bitfieldwarning,preferrednotes -std=c11 -Wno-unused-value -Wno-unused-but-set-variable -Wbitfield-width -Wbitfield-enum-conversion
-// RUN: %clang_cc1 %s -triple=x86_64-apple-darwin10 -fsyntax-only -verify=noerror,preferrednotes -std=c23 -Wno-unused-value -Wno-unused-but-set-variable -Wno-error=preferred-type-bitfield-enum-conversion -Wno-error=preferred-type-bitfield-width
-
-enum A {
-  A_a,
-  A_b,
-  A_c,
-  A_d
-};
-
-struct S {
-  enum A a1 : 1; // #S_a1_decl
-  enum A a2 : 2;
-  enum A a3 : 8;
-  __attribute__((preferred_type(enum A))) // #preferred_S_a4
-  unsigned a4 : 1; // #S_a4_decl
-  __attribute__((preferred_type(enum A)))
-  unsigned a5 : 2;
-  __attribute__((preferred_type(enum A)))
-  unsigned a6 : 8;
-  __attribute__((preferred_type(enum A)))  // #preferred_S_a7
-  int a7 : 1; // #S_a7_decl
-  __attribute__((preferred_type(enum A))) // #preferred_S_a8
-  int a8 : 2; // #S_a8_decl
-  __attribute__((preferred_type(enum A)))
-  int a9 : 8;
-};
-
-void read_enum(struct S *s) {
-  enum A x;
-  x = s->a1;
-  x = s->a2;
-  x = s->a3;
-  x = s->a4;
-  x = s->a5;
-  x = s->a6;
-  x = s->a7;
-  x = s->a8;
-  x = s->a9;
-}
-
-void write_enum(struct S *s, enum A x) {
-  s->a1 = x;
-  // bitfieldwarning-warning at -1 {{bit-field 'a1' is not wide enough to store all enumerators of 'A'}}
-  // bitfieldwarning-note@#S_a1_decl {{widen this field to 2 bits to store all values of 'A'}}
-  s->a2 = x;
-  s->a3 = x;
-  s->a4 = x;
-  // bitfieldwarning-warning at -1 {{bit-field 'a4' is not wide enough to store all enumerators of 'A'}}
-  // bitfieldwarning-note@#S_a4_decl {{widen this field to 2 bits to store all values of 'A'}}
-  s->a5 = x;
-  s->a6 = x;
-  s->a7 = x;
-  // bitfieldwarning-warning at -1 {{bit-field 'a7' is not wide enough to store all enumerators of 'A'}}
-  // bitfieldwarning-note@#S_a7_decl {{widen this field to 2 bits to store all values of 'A'}}
-  s->a8 = x;
-  // bitfieldwarning-warning at -1 {{signed bit-field 'a8' needs an extra bit to represent the largest positive enumerators of 'A'}}
-  // bitfieldwarning-note@#S_a8_decl {{consider making the bit-field type unsigned}}
-  s->a9 = x;
-}
-
-void write_enum_int(struct S *s, int x) {
-  s->a1 = x;
-  s->a2 = x;
-  s->a3 = x;
-  s->a4 = x;
-  // expected-error at -1 {{bit-field 'a4' is not wide enough to store all enumerators of preferred type 'A'}}
-  // noerror-warning at -2 {{bit-field 'a4' is not wide enough to store all enumerators of preferred type 'A'}}
-  // preferrednotes-note@#S_a4_decl {{widen this field to 2 bits to store all values of 'A'}}
-  // preferrednotes-note@#preferred_S_a4 {{preferred type for bit-field 'A' specified here}}
-  s->a5 = x;
-  s->a6 = x;
-  s->a7 = x;
-  // expected-error at -1 {{bit-field 'a7' is not wide enough to store all enumerators of preferred type 'A'}}
-  // noerror-warning at -2 {{bit-field 'a7' is not wide enough to store all enumerators of preferred type 'A'}}
-  // preferrednotes-note@#S_a7_decl {{widen this field to 2 bits to store all values of 'A'}}
-  // preferrednotes-note@#preferred_S_a7 {{preferred type for bit-field 'A' specified here}}
-  s->a8 = x;
-  // expected-error at -1 {{signed bit-field 'a8' needs an extra bit to represent the largest positive enumerators of preferred type 'A'}}
-  // noerror-warning at -2 {{signed bit-field 'a8' needs an extra bit to represent the largest positive enumerators of preferred type 'A'}}
-  // preferrednotes-note@#S_a8_decl {{consider making the bit-field type unsigned}}
-  // preferrednotes-note@#preferred_S_a8 {{preferred type for bit-field 'A' specified here}}
-  s->a9 = x;
-}
-
-void write_low_constant(struct S *s) {
-  s->a1 = A_a;
-  s->a2 = A_a;
-  s->a3 = A_a;
-  s->a4 = A_a;
-  s->a5 = A_a;
-  s->a6 = A_a;
-  s->a7 = A_a;
-  s->a8 = A_a;
-  s->a9 = A_a;
-};
-
-void write_high_constant(struct S *s) {
-  s->a1 = A_d;
-  // preferrednotes-warning at -1 {{implicit truncation from 'int' to bit-field changes value from 3 to 1}}
-  s->a2 = A_d;
-  s->a3 = A_d;
-  s->a4 = A_d;
-  // preferrednotes-warning at -1 {{implicit truncation from 'int' to bit-field changes value from 3 to 1}}
-  s->a5 = A_d;
-  s->a6 = A_d;
-  s->a7 = A_d;
-  // preferrednotes-warning at -1 {{implicit truncation from 'int' to bit-field changes value from 3 to -1}}
-  s->a8 = A_d;
-  // preferrednotes-warning at -1 {{implicit truncation from 'int' to bit-field changes value from 3 to -1}}
-  s->a9 = A_d;
-};
diff --git a/clang/test/SemaCXX/bitfield-preferred-type-sizing.cpp b/clang/test/SemaCXX/bitfield-preferred-type-sizing.cpp
index c0ea3d1c503ec..5eaa3eb2d85e3 100644
--- a/clang/test/SemaCXX/bitfield-preferred-type-sizing.cpp
+++ b/clang/test/SemaCXX/bitfield-preferred-type-sizing.cpp
@@ -177,20 +177,19 @@ void write_enumB(S_B *s, B x) {
   s->field2 = x;
   // bitfieldwarnings-warning at -1 {{signed bit-field 'field2' needs an extra bit to represent the largest positive enumerators of 'B'}}
   // bitfieldwarnings-note@#S_B_field2 {{consider making the bit-field type unsigned}}
-  
   s->field3 = x;
   s->field4 = (unsigned)x;
-  // expected-error at -1 {{bit-field 'field4' is not wide enough to store all enumerators of preferred type 'B'}}
+  // expected-warning at -1 {{bit-field 'field4' is not wide enough to store all enumerators of preferred type 'B'}}
   // expected-note@#S_B_field4 {{widen this field to 2 bits to store all values of 'B'}}
   // expected-note@#preferred_S_B_field4 {{preferred type for bit-field 'B' specified here}}
   s->field5 = (unsigned)x;
   s->field6 = (unsigned)x;
   s->field7 = (int)x;
-  // expected-error at -1 {{bit-field 'field7' is not wide enough to store all enumerators of preferred type 'B'}}
+  // expected-warning at -1 {{bit-field 'field7' is not wide enough to store all enumerators of preferred type 'B'}}
   // expected-note@#S_B_field7 {{widen this field to 2 bits to store all values of 'B'}}
   // expected-note@#preferred_S_B_field7 {{preferred type for bit-field 'B' specified here}}
   s->field8 = (int)x;
-  // expected-error at -1 {{signed bit-field 'field8' needs an extra bit to represent the largest positive enumerators of preferred type 'B'}}
+  // expected-warning at -1 {{signed bit-field 'field8' needs an extra bit to represent the largest positive enumerators of preferred type 'B'}}
   // expected-note@#S_B_field8 {{consider making the bit-field type unsigned}}
   // expected-note@#preferred_S_B_field8 {{preferred type for bit-field 'B' specified here}}
   s->field9 = (int)x;
@@ -198,6 +197,7 @@ void write_enumB(S_B *s, B x) {
   s->field11 = (D)x;
   s->field12 = (D)x;
 }
+
 void write_enumC(S_C *s, C x) {
   s->field1 = x;
   // bitfieldwarnings-warning at -1 {{bit-field 'field1' is not wide enough to store all enumerators of 'C'}}
@@ -205,17 +205,17 @@ void write_enumC(S_C *s, C x) {
   s->field2 = x;
   s->field3 = x;
   s->field4 = (unsigned)x;
-  // expected-error at -1 {{bit-field 'field4' is not wide enough to store all enumerators of preferred type 'C'}}
+  // expected-warning at -1 {{bit-field 'field4' is not wide enough to store all enumerators of preferred type 'C'}}
   // expected-note@#S_C_field4 {{widen this field to 2 bits to store all values of 'C'}}
   // expected-note@#preferred_S_C_field4 {{preferred type for bit-field 'C' specified here}}
   s->field5 = (unsigned)x;
   s->field6 = (unsigned)x;
   s->field7 = (int)x;
-  // expected-error at -1 {{bit-field 'field7' is not wide enough to store all enumerators of preferred type 'C'}}
+  // expected-warning at -1 {{bit-field 'field7' is not wide enough to store all enumerators of preferred type 'C'}}
   // expected-note@#S_C_field7 {{widen this field to 2 bits to store all values of 'C'}}
   // expected-note@#preferred_S_C_field7 {{preferred type for bit-field 'C' specified here}}
   s->field8 = (int)x;
-  // expected-error at -1 {{signed bit-field 'field8' needs an extra bit to represent the largest positive enumerators of preferred type 'C'}}
+  // expected-warning at -1 {{signed bit-field 'field8' needs an extra bit to represent the largest positive enumerators of preferred type 'C'}}
   // expected-note@#S_C_field8 {{consider making the bit-field type unsigned}}
   // expected-note@#preferred_S_C_field8 {{preferred type for bit-field 'C' specified here}}
   s->field9 = (int)x;
@@ -231,17 +231,17 @@ void write_enum_intA(struct S_A *s, int x) {
   s->field2 = (A)x;
   s->field3 = (A)x;
   s->field4 = x;
-  // expected-error at -1 {{bit-field 'field4' is not wide enough to store all enumerators of preferred type 'A'}}
+  // expected-warning at -1 {{bit-field 'field4' is not wide enough to store all enumerators of preferred type 'A'}}
   // expected-note@#S_A_field4 {{widen this field to 2 bits to store all values of 'A'}}
   // expected-note@#preferred_S_A_field4 {{preferred type for bit-field 'A' specified here}}
   s->field5 = x;
   s->field6 = x;
   s->field7 = x;
-  // expected-error at -1 {{bit-field 'field7' is not wide enough to store all enumerators of preferred type 'A'}}
+  // expected-warning at -1 {{bit-field 'field7' is not wide enough to store all enumerators of preferred type 'A'}}
   // expected-note@#S_A_field7 {{widen this field to 2 bits to store all values of 'A'}}
   // expected-note@#preferred_S_A_field7 {{preferred type for bit-field 'A' specified here}}
   s->field8 = x;
-  // expected-error at -1 {{signed bit-field 'field8' needs an extra bit to represent the largest positive enumerators of preferred type 'A'}}
+  // expected-warning at -1 {{signed bit-field 'field8' needs an extra bit to represent the largest positive enumerators of preferred type 'A'}}
   // expected-note@#S_A_field8 {{consider making the bit-field type unsigned}}
   // expected-note@#preferred_S_A_field8 {{preferred type for bit-field 'A' specified here}}
   s->field9 = x;
@@ -259,17 +259,17 @@ void write_enum_intB(struct S_B *s, int x) {
   // bitfieldwarnings-note@#S_B_field2 {{consider making the bit-field type unsigned}}
   s->field3 = (B)x;
   s->field4 = x;
-  // expected-error at -1 {{bit-field 'field4' is not wide enough to store all enumerators of preferred type 'B'}}
+  // expected-warning at -1 {{bit-field 'field4' is not wide enough to store all enumerators of preferred type 'B'}}
   // expected-note@#S_B_field4 {{widen this field to 2 bits to store all values of 'B'}}
   // expected-note@#preferred_S_B_field4 {{preferred type for bit-field 'B' specified here}}
   s->field5 = x;
   s->field6 = x;
   s->field7 = x;
-  // expected-error at -1 {{bit-field 'field7' is not wide enough to store all enumerators of preferred type 'B'}}
+  // expected-warning at -1 {{bit-field 'field7' is not wide enough to store all enumerators of preferred type 'B'}}
   // expected-note@#S_B_field7 {{widen this field to 2 bits to store all values of 'B'}}
   // expected-note@#preferred_S_B_field7 {{preferred type for bit-field 'B' specified here}}
   s->field8 = x;
-  // expected-error at -1 {{signed bit-field 'field8' needs an extra bit to represent the largest positive enumerators of preferred type 'B'}}
+  // expected-warning at -1 {{signed bit-field 'field8' needs an extra bit to represent the largest positive enumerators of preferred type 'B'}}
   // expected-note@#S_B_field8 {{consider making the bit-field type unsigned}}
   // expected-note@#preferred_S_B_field8 {{preferred type for bit-field 'B' specified here}}
   s->field9 = x;
@@ -285,17 +285,17 @@ void write_enum_intC(struct S_C *s, int x) {
   s->field2 = (C)x;
   s->field3 = (C)x;
   s->field4 = x;
-  // expected-error at -1 {{bit-field 'field4' is not wide enough to store all enumerators of preferred type 'C'}}
+  // expected-warning at -1 {{bit-field 'field4' is not wide enough to store all enumerators of preferred type 'C'}}
   // expected-note@#S_C_field4 {{widen this field to 2 bits to store all values of 'C'}}
   // expected-note@#preferred_S_C_field4 {{preferred type for bit-field 'C' specified here}}
   s->field5 = x;
   s->field6 = x;
   s->field7 = x;
-  // expected-error at -1 {{bit-field 'field7' is not wide enough to store all enumerators of preferred type 'C'}}
+  // expected-warning at -1 {{bit-field 'field7' is not wide enough to store all enumerators of preferred type 'C'}}
   // expected-note@#S_C_field7 {{widen this field to 2 bits to store all values of 'C'}}
   // expected-note@#preferred_S_C_field7 {{preferred type for bit-field 'C' specified here}}
   s->field8 = x;
-  // expected-error at -1 {{signed bit-field 'field8' needs an extra bit to represent the largest positive enumerators of preferred type 'C'}}
+  // expected-warning at -1 {{signed bit-field 'field8' needs an extra bit to represent the largest positive enumerators of preferred type 'C'}}
   // expected-note@#S_C_field8 {{consider making the bit-field type unsigned}}
   // expected-note@#preferred_S_C_field8 {{preferred type for bit-field 'C' specified here}}
   s->field9 = x;

>From d9f14216e997466cc6777d521deb64b660256d20 Mon Sep 17 00:00:00 2001
From: Oliver Hunt <oliver at apple.com>
Date: Sat, 12 Apr 2025 23:29:45 -0700
Subject: [PATCH 9/9] format errors once again

---
 clang/include/clang/Basic/DiagnosticGroups.td |  3 +-
 .../clang/Basic/DiagnosticSemaKinds.td        | 31 ++++++++++---------
 2 files changed, 19 insertions(+), 15 deletions(-)

diff --git a/clang/include/clang/Basic/DiagnosticGroups.td b/clang/include/clang/Basic/DiagnosticGroups.td
index 3c8881d2a99ef..df0342ab62322 100644
--- a/clang/include/clang/Basic/DiagnosticGroups.td
+++ b/clang/include/clang/Basic/DiagnosticGroups.td
@@ -49,7 +49,8 @@ def SingleBitBitFieldConstantConversion :
   DiagGroup<"single-bit-bitfield-constant-conversion">;
 def BitFieldConstantConversion : DiagGroup<"bitfield-constant-conversion",
                                            [SingleBitBitFieldConstantConversion]>;
-def PreferredTypeBitFieldEnumConversion : DiagGroup<"preferred-type-bitfield-enum-conversion">;
+def PreferredTypeBitFieldEnumConversion
+    : DiagGroup<"preferred-type-bitfield-enum-conversion">;
 def PreferredTypeBitFieldWidth : DiagGroup<"preferred-type-bitfield-width">;
 def BitFieldEnumConversion : DiagGroup<"bitfield-enum-conversion">;
 def BitFieldWidth : DiagGroup<"bitfield-width">;
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 1d6d6691c0b76..8f083bb6edab8 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -6466,22 +6466,25 @@ def warn_signed_bitfield_enum_conversion : Warning<
   "signed bit-field %0 needs an extra bit to represent the largest positive "
   "enumerators of %1">,
   InGroup<BitFieldEnumConversion>, DefaultIgnore;
-def warn_preferred_type_bitfield_too_small_for_enum : Warning<
-  "bit-field %0 is not wide enough to store all enumerators of preferred type %1">,
-  InGroup<PreferredTypeBitFieldEnumConversion>;
-def warn_preferred_type_unsigned_bitfield_assigned_signed_enum : Warning<
-  "assigning value of preferred signed enum type %1 to unsigned bit-field %0; "
-  "negative enumerators of enum %1 will be converted to positive values">,
-  InGroup<PreferredTypeBitFieldEnumConversion>;
-def warn_preferred_type_signed_bitfield_enum_conversion : Warning<
-  "signed bit-field %0 needs an extra bit to represent the largest positive "
-  "enumerators of preferred type %1">,
-  InGroup<PreferredTypeBitFieldEnumConversion>;
+def warn_preferred_type_bitfield_too_small_for_enum
+    : Warning<"bit-field %0 is not wide enough to store all enumerators of "
+              "preferred type %1">,
+      InGroup<PreferredTypeBitFieldEnumConversion>;
+def warn_preferred_type_unsigned_bitfield_assigned_signed_enum
+    : Warning<"assigning value of preferred signed enum type %1 to unsigned "
+              "bit-field %0; "
+              "negative enumerators of enum %1 will be converted to positive "
+              "values">,
+      InGroup<PreferredTypeBitFieldEnumConversion>;
+def warn_preferred_type_signed_bitfield_enum_conversion
+    : Warning<"signed bit-field %0 needs an extra bit to represent the largest "
+              "positive "
+              "enumerators of preferred type %1">,
+      InGroup<PreferredTypeBitFieldEnumConversion>;
 def note_change_bitfield_sign : Note<
   "consider making the bit-field type %select{unsigned|signed}0">;
-def note_bitfield_preferred_type : Note<
-  "preferred type for bit-field %0 specified here"
->;
+def note_bitfield_preferred_type
+    : Note<"preferred type for bit-field %0 specified here">;
 
 def warn_missing_braces : Warning<
   "suggest braces around initialization of subobject">,



More information about the cfe-commits mailing list