Patchwork [C++,/RFC] PR 51912

login
register
mail settings
Submitter Paolo Carlini
Date Aug. 14, 2013, 7:20 p.m.
Message ID <520BD862.1070104@oracle.com>
Download mbox | patch
Permalink /patch/267185/
State New
Headers show

Comments

Paolo Carlini - Aug. 14, 2013, 7:20 p.m.
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.

//////////////////////
Jason Merrill - Aug. 14, 2013, 7:31 p.m.
On 08/14/2013 03:20 PM, Paolo Carlini wrote:
> +/* Used in case_conversion.  */

Also say what it means.  OK with that change.

Jason

Patch

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" }
+    }
+}