This is the mail archive of the gcc-bugs@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]
Other format: [Raw text]

[Bug debug/27851] Hour-long segfault with -O1 -g on gcc.dg/parm-impl-decl-1.c



------- Comment #3 from wilson at gcc dot gnu dot org  2006-06-10 01:19 -------
This is a C front end bug.  The C front end is creating a circular symbol
table, where the function h is defined both in the external scope and inside
itself.  The dwarf2out.c code then goes into an infinite recursion trying to
tree walk the circular symbol table.

The syntax error is not needed to reproduce the problem.  You just need two
functions with implicit function declarations in their parameter list.  For
instance:
foo (int (*p)[sizeof(j())])
{
}
h (int (*p)[sizeof(i())])
{
}
The C front end problem can be reproduced with only one function, but you need
two to trigger the dwarf2out.c failure.

You also don't need a checking enabled build to reproduce this.

The dwarf code works in the presence of a single circular reference in the
symbol table because there is code in gen_subprogram_die that catches the case
where we try to define a function twice.  This doesn't work when we have two
circular references.  Now the function h is defined in 3 places, externally,
inside itself, and inside foo.  The one inside foo is turned into a
declaration, and now the short circuit code in gen_subprogram_die doesn't work,
and we get the infinite recursion.

The problem occurs in get_parm_info and store_parm_decls_newstyle in c-decl.c. 
The first function tears apart the binding scope for parameters.  When it sees
a function, it puts it on the others list.  Then store_parm_decls_newstyle
reinserts it in the proper place in the proper scope with nested=0 regardless
of what the original value of nested was.  This appears to be the bug.

When the function i, for instance, was inserted into binding scopes, it was put
in two of them.  It was put in the external scope with nested=0, and it was put
in the param scope with nested=1.  If this info was preserved by get_parm_info
and store_parm_decls_newstyle, then the bug would not occur.

The circular refernence is created in pop_scope.  When popping the scope for
the function h, i is inserted into the BLOCK_VARS for the function body because
nested is 0.  When popping the external scope, i is inserted into the
BLOCK_VARS for the external scope, because nested is 0.  Now we have the same
decl in two places in the symbol table.  When we handle the function h for the
external scope, it is chained to i, and now since i is also declared inside the
function h, the function h is also declared inside itself.  When we add foo, h
is now also declared inside foo, and foo inside h.

I don't see an easy way to fix this without adding aanother datastructure.  We
could change the others field to be a structure containing a tree and the
nested info, and then store_parm_decls_newstyle can get the nested value
correct when it reinserts the tree into the symbol table.


-- 

wilson at gcc dot gnu dot org changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |wilson at gcc dot gnu dot
                   |                            |org
             Status|UNCONFIRMED                 |NEW
     Ever Confirmed|0                           |1
   Last reconfirmed|0000-00-00 00:00:00         |2006-06-10 01:19:03
               date|                            |


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=27851


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