re PR middle-end/41257 (Bogus error '*.LTHUNK0' aliased to undefined symbol '_ZN1CD1Ev')

2009-09-04  Richard Guenther  <rguenther@suse.de>

	PR middle-end/41257
	* (cgraph_finalize_compilation_unit): Move finalizing aliases
	after emitting tunks.  Move emitting thunks and ctors from ...
	(cgraph_optimize): ... here.  Remove redundant
	cgraph_analyze_functions.
	* varasm.c (find_decl_and_mark_needed): Remove no longer
	necessary check.
	(finish_aliases_1): Adjust check for thunk aliases.

	* g++.dg/torture/pr41257.C: New testcase.

From-SVN: r151431
This commit is contained in:
Richard Guenther 2009-09-04 18:54:01 +00:00 committed by Richard Biener
parent 8d142c15c9
commit 5f1a9ebbc1
5 changed files with 75 additions and 45 deletions

View File

@ -1,3 +1,14 @@
2009-09-04 Richard Guenther <rguenther@suse.de>
PR middle-end/41257
* (cgraph_finalize_compilation_unit): Move finalizing aliases
after emitting tunks. Move emitting thunks and ctors from ...
(cgraph_optimize): ... here. Remove redundant
cgraph_analyze_functions.
* varasm.c (find_decl_and_mark_needed): Remove no longer
necessary check.
(finish_aliases_1): Adjust check for thunk aliases.
2009-09-04 Daniel Gutson <dgutson@codesourcery.com>
* config/arm/arm.md (ctzsi2): Added braces

View File

@ -1018,6 +1018,30 @@ cgraph_analyze_functions (void)
ggc_collect ();
}
/* Emit thunks for every node in the cgraph.
FIXME: We really ought to emit thunks only for functions that are needed. */
static void
cgraph_emit_thunks (void)
{
struct cgraph_node *n;
for (n = cgraph_nodes; n; n = n->next)
{
/* Only emit thunks on functions defined in this TU.
Note that this may emit more thunks than strictly necessary.
During optimization some nodes may disappear. It would be
nice to only emit thunks only for the functions that will be
emitted, but we cannot know that until the inliner and other
IPA passes have run (see the sequencing of the call to
cgraph_mark_functions_to_output in cgraph_optimize). */
if (!DECL_EXTERNAL (n->decl))
lang_hooks.callgraph.emit_associated_thunks (n->decl);
}
}
/* Analyze the whole compilation unit once it is parsed completely. */
void
@ -1026,8 +1050,16 @@ cgraph_finalize_compilation_unit (void)
/* Do not skip analyzing the functions if there were errors, we
miss diagnostics for following functions otherwise. */
/* Emit size functions we didn't inline. */
finalize_size_functions ();
finish_aliases_1 ();
/* Emit thunks, if needed. */
if (lang_hooks.callgraph.emit_associated_thunks)
cgraph_emit_thunks ();
/* Call functions declared with the "constructor" or "destructor"
attribute. */
cgraph_build_cdtor_fns ();
if (!quiet_flag)
{
@ -1035,6 +1067,10 @@ cgraph_finalize_compilation_unit (void)
fflush (stderr);
}
/* Mark alias targets necessary and emit diagnostics. */
finish_aliases_1 ();
/* Gimplify and lower all functions. */
timevar_push (TV_CGRAPH);
cgraph_analyze_functions ();
timevar_pop (TV_CGRAPH);
@ -1322,29 +1358,6 @@ ipa_passes (void)
}
/* Emit thunks for every node in the cgraph.
FIXME: We really ought to emit thunks only for functions that are needed. */
static void
cgraph_emit_thunks (void)
{
struct cgraph_node *n;
for (n = cgraph_nodes; n; n = n->next)
{
/* Only emit thunks on functions defined in this TU.
Note that this may emit more thunks than strictly necessary.
During optimization some nodes may disappear. It would be
nice to only emit thunks only for the functions that will be
emitted, but we cannot know that until the inliner and other
IPA passes have run (see the sequencing of the call to
cgraph_mark_functions_to_output in cgraph_optimize). */
if (!DECL_EXTERNAL (n->decl))
lang_hooks.callgraph.emit_associated_thunks (n->decl);
}
}
/* Perform simple optimizations based on callgraph. */
static void
@ -1357,22 +1370,9 @@ cgraph_optimize (void)
verify_cgraph ();
#endif
/* Emit thunks, if needed. */
if (lang_hooks.callgraph.emit_associated_thunks)
{
cgraph_emit_thunks ();
if (errorcount || sorrycount)
return;
}
/* Call functions declared with the "constructor" or "destructor"
attribute. */
cgraph_build_cdtor_fns ();
/* Frontend may output common variables after the unit has been finalized.
It is safe to deal with them here as they are always zero initialized. */
varpool_analyze_pending_decls ();
cgraph_analyze_functions ();
timevar_push (TV_CGRAPHOPT);
if (pre_ipa_mem_report)

View File

@ -1,3 +1,8 @@
2009-09-04 Richard Guenther <rguenther@suse.de>
PR middle-end/41257
* g++.dg/torture/pr41257.C: New testcase.
2009-09-04 Martin Jambor <mjambor@suse.cz>
PR tree-optimization/41112

View File

@ -0,0 +1,20 @@
/* { dg-do compile } */
struct A
{
virtual void foo();
virtual ~A();
int i;
};
struct B : virtual A {};
struct C : B
{
virtual void foo();
};
void bar()
{
C().foo();
}

View File

@ -5395,13 +5395,7 @@ find_decl_and_mark_needed (tree decl, tree target)
if (fnode)
{
/* We can't mark function nodes as used after cgraph global info
is finished. This wouldn't generally be necessary, but C++
virtual table thunks are introduced late in the game and
might seem like they need marking, although in fact they
don't. */
if (! cgraph_global_info_ready)
cgraph_mark_needed_node (fnode);
cgraph_mark_needed_node (fnode);
return fnode->decl;
}
else if (vnode)
@ -5571,7 +5565,7 @@ finish_aliases_1 (void)
to bind locally. Of course this is a hack - to keep it
working do the following (which is not strictly correct). */
&& (! TREE_CODE (target_decl) == FUNCTION_DECL
|| ! TREE_STATIC (target_decl))
|| ! DECL_VIRTUAL_P (target_decl))
&& ! lookup_attribute ("weakref", DECL_ATTRIBUTES (p->decl)))
error ("%q+D aliased to external symbol %qE",
p->decl, p->target);