]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
backport: class.c (build_vtbl_ref_1): Use fixed_type_or_null.
authorJakub Jelinek <jakub@redhat.com>
Mon, 24 Mar 2003 11:33:50 +0000 (12:33 +0100)
committerJakub Jelinek <jakub@gcc.gnu.org>
Mon, 24 Mar 2003 11:33:50 +0000 (12:33 +0100)
* Backport from mainline:
2002-05-13  Jason Merrill  <jason@redhat.com>

* class.c (build_vtbl_ref_1): Use fixed_type_or_null.
(fixed_type_or_null): See through reference vars.
(build_base_path): Vtable contents are constant.

* g++.dg/opt/rtti1.C: New test.

From-SVN: r64786

gcc/cp/ChangeLog
gcc/cp/class.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/opt/rtti1.C [new file with mode: 0644]

index aaf965806e616f7f3cd6e32c7af948c6901c292b..047d593cff31948b4d375cc61d9764f688a41939 100644 (file)
@@ -1,3 +1,12 @@
+2003-03-24  Jakub Jelinek  <jakub@redhat.com>
+
+       * Backport from mainline:
+       2002-05-13  Jason Merrill  <jason@redhat.com>
+
+       * class.c (build_vtbl_ref_1): Use fixed_type_or_null.
+       (fixed_type_or_null): See through reference vars.
+       (build_base_path): Vtable contents are constant.
+
 2003-03-19  Jason Merrill  <jason@redhat.com>
 
        PR c++/8316, c++/9315, c++/10136
index 2ac4e30f6c3cb09dbbe128a5a5e0c00866e2b5e7..ac174b3c275163d382e1e33bccf92d5a05a07f8e 100644 (file)
@@ -315,7 +315,8 @@ build_base_path (code, expr, binfo, nonnull)
                         build_pointer_type (ptrdiff_type_node),
                         v_offset);
       v_offset = build_indirect_ref (v_offset, NULL);
-      
+      TREE_CONSTANT (v_offset) = 1;
+
       offset = cp_convert (ptrdiff_type_node,
                           size_diffop (offset, BINFO_OFFSET (v_binfo)));
 
@@ -400,75 +401,36 @@ static tree
 build_vtbl_ref_1 (instance, idx)
      tree instance, idx;
 {
-  tree vtbl, aref;
-  tree basetype = TREE_TYPE (instance);
+  tree aref;
+  tree vtbl = NULL_TREE;
+
+  /* Try to figure out what a reference refers to, and
+     access its virtual function table directly.  */
+
+  int cdtorp = 0;
+  tree fixed_type = fixed_type_or_null (instance, NULL, &cdtorp);
 
+  tree basetype = TREE_TYPE (instance);
   if (TREE_CODE (basetype) == REFERENCE_TYPE)
     basetype = TREE_TYPE (basetype);
 
-  if (instance == current_class_ref)
-    vtbl = build_vfield_ref (instance, basetype);
-  else
+  if (fixed_type && !cdtorp)
     {
-      if (optimize)
-       {
-         /* Try to figure out what a reference refers to, and
-            access its virtual function table directly.  */
-         tree ref = NULL_TREE;
-
-         if (TREE_CODE (instance) == INDIRECT_REF
-             && TREE_CODE (TREE_TYPE (TREE_OPERAND (instance, 0))) == REFERENCE_TYPE)
-           ref = TREE_OPERAND (instance, 0);
-         else if (TREE_CODE (TREE_TYPE (instance)) == REFERENCE_TYPE)
-           ref = instance;
-
-         if (ref && TREE_CODE (ref) == VAR_DECL
-             && DECL_INITIAL (ref))
-           {
-             tree init = DECL_INITIAL (ref);
-
-             while (TREE_CODE (init) == NOP_EXPR
-                    || TREE_CODE (init) == NON_LVALUE_EXPR)
-               init = TREE_OPERAND (init, 0);
-             if (TREE_CODE (init) == ADDR_EXPR)
-               {
-                 init = TREE_OPERAND (init, 0);
-                 if (IS_AGGR_TYPE (TREE_TYPE (init))
-                     && (TREE_CODE (init) == PARM_DECL
-                         || TREE_CODE (init) == VAR_DECL))
-                   instance = init;
-               }
-           }
-       }
+      tree binfo = lookup_base (fixed_type, basetype,
+                               ba_ignore|ba_quiet, NULL);
+      if (binfo)
+       vtbl = BINFO_VTABLE (binfo);
+    }
 
-      if (IS_AGGR_TYPE (TREE_TYPE (instance))
-         && (TREE_CODE (instance) == RESULT_DECL
-             || TREE_CODE (instance) == PARM_DECL
-             || TREE_CODE (instance) == VAR_DECL))
-       {
-         vtbl = TYPE_BINFO_VTABLE (basetype);
-         /* Knowing the dynamic type of INSTANCE we can easily obtain
-            the correct vtable entry.  We resolve this back to be in
-            terms of the primary vtable.  */
-         if (TREE_CODE (vtbl) == PLUS_EXPR)
-           {
-             idx = fold (build (PLUS_EXPR,
-                                TREE_TYPE (idx),
-                                idx,
-                                build (EXACT_DIV_EXPR,
-                                       TREE_TYPE (idx),
-                                       TREE_OPERAND (vtbl, 1),
-                                       TYPE_SIZE_UNIT (vtable_entry_type))));
-             vtbl = get_vtbl_decl_for_binfo (TYPE_BINFO (basetype));
-           }
-       }
-      else
-       vtbl = build_vfield_ref (instance, basetype);
+  if (!vtbl)
+    {
+      vtbl = build_vfield_ref (instance, basetype);
     }
 
   assemble_external (vtbl);
 
   aref = build_array_ref (vtbl, idx);
+  TREE_CONSTANT (aref) = 1;
 
   return aref;
 }
@@ -5370,7 +5332,7 @@ fixed_type_or_null (instance, nonnull, cdtorp)
        return fixed_type_or_null (TREE_OPERAND (instance, 0), nonnull, cdtorp);
       if (TREE_CODE (TREE_OPERAND (instance, 1)) == INTEGER_CST)
        /* Propagate nonnull.  */
-       fixed_type_or_null (TREE_OPERAND (instance, 0), nonnull, cdtorp);
+       return fixed_type_or_null (TREE_OPERAND (instance, 0), nonnull, cdtorp);
       return NULL_TREE;
 
     case NOP_EXPR:
@@ -5397,6 +5359,7 @@ fixed_type_or_null (instance, nonnull, cdtorp)
       /* fall through...  */
     case TARGET_EXPR:
     case PARM_DECL:
+    case RESULT_DECL:
       if (IS_AGGR_TYPE (TREE_TYPE (instance)))
        {
          if (nonnull)
@@ -5423,6 +5386,11 @@ fixed_type_or_null (instance, nonnull, cdtorp)
           /* Reference variables should be references to objects.  */
           if (nonnull)
            *nonnull = 1;
+
+         if (TREE_CODE (instance) == VAR_DECL
+             && DECL_INITIAL (instance))
+           return fixed_type_or_null (DECL_INITIAL (instance),
+                                      nonnull, cdtorp);
        }
       return NULL_TREE;
 
index 7ffcccc024fcbbd824769fb9ef4511b20ee1f1a7..050c59e8e2ef9aca64f9f4711c3b52d6345b9640 100644 (file)
@@ -1,3 +1,7 @@
+2003-03-24  Jakub Jelinek  <jakub@redhat.com>
+
+       * g++.dg/opt/rtti1.C: New test.
+
 2003-03-23  Daniel Jacobowitz  <drow@mvista.com>
 
        * gcc.c-torture/execute/20030224-2.c: New test.
diff --git a/gcc/testsuite/g++.dg/opt/rtti1.C b/gcc/testsuite/g++.dg/opt/rtti1.C
new file mode 100644 (file)
index 0000000..32daaef
--- /dev/null
@@ -0,0 +1,20 @@
+// Test that typeid sees through references even when optimizing.
+// { dg-do run }
+// { dg-options "-O2" }
+
+#include <typeinfo>
+
+struct A
+{
+  virtual ~A() { }
+};
+
+class B : public A { };
+
+int main ()
+{
+  B b;
+  A &aref = b;
+
+  return typeid (aref) != typeid (b);
+}