------- 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