re PR c++/48450 ([C++0x][SFINAE] Hard errors with static_cast expressions)
authorJason Merrill <jason@redhat.com>
Thu, 7 Apr 2011 21:46:48 +0000 (17:46 -0400)
committerJason Merrill <jason@gcc.gnu.org>
Thu, 7 Apr 2011 21:46:48 +0000 (17:46 -0400)
PR c++/48450
* c-family/c-common.c (c_common_truthvalue_conversion): Don't ignore
conversion from C++0x scoped enum.
* cp/cvt.c (ocp_convert): Handle converting scoped enum to bool.

From-SVN: r172138

gcc/c-family/ChangeLog
gcc/c-family/c-common.c
gcc/cp/ChangeLog
gcc/cp/cvt.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/cpp0x/enum9.C [new file with mode: 0644]

index a7efe84e418b4649d6f6e0a20a541b8eafe2753d..b859db6180e04ca72a76182b53a3b9daabde0660 100644 (file)
@@ -1,3 +1,9 @@
+2011-04-07  Jason Merrill  <jason@redhat.com>
+
+       PR c++/48450
+       * c-common.c (c_common_truthvalue_conversion): Don't ignore
+       conversion from C++0x scoped enum.
+
 2011-04-06  Joseph Myers  <joseph@codesourcery.com>
 
        * c-target-def.h: New file.
index 1252b18b820c04a9fb2ff850789387ac1daba430..e0acfea5ca823bb26a7b44c70a6e861d25e17001 100644 (file)
@@ -3939,16 +3939,25 @@ c_common_truthvalue_conversion (location_t location, tree expr)
        }
 
     CASE_CONVERT:
-      /* Don't cancel the effect of a CONVERT_EXPR from a REFERENCE_TYPE,
-        since that affects how `default_conversion' will behave.  */
-      if (TREE_CODE (TREE_TYPE (expr)) == REFERENCE_TYPE
-         || TREE_CODE (TREE_TYPE (TREE_OPERAND (expr, 0))) == REFERENCE_TYPE)
-       break;
-      /* If this is widening the argument, we can ignore it.  */
-      if (TYPE_PRECISION (TREE_TYPE (expr))
-         >= TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (expr, 0))))
-       return c_common_truthvalue_conversion (location,
-                                              TREE_OPERAND (expr, 0));
+      {
+       tree totype = TREE_TYPE (expr);
+       tree fromtype = TREE_TYPE (TREE_OPERAND (expr, 0));
+
+       /* Don't cancel the effect of a CONVERT_EXPR from a REFERENCE_TYPE,
+          since that affects how `default_conversion' will behave.  */
+       if (TREE_CODE (totype) == REFERENCE_TYPE
+           || TREE_CODE (fromtype) == REFERENCE_TYPE)
+         break;
+       /* Don't strip a conversion from C++0x scoped enum, since they
+          don't implicitly convert to other types.  */
+       if (TREE_CODE (fromtype) == ENUMERAL_TYPE
+           && ENUM_IS_SCOPED (fromtype))
+         break;
+       /* If this isn't narrowing the argument, we can ignore it.  */
+       if (TYPE_PRECISION (totype) >= TYPE_PRECISION (fromtype))
+         return c_common_truthvalue_conversion (location,
+                                                TREE_OPERAND (expr, 0));
+      }
       break;
 
     case MODIFY_EXPR:
index 387677e8e7732f0db36d31175619543703dcd346..5ffe1f5ed5fa9cb945028bcf49e5364a678258f9 100644 (file)
@@ -1,3 +1,8 @@
+2011-04-07  Jason Merrill  <jason@redhat.com>
+
+       PR c++/48450
+       * cvt.c (ocp_convert): Handle converting scoped enum to bool.
+
 2011-03-31  Jason Merrill  <jason@redhat.com>
 
        PR c++/48277
index 8ab0001143253ac07468447673b62f9a89d5b8a3..290b926ebb725a8db54b28c499118e824bd554bc 100644 (file)
@@ -727,7 +727,13 @@ ocp_convert (tree type, tree expr, int convtype, int flags)
          return error_mark_node;
        }
       if (code == BOOLEAN_TYPE)
-       return cp_truthvalue_conversion (e);
+       {
+         /* We can't implicitly convert a scoped enum to bool, so convert
+            to the underlying type first.  */
+         if (SCOPED_ENUM_P (intype) && (convtype & CONV_STATIC))
+           e = convert (ENUM_UNDERLYING_TYPE (intype), e);
+         return cp_truthvalue_conversion (e);
+       }
 
       converted = fold_if_not_in_template (convert_to_integer (type, e));
 
index 1e572c7f776430707bbe4de052829e1eb8eab10a..dabb816393ee7763734836a7e6414741c1f52bdb 100644 (file)
@@ -1,3 +1,7 @@
+2011-04-07  Jason Merrill  <jason@redhat.com>
+
+       * g++.dg/cpp0x/enum9.C: New.
+
 2011-04-07  Mike Stump  <mikestump@comcast.net>
 
        * gcc.dg/torture/stackalign/non-local-goto-5.c: Fix for targets
diff --git a/gcc/testsuite/g++.dg/cpp0x/enum9.C b/gcc/testsuite/g++.dg/cpp0x/enum9.C
new file mode 100644 (file)
index 0000000..10e510b
--- /dev/null
@@ -0,0 +1,5 @@
+// { dg-options -std=c++0x }
+
+enum class E { };
+E f();
+bool b2 = static_cast<bool>(f());