In an arm target which is not in gcc svn (see http://gccsdk.riscos.info/) we have the following options defined in its .opt file: --8<-- mlibscl Target Report RejectNegative InverseMask(UNIXLIB,LIBSCL) Compile with the SharedCLibrary headers munixlib Target Report RejectNegative Mask(UNIXLIB) Compile with the UnixLib headers (default) mmodule Target Report RejectNegative Negative(munixlib) Mask(MODULE) Target for RISC OS modules --8<-- I.e. the mlibscl and munixlib options are exclusive and the option mmodule can only be used with mlibscl (munixlib is default). When cross-compiling gcc 4.2.0 I get an ICE in the cancel_option() routine: --8<-- /home/john/gccsdk/gccsdk_svn2/gcc4/arm-unknown-riscos/gcc/xgcc -B/home/john/gccsdk/gccsdk_svn2/gcc4/arm-unknown-riscos/./gcc/ -B/home/john/gccsdk/gccsdk_svn2/gcc4/arm-unknown-riscos/arm-unknown-riscos/libunixlib/ -B/home/john/gccsdk/gccsdk_svn2/gcc4/arm-unknown-riscos/arm-unknown-riscos/libunixlib/.libs/ -isystem /home/john/gccsdk/gccsdk_svn2/gcc4/srcdir/libunixlib/include -B/home/john/gccsdk/riscos2/cross/arm-unknown-riscos/bin/ -B/home/john/gccsdk/riscos2/cross/arm-unknown-riscos/lib/ -isystem /home/john/gccsdk/riscos2/cross/arm-unknown-riscos/include -isystem /home/john/gccsdk/riscos2/cross/arm-unknown-riscos/sys-include -L/home/john/gccsdk/gccsdk_svn2/gcc4/arm-unknown-riscos/./ld -O2 -O0 -g -DIN_GCC -DCROSS_COMPILE -W -Wall -Wwrite-strings -Wstrict-prototypes -Wmissing-prototypes -Wold-style-definition -isystem ./include -mlibscl -mhard-float -mmodule -I. -Iscl/fpu/module -I/home/john/gccsdk/gccsdk_svn2/gcc4/srcdir/gcc -I/home/john/gccsdk/gccsdk_svn2/gcc4/srcdir/gcc/scl/fpu/module -I/home/john/gccsdk/gccsdk_svn2/gcc4/srcdir/gcc/../include -I/home/john/gccsdk/gccsdk_svn2/gcc4/srcdir/gcc/../libcpp/include -I/home/john/gccsdk/gccsdk_svn2/gcc4/srcdir/gcc/../libdecnumber -I../libdecnumber -c -o scl/fpu/module/crti-riscos.o -x assembler-with-cpp /home/john/gccsdk/gccsdk_svn2/gcc4/srcdir/gcc/config/arm/crti-riscos.asm Program received signal SIGSEGV, Segmentation fault. 0x00000000004132a1 in cancel_option (opt_idx=35, next_opt_idx=1936942450, orig_next_opt_idx=563) at /home/john/gccsdk/gccsdk_svn2/gcc4/srcdir/gcc/opts-common.c:119 119 if (cl_options [next_opt_idx].neg_index == opt_idx) (gdb) where #0 0x00000000004132a1 in cancel_option (opt_idx=35, next_opt_idx=1936942450, orig_next_opt_idx=563) at /home/john/gccsdk/gccsdk_svn2/gcc4/srcdir/gcc/opts-common.c:119 #1 0x00000000004132f7 in cancel_option (opt_idx=35, next_opt_idx=-1, orig_next_opt_idx=563) at /home/john/gccsdk/gccsdk_svn2/gcc4/srcdir/gcc/opts-common.c:123 #2 0x00000000004132f7 in cancel_option (opt_idx=35, next_opt_idx=576, orig_next_opt_idx=563) at /home/john/gccsdk/gccsdk_svn2/gcc4/srcdir/gcc/opts-common.c:123 #3 0x00000000004132f7 in cancel_option (opt_idx=35, next_opt_idx=563, orig_next_opt_idx=563) at /home/john/gccsdk/gccsdk_svn2/gcc4/srcdir/gcc/opts-common.c:123 #4 0x00000000004135de in prune_options (argcp=0x7fff5a200ef4, argvp=0x7fff5a200ee8) at /home/john/gccsdk/gccsdk_svn2/gcc4/srcdir/gcc/opts-common.c:208 #5 0x000000000040e623 in main (argc=43, argv=0x7fff5a201168) at /home/john/gccsdk/gccsdk_svn2/gcc4/srcdir/gcc/gcc.c:6115 --8<-- Investigation learns me that the it goes wrong when calling cancel_option() for the mmodule option. In the produced options.c file I have: --8<-- Option 563: { "-mmodule", "Target for RISC OS modules", N_OPTS, 7, 576, CL_TARGET | CL_REJECT_NEGATIVE | CL_REPORT, &target_flags, CLVC_BIT_SET, MASK_MODULE }, Option 576: { "-munixlib", "Compile with the UnixLib headers (default)", N_OPTS, 8, -1, CL_TARGET | CL_REJECT_NEGATIVE | CL_REPORT, &target_flags, CLVC_BIT_SET, MASK_UNIXLIB }, --8<-- cancel_option() will recursively call itself when cl_options [next_opt_idx].neg_index != orig_next_opt_idx for the value cl_options [next_opt_idx].neg_index however when the option munixlib is reached, its neg_index is -1 which results in a nonsense situation to continue calling cancel_option(). My proposed fix is: --8<-- --- gcc/opts-common.c.orig 2007-05-17 14:42:41.000000000 +0200 +++ gcc/opts-common.c 2007-05-17 14:42:21.000000000 +0200 @@ -119,7 +119,8 @@ if (cl_options [next_opt_idx].neg_index == opt_idx) return true; - if (cl_options [next_opt_idx].neg_index != orig_next_opt_idx) + if (cl_options [next_opt_idx].neg_index >= 0 + && cl_options [next_opt_idx].neg_index != orig_next_opt_idx) return cancel_option (opt_idx, cl_options [next_opt_idx].neg_index, orig_next_opt_idx); --8<-- which seems to solve my problem.
I don't think you want the options to be in the MASK anyways. Use Var(a, 0) Var(a, 1) Var(a, 2) etc. instead and that should fix your ICE.
Is this solved? Anyway, this does not seem to be a bug in GCC.
I'm updating my port for 4.6trunk and this gcc problem is still there. My suggested patch in comment #1 is still applicable and attached it after having brought up-to-date for trunk. ChangeLog: John Tytgat <John.Tytgat@aaug.net> * gcc/opts-common.c (cancel_option): Don't recurse for Negative marked options.
Created attachment 21241 [details] Fix ICE in cancel_option() by repreventing a recursive call for Negative marked option