]> gcc.gnu.org Git - gcc.git/commitdiff
re PR c++/67407 (ice in friend_accessible_p)
authorJason Merrill <jason@redhat.com>
Thu, 28 Jan 2016 15:07:56 +0000 (10:07 -0500)
committerJason Merrill <jason@gcc.gnu.org>
Thu, 28 Jan 2016 15:07:56 +0000 (10:07 -0500)
PR c++/67407

* search.c (dfs_walk_once, dfs_walk_once_r)
(dfs_walk_once_accessible_r, dfs_walk_once_accessible): Use
hash_set instead of BINFO_MARKED.
(dfs_unmark_r): Remove.

From-SVN: r232929

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

index 6b790e10511d5e28ee106e5200310d1d7d31f5d5..83a25f707789f8ce0442af50e91536d5cd0fdc21 100644 (file)
@@ -1,3 +1,11 @@
+2016-01-28  Jason Merrill  <jason@redhat.com>
+
+       PR c++/67407
+       * search.c (dfs_walk_once, dfs_walk_once_r)
+       (dfs_walk_once_accessible_r, dfs_walk_once_accessible): Use
+       hash_set instead of BINFO_MARKED.
+       (dfs_unmark_r): Remove.
+
 2016-01-28  Patrick Palka  <ppalka@gcc.gnu.org>
 
        PR c++/24208
index fc47f9179ca2ee2b355b1798c83e62fab9e51487..45d8a2432459b728bf74bade9d457241ca73eb53 100644 (file)
@@ -2608,9 +2608,7 @@ update_vtable_entry_for_fn (tree t, tree binfo, tree fn, tree* virtuals,
          /* There was no existing virtual thunk (which takes
             precedence).  So find the binfo of the base function's
             return type within the overriding function's return type.
-            We cannot call lookup base here, because we're inside a
-            dfs_walk, and will therefore clobber the BINFO_MARKED
-            flags.  Fortunately we know the covariancy is valid (it
+            Fortunately we know the covariancy is valid (it
             has already been checked), so we can just iterate along
             the binfos, which have been chained in inheritance graph
             order.  Of course it is lame that we have to repeat the
index 455073ebd3a6da2a719b5d2635299b4e45368f15..792461189152ad68c40023ae4756d5c3403c7e3a 100644 (file)
@@ -34,9 +34,6 @@ static tree dfs_lookup_base (tree, void *);
 static tree dfs_dcast_hint_pre (tree, void *);
 static tree dfs_dcast_hint_post (tree, void *);
 static tree dfs_debug_mark (tree, void *);
-static tree dfs_walk_once_r (tree, tree (*pre_fn) (tree, void *),
-                            tree (*post_fn) (tree, void *), void *data);
-static void dfs_unmark_r (tree);
 static int check_hidden_convs (tree, int, int, tree, tree, tree);
 static tree split_conversions (tree, tree, tree, tree);
 static int lookup_conversions_r (tree, int, int,
@@ -44,10 +41,6 @@ static int lookup_conversions_r (tree, int, int,
 static int look_for_overrides_r (tree, tree);
 static tree lookup_field_r (tree, void *);
 static tree dfs_accessible_post (tree, void *);
-static tree dfs_walk_once_accessible_r (tree, bool, bool,
-                                       tree (*pre_fn) (tree, void *),
-                                       tree (*post_fn) (tree, void *),
-                                       void *data);
 static tree dfs_walk_once_accessible (tree, bool,
                                      tree (*pre_fn) (tree, void *),
                                      tree (*post_fn) (tree, void *),
@@ -1826,7 +1819,8 @@ dfs_walk_all (tree binfo, tree (*pre_fn) (tree, void *),
 
 static tree
 dfs_walk_once_r (tree binfo, tree (*pre_fn) (tree, void *),
-                tree (*post_fn) (tree, void *), void *data)
+                tree (*post_fn) (tree, void *), hash_set<tree> *pset,
+                void *data)
 {
   tree rval;
   unsigned ix;
@@ -1849,13 +1843,10 @@ dfs_walk_once_r (tree binfo, tree (*pre_fn) (tree, void *),
   for (ix = 0; BINFO_BASE_ITERATE (binfo, ix, base_binfo); ix++)
     {
       if (BINFO_VIRTUAL_P (base_binfo))
-       {
-         if (BINFO_MARKED (base_binfo))
-           continue;
-         BINFO_MARKED (base_binfo) = 1;
-       }
+       if (pset->add (base_binfo))
+         continue;
 
-      rval = dfs_walk_once_r (base_binfo, pre_fn, post_fn, data);
+      rval = dfs_walk_once_r (base_binfo, pre_fn, post_fn, pset, data);
       if (rval)
        return rval;
     }
@@ -1872,30 +1863,6 @@ dfs_walk_once_r (tree binfo, tree (*pre_fn) (tree, void *),
   return NULL_TREE;
 }
 
-/* Worker for dfs_walk_once. Recursively unmark the virtual base binfos of
-   BINFO.  */
-
-static void
-dfs_unmark_r (tree binfo)
-{
-  unsigned ix;
-  tree base_binfo;
-
-  /* Process the basetypes.  */
-  for (ix = 0; BINFO_BASE_ITERATE (binfo, ix, base_binfo); ix++)
-    {
-      if (BINFO_VIRTUAL_P (base_binfo))
-       {
-         if (!BINFO_MARKED (base_binfo))
-           continue;
-         BINFO_MARKED (base_binfo) = 0;
-       }
-      /* Only walk, if it can contain more virtual bases.  */
-      if (CLASSTYPE_VBASECLASSES (BINFO_TYPE (base_binfo)))
-       dfs_unmark_r (base_binfo);
-    }
-}
-
 /* Like dfs_walk_all, except that binfos are not multiply walked.  For
    non-diamond shaped hierarchies this is the same as dfs_walk_all.
    For diamond shaped hierarchies we must mark the virtual bases, to
@@ -1918,22 +1885,8 @@ dfs_walk_once (tree binfo, tree (*pre_fn) (tree, void *),
     rval = dfs_walk_all (binfo, pre_fn, post_fn, data);
   else
     {
-      rval = dfs_walk_once_r (binfo, pre_fn, post_fn, data);
-      if (!BINFO_INHERITANCE_CHAIN (binfo))
-       {
-         /* We are at the top of the hierarchy, and can use the
-            CLASSTYPE_VBASECLASSES list for unmarking the virtual
-            bases.  */
-         vec<tree, va_gc> *vbases;
-         unsigned ix;
-         tree base_binfo;
-
-         for (vbases = CLASSTYPE_VBASECLASSES (BINFO_TYPE (binfo)), ix = 0;
-              vec_safe_iterate (vbases, ix, &base_binfo); ix++)
-           BINFO_MARKED (base_binfo) = 0;
-       }
-      else
-       dfs_unmark_r (binfo);
+      hash_set<tree> pset;
+      rval = dfs_walk_once_r (binfo, pre_fn, post_fn, &pset, data);
     }
 
   active--;
@@ -1947,7 +1900,7 @@ dfs_walk_once (tree binfo, tree (*pre_fn) (tree, void *),
    indicates whether bases should be marked during traversal.  */
 
 static tree
-dfs_walk_once_accessible_r (tree binfo, bool friends_p, bool once,
+dfs_walk_once_accessible_r (tree binfo, bool friends_p, hash_set<tree> *pset,
                            tree (*pre_fn) (tree, void *),
                            tree (*post_fn) (tree, void *), void *data)
 {
@@ -1971,9 +1924,9 @@ dfs_walk_once_accessible_r (tree binfo, bool friends_p, bool once,
   /* Find the next child binfo to walk.  */
   for (ix = 0; BINFO_BASE_ITERATE (binfo, ix, base_binfo); ix++)
     {
-      bool mark = once && BINFO_VIRTUAL_P (base_binfo);
+      bool mark = pset && BINFO_VIRTUAL_P (base_binfo);
 
-      if (mark && BINFO_MARKED (base_binfo))
+      if (mark && pset->contains (base_binfo))
        continue;
 
       /* If the base is inherited via private or protected
@@ -1992,9 +1945,9 @@ dfs_walk_once_accessible_r (tree binfo, bool friends_p, bool once,
        }
 
       if (mark)
-       BINFO_MARKED (base_binfo) = 1;
+       pset->add (base_binfo);
 
-      rval = dfs_walk_once_accessible_r (base_binfo, friends_p, once,
+      rval = dfs_walk_once_accessible_r (base_binfo, friends_p, pset,
                                         pre_fn, post_fn, data);
       if (rval)
        return rval;
@@ -2021,28 +1974,14 @@ dfs_walk_once_accessible (tree binfo, bool friends_p,
                            tree (*pre_fn) (tree, void *),
                            tree (*post_fn) (tree, void *), void *data)
 {
-  bool diamond_shaped = CLASSTYPE_DIAMOND_SHAPED_P (BINFO_TYPE (binfo));
-  tree rval = dfs_walk_once_accessible_r (binfo, friends_p, diamond_shaped,
+  hash_set<tree> *pset = NULL;
+  if (CLASSTYPE_DIAMOND_SHAPED_P (BINFO_TYPE (binfo)))
+    pset = new hash_set<tree>;
+  tree rval = dfs_walk_once_accessible_r (binfo, friends_p, pset,
                                          pre_fn, post_fn, data);
 
-  if (diamond_shaped)
-    {
-      if (!BINFO_INHERITANCE_CHAIN (binfo))
-       {
-         /* We are at the top of the hierarchy, and can use the
-            CLASSTYPE_VBASECLASSES list for unmarking the virtual
-            bases.  */
-         vec<tree, va_gc> *vbases;
-         unsigned ix;
-         tree base_binfo;
-
-         for (vbases = CLASSTYPE_VBASECLASSES (BINFO_TYPE (binfo)), ix = 0;
-              vec_safe_iterate (vbases, ix, &base_binfo); ix++)
-           BINFO_MARKED (base_binfo) = 0;
-       }
-      else
-       dfs_unmark_r (binfo);
-    }
+  if (pset)
+    delete pset;
   return rval;
 }
 
diff --git a/gcc/testsuite/g++.dg/inherit/protected1.C b/gcc/testsuite/g++.dg/inherit/protected1.C
new file mode 100644 (file)
index 0000000..c71be53
--- /dev/null
@@ -0,0 +1,51 @@
+// PR c++/67407
+
+template <class> class A;
+template <class> struct B;
+template <class X> struct B<A<X> >
+{
+  static int
+  check ()
+  {
+    A<X> a;
+    a.m_class->m_object;
+  }
+};
+template <class T> class A
+{
+public:
+  template <class X> bool operator== (const X &) const;
+  T *m_class;
+};
+template <class T>
+template <class X>
+bool
+A<T>::operator== (const X &) const
+{
+  B<X>::check;
+}
+class C
+{
+protected:
+  template <class> friend struct B;
+  void *m_object;
+};
+class F : virtual C
+{
+};
+class G : virtual public C
+{
+};
+class H : F, public G
+{
+};
+class D
+{
+  void onBusMessage (const A<int> &);
+  A<H> m_pipeline;
+};
+void
+D::onBusMessage (const A<int> &p1)
+{
+  p1 == m_pipeline;
+}
This page took 0.082747 seconds and 5 git commands to generate.