[cfe-commits] r125825 - in /cfe/trunk: lib/Sema/SemaCXXCast.cpp test/CXX/expr/expr.post/expr.static.cast/p9-0x.cpp

Douglas Gregor dgregor at apple.com
Thu Feb 17 19:01:42 PST 2011


Author: dgregor
Date: Thu Feb 17 21:01:41 2011
New Revision: 125825

URL: http://llvm.org/viewvc/llvm-project?rev=125825&view=rev
Log:
Implement C++0x [expr.static.cast]p9, which permits explicitly casting
a scoped enumeration type to an integral or floating type,
properly. There was an over-eager assertion, and it was missing the
floating-point case.

Fixes PR9107/<rdar://problem/8937402>. 

Added:
    cfe/trunk/test/CXX/expr/expr.post/expr.static.cast/p9-0x.cpp
Modified:
    cfe/trunk/lib/Sema/SemaCXXCast.cpp

Modified: cfe/trunk/lib/Sema/SemaCXXCast.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaCXXCast.cpp?rev=125825&r1=125824&r2=125825&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaCXXCast.cpp (original)
+++ cfe/trunk/lib/Sema/SemaCXXCast.cpp Thu Feb 17 21:01:41 2011
@@ -688,18 +688,23 @@
   QualType SrcType = Self.Context.getCanonicalType(SrcExpr->getType());
 
   // C++0x 5.2.9p9: A value of a scoped enumeration type can be explicitly
-  // converted to an integral type.
-  if (Self.getLangOptions().CPlusPlus0x && SrcType->isEnumeralType()) {
-    assert(SrcType->getAs<EnumType>()->getDecl()->isScoped());
-    if (DestType->isBooleanType()) {
-      Kind = CK_IntegralToBoolean;
-      return TC_Success;
-    } else if (DestType->isIntegralType(Self.Context)) {
-      Kind = CK_IntegralCast;
-      return TC_Success;
+  // converted to an integral type. [...] A value of a scoped enumeration type
+  // can also be explicitly converted to a floating-point type [...].
+  if (const EnumType *Enum = SrcType->getAs<EnumType>()) {
+    if (Enum->getDecl()->isScoped()) {
+      if (DestType->isBooleanType()) {
+        Kind = CK_IntegralToBoolean;
+        return TC_Success;
+      } else if (DestType->isIntegralType(Self.Context)) {
+        Kind = CK_IntegralCast;
+        return TC_Success;
+      } else if (DestType->isRealFloatingType()) {
+        Kind = CK_IntegralToFloating;
+        return TC_Success;
+      }
     }
   }
-
+  
   // Reverse integral promotion/conversion. All such conversions are themselves
   // again integral promotions or conversions and are thus already handled by
   // p2 (TryDirectInitialization above).

Added: cfe/trunk/test/CXX/expr/expr.post/expr.static.cast/p9-0x.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/expr/expr.post/expr.static.cast/p9-0x.cpp?rev=125825&view=auto
==============================================================================
--- cfe/trunk/test/CXX/expr/expr.post/expr.static.cast/p9-0x.cpp (added)
+++ cfe/trunk/test/CXX/expr/expr.post/expr.static.cast/p9-0x.cpp Thu Feb 17 21:01:41 2011
@@ -0,0 +1,29 @@
+// RUN: %clang_cc1 -std=c++0x -fsyntax-only -verify %s
+
+enum class EC { ec1 };
+
+void test0(EC ec) {
+  (void)static_cast<bool>(ec);
+  (void)static_cast<bool>(EC::ec1);
+  (void)static_cast<char>(ec);
+  (void)static_cast<char>(EC::ec1);
+  (void)static_cast<int>(ec);
+  (void)static_cast<int>(EC::ec1);
+  (void)static_cast<unsigned long>(ec);
+  (void)static_cast<unsigned long>(EC::ec1);
+  (void)static_cast<float>(ec);
+  (void)static_cast<float>(EC::ec1);
+  (void)static_cast<double>(ec);
+  (void)static_cast<double>(EC::ec1);
+}
+
+namespace PR9107 {
+  enum E {};
+  template <class _Tp> inline _Tp* addressof(_Tp& __x) {
+    return (_Tp*)&(char&)__x;
+  }
+  void test() {
+    E a;
+    addressof(a);
+  }
+}





More information about the cfe-commits mailing list