Hi all, Jason,

thus, per the notes I left on the audit trail some time ago, this seems to me a possible approach to reject this kind of invalid code. What do you think?

Booted & tested x86_64-linux.

Thanks,
Paolo.

//////////////////////
Index: cp/call.c
===================================================================
--- cp/call.c   (revision 201731)
+++ cp/call.c   (working copy)
@@ -1314,7 +1314,8 @@ standard_conversion (tree to, tree from, tree expr
   /* As an extension, allow conversion to complex type.  */
   else if (ARITHMETIC_TYPE_P (to))
     {
-      if (! (INTEGRAL_CODE_P (fcode) || fcode == REAL_TYPE)
+      if (! (INTEGRAL_CODE_P (fcode)
+            || (fcode == REAL_TYPE && !(flags & LOOKUP_NO_NON_INTEGRAL)))
           || SCOPED_ENUM_P (from))
        return NULL;
       conv = build_conv (ck_std, to, conv);
@@ -1681,7 +1682,7 @@ implicit_conversion (tree to, tree from, tree expr
      resolution, or after we've chosen one.  */
   flags &= (LOOKUP_ONLYCONVERTING|LOOKUP_NO_CONVERSION|LOOKUP_COPY_PARM
            |LOOKUP_NO_TEMP_BIND|LOOKUP_NO_RVAL_BIND|LOOKUP_PREFER_RVALUE
-           |LOOKUP_NO_NARROWING|LOOKUP_PROTECT);
+           |LOOKUP_NO_NARROWING|LOOKUP_PROTECT|LOOKUP_NO_NON_INTEGRAL);
 
   /* FIXME: actually we don't want warnings either, but we can't just
      have 'complain &= ~(tf_warning|tf_error)' because it would cause
Index: cp/cp-tree.h
===================================================================
--- cp/cp-tree.h        (revision 201731)
+++ cp/cp-tree.h        (working copy)
@@ -4510,6 +4510,8 @@ enum overload_flags { NO_SPECIAL = 0, DTOR_FLAG, T
 #define LOOKUP_EXPLICIT_TMPL_ARGS (LOOKUP_ALREADY_DIGESTED << 1)
 /* Like LOOKUP_NO_TEMP_BIND, but also prevent binding to xvalues.  */
 #define LOOKUP_NO_RVAL_BIND (LOOKUP_EXPLICIT_TMPL_ARGS << 1)
+/* Used in case_conversion.  */
+#define LOOKUP_NO_NON_INTEGRAL (LOOKUP_NO_RVAL_BIND << 1)
 
 #define LOOKUP_NAMESPACES_ONLY(F)  \
   (((F) & LOOKUP_PREFER_NAMESPACES) && !((F) & LOOKUP_PREFER_TYPES))
Index: cp/decl.c
===================================================================
--- cp/decl.c   (revision 201731)
+++ cp/decl.c   (working copy)
@@ -3103,7 +3103,9 @@ case_conversion (tree type, tree value)
     {
       if (INTEGRAL_OR_UNSCOPED_ENUMERATION_TYPE_P (type))
        type = type_promotes_to (type);
-      value = perform_implicit_conversion (type, value, tf_warning_or_error);
+      value = (perform_implicit_conversion_flags
+              (type, value, tf_warning_or_error,
+               LOOKUP_IMPLICIT | LOOKUP_NO_NON_INTEGRAL));
     }
   return cxx_constant_value (value);
 }
Index: testsuite/g++.dg/cpp0x/enum15.C
===================================================================
--- testsuite/g++.dg/cpp0x/enum15.C     (revision 201726)
+++ testsuite/g++.dg/cpp0x/enum15.C     (working copy)
@@ -15,6 +15,6 @@ void foo (A a, int i)
     {
     case A::Val0: break;       // { dg-error "" }
     case 1: break;
-    case 2.0: break;
+    case 2.0: break;            // { dg-error "" }
     }
 }
Index: testsuite/g++.dg/cpp0x/enum28.C
===================================================================
--- testsuite/g++.dg/cpp0x/enum28.C     (revision 0)
+++ testsuite/g++.dg/cpp0x/enum28.C     (working copy)
@@ -0,0 +1,17 @@
+// PR c++/51912
+// { dg-do compile { target c++11 } }
+
+constexpr double g() { return 2.0; }
+
+void f(int i)
+{
+  switch (i)
+    {
+    case 1.0:;    // { dg-error "could not convert" }
+    }
+
+  switch (i)
+    {
+    case g():;    // { dg-error "could not convert" }
+    }
+}

Reply via email to