The code below causes a checking=yes build of GCC 4.1.1 to report "Internal error: Segmentation fault (program cc1)" after more than an hour. (Ninety minutes in the session below; sixty-eight minutes the first time, on a faster and less loaded machine.) Likewise a checking=all build of GCC 4.1.0. A checking=all build of GCC 4.0.2 completes without error in a fifth of a second. foo (int __attribute__ ((__mode__ (vector_size(8)))) i) /* { dg-warning "warning: '__mode__' attribute ignored" } */ { } h (int (*p)[sizeof(i())]) { } The above code is Delta-reduced from the test suite file gcc/testsuite/gcc.dg/parm-impl-decl-1.c. This sounds reminiscent of bug 18239 or bug 16873, but those are supposedly fixed. ============================ Here are sessions; I'll attach the preprocessed file. First session, -O1, crash: 8> time /opt/gcc411/bin/gcc -O1 -g -c ../cpp/bugfiles/GCC_bugfiles/error/131357_parm-impl-decl-1_min.c ../cpp/bugfiles/GCC_bugfiles/error/131357_parm-impl-decl-1_min.c:1: warning: ‘__mode__’ attribute ignored gcc: Internal error: Segmentation fault (program cc1) Please submit a full bug report. See <URL:http://gcc.gnu.org/bugs.html> for instructions. real 89m59.067s user 44m27.227s sys 0m4.422s Second session, no optimization, -v -save-temps, no crash: 10> /opt/gcc411/bin/gcc -v -save-temps -O0 -g -c ../cpp/bugfiles/GCC_bugfiles/error/131357_parm-impl-decl-1_min.cUsing built-in specs. Target: i686-pc-linux-gnu Configured with: /third-party_source/gcc-4.1.1/configure --enable-checking=yes --prefix=/opt/gcc411 --enable-languages=c,c++ --with-comment=PalmSource checking=yes build by Flash Sheridan 5/31/06 on Kondal Thread model: posix gcc version 4.1.1 /home/opt/gcc411/bin/../libexec/gcc/i686-pc-linux-gnu/4.1.1/cc1 -E -quiet -v -iprefix /home/opt/gcc411/bin/../lib/gcc/i686-pc-linux-gnu/4.1.1/ ../cpp/bugfiles/GCC_bugfiles/error/131357_parm-impl-decl-1_min.c -mtune=pentiumpro -fworking-directory -O0 -fpch-preprocess -o 131357_parm-impl-decl-1_min.i ignoring nonexistent directory "/home/opt/gcc411/bin/../lib/gcc/i686-pc-linux-gnu/4.1.1/../../../../i686-pc-linux-gnu/include" ignoring duplicate directory "/opt/gcc411/lib/gcc/i686-pc-linux-gnu/4.1.1/include" ignoring nonexistent directory "/opt/gcc411/lib/gcc/i686-pc-linux-gnu/4.1.1/../../../../i686-pc-linux-gnu/include" #include "..." search starts here: #include <...> search starts here: /home/opt/gcc411/bin/../lib/gcc/i686-pc-linux-gnu/4.1.1/include /usr/local/include /opt/gcc411/include /usr/include End of search list. /home/opt/gcc411/bin/../libexec/gcc/i686-pc-linux-gnu/4.1.1/cc1 -fpreprocessed 131357_parm-impl-decl-1_min.i -quiet -dumpbase 131357_parm-impl-decl-1_min.c -mtune=pentiumpro -auxbase 131357_parm-impl-decl-1_min -g -O0 -version -o 131357_parm-impl-decl-1_min.s GNU C version 4.1.1 (i686-pc-linux-gnu) compiled by GNU C version 3.3.5 (Debian 1:3.3.5-8ubuntu2). GGC heuristics: --param ggc-min-expand=30 --param ggc-min-heapsize=4096 Compiler executable checksum: e8d2a74fbd215574b08a58c63cf2b2c4 ../cpp/bugfiles/GCC_bugfiles/error/131357_parm-impl-decl-1_min.c:1: warning: ‘__mode__’ attribute ignored as -V -Qy -o 131357_parm-impl-decl-1_min.o 131357_parm-impl-decl-1_min.s GNU assembler version 2.15 (i386-linux) using BFD version 2.15 --- PalmSource bug 131357
Created attachment 11562 [details] Preprocessed Delta-reduced source file
#20 0x0000000000572359 in get_AT (die=0x2aaaab0a86e0, attr_kind=DW_AT_inline) at /home/pinskia/src/gcc-4.1/gcc/gcc/dwarf2out.c:5235 #21 0x0000000000572359 in get_AT (die=0x2aaaab0a8870, attr_kind=DW_AT_inline) at /home/pinskia/src/gcc-4.1/gcc/gcc/dwarf2out.c:5235 #22 0x0000000000572359 in get_AT (die=0x2aaaab0a8a00, attr_kind=DW_AT_inline) at /home/pinskia/src/gcc-4.1/gcc/gcc/dwarf2out.c:5235 #23 0x0000000000572359 in get_AT (die=0x2aaaab0a8b90, attr_kind=DW_AT_inline) at /home/pinskia/src/gcc-4.1/gcc/gcc/dwarf2out.c:5235 #24 0x0000000000572359 in get_AT (die=0x2aaaab0a8d20, attr_kind=DW_AT_inline) at /home/pinskia/src/gcc-4.1/gcc/gcc/dwarf2out.c:5235
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.
Most likely a dup of bug 28504. So fixed in GCC 4.2.0.