summaryrefslogtreecommitdiffstats
path: root/clang/lib/AST/ASTContext.cpp
diff options
context:
space:
mode:
authorRichard Smith <richard-llvm@metafoo.co.uk>2018-06-28 21:17:55 +0000
committerRichard Smith <richard-llvm@metafoo.co.uk>2018-06-28 21:17:55 +0000
commitaadb254a79558de8ad5911ac7b4a6dacb45d44dc (patch)
tree5893a0f17b5372e26ddbbe6d1f4c9bb87d777e49 /clang/lib/AST/ASTContext.cpp
parent019d3cd3b4c08dd2d39def08c983f3af9f9b2cd9 (diff)
downloadbcm5719-llvm-aadb254a79558de8ad5911ac7b4a6dacb45d44dc.tar.gz
bcm5719-llvm-aadb254a79558de8ad5911ac7b4a6dacb45d44dc.zip
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
Diffstat (limited to 'clang/lib/AST/ASTContext.cpp')
-rw-r--r--clang/lib/AST/ASTContext.cpp10
1 files changed, 9 insertions, 1 deletions
diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp
index 43577e8640a..ca54d8f6759 100644
--- a/clang/lib/AST/ASTContext.cpp
+++ b/clang/lib/AST/ASTContext.cpp
@@ -5456,6 +5456,12 @@ QualType ASTContext::isPromotableBitField(Expr *E) const {
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 @@ QualType ASTContext::isPromotableBitField(Expr *E) const {
//
// 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
OpenPOWER on IntegriCloud