This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [Bug optimization/11421] New: [3.4 regression] vtables are not emitted in unit-at-a-time mode
- From: Jan Hubicka <jh at suse dot cz>
- To: martin at mpa-garching dot mpg dot de <gcc-bugzilla at gcc dot gnu dot org>,gcc-patches at gcc dot gnu dot org, mark at codesourcery dot com
- Cc: jh at suse dot cz
- Date: Thu, 3 Jul 2003 14:23:32 +0200
- Subject: Re: [Bug optimization/11421] New: [3.4 regression] vtables are not emitted in unit-at-a-time mode
- References: <20030703085958.11421.martin@mpa-garching.mpg.de>
>
> struct foo {
> virtual void bar();
> };
>
> void foo::bar() {}
>
> >>>>>>>> end of foo.cc
>
> main.cc
>
> struct foo {
> virtual void bar();
> };
>
> int main() {
> foo var1;
> }
>
> >>>>>>>> end of main.cc
>
> Compiling with
> g++ main.cc foo.cc
> works, but
> g++ -funit-at-a-time main.cc foo.cc
> results in
> /tmp/cc85sQ35.o: In function `foo::foo[in-charge]()':
> /tmp/cc85sQ35.o(.gnu.linkonce.t._ZN3fooC1Ev+0x8): undefined reference to
> `vtable for foo'
> collect2: ld returned 1 exit status
Thanks, this is also usefull testcase as it finally got me into the
problem of explicit inline instantiations we were discussing with Mark.
Mark, the situation seems to be that all classes put into keyed_vtables
list must be always output and the extension works by forcing vtable on
that list.
The attached patch makes this to happen and replaced the
EXPLICIT_INSTANTIATION test we concluded to last time.
Regtested/bootstrapped i686, OK?
Honza
Thu Jul 3 14:19:25 CEST 2003 Jan Hubicka <jh@suse.cz>
* decl2.c (maybe_emit_vtables): New argument keyed; when set; mark
vtable as needed.
(finish_file): Update call of maybe_emit_vtables.
Index: decl2.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/decl2.c,v
retrieving revision 1.636
diff -c -3 -p -r1.636 decl2.c
*** decl2.c 2 Jul 2003 09:36:17 -0000 1.636
--- decl2.c 3 Jul 2003 12:17:36 -0000
*************** typedef struct priority_info_s {
*** 63,69 ****
static void mark_vtable_entries (tree);
static void grok_function_init (tree, tree);
! static bool maybe_emit_vtables (tree);
static void add_using_namespace (tree, tree, bool);
static cxx_binding *ambiguous_decl (tree, cxx_binding *, cxx_binding *, int);
static tree build_anon_union_vars (tree);
--- 63,69 ----
static void mark_vtable_entries (tree);
static void grok_function_init (tree, tree);
! static bool maybe_emit_vtables (tree, bool);
static void add_using_namespace (tree, tree, bool);
static cxx_binding *ambiguous_decl (tree, cxx_binding *, cxx_binding *, int);
static tree build_anon_union_vars (tree);
*************** prepare_assemble_variable (tree vars)
*** 1631,1640 ****
}
/* If necessary, write out the vtables for the dynamic class CTYPE.
! Returns true if any vtables were emitted. */
static bool
! maybe_emit_vtables (tree ctype)
{
tree vtbl;
tree primary_vtbl;
--- 1643,1655 ----
}
/* If necessary, write out the vtables for the dynamic class CTYPE.
! Returns true if any vtables were emitted.
! When KEYED is true, ensure that the vtables are marked as needed when they
! are output. This is used for virtual tables that are output only in files
! deifning some method and thus must appear even when they are unused. */
static bool
! maybe_emit_vtables (tree ctype, bool keyed)
{
tree vtbl;
tree primary_vtbl;
*************** maybe_emit_vtables (tree ctype)
*** 1676,1682 ****
mark_vtable_entries (vtbl);
/* If we know that DECL is needed, mark it as such for the varpool. */
! if (CLASSTYPE_EXPLICIT_INSTANTIATION (ctype))
cgraph_varpool_mark_needed_node (cgraph_varpool_node (vtbl));
if (TREE_TYPE (DECL_INITIAL (vtbl)) == 0)
--- 1691,1697 ----
mark_vtable_entries (vtbl);
/* If we know that DECL is needed, mark it as such for the varpool. */
! if (keyed)
cgraph_varpool_mark_needed_node (cgraph_varpool_node (vtbl));
if (TREE_TYPE (DECL_INITIAL (vtbl)) == 0)
*************** finish_file ()
*** 2647,2653 ****
have to look at it again. */
while (keyed_classes != NULL_TREE
! && maybe_emit_vtables (TREE_VALUE (keyed_classes)))
{
reconsider = true;
keyed_classes = TREE_CHAIN (keyed_classes);
--- 2662,2668 ----
have to look at it again. */
while (keyed_classes != NULL_TREE
! && maybe_emit_vtables (TREE_VALUE (keyed_classes), true))
{
reconsider = true;
keyed_classes = TREE_CHAIN (keyed_classes);
*************** finish_file ()
*** 2660,2666 ****
while (next)
{
! if (maybe_emit_vtables (TREE_VALUE (next)))
{
reconsider = true;
TREE_CHAIN (t) = TREE_CHAIN (next);
--- 2675,2681 ----
while (next)
{
! if (maybe_emit_vtables (TREE_VALUE (next), false))
{
reconsider = true;
TREE_CHAIN (t) = TREE_CHAIN (next);