aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/ChangeLog12
-rw-r--r--gcc/cp/cp-tree.h10
-rw-r--r--gcc/cp/search.c87
-rw-r--r--gcc/testsuite/ChangeLog4
-rw-r--r--gcc/testsuite/g++.dg/abi/vbase9.C29
5 files changed, 69 insertions, 73 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 870a697..6f31ebd 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,15 @@
+2002-03-26 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/5682
+ * cp-tree.h (BINFO_PRIMARY_P): Explain meaning better.
+ (dfs_skip_nonprimary_vbases_unmarkedp): Remove.
+ (dfs_skip_nonprimary_vbases_markedp): Remove.
+ * search.c (get_shared_vbase_if_not_primary): Remove.
+ (dfs_skip_nonprimary_vbases_unmarkedp): Remove.
+ (dfs_skip_nonprimary_vbases_markedp): Remove.
+ (dfs_unmarked_real_bases_queue_p): Just get the canonical binfo.
+ (dfs_marked_real_bases_queue_p): Likewise.
+
2002-03-26 Neil Booth <neil@daikokuya.demon.co.uk>
* cp-lang.c (LANG_HOOKS_MARK_TREE): Redefine.
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index 244b01e..783d382 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -1638,12 +1638,10 @@ struct lang_type
#define SET_BINFO_PUSHDECLS_MARKED(NODE) SET_BINFO_VTABLE_PATH_MARKED (NODE)
#define CLEAR_BINFO_PUSHDECLS_MARKED(NODE) CLEAR_BINFO_VTABLE_PATH_MARKED (NODE)
-/* Nonzero if this BINFO is a primary base class.
+/* Nonzero if this BINFO is a primary base class. Note, this can be
+ set for non-canononical virtual bases. For a virtual primary base
+ you might also need to check whether it is canonical. */
- In the TYPE_BINFO hierarchy, this flag is never set for a base
- class of a non-primary virtual base. This flag is only valid for
- paths (given by BINFO_INHERITANCE_CHAIN) that really exist in the
- final object. */
#define BINFO_PRIMARY_P(NODE) \
(BINFO_PRIMARY_BASE_OF (NODE) != NULL_TREE)
@@ -4116,8 +4114,6 @@ extern tree dfs_walk_real PARAMS ((tree,
extern tree dfs_unmark PARAMS ((tree, void *));
extern tree markedp PARAMS ((tree, void *));
extern tree unmarkedp PARAMS ((tree, void *));
-extern tree dfs_skip_nonprimary_vbases_unmarkedp PARAMS ((tree, void *));
-extern tree dfs_skip_nonprimary_vbases_markedp PARAMS ((tree, void *));
extern tree dfs_unmarked_real_bases_queue_p PARAMS ((tree, void *));
extern tree dfs_marked_real_bases_queue_p PARAMS ((tree, void *));
extern tree dfs_skip_vbases PARAMS ((tree, void *));
diff --git a/gcc/cp/search.c b/gcc/cp/search.c
index adcb076..6e8ac11 100644
--- a/gcc/cp/search.c
+++ b/gcc/cp/search.c
@@ -127,7 +127,6 @@ static int protected_accessible_p PARAMS ((tree, tree, tree));
static int friend_accessible_p PARAMS ((tree, tree, tree));
static void setup_class_bindings PARAMS ((tree, int));
static int template_self_reference_p PARAMS ((tree, tree));
-static tree get_shared_vbase_if_not_primary PARAMS ((tree, void *));
static tree dfs_find_vbase_instance PARAMS ((tree, void *));
static tree dfs_get_pure_virtuals PARAMS ((tree, void *));
static tree dfs_build_inheritance_graph_order PARAMS ((tree, void *));
@@ -1950,81 +1949,30 @@ look_for_overrides_r (type, fndecl)
return look_for_overrides (type, fndecl);
}
-/* A queue function for dfs_walk that skips any nonprimary virtual
- bases and any already marked bases. */
+/* A queue function to use with dfs_walk that only walks into
+ canonical bases. DATA should be the type of the complete object,
+ or a TREE_LIST whose TREE_PURPOSE is the type of the complete
+ object. By using this function as a queue function, you will walk
+ over exactly those BINFOs that actually exist in the complete
+ object, including those for virtual base classes. If you
+ SET_BINFO_MARKED for each binfo you process, you are further
+ guaranteed that you will walk into each virtual base class exactly
+ once. */
tree
-dfs_skip_nonprimary_vbases_unmarkedp (binfo, data)
- tree binfo;
- void *data ATTRIBUTE_UNUSED;
-{
- if (TREE_VIA_VIRTUAL (binfo) && !BINFO_PRIMARY_P (binfo))
- /* This is a non-primary virtual base. Skip it. */
- return NULL_TREE;
-
- return unmarkedp (binfo, NULL);
-}
-
-/* A queue function for dfs_walk that skips any nonprimary virtual
- bases and any unmarked bases. */
-
-tree
-dfs_skip_nonprimary_vbases_markedp (binfo, data)
- tree binfo;
- void *data ATTRIBUTE_UNUSED;
-{
- if (TREE_VIA_VIRTUAL (binfo) && !BINFO_PRIMARY_P (binfo))
- /* This is a non-primary virtual base. Skip it. */
- return NULL_TREE;
-
- return markedp (binfo, NULL);
-}
-
-/* If BINFO is a non-primary virtual baseclass (in the hierarchy
- dominated by TYPE), and no primary copy appears anywhere in the
- hierarchy, return the shared copy. If a primary copy appears
- elsewhere, return NULL_TREE. Otherwise, return BINFO itself; it is
- either a non-virtual base or a primary virtual base. */
-
-static tree
-get_shared_vbase_if_not_primary (binfo, data)
+dfs_unmarked_real_bases_queue_p (binfo, data)
tree binfo;
void *data;
{
- if (TREE_VIA_VIRTUAL (binfo) && !BINFO_PRIMARY_P (binfo))
+ if (TREE_VIA_VIRTUAL (binfo))
{
tree type = (tree) data;
if (TREE_CODE (type) == TREE_LIST)
type = TREE_PURPOSE (type);
-
- /* This is a non-primary virtual base. If there is no primary
- version, get the shared version. */
binfo = binfo_for_vbase (BINFO_TYPE (binfo), type);
- if (BINFO_PRIMARY_P (binfo))
- return NULL_TREE;
}
-
- return binfo;
-}
-
-/* A queue function to use with dfs_walk that prevents travel into any
- nonprimary virtual base, or its baseclasses. DATA should be the
- type of the complete object, or a TREE_LIST whose TREE_PURPOSE is
- the type of the complete object. By using this function as a queue
- function, you will walk over exactly those BINFOs that actually
- exist in the complete object, including those for virtual base
- classes. If you SET_BINFO_MARKED for each binfo you process, you
- are further guaranteed that you will walk into each virtual base
- class exactly once. */
-
-tree
-dfs_unmarked_real_bases_queue_p (binfo, data)
- tree binfo;
- void *data;
-{
- binfo = get_shared_vbase_if_not_primary (binfo, data);
- return binfo ? unmarkedp (binfo, NULL) : NULL_TREE;
+ return unmarkedp (binfo, NULL);
}
/* Like dfs_unmarked_real_bases_queue_p but walks only into things
@@ -2035,8 +1983,15 @@ dfs_marked_real_bases_queue_p (binfo, data)
tree binfo;
void *data;
{
- binfo = get_shared_vbase_if_not_primary (binfo, data);
- return binfo ? markedp (binfo, NULL) : NULL_TREE;
+ if (TREE_VIA_VIRTUAL (binfo))
+ {
+ tree type = (tree) data;
+
+ if (TREE_CODE (type) == TREE_LIST)
+ type = TREE_PURPOSE (type);
+ binfo = binfo_for_vbase (BINFO_TYPE (binfo), type);
+ }
+ return markedp (binfo, NULL);
}
/* A queue function that skips all virtual bases (and their
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 7720461..f78d27e 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,7 @@
+2002-03-26 Nathan Sidwell <nathan@codesourcery.com>
+
+ * g++.dg/abi/vbase9.C: New test.
+
2002-03-26 Richard Earnshaw <rearnsha@arm.com>
* gcc.dg/arm-asm.c: New test.
diff --git a/gcc/testsuite/g++.dg/abi/vbase9.C b/gcc/testsuite/g++.dg/abi/vbase9.C
new file mode 100644
index 0000000..4a0540d
--- /dev/null
+++ b/gcc/testsuite/g++.dg/abi/vbase9.C
@@ -0,0 +1,29 @@
+// { dg-do compile }
+
+// Copyright (C) 2002 Free Software Foundation, Inc.
+// Contributed by Nathan Sidwell 17 Mar 2002 <nathan@codesourcery.com>
+// Origin: Jakub Jelinek <jakub@redhat.com>
+
+// PR 5681. ICE in build_secondary_vtable
+
+struct A {
+ virtual int f1 ();
+};
+
+struct B : virtual A {};
+
+struct C {
+ virtual int f2 ();
+};
+
+struct E : A {};
+
+struct D : E, B {};
+
+struct F : virtual D {};
+
+struct G : virtual F, C {};
+
+struct H : virtual F {};
+
+struct I : G, H {};