the exact version of GCC is 4.1.1 the system type is sparc-sun-solaris2.8 the options given when GCC was configured/built: --prefix=/tmp/local/unixutil/gcc-4.1.1 --with-local-prefix=/usr/local/myCompanyName ("myCompanyName" is not the exact wording) (also, there is a symlink /tmp/local/unixutil/gcc -> gcc-4.1.1) the complete command line that triggers the bug: gcc -Wall -o foo.o -c foo.cc the compiler output (error messages, warnings, etc.): stdout: nothing stderr: gcc: Internal error: Segmentation Fault (program cc1plus) Please submit a full bug report. See <URL:http://gcc.gnu.org/bugs.html> for instructions. foo.o: not created the preprocessed file: see below; for ease of transmission, the full source is not given; to have it, replace the ZZZZZ by the missing 65524 values (in increasing order) additional remarks: 1) if the file is renamed foo.c (the C language is triggered instead of C++), the bug does not show up 2) if the command is installed in a Makefile: ---Makefile-------------------------- all: /tmp/local/unixutil/gcc/bin/gcc -Wall -o foo.o -c foo.cc ------------------------------------- then the bug does not show up if the GNU make is used, however the bug still shows up if the /usr/ccs/bin/make is used ---foo.ii---------------------------- # 1 "foo.cc" # 1 "<built-in>" # 1 "<command line>" # 1 "foo.cc" void myfunction(unsigned short localChar) { switch (localChar) { case 0: case 1: case 2: case 3: case 4: case 5: ZZZZZ case 65530: case 65531: case 65532: case 65533: case 65534: case 65535: break; }; return; }; -------------------------------------
Confirmed. It looks like the C++ frontend recursively parses switch statements... #1052 0x0815ceae in cp_parser_statement (parser=0xb7d85ea0, in_statement_expr=0x0) at /space/rguenther/src/svn/gcc-4_1-branch/gcc/cp/parser.c:6101 #1053 0x0815d1f5 in cp_parser_labeled_statement (parser=0xb7d85ea0, in_statement_expr=0x0) at /space/rguenther/src/svn/gcc-4_1-branch/gcc/cp/parser.c:6274 #1054 0x0815ceae in cp_parser_statement (parser=0xb7d85ea0, in_statement_expr=0x0) at /space/rguenther/src/svn/gcc-4_1-branch/gcc/cp/parser.c:6101 #1055 0x0815d1f5 in cp_parser_labeled_statement (parser=0xb7d85ea0, in_statement_expr=0x0) at /space/rguenther/src/svn/gcc-4_1-branch/gcc/cp/parser.c:6274 ...
Re. comment #1 Yes, it is a _Recursive_ descent parser after all... Probably the only solution is to parse the label and not descend. This is what the C front end does, see c_parser_statement.
Trying a fix (but don't hold your breath, the c++ parser is unexplored territory for me ;-)
Created attachment 12279 [details] tentative patch This removes the recursion cycle "cp_parser_statement -> cp_parser_labeled_statement -> cp_parser_statement" but it does not at this moment solve the whole problem because recursion of the form "cp_parser_statement -> cp_parser_statement" still occurs. With a minor change, the two new calls in the patch to cp_parser_statement from itself could be replaced with "goto restart;" to hard-code the obvious tail recursion opportunity. I may try that later. For now, this patch is being tested (by Eric Christopher at Apple) and I hope we'll get good results with it.
Test case: ------------------------------------- extern void bar (); extern void baz (); #define L1(x) \ case x##0: case x##1: case x##2: case x##3: \ case x##4: case x##5: case x##6: case x##7 #define L2(x) \ L1(x##0): L1(x##1): L1(x##2): L1(x##3): \ L1(x##4): L1(x##5): L1(x##6): L1(x##7) #define L3(x) \ L2(x##0): L2(x##1): L2(x##2): L2(x##3): \ L2(x##4): L2(x##5): L2(x##6): L2(x##7) #define L4(x) \ L3(x##0): L3(x##1): L3(x##2): L3(x##3): \ L3(x##4): L3(x##5): L3(x##6): L3(x##7) #define L5(x) \ L4(x##0): L4(x##1): L4(x##2): L4(x##3): \ L4(x##4): L4(x##5): L4(x##6): L4(x##7) #define CASES1 L5(00): L5(01): L5(02): L5(03) #define CASES2 L5(04): L5(05): L5(06): L5(07) void myfunction(unsigned int localChar) { switch (localChar) { CASES1: bar (); CASES2: baz (); break; }; return; }; -------------------------------------
Created attachment 12281 [details] Alternative patch (less obviously safe) This one should resolve the problem completely by not recursing with calls. Not sure if this is entirely safe. Will test.
Subject: Bug number PR 29087 A patch for this bug has been added to the patch tracker. The mailing list url for the patch is http://gcc.gnu.org/ml/gcc-patches/2006-09/msg00637.html
Subject: Bug 29087 Author: steven Date: Mon Sep 18 15:32:43 2006 New Revision: 117026 URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=117026 Log: PR c++/29087 * parser.c (cp_parser_labeled_statement): Return nothing. Do not take in_statement_expr and in_compound as arguments. Rename to cp_parser_label_for_labeled_statement. Parse only the label, not the statement. (cp_parser_statement): Parse the statement of a labeled-statement from here, using tail recursion. Modified: trunk/gcc/cp/ChangeLog trunk/gcc/cp/parser.c
Fix for GCC 4.1 coming later today.
Subject: Bug 29087 Author: steven Date: Thu Sep 21 20:27:36 2006 New Revision: 117120 URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=117120 Log: 2006-09-21 Steven Bosscher <steven@gcc.gnu.org> PR c++/29087 Backport from mainline: * parser.c (cp_parser_labeled_statement): Return nothing. Do not take in_statement_expr and in_compound as arguments. Rename to cp_parser_label_for_labeled_statement. Parse only the label, not the statement. (cp_parser_statement): Parse the statement of a labeled-statement from here, using tail recursion. Modified: branches/gcc-4_1-branch/gcc/cp/ChangeLog branches/gcc-4_1-branch/gcc/cp/parser.c
Fixed.
Denis, this should be fixed in the next release of GCC 4.1 (which will be GCC 4.1.2) and in GCC 4.2. Thanks for reporting the bug.