[cfe-commits] r163841 - in /cfe/trunk: lib/Sema/SemaExprCXX.cpp lib/Sema/SemaOverload.cpp test/CXX/conv/conv.prom/p4.cpp

Richard Smith richard-llvm at metafoo.co.uk
Thu Sep 13 14:18:55 PDT 2012


Author: rsmith
Date: Thu Sep 13 16:18:54 2012
New Revision: 163841

URL: http://llvm.org/viewvc/llvm-project?rev=163841&view=rev
Log:
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.

Modified:
    cfe/trunk/lib/Sema/SemaExprCXX.cpp
    cfe/trunk/lib/Sema/SemaOverload.cpp
    cfe/trunk/test/CXX/conv/conv.prom/p4.cpp

Modified: cfe/trunk/lib/Sema/SemaExprCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExprCXX.cpp?rev=163841&r1=163840&r2=163841&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExprCXX.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExprCXX.cpp Thu Sep 13 16:18:54 2012
@@ -2593,8 +2593,16 @@
 
   case ICK_Integral_Promotion:
   case ICK_Integral_Conversion:
-    From = ImpCastExprToType(From, ToType, CK_IntegralCast, 
-                             VK_RValue, /*BasePath=*/0, CCK).take();
+    if (ToType->isBooleanType()) {
+      assert(FromType->castAs<EnumType>()->getDecl()->isFixed() &&
+             SCS.Second == ICK_Integral_Promotion &&
+             "only enums with fixed underlying type can promote to bool");
+      From = ImpCastExprToType(From, ToType, CK_IntegralToBoolean,
+                               VK_RValue, /*BasePath=*/0, CCK).take();
+    } else {
+      From = ImpCastExprToType(From, ToType, CK_IntegralCast,
+                               VK_RValue, /*BasePath=*/0, CCK).take();
+    }
     break;
 
   case ICK_Floating_Promotion:

Modified: cfe/trunk/lib/Sema/SemaOverload.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaOverload.cpp?rev=163841&r1=163840&r2=163841&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaOverload.cpp (original)
+++ cfe/trunk/lib/Sema/SemaOverload.cpp Thu Sep 13 16:18:54 2012
@@ -1674,7 +1674,7 @@
     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 @@
   //   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))

Modified: cfe/trunk/test/CXX/conv/conv.prom/p4.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/conv/conv.prom/p4.cpp?rev=163841&r1=163840&r2=163841&view=diff
==============================================================================
--- cfe/trunk/test/CXX/conv/conv.prom/p4.cpp (original)
+++ cfe/trunk/test/CXX/conv/conv.prom/p4.cpp Thu Sep 13 16:18:54 2012
@@ -7,3 +7,20 @@
 enum Y : long { C, D };
 extern decltype(+C) y;
 extern long y;
+
+// An enum with a fixed underlying type has an integral promotion to that type,
+// and to its promoted type.
+enum B : bool { false_, true_ };
+template<bool> struct T {};
+T<false_> f;
+T<true_> t;
+T<+true_> t; // expected-error {{conversion from 'int' to 'bool'}}
+
+enum B2 : bool {
+  a = false,
+  b = true,
+  c = false_,
+  d = true_,
+  e = +false_ // expected-error {{conversion from 'int' to 'bool'}} \
+              // FIXME: expected-error {{enumerator value 2 is not representable}}
+};





More information about the cfe-commits mailing list