typeck.c (comp_cv_target_types): Split out...
authorJason Merrill <jason@yorick.cygnus.com>
Tue, 25 Aug 1998 17:17:51 +0000 (17:17 +0000)
committerJason Merrill <jason@gcc.gnu.org>
Tue, 25 Aug 1998 17:17:51 +0000 (13:17 -0400)
* typeck.c (comp_cv_target_types): Split out...
(comp_target_types): From here.  Don't allow cv-qual changes under
a pointer if nptrs == 0.  Fix OFFSET_TYPE handling.
(build_ptrmemfunc): Pass 1 to nptrs.
* cvt.c (perform_qualification_conversions): Use comp_ptr_ttypes.

From-SVN: r21974

gcc/cp/ChangeLog
gcc/cp/cvt.c
gcc/cp/typeck.c

index 0af040726e7c82b149061de594a48e5ba9f5ad7d..dfb6e518be7bdeee496896ab5e12aae0f5e6e158 100644 (file)
@@ -1,3 +1,11 @@
+1998-08-25  Jason Merrill  <jason@yorick.cygnus.com>
+
+       * typeck.c (comp_cv_target_types): Split out...
+       (comp_target_types): From here.  Don't allow cv-qual changes under
+       a pointer if nptrs == 0.  Fix OFFSET_TYPE handling.
+       (build_ptrmemfunc): Pass 1 to nptrs.
+       * cvt.c (perform_qualification_conversions): Use comp_ptr_ttypes.
+
 1998-08-25  Mark Mitchell  <mark@markmitchell.com>
 
        * search.c (dependent_base_p): Don't compare a binfo to
index 99289e824e36efd742467462a87044fb8515ad43..ff69fbfabafcbf59f27150f21d9f9dcf6b44a6ed 100644 (file)
@@ -1094,7 +1094,6 @@ type_promotes_to (type)
   return cp_build_type_variant (type, constp, volatilep);
 }
 
-
 /* The routines below this point are carefully written to conform to
    the standard.  They use the same terminology, and follow the rules
    closely.  Although they are used only in pt.c at the moment, they
@@ -1109,7 +1108,9 @@ perform_qualification_conversions (type, expr)
      tree type;
      tree expr;
 {
-  if (comp_target_types (type, TREE_TYPE (expr), 0) == 1)
+  if (TREE_CODE (type) == POINTER_TYPE
+      && TREE_CODE (TREE_TYPE (expr)) == POINTER_TYPE
+      && comp_ptr_ttypes (TREE_TYPE (type), TREE_TYPE (TREE_TYPE (expr))))
     return build1 (NOP_EXPR, type, expr);
   else
     return error_mark_node;
index c7530f06d7ba056a051e08610d7df45b643a7093..7859c0414018ee625372afae868eaf790f8f59e5 100644 (file)
@@ -912,6 +912,31 @@ comptypes (type1, type2, strict)
   return attrval == 2 && val == 1 ? 2 : val;
 }
 
+/* Subroutine of comp_target-types.  Make sure that the cv-quals change
+   only in the same direction as the target type.  */
+
+static int
+comp_cv_target_types (ttl, ttr, nptrs)
+     tree ttl, ttr;
+     int nptrs;
+{
+  int t;
+  int c = TYPE_READONLY (ttl) - TYPE_READONLY (ttr);
+  int v = TYPE_VOLATILE (ttl) - TYPE_VOLATILE (ttr);
+
+  if ((c > 0 && v < 0) || (c < 0 && v > 0))
+    return 0;
+
+  if (TYPE_MAIN_VARIANT (ttl) == TYPE_MAIN_VARIANT (ttr))
+    return (c + v < 0) ? -1 : 1;
+
+  t = comp_target_types (ttl, ttr, nptrs);
+  if ((t == 1 && c + v >= 0) || (t == -1 && c + v <= 0))
+    return t;
+
+  return 0;
+}
+
 /* Return 1 or -1 if TTL and TTR are pointers to types that are equivalent,
    ignoring their qualifiers, 0 if not. Return 1 means that TTR can be
    converted to TTL. Return -1 means that TTL can be converted to TTR but
@@ -937,15 +962,20 @@ comp_target_types (ttl, ttr, nptrs)
   if (TREE_CODE (ttr) != TREE_CODE (ttl))
     return 0;
 
-  if (TREE_CODE (ttr) == POINTER_TYPE
-      || (TREE_CODE (ttr) == REFERENCE_TYPE))
+  if ((TREE_CODE (ttr) == POINTER_TYPE
+       || TREE_CODE (ttr) == REFERENCE_TYPE)
+      /* If we get a pointer with nptrs == 0, we don't allow any tweaking
+        of the type pointed to.  This is necessary for reference init
+        semantics.  We won't get here from a previous call with nptrs == 1;
+        for multi-level pointers we end up in comp_ptr_ttypes.  */
+      && nptrs > 0)
     {
       int is_ptr = TREE_CODE (ttr) == POINTER_TYPE;
 
       ttl = TREE_TYPE (ttl);
       ttr = TREE_TYPE (ttr);
 
-      if (nptrs > 0 && is_ptr)
+      if (is_ptr)
        {
          if (TREE_CODE (ttl) == UNKNOWN_TYPE
              || TREE_CODE (ttr) == UNKNOWN_TYPE)
@@ -976,25 +1006,7 @@ comp_target_types (ttl, ttr, nptrs)
       if (TREE_CODE (ttl) == FUNCTION_TYPE || TREE_CODE (ttl) == METHOD_TYPE)
        return comp_target_types (ttl, ttr, nptrs - 1);
 
-      /* Make sure that the cv-quals change only in the same direction as
-        the target type.  */
-      {
-       int t;
-       int c = TYPE_READONLY (ttl) - TYPE_READONLY (ttr);
-       int v = TYPE_VOLATILE (ttl) - TYPE_VOLATILE (ttr);
-
-       if ((c > 0 && v < 0) || (c < 0 && v > 0))
-         return 0;
-
-       if (TYPE_MAIN_VARIANT (ttl) == TYPE_MAIN_VARIANT (ttr))
-         return (c + v < 0) ? -1 : 1;
-
-       t = comp_target_types (ttl, ttr, nptrs - 1);
-       if ((t == 1 && c + v >= 0) || (t == -1 && c + v <= 0))
-         return t;
-
-       return 0;
-      }
+      return comp_cv_target_types (ttl, ttr, nptrs - 1);
     }
 
   if (TREE_CODE (ttr) == ARRAY_TYPE)
@@ -1054,16 +1066,42 @@ comp_target_types (ttl, ttr, nptrs)
   /* for C++ */
   else if (TREE_CODE (ttr) == OFFSET_TYPE)
     {
+      int base;
+      tree tmp;
+
       /* Contravariance: we can assign a pointer to base member to a pointer
         to derived member.  Note difference from simple pointer case, where
         we can pass a pointer to derived to a pointer to base.  */
       if (comptypes (TYPE_OFFSET_BASETYPE (ttr),
                     TYPE_OFFSET_BASETYPE (ttl), 0))
-       return comp_target_types (TREE_TYPE (ttl), TREE_TYPE (ttr), nptrs);
+       base = 1;
       else if (comptypes (TYPE_OFFSET_BASETYPE (ttl),
-                         TYPE_OFFSET_BASETYPE (ttr), 0)
-              && comp_target_types (TREE_TYPE (ttl), TREE_TYPE (ttr), nptrs))
-       return -1;
+                         TYPE_OFFSET_BASETYPE (ttr), 0))
+       {
+         tree tmp = ttl;
+         ttl = ttr;
+         ttr = tmp;
+         base = -1;
+       }
+      else
+       return 0;
+
+      ttl = TREE_TYPE (ttl);
+      ttr = TREE_TYPE (ttr);
+
+      if (TREE_CODE (ttl) == POINTER_TYPE
+         || TREE_CODE (ttl) == ARRAY_TYPE)
+       {
+         if (comp_ptr_ttypes (ttl, ttr))
+           return base;
+         return 0;
+       }
+      else
+       {
+         if (comp_cv_target_types (ttl, ttr, nptrs) == 1)
+           return base;
+         return 0;
+       }
     }
   else if (IS_AGGR_TYPE (ttl))
     {
@@ -6515,7 +6553,7 @@ build_ptrmemfunc (type, pfn, force)
 
       pfn_type = TYPE_PTRMEMFUNC_FN_TYPE (TREE_TYPE (pfn));
       if (!force
-         && comp_target_types (type, pfn_type, 0) != 1)
+         && comp_target_types (type, pfn_type, 1) != 1)
        cp_error ("conversion to `%T' from `%T'", type, pfn_type);
 
       ndelta = cp_convert (ptrdiff_type_node, build_component_ref (pfn, delta_identifier, NULL_TREE, 0));