Compiling gdb on i586 I get the following ICE: gcc -c -O2 -march=i686 -mtune=i686 -fmessage-length=0 -Wall -Wno-pointer-sign -I. -I. -I./config -DLOCALEDIR="\"/usr/share/locale\"" -DHAVE_CONFIG_H -I./../include/opcode -I../bfd -I./../bfd-I./../include -I../intl -I./../intl -DMI_OUT=1 -DTUI=1 -Wimplicit -Wreturn-type -Wcomment -Wtrigraphs -Wformat -Wparentheses -Wpointer-arith -Wuninitialized -Wformat-nonliteral -Wunused-label -Wunused-function coffread.c -v -save-temps Using built-in specs. Configured with: ../configure --enable-threads=posix --prefix=/usr --with-local-prefix=/usr/local --infodir=/usr/share/info --mandir=/usr/share/man --libdir=/usr/lib --libexecdir=/usr/lib --enable-languages=c,c++,objc,f95,java,ada --enable-checking --with-gxx-include-dir=/usr/include/c++/4.0.0 --with-slibdir=/lib --with-system-zlib --enable-shared --enable-__cxa_atexit --without-system-libunwind i586-suse-linux Thread model: posix gcc version 4.0.0 20050128 (experimental) (SUSE Linux) /usr/lib/gcc/i586-suse-linux/4.0.0/cc1 -E -quiet -v -I. -I. -I./config -I./../include/opcode -I../bfd -I./../bfd -I./../include -I../intl -I./../intl -DLOCALEDIR="/usr/share/locale" -DHAVE_CONFIG_H -DMI_OUT=1 -DTUI=1 coffread.c -march=i686 -mtune=i686 -Wall -Wno-pointer-sign -Wimplicit -Wreturn-type -Wcomment -Wtrigraphs -Wformat -Wparentheses -Wpointer-arith -Wuninitialized -Wformat-nonliteral -Wunused-label -Wunused-function -fmessage-length=0 -O2 -fpch-preprocess -o coffread.i ignoring duplicate directory "." ignoring duplicate directory "./../bfd" ignoring nonexistent directory "../intl" ignoring nonexistent directory "./../intl" #include "..." search starts here: #include <...> search starts here: . ./config ./../include/opcode ../bfd ./../include /usr/local/include /usr/lib/gcc/i586-suse-linux/4.0.0/include /usr/lib/gcc/i586-suse-linux/4.0.0/../../../../i586-suse-linux/include /usr/include End of search list. /usr/lib/gcc/i586-suse-linux/4.0.0/cc1 -fpreprocessed coffread.i -quiet -dumpbase coffread.c -march=i686 -mtune=i686 -auxbase coffread -O2 -Wall -Wno-pointer-sign -Wimplicit -Wreturn-type -Wcomment -Wtrigraphs -Wformat -Wparentheses -Wpointer-arith -Wuninitialized -Wformat-nonliteral -Wunused-label -Wunused-function -version -fmessage-length=0 -o coffread.s GNU C version 4.0.0 20050128 (experimental) (SUSE Linux) (i586-suse-linux) compiled by GNU C version 4.0.0 20050128 (experimental) (SUSE Linux). GGC heuristics: --param ggc-min-expand=30 --param ggc-min-heapsize=4096 coffread.c: In function ?coff_symfile_read?: coffread.c:513: warning: unused variable ?target? coffread.c:512: warning: unused variable ?len? coffread.c: In function ?coff_read_struct_type?: coffread.c:1993: internal compiler error: in store_bit_field, at expmed.c:731 Please submit a full bug report, with preprocessed source if appropriate. Note the same ICE occurs also on Linux/ia64 and Linux/x86-64.
Created attachment 8098 [details] Preprocessed source file
Note this bug has been introduced after 2005-01-25.
// reduced testcase, compile with '-O1': struct { int b : 29; } f; void foo (short j) { f.b = j; }
Caused by this patch: 2005-01-26 Richard Henderson <rth@redhat.com> PR middle-end/18008 * c-decl.c (finish_struct): Set DECL_MODE after resetting a field's type. * expr.c (store_field): Strip conversions to odd-bit-sized types if the destination field width matches.
#1 0x0000000000645c3a in store_bit_field (str_rtx=0x2a9598d7e0, bitsize=29, bitnum=0, fieldmode=VOIDmode, value=0x2a9598d6c0) at expmed.c:731 731 gcc_assert (CONSTANT_P (value)); (gdb) l 726 else 727 /* Parse phase is supposed to make VALUE's data type 728 match that of the component reference, which is a type 729 at least as wide as the field; so VALUE should have 730 a mode that corresponds to that type. */ 731 gcc_assert (CONSTANT_P (value)); 732 } 733 734 /* If this machine's insv insists on a register, 735 get VALUE1 into a register. */ (gdb) p debug_rtx(value) (reg/v:HI 58 [ j ]) $1 = void (gdb) bt #0 fancy_abort (file=0xa73574 "../../mainline/gcc/expmed.c", line=731, function=0xa73590 "store_bit_field") at diagnostic.c:556 #1 0x0000000000645c3a in store_bit_field (str_rtx=0x2a9598d7e0, bitsize=29, bitnum=0, fieldmode=VOIDmode, value=0x2a9598d6c0) at expmed.c:731 #2 0x0000000000645a16 in store_bit_field (str_rtx=0x2a9598d7a0, bitsize=29, bitnum=0, fieldmode=VOIDmode, value=0x2a9598d6c0) at expmed.c:667 #3 0x000000000065fc01 in store_field (target=0x2a9598d7a0, bitsize=29, bitpos=0, mode=VOIDmode, exp=0x2a95988c30, type=0x2a959888f0, alias_set=0) at expr.c:5270 #4 0x000000000065a23f in expand_assignment (to=0x2a95895870, from=0x2a95a31000) at expr.c:3876 #5 0x00000000006755e2 in expand_expr_real_1 (exp=0x2a958958c0, target=0x0, tmode=VOIDmode, modifier=EXPAND_NORMAL, alt_rtl=0x0) at expr.c:8120 #6 0x0000000000664d4a in expand_expr_real (exp=0x2a958958c0, target=0x2a95894400, tmode=VOIDmode, modifier=EXPAND_NORMAL, alt_rtl=0x0) at expr.c:6336 #7 0x00000000008aaff1 in expand_expr (exp=0x2a958958c0, target=0x2a95894400, mode=VOIDmode, modifier=EXPAND_NORMAL) at expr.h:482 #8 0x00000000008a3d79 in expand_expr_stmt (exp=0x2a958958c0) at stmt.c:1326 The statement we choque on is "fD.1449.bD.1447 = (<unnamed type>) jD.1450;" The final_cleanup dumps looks like this: ;; Function foo (foo) foo (jD.1450) { # BLOCK 0 # PRED: ENTRY [100.0%] (fallthru,exec) # fD.1449_4 = V_MAY_DEF <fD.1449_3>; fD.1449.bD.1447 = (<unnamed type>) jD.1450; return; # SUCC: EXIT [100.0%] } (note btw that the virtual operands are still renamed, which is also a but really... :-/) The patch that introduced this bug is this one: http://gcc.gnu.org/ml/gcc-cvs/2005-01/msg01091.html
rth's comment on the patch: 5220 /* If EXP is a NOP_EXPR of precision less than its mode, then that 5221 implies a mask operation. If the precision is the same size as 5222 the field we're storing into, that mask is redundant. This is 5223 particularly common with bit field assignments generated by the 5224 C front end. */ 5225 if (TREE_CODE (exp) == NOP_EXPR 5226 && INTEGRAL_TYPE_P (TREE_TYPE (exp)) 5227 && (TYPE_PRECISION (TREE_TYPE (exp)) 5228 < GET_MODE_BITSIZE (TYPE_MODE (TREE_TYPE (exp)))) 5229 && bitsize == TYPE_PRECISION (TREE_TYPE (exp))) But in this case the NOP_EXPR also changes the mode of its operand from HImode to SImode: (gdb) p debug_tree(exp) <nop_expr 0x2a95a31000 type <integer_type 0x2a95988a90 SI size <integer_cst 0x2a95890a80 constant invariant 32> unit size <integer_cst 0x2a958905a0 constant invariant 4> align 32 symtab 0 alias set -1 precision 29 min <integer_cst 0x2a958a8d80 -268435456> max <integer_cst 0x2a95a2e270 268435455>> arg 0 <parm_decl 0x2a95988c30 j type <integer_type 0x2a958968f0 short int HI size <integer_cst 0x2a958908a0 constant invariant 16> unit size <integer_cst 0x2a958908d0 constant invariant 2> align 16 symtab 0 alias set -1 precision 16 min <integer_cst 0x2a958907e0 -32768> max <integer_cst 0x2a95890840 32767> pointer_to_this <pointer_type 0x2a95928000>> used HI file t.c line 8 size <integer_cst 0x2a958908a0 16> unit size <integer_cst 0x2a958908d0 2> align 16 context <function_decl 0x2a95988dd0 foo> result <integer_type 0x2a958968f0 short int> initial <integer_type 0x2a95896a90 int> (reg/v:HI 58 [ j ]) arg-type <integer_type 0x2a95896a90 int public SI size <integer_cst 0x2a95890a80 32> unit size <integer_cst 0x2a958905a0 4> align 32 symtab 0 alias set -1 precision 32 min <integer_cst 0x2a958909f0 -2147483648> max <integer_cst 0x2a95890a20 2147483647> pointer_to_this <pointer_type 0x2a958ae4e0>> arg-type-as-written <integer_type 0x2a958968f0 short int> incoming-rtl (reg:SI 5 di [ j ])>>
Something like this?? Index: expr.c =================================================================== RCS file: /cvs/gcc/gcc/gcc/expr.c,v retrieving revision 1.776 diff -u -3 -p -r1.776 expr.c --- expr.c 27 Jan 2005 00:07:41 -0000 1.776 +++ expr.c 29 Jan 2005 12:54:25 -0000 @@ -5224,6 +5224,8 @@ store_field (rtx target, HOST_WIDE_INT b C front end. */ if (TREE_CODE (exp) == NOP_EXPR && INTEGRAL_TYPE_P (TREE_TYPE (exp)) + && (TYPE_MODE (TREE_TYPE (exp)) + == TYPE_MODE (TREE_TYPE (TREE_OPERAND (exp, 0)))) && (TYPE_PRECISION (TREE_TYPE (exp)) < GET_MODE_BITSIZE (TYPE_MODE (TREE_TYPE (exp)))) && bitsize == TYPE_PRECISION (TREE_TYPE (exp)))
Subject: Bug 19689 CVSROOT: /cvs/gcc Module name: gcc Changes by: rth@gcc.gnu.org 2005-01-30 02:33:28 Modified files: gcc : ChangeLog expr.c Added files: gcc/testsuite/gcc.c-torture/execute: pr19689.c Log message: PR middle-end/19689 * expr.c (store_field): Don't strip sub-mode cast when the input data is even smaller. Patches: http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/ChangeLog.diff?cvsroot=gcc&r1=2.7328&r2=2.7329 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/expr.c.diff?cvsroot=gcc&r1=1.777&r2=1.778 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/gcc.c-torture/execute/pr19689.c.diff?cvsroot=gcc&r1=NONE&r2=1.1
Fixed.