call.c (can_convert): Allow user-defined conversions.
authorJason Merrill <jason@redhat.com>
Sat, 13 Jul 2013 23:10:12 +0000 (19:10 -0400)
committerJason Merrill <jason@gcc.gnu.org>
Sat, 13 Jul 2013 23:10:12 +0000 (19:10 -0400)
* call.c (can_convert): Allow user-defined conversions.
(can_convert_standard): New.
* cp-tree.h: Declare it.
* cvt.c (convert_to_reference): Use it.
* pt.c (convert_nontype_argument): Likewise.
* search.c (check_final_overrider): Likewise.
Don't worry about user-defined conversions.

From-SVN: r200937

gcc/cp/ChangeLog
gcc/cp/call.c
gcc/cp/cp-tree.h
gcc/cp/cvt.c
gcc/cp/pt.c
gcc/cp/search.c

index 3dede36..3b59f21 100644 (file)
@@ -1,3 +1,13 @@
+2013-07-13  Jason Merrill  <jason@redhat.com>
+
+       * call.c (can_convert): Allow user-defined conversions.
+       (can_convert_standard): New.
+       * cp-tree.h: Declare it.
+       * cvt.c (convert_to_reference): Use it.
+       * pt.c (convert_nontype_argument): Likewise.
+       * search.c (check_final_overrider): Likewise.
+       Don't worry about user-defined conversions.
+
 2013-07-10  Paolo Carlini  <paolo.carlini@oracle.com>
 
        PR c++/57869
index 78899ab..02daf82 100644 (file)
@@ -8814,6 +8814,20 @@ tourney (struct z_candidate *candidates, tsubst_flags_t complain)
 bool
 can_convert (tree to, tree from, tsubst_flags_t complain)
 {
+  tree arg = NULL_TREE;
+  /* implicit_conversion only considers user-defined conversions
+     if it has an expression for the call argument list.  */
+  if (CLASS_TYPE_P (from) || CLASS_TYPE_P (to))
+    arg = build1 (CAST_EXPR, from, NULL_TREE);
+  return can_convert_arg (to, from, arg, LOOKUP_IMPLICIT, complain);
+}
+
+/* Returns nonzero if things of type FROM can be converted to TO with a
+   standard conversion.  */
+
+bool
+can_convert_standard (tree to, tree from, tsubst_flags_t complain)
+{
   return can_convert_arg (to, from, NULL_TREE, LOOKUP_IMPLICIT, complain);
 }
 
index 1971bc5..a837d22 100644 (file)
@@ -5007,6 +5007,7 @@ extern tree build_op_delete_call          (enum tree_code, tree, tree,
                                                 bool, tree, tree,
                                                 tsubst_flags_t);
 extern bool can_convert                                (tree, tree, tsubst_flags_t);
+extern bool can_convert_standard               (tree, tree, tsubst_flags_t);
 extern bool can_convert_arg                    (tree, tree, tree, int,
                                                 tsubst_flags_t);
 extern bool can_convert_arg_bad                        (tree, tree, tree, int,
index d9e905e..532e8fd 100644 (file)
@@ -428,7 +428,7 @@ convert_to_reference (tree reftype, tree expr, int convtype,
 
   intype = TYPE_MAIN_VARIANT (intype);
 
-  can_convert_intype_to_type = can_convert (type, intype, complain);
+  can_convert_intype_to_type = can_convert_standard (type, intype, complain);
 
   if (!can_convert_intype_to_type
       && (convtype & CONV_IMPLICIT) && MAYBE_CLASS_TYPE_P (intype)
@@ -449,7 +449,8 @@ convert_to_reference (tree reftype, tree expr, int convtype,
        }
     }
 
-  if (((convtype & CONV_STATIC) && can_convert (intype, type, complain))
+  if (((convtype & CONV_STATIC)
+       && can_convert_standard (intype, type, complain))
       || ((convtype & CONV_IMPLICIT) && can_convert_intype_to_type))
     {
       {
index 877d3b7..de054ac 100644 (file)
@@ -5854,7 +5854,7 @@ convert_nontype_argument (tree type, tree expr, tsubst_flags_t complain)
                 "because it is of type %qT", expr, type,
                 TREE_TYPE (expr));
          /* If we are just one standard conversion off, explain.  */
-         if (can_convert (type, TREE_TYPE (expr), complain))
+         if (can_convert_standard (type, TREE_TYPE (expr), complain))
            inform (input_location,
                    "standard conversions are not allowed in this context");
          return NULL_TREE;
index b113477..166ac11 100644 (file)
@@ -1889,22 +1889,16 @@ check_final_overrider (tree overrider, tree basefn)
                fail = 1;
            }
        }
-      else if (!pedantic
-              && can_convert (TREE_TYPE (base_type), TREE_TYPE (over_type),
-                              tf_warning_or_error))
+      else if (can_convert_standard (TREE_TYPE (base_type),
+                                    TREE_TYPE (over_type),
+                                    tf_warning_or_error))
        /* GNU extension, allow trivial pointer conversions such as
           converting to void *, or qualification conversion.  */
        {
-         /* can_convert will permit user defined conversion from a
-            (reference to) class type. We must reject them.  */
-         if (CLASS_TYPE_P (non_reference (over_return)))
-           fail = 2;
-         else
-           {
-             warning (0, "deprecated covariant return type for %q+#D",
-                            overrider);
-             warning (0, "  overriding %q+#D", basefn);
-           }
+         if (pedwarn (DECL_SOURCE_LOCATION (overrider), 0,
+                      "invalid covariant return type for %q#D", overrider))
+           inform (DECL_SOURCE_LOCATION (basefn),
+                   "  overriding %q+#D", basefn);
        }
       else
        fail = 2;