OSDN Git Service

* method.c (make_thunk): Use overload machinery to make name.
authorjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 4 Jun 1998 00:34:57 +0000 (00:34 +0000)
committerjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 4 Jun 1998 00:34:57 +0000 (00:34 +0000)
* search.c (covariant_return_p): New fn.
(get_matching_virtual): Use it.
* init.c (build_new_1): Fix check for void.

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

gcc/cp/ChangeLog
gcc/cp/init.c
gcc/cp/method.c
gcc/cp/search.c

index ef04867..6f115d6 100644 (file)
@@ -1,3 +1,11 @@
+1998-06-03  Jason Merrill  <jason@yorick.cygnus.com>
+
+       * method.c (make_thunk): Use overload machinery to make name.
+       * search.c (covariant_return_p): New fn.
+       (get_matching_virtual): Use it.
+
+       * init.c (build_new_1): Fix check for void.
+
 1998-06-01  Per Bothner  <bothner@cygnus.com>
 
        * cp-tree.h (TYPE_FOR_JAVA):  New macro.
index c706a04..4eca6b6 100644 (file)
@@ -2261,7 +2261,7 @@ build_new_1 (exp)
   else
     size = size_in_bytes (type);
 
-  if (true_type == void_type_node)
+  if (TREE_CODE (true_type) == VOID_TYPE)
     {
       error ("invalid type `void' for new");
       return error_mark_node;
index effaf33..cc01371 100644 (file)
@@ -1917,23 +1917,30 @@ make_thunk (function, delta)
      tree function;
      int delta;
 {
-  char *buffer;
   tree thunk_id;
   tree thunk;
-  char *func_name;
   tree func_decl;
+
   if (TREE_CODE (function) != ADDR_EXPR)
     abort ();
   func_decl = TREE_OPERAND (function, 0);
   if (TREE_CODE (func_decl) != FUNCTION_DECL)
     abort ();
-  func_name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (func_decl));
-  buffer = (char *)alloca (strlen (func_name) + 32);
-  if (delta<=0)
-    sprintf (buffer, "__thunk_%d_%s", -delta, func_name);
+
+  OB_INIT ();
+  OB_PUTS ("__thunk_");
+  if (delta > 0)
+    {
+      OB_PUTC ('n');
+      icat (delta);
+    }
   else
-    sprintf (buffer, "__thunk_n%d_%s", delta, func_name);
-  thunk_id = get_identifier (buffer);
+    icat (-delta);
+  OB_PUTC ('_');
+  OB_PUTID (DECL_ASSEMBLER_NAME (func_decl));
+  OB_FINISH ();
+  thunk_id = get_identifier (obstack_base (&scratch_obstack));
+
   thunk = IDENTIFIER_GLOBAL_VALUE (thunk_id);
   if (thunk && TREE_CODE (thunk) != THUNK_DECL)
     {
index f199b2f..d2ad247 100644 (file)
@@ -2133,6 +2133,57 @@ tree_has_any_destructor_p (binfo, i)
   return TYPE_NEEDS_DESTRUCTOR (type);
 }
 
+/* Returns > 0 if a function with type DRETTYPE overriding a function
+   with type BRETTYPE is covariant, as defined in [class.virtual].
+
+   Returns 1 if trivial covariance, 2 if non-trivial (requiring runtime
+   adjustment), or -1 if pedantically invalid covariance.  */
+
+int
+covariant_return_p (brettype, drettype)
+     tree brettype, drettype;
+{
+  tree binfo;
+
+  if (TREE_CODE (brettype) == FUNCTION_DECL
+      || TREE_CODE (brettype) == THUNK_DECL)
+    {
+      brettype = TREE_TYPE (TREE_TYPE (brettype));
+      drettype = TREE_TYPE (TREE_TYPE (drettype));
+    }
+  else if (TREE_CODE (brettype) == METHOD_TYPE)
+    {
+      brettype = TREE_TYPE (brettype);
+      drettype = TREE_TYPE (drettype);
+    }
+
+  if (comptypes (brettype, drettype, 1))
+    return 0;
+
+  if (! (TREE_CODE (brettype) == TREE_CODE (drettype)
+        && (TREE_CODE (brettype) == POINTER_TYPE
+            || TREE_CODE (brettype) == REFERENCE_TYPE)
+        && TYPE_READONLY (brettype) == TYPE_READONLY (drettype)
+        && TYPE_VOLATILE (brettype) == TYPE_VOLATILE (drettype)))
+    return 0;
+
+  if (! can_convert (brettype, drettype))
+    return 0;
+
+  brettype = TREE_TYPE (brettype);
+  drettype = TREE_TYPE (drettype);
+
+  /* If not pedantic, allow any standard pointer conversion.  */
+  if (! IS_AGGR_TYPE (drettype) || ! IS_AGGR_TYPE (brettype))
+    return -1;
+
+  binfo = get_binfo (brettype, drettype, 0);
+
+  if (! BINFO_OFFSET_ZEROP (binfo) || TREE_VIA_VIRTUAL (binfo))
+    return 2;
+  return 1;
+}
+
 /* Given a class type TYPE, and a function decl FNDECL, look for a
    virtual function in TYPE's hierarchy which FNDECL could match as a
    virtual function.  It doesn't matter which one we find.
@@ -2146,6 +2197,7 @@ get_matching_virtual (binfo, fndecl, dtorp)
      int dtorp;
 {
   tree tmp = NULL_TREE;
+  int i;
 
   /* Breadth first search routines start searching basetypes
      of TYPE, so we must perform first ply of search here.  */
@@ -2209,36 +2261,15 @@ get_matching_virtual (binfo, fndecl, dtorp)
                  tree brettype = TREE_TYPE (TREE_TYPE (tmp));
                  if (comptypes (brettype, drettype, 1))
                    /* OK */;
-                 else if
-                   (TREE_CODE (brettype) == TREE_CODE (drettype)
-                    && (TREE_CODE (brettype) == POINTER_TYPE
-                        || TREE_CODE (brettype) == REFERENCE_TYPE)
-                    && comptypes (TYPE_MAIN_VARIANT (TREE_TYPE (brettype)),
-                                  TYPE_MAIN_VARIANT (TREE_TYPE (drettype)),
-                                  0))
-                     /* covariant return type */
+                 else if ((i = covariant_return_p (brettype, drettype)))
                    {
-                     tree b = TREE_TYPE (brettype), d = TREE_TYPE (drettype);
-                     if (TYPE_MAIN_VARIANT (b) != TYPE_MAIN_VARIANT (d))
-                       {
-                         tree binfo = get_binfo (b, d, 1);
-                         if (binfo != error_mark_node
-                             && (! BINFO_OFFSET_ZEROP (binfo)
-                                 || TREE_VIA_VIRTUAL (binfo)))
-                           sorry ("adjusting pointers for covariant returns");
-                       }
-                     if (TYPE_READONLY (d) > TYPE_READONLY (b))
-                       {
-                         cp_error_at ("return type of `%#D' adds const", fndecl);
-                         cp_error_at ("  overriding definition as `%#D'",
-                                      tmp);
-                       }
-                     else if (TYPE_VOLATILE (d) > TYPE_VOLATILE (b))
+                     if (i == 2)
+                       sorry ("adjusting pointers for covariant returns");
+
+                     if (pedantic && i == -1)
                        {
-                         cp_error_at ("return type of `%#D' adds volatile",
-                                   fndecl);
-                         cp_error_at ("  overriding definition as `%#D'",
-                                      tmp);
+                         cp_pedwarn_at ("invalid covariant return type for `%#D' (must be pointer or reference to class)", fndecl);
+                         cp_pedwarn_at ("  overriding `%#D'", tmp);
                        }
                    }
                  else if (IS_AGGR_TYPE_2 (brettype, drettype)