This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
[Bug debug/77947] [7 Regression] ICE with -g and -O2 in strip_naming_typedef
- From: "rguenther at suse dot de" <gcc-bugzilla at gcc dot gnu dot org>
- To: gcc-bugs at gcc dot gnu dot org
- Date: Wed, 12 Oct 2016 10:06:24 +0000
- Subject: [Bug debug/77947] [7 Regression] ICE with -g and -O2 in strip_naming_typedef
- Auto-submitted: auto-generated
- References: <bug-77947-4@http.gcc.gnu.org/bugzilla/>
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=77947
--- Comment #6 from rguenther at suse dot de <rguenther at suse dot de> ---
On Wed, 12 Oct 2016, marxin at gcc dot gnu.org wrote:
> https://gcc.gnu.org/bugzilla/show_bug.cgi?id=77947
>
> --- Comment #5 from Martin Liška <marxin at gcc dot gnu.org> ---
> Created attachment 39791
> --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=39791&action=edit
> Really reduced test-case
So we are properly creating a DIE for m_fn1 early but then end up
removing it via prune_unused_types. It looks like this is because
the DIE for C has the CU as parent rather than B::m_fn2. It
first gets created in limbo (via dwarf2out_type_decl) because:
/* If we're a function-scope tag, initially use a parent of NULL;
this will be fixed up in decls_for_scope. */
if (decl_function_context (decl))
context_die = NULL;
but we never end up calling dwarf2out_early_global_decl for B::m_fn2
and thus the limbo gets re-parented to the CU DIE (as we record
the TREE_TYPE for DW_TAG_class_type DIEs, not the TYPE_DECL):
if (DECL_P (node->created_for))
origin = get_context_die (DECL_CONTEXT
(node->created_for));
else if (TYPE_P (node->created_for))
origin = scope_die_for (node->created_for, comp_unit_die
());
and scope_die_for simply doesn't handle FUNCTION_DECL as containing_scope.
B::m_fn2 has been optimized out as unreachable which is the reason we
are not ending up in decls_for_scope eventually.
IMHO optimizing C as unused is ok. The question is why we end up
with inlining m_fn1 ...
looks like we devirtualize the call in fn1 to B::C::m_fn1:
t.ii:25:14: note: speculatively devirtualizing call in void fn1(A&)/8 to
virtual bool B::m_fn2() const::C::m_fn1() const/0
Indirect call -> speculative call void fn1(A&)/8 => virtual bool
B::m_fn2() const::C::m_fn1() const/0
1 polymorphic calls, 0 devirtualized, 1 speculatively devirtualized, 0
cold
0 have multiple targets, 0 overwritable, 0 already speculated (0 agree, 0
disagree), 0 external, 0 not defined, 0 artificial, 0 infos dropped
Symbol table:
and -fno-devirtualize fixes it.
-> we shouldn't reclaim B::m_fn2 when we later end up devirtualizing
to B::m_fn2::C::m_fn1 (or rather we should never devirtualize to
a local class method?)