This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Re: More Dwarf2 issues


Sorry about the delay, I was in meetings for a week and a half.

	Here, we've made a copy of `S' in pushdecl, when called from
	integrate_decl_trees, and that causes the confusion.  I've attached a
	patch for this bug, but I did not check this in, because I'm not sure
	it's the right thing to do.  What do you two think?

The reason we copy the type tree is so that we can emit debug info that
distinguishes typedef types from other types.  E.g. we want
	struct foo { }
	typedef struct foo bar;
to be two different types, so we copy the `struct foo { }' tree to create
a distinct type for the typedef.

In C++, a structure definition creates an implicit typedef type.  When this
happens, we still want these two types to be the same type, so we must disable
the type tree copy for such a typedef.  This is what the
	TYPE_NAME (type) != x
check is for.  

In the presense of inlining, we need to check DECL_ABSTRACT_ORIGIN as you've
done.  Your patch looks reasonable to me, but you might be better off
with something like
	TYPE_NAME (type) != x
	&& (DECL_ABSTRACT_ORIGIN (x) == NULL_TREE
	    || decl_ultimate_origin (decl) != TYPE_NAME (type))
This work even if TYPE_NAME (type) is NULL, and it works even if you have
multiple levels of inlining.  decl_ultimate_origin can be found in dwarf2out.c.

Incidentally, there is some related code in dwarf2out.c, but it performs the
check differently.  It does
	(DECL_ARTIFICIAL (decl)
         && is_tagged_type (TREE_TYPE (decl))
         && decl == TYPE_STUB_DECL (TREE_TYPE (decl)))
to detect what I think is the same case.  See the TYPE_DECL_IS_STUB macro
in dwarf2out.c.  It uses decl_ultimate_origin for the nested inline function
case.  At one time it just used DECL_ABTRACT_ORIGIN directly, but that wasn't
good enough.

	The bug only
	appears with -gdwarf-2 -O2 -funroll-loops.  There, the trap happens in
	scope_die_for, called from decls_for_scope.  The parameter `t' to
	scope_die_for is the TYPE_DECL for f(S)::I, whose DECL_CONTEXT is a
	FUNCTION_DECL.  This FUNCTION_DECL becomes the `containing_scope'
	variable, but the containing_scope is not in the decl_scope_table, and
	scope_die_for aborts.  What do you two think about all this?

I don't think this is related.  I think this is a problem with the tree
copy routines in integrate.c that I've run into before.  integrate_decl_tree
is supposed to insert a copy of the decl tree (symbol table essentially) of an
inlined function into the current function.  It handles BLOCK_VARS, but it
makes no attempt to handle BLOCK_TYPE_TAGS, and it makes no attempt to handle
TYPE_DECLS within BLOCK_VARS.  The result is that the TYPE_DECL is copied,
but the TREE_TYPE of the TYPE_DECL is not copied.  Thus the TYPE_CONTEXT of
the TREE_TYPE of the TYPE_DECL is wrong, as it points back to the original
function/block, not the inlined function/block.

This code is used by both function inlining and loop unrolling (both of
them involve making copies of lexical blocks), so it is feasible that such
a bug could turn up when -funroll-loops is used.

I added a hack to dwarf2out.c to work around this problem, but my hack only
works in the case where DECL_CONTEXT is a BLOCK node.  The only reason for
this is that I wanted my hack to be as conservative as possible, and my
testcase involved a containing_scope which was a BLOCK node.

See the code in dwarf2out.c at this comment:
      /* ??? Integrate_decl_tree does not handle BLOCK_TYPE_TAGS, nor
         does it try to handle types defined by TYPE_DECLs.  Such types

Here is the testcase that prompted this hack.  Compile with -O -g -gdwarf-2
and you will trigger the code I referred to.

inline int sub (int i)
{
  int result;

  if (i == 0)
    {
      result = i;
    }
  else
    {
      union { double d; int i;} u;
      u.d = i;
      result = u.i;
    }
  return result;
}

main()
{
  return sub (10);
}



Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]