aboutsummaryrefslogtreecommitdiff
path: root/lib/Sema/SemaOverload.cpp
diff options
context:
space:
mode:
authorRichard Smith <richard-llvm@metafoo.co.uk>2012-09-13 21:18:54 +0000
committerRichard Smith <richard-llvm@metafoo.co.uk>2012-09-13 21:18:54 +0000
commite7ff9191f39fa5a0f48168f51f55f1f7556d5993 (patch)
tree227679a263577bfa49729bb04a64706c01243a81 /lib/Sema/SemaOverload.cpp
parentae19fbba559d8199d1f2b7154863180b0ae22ac7 (diff)
Implement C++11 [conv.prom]p4: an enumeration with a fixed underlying type has
integral promotions to both its underlying type and to its underlying type's promoted type. This matters now that boolean conversions aren't permitted in converted constant expressions (a la DR1407): an enumerator with a fixed underlying type of bool still can be. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@163841 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaOverload.cpp')
-rw-r--r--lib/Sema/SemaOverload.cpp16
1 files changed, 15 insertions, 1 deletions
diff --git a/lib/Sema/SemaOverload.cpp b/lib/Sema/SemaOverload.cpp
index b607ab63b4..4d8795ea96 100644
--- a/lib/Sema/SemaOverload.cpp
+++ b/lib/Sema/SemaOverload.cpp
@@ -1674,7 +1674,7 @@ bool Sema::IsIntegralPromotion(Expr *From, QualType FromType, QualType ToType) {
return To->getKind() == BuiltinType::UInt;
}
- // C++0x [conv.prom]p3:
+ // C++11 [conv.prom]p3:
// A prvalue of an unscoped enumeration type whose underlying type is not
// fixed (7.2) can be converted to an rvalue a prvalue of the first of the
// following types that can represent all the values of the enumeration
@@ -1686,12 +1686,26 @@ bool Sema::IsIntegralPromotion(Expr *From, QualType FromType, QualType ToType) {
// with lowest integer conversion rank (4.13) greater than the rank of long
// long in which all the values of the enumeration can be represented. If
// there are two such extended types, the signed one is chosen.
+ // C++11 [conv.prom]p4:
+ // A prvalue of an unscoped enumeration type whose underlying type is fixed
+ // can be converted to a prvalue of its underlying type. Moreover, if
+ // integral promotion can be applied to its underlying type, a prvalue of an
+ // unscoped enumeration type whose underlying type is fixed can also be
+ // converted to a prvalue of the promoted underlying type.
if (const EnumType *FromEnumType = FromType->getAs<EnumType>()) {
// C++0x 7.2p9: Note that this implicit enum to int conversion is not
// provided for a scoped enumeration.
if (FromEnumType->getDecl()->isScoped())
return false;
+ // We can perform an integral promotion to the underlying type of the enum,
+ // even if that's not the promoted type.
+ if (FromEnumType->getDecl()->isFixed()) {
+ QualType Underlying = FromEnumType->getDecl()->getIntegerType();
+ return Context.hasSameUnqualifiedType(Underlying, ToType) ||
+ IsIntegralPromotion(From, Underlying, ToType);
+ }
+
// We have already pre-calculated the promotion type, so this is trivial.
if (ToType->isIntegerType() &&
!RequireCompleteType(From->getLocStart(), FromType, 0))