PR37979: integral promotions in C++ treat enum bit-fields like enums,
not like bit-fields.
We used to get this right "by accident", because conversions for the
selected built-in overloaded operator would convert the enum bit-field
to its corresponding underlying type early. But after DR1687 that no
longer happens.
Technically this change should also apply to C, where bit-fields only
have special promotion rules if the bit-field's declared type is
_Bool, int, signed int, or unsigned int, but for GCC compatibility we
only look at the bit-width and not the underlying type when performing
bit-field integral promotions in C.
llvm-svn: 335925
diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp
index 43577e8..ca54d8f6 100644
--- a/clang/lib/AST/ASTContext.cpp
+++ b/clang/lib/AST/ASTContext.cpp
@@ -5456,6 +5456,12 @@
if (E->isTypeDependent() || E->isValueDependent())
return {};
+ // C++ [conv.prom]p5:
+ // If the bit-field has an enumerated type, it is treated as any other
+ // value of that type for promotion purposes.
+ if (getLangOpts().CPlusPlus && E->getType()->isEnumeralType())
+ return {};
+
// FIXME: We should not do this unless E->refersToBitField() is true. This
// matters in C where getSourceBitField() will find bit-fields for various
// cases where the source expression is not a bit-field designator.
@@ -5482,13 +5488,15 @@
//
// FIXME: C does not permit promotion of a 'long : 3' bitfield to int.
// We perform that promotion here to match GCC and C++.
+ // FIXME: C does not permit promotion of an enum bit-field whose rank is
+ // greater than that of 'int'. We perform that promotion to match GCC.
if (BitWidth < IntSize)
return IntTy;
if (BitWidth == IntSize)
return FT->isSignedIntegerType() ? IntTy : UnsignedIntTy;
- // Types bigger than int are not subject to promotions, and therefore act
+ // Bit-fields wider than int are not subject to promotions, and therefore act
// like the base type. GCC has some weird bugs in this area that we
// deliberately do not follow (GCC follows a pre-standard resolution to
// C's DR315 which treats bit-width as being part of the type, and this leaks