Commit 5f1a9ebb by Richard Guenther Committed by Richard Biener

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
parent 8d142c15
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> 2009-09-04 Daniel Gutson <dgutson@codesourcery.com>
* config/arm/arm.md (ctzsi2): Added braces * config/arm/arm.md (ctzsi2): Added braces
......
...@@ -1018,6 +1018,30 @@ cgraph_analyze_functions (void) ...@@ -1018,6 +1018,30 @@ cgraph_analyze_functions (void)
ggc_collect (); 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. */ /* Analyze the whole compilation unit once it is parsed completely. */
void void
...@@ -1026,8 +1050,16 @@ cgraph_finalize_compilation_unit (void) ...@@ -1026,8 +1050,16 @@ cgraph_finalize_compilation_unit (void)
/* Do not skip analyzing the functions if there were errors, we /* Do not skip analyzing the functions if there were errors, we
miss diagnostics for following functions otherwise. */ miss diagnostics for following functions otherwise. */
/* Emit size functions we didn't inline. */
finalize_size_functions (); 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) if (!quiet_flag)
{ {
...@@ -1035,6 +1067,10 @@ cgraph_finalize_compilation_unit (void) ...@@ -1035,6 +1067,10 @@ cgraph_finalize_compilation_unit (void)
fflush (stderr); fflush (stderr);
} }
/* Mark alias targets necessary and emit diagnostics. */
finish_aliases_1 ();
/* Gimplify and lower all functions. */
timevar_push (TV_CGRAPH); timevar_push (TV_CGRAPH);
cgraph_analyze_functions (); cgraph_analyze_functions ();
timevar_pop (TV_CGRAPH); timevar_pop (TV_CGRAPH);
...@@ -1322,29 +1358,6 @@ ipa_passes (void) ...@@ -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. */ /* Perform simple optimizations based on callgraph. */
static void static void
...@@ -1357,22 +1370,9 @@ cgraph_optimize (void) ...@@ -1357,22 +1370,9 @@ cgraph_optimize (void)
verify_cgraph (); verify_cgraph ();
#endif #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. /* 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. */ It is safe to deal with them here as they are always zero initialized. */
varpool_analyze_pending_decls (); varpool_analyze_pending_decls ();
cgraph_analyze_functions ();
timevar_push (TV_CGRAPHOPT); timevar_push (TV_CGRAPHOPT);
if (pre_ipa_mem_report) if (pre_ipa_mem_report)
......
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> 2009-09-04 Martin Jambor <mjambor@suse.cz>
PR tree-optimization/41112 PR tree-optimization/41112
......
/* { 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();
}
...@@ -5395,13 +5395,7 @@ find_decl_and_mark_needed (tree decl, tree target) ...@@ -5395,13 +5395,7 @@ find_decl_and_mark_needed (tree decl, tree target)
if (fnode) if (fnode)
{ {
/* We can't mark function nodes as used after cgraph global info cgraph_mark_needed_node (fnode);
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);
return fnode->decl; return fnode->decl;
} }
else if (vnode) else if (vnode)
...@@ -5571,7 +5565,7 @@ finish_aliases_1 (void) ...@@ -5571,7 +5565,7 @@ finish_aliases_1 (void)
to bind locally. Of course this is a hack - to keep it to bind locally. Of course this is a hack - to keep it
working do the following (which is not strictly correct). */ working do the following (which is not strictly correct). */
&& (! TREE_CODE (target_decl) == FUNCTION_DECL && (! TREE_CODE (target_decl) == FUNCTION_DECL
|| ! TREE_STATIC (target_decl)) || ! DECL_VIRTUAL_P (target_decl))
&& ! lookup_attribute ("weakref", DECL_ATTRIBUTES (p->decl))) && ! lookup_attribute ("weakref", DECL_ATTRIBUTES (p->decl)))
error ("%q+D aliased to external symbol %qE", error ("%q+D aliased to external symbol %qE",
p->decl, p->target); p->decl, p->target);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment