OSDN Git Service

* call.c (standard_conversion): Add bad conversion between
authorjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 9 Oct 2001 15:42:44 +0000 (15:42 +0000)
committerjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 9 Oct 2001 15:42:44 +0000 (15:42 +0000)
        integers and pointers.
        (convert_like_real): Don't use convert_for_initialization for bad
        conversions; complain here and use cp_convert.
        (build_over_call): Don't handle bad conversions specially.
        (perform_implicit_conversion): Allow bad conversions.
        (can_convert_arg_bad): New fn.
        * cp-tree.h: Declare it.
        * typeck.c (convert_for_assignment): Use it.
        (ptr_reasonably_similar): Any target type is similar to void.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@46123 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/cp/ChangeLog
gcc/cp/call.c
gcc/cp/cp-tree.h
gcc/cp/typeck.c
gcc/testsuite/g++.dg/ext/conv1.C [new file with mode: 0644]

index 5b934e3..4ab1f19 100644 (file)
@@ -1,3 +1,20 @@
+2001-10-04  Jason Merrill  <jason_merrill@redhat.com>
+
+       * call.c (standard_conversion): Add bad conversion between
+       integers and pointers.
+       (convert_like_real): Don't use convert_for_initialization for bad
+       conversions; complain here and use cp_convert.
+       (build_over_call): Don't handle bad conversions specially.
+       (perform_implicit_conversion): Allow bad conversions.
+       (can_convert_arg_bad): New fn.
+       * cp-tree.h: Declare it.
+       * typeck.c (convert_for_assignment): Use it.
+       (ptr_reasonably_similar): Any target type is similar to void.
+
+2001-10-02  Jason Merrill  <jason_merrill@redhat.com>
+
+       * decl2.c (cxx_decode_option): Add 'else'.
+
 2001-10-08  Alexandre Oliva  <aoliva@redhat.com>
 
        * Make-lang.in (CXX_OBJS): Added cp-lang.o.
@@ -238,7 +255,7 @@ Fri Sep 21 08:16:19 2001  J"orn Rennecke <amylaar@redhat.com>
        CLASSTYPE_PURE_VIRTUALS.
        (TYPE_RAISES_EXCEPTIONS): Map onto TYPE_BINFO.
        * class.c (duplicate_tag_error): Remove TYPE_NONCOPIED_PARTS.
-       (layout_class_type): Don't call fixup_inlin_methods here ...
+       (layout_class_type): Don't call fixup_inline_methods here ...
        (finish_struct_1): ... call it here.
 
 2001-09-04  Mark Mitchell  <mark@codesourcery.com>
index 437d67c..43d2baf 100644 (file)
@@ -745,6 +745,14 @@ standard_conversion (to, from, expr)
     {
       conv = build_conv (STD_CONV, to, conv);
     }
+  else if ((tcode == INTEGER_TYPE && fcode == POINTER_TYPE)
+          || (tcode == POINTER_TYPE && fcode == INTEGER_TYPE))
+    {
+      /* For backwards brain damage compatibility, allow interconversion of
+        pointers and integers with a pedwarn.  */
+      conv = build_conv (STD_CONV, to, conv);
+      ICS_BAD_FLAG (conv) = 1;
+    }
   else if (tcode == POINTER_TYPE && fcode == POINTER_TYPE)
     {
       enum tree_code ufcode = TREE_CODE (TREE_TYPE (from));
@@ -3750,9 +3758,10 @@ convert_like_real (convs, expr, fn, argnum, inner)
          else if (TREE_CODE (t) == IDENTITY_CONV)
            break;
        }
-      return convert_for_initialization
-       (NULL_TREE, totype, expr, LOOKUP_NORMAL,
-        "conversion", fn, argnum);
+      cp_pedwarn ("invalid conversion from `%T' to `%T'", TREE_TYPE (expr), totype);
+      if (fn)
+       cp_pedwarn ("  initializing argument %P of `%D'", argnum, fn);
+      return cp_convert (totype, expr);
     }
   
   if (!inner)
@@ -4152,32 +4161,8 @@ build_over_call (cand, args, flags)
       tree type = TREE_VALUE (parm);
 
       conv = TREE_VEC_ELT (convs, i);
-      if (ICS_BAD_FLAG (conv))
-       {
-         tree t = conv;
-         val = TREE_VALUE (arg);
-
-         for (; t; t = TREE_OPERAND (t, 0))
-           {
-             if (TREE_CODE (t) == USER_CONV
-                 || TREE_CODE (t) == AMBIG_CONV)
-               {
-                 val = convert_like_with_context (t, val, fn, i - is_method);
-                 break;
-               }
-             else if (TREE_CODE (t) == IDENTITY_CONV)
-               break;
-           }
-         val = convert_for_initialization
-           (NULL_TREE, type, val, LOOKUP_NORMAL,
-            "argument", fn, i - is_method);
-       }
-      else
-       {
-         val = TREE_VALUE (arg);
-         val = convert_like_with_context
-                 (conv, TREE_VALUE (arg), fn, i - is_method);
-       }
+      val = convert_like_with_context
+       (conv, TREE_VALUE (arg), fn, i - is_method);
 
       if (PROMOTE_PROTOTYPES
          && INTEGRAL_TYPE_P (type)
@@ -5550,7 +5535,21 @@ can_convert_arg (to, from, arg)
   return (t && ! ICS_BAD_FLAG (t));
 }
 
-/* Convert EXPR to TYPE.  Return the converted expression.  */
+/* Like can_convert_arg, but allows dubious conversions as well.  */
+
+int
+can_convert_arg_bad (to, from, arg)
+     tree to, from, arg;
+{
+  tree t = implicit_conversion (to, from, arg, LOOKUP_NORMAL);
+  return !!t;
+}
+
+/* Convert EXPR to TYPE.  Return the converted expression.
+
+   Note that we allow bad conversions here because by the time we get to
+   this point we are committed to doing the conversion.  If we end up
+   doing a bad conversion, convert_like will complain.  */
 
 tree
 perform_implicit_conversion (type, expr)
@@ -5563,7 +5562,7 @@ perform_implicit_conversion (type, expr)
     return error_mark_node;
   conv = implicit_conversion (type, TREE_TYPE (expr), expr,
                              LOOKUP_NORMAL);
-  if (!conv || ICS_BAD_FLAG (conv))
+  if (!conv)
     {
       cp_error ("could not convert `%E' to `%T'", expr, type);
       return error_mark_node;
index 116a2cd..4f6bcab 100644 (file)
@@ -3489,6 +3489,7 @@ extern tree build_new_op                  PARAMS ((enum tree_code, int, tree, tree, tree));
 extern tree build_op_delete_call               PARAMS ((enum tree_code, tree, tree, int, tree));
 extern int can_convert                         PARAMS ((tree, tree));
 extern int can_convert_arg                     PARAMS ((tree, tree, tree));
+extern int can_convert_arg_bad                 PARAMS ((tree, tree, tree));
 extern int enforce_access                       PARAMS ((tree, tree));
 extern tree convert_default_arg                 PARAMS ((tree, tree, tree, int));
 extern tree convert_arg_to_ellipsis             PARAMS ((tree));
index c57bb08..850ce8b 100644 (file)
@@ -6295,8 +6295,12 @@ convert_for_assignment (type, rhs, errtype, fndecl, parmnum)
   /* [expr.ass]
 
      The expression is implicitly converted (clause _conv_) to the
-     cv-unqualified type of the left operand.  */
-  if (!can_convert_arg (type, rhstype, rhs))
+     cv-unqualified type of the left operand.
+
+     We allow bad conversions here because by the time we get to this point
+     we are committed to doing the conversion.  If we end up doing a bad
+     conversion, convert_like will complain.  */
+  if (!can_convert_arg_bad (type, rhstype, rhs))
     {
       /* When -Wno-pmf-conversions is use, we just silently allow
         conversions from pointers-to-members to plain pointers.  If
@@ -6305,7 +6309,7 @@ convert_for_assignment (type, rhs, errtype, fndecl, parmnum)
          && TYPE_PTR_P (type) 
          && TYPE_PTRMEMFUNC_P (rhstype))
        rhs = cp_convert (strip_top_quals (type), rhs);
-      else 
+      else
        {
          /* If the right-hand side has unknown type, then it is an
             overloaded function.  Call instantiate_type to get error
@@ -6798,6 +6802,11 @@ ptr_reasonably_similar (to, from)
 {
   for (; ; to = TREE_TYPE (to), from = TREE_TYPE (from))
     {
+      /* Any target type is similar enough to void.  */
+      if (TREE_CODE (to) == VOID_TYPE
+         || TREE_CODE (from) == VOID_TYPE)
+       return 1;
+
       if (TREE_CODE (to) != TREE_CODE (from))
        return 0;
 
diff --git a/gcc/testsuite/g++.dg/ext/conv1.C b/gcc/testsuite/g++.dg/ext/conv1.C
new file mode 100644 (file)
index 0000000..4c0d848
--- /dev/null
@@ -0,0 +1,16 @@
+// Test for backwards brain-damage compatibility with -fpermissive.
+// { dg-options "-fpermissive -w" }
+
+void f ();
+void f (int *);
+void g (int);
+
+int main ()
+{
+  void *v = 1234;
+  void (*p)() = v;
+  int i = v;
+  f (i);
+  f (v);
+  g (v);
+}