$ gcc --version gcc (GCC) 3.5.0 20040909 (experimental) Copyright (C) 2004 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. $ cat t.i typedef struct libxml_xpathCallback { void *ns_uri; } libxml_xpathCallback; typedef libxml_xpathCallback libxml_xpathCallbackArray[]; libxml_xpathCallbackArray *libxml_xpathCallbacks; void foo (void) { if ((*libxml_xpathCallbacks)[3].ns_uri != ((void *)0)) ; } $ gcc t.i t.i: In function `foo': t.i:12: internal compiler error: in int_mode_for_mode, at stor-layout.c:253 Happens on at least ia64 and amd64
Hmm, this does not happen on x86 at least with "3.5.0 20040909" (my build failed last night I have to figure out why still).
Now only happens on ia64 for me.
I'm getting out of my depth, but I thought I'd submit my analysis so far. The failure on ia64 is from calling int_mode_for_mode with VOIDmode. This erroneous call is from extract_bit_field which is called from expand_real with op0 == (mem/s (reg/f:DI 340 [ libxml_xpathCallbacks.0 ]) [0 S0 A8]) You'll notice that the MEM has no mode, resulting in the problematic VOIDmode. My obvious question (and why I'm out of my depth) is are MEMs required to have a mode? This MEM is created INDIRECT_REF section of expand_expr, where we call gen_rtx_MEM with VOIDmode, because TYPE_MODE (type) returned VOIDmode for type: <array_type 0x200000000048e300 type <record_type 0x200000000048e220 libxml_xpathCallback type_0 DI size <integer_cst 0x20000000000b4ab0 constant invariant 64> unit size <integer_cst 0x20000000000b4ae0 constant invariant 8> align 64 symtab 0 alias set -1 fields <field_decl 0x200000000048e060 ns_uri type <pointer_type 0x200000 00000c6ae0> unsigned DI file /home/roger/pr17407.c line 2 size <integer_cst 0x20 000000000b4ab0 64> unit size <integer_cst 0x20000000000b4ae0 8> align 64 offset_align 128 offset <integer_cst 0x20000000000b4330 constant invariant 0> bit offset <integer_cst 0x20000000000b56e0 constant invariant 0> con text <record_type 0x200000000048dea0 libxml_xpathCallback> arguments <integer_cs t 0x20000000000b4330 0>>> VOID align 8 symtab 0 alias set -1> At this point tmode is also VOIDmode. It really isn't clear to me where best to fix the problem. The conditional tests prior to the call of extract_bit_field at around line 7129 of expr.c look daunting. Perhaps extract_bit_field is supposed to be able to handle VOIDmode arguments, and should guard its call to int_mode_for_mode?
Still thinking, shouldn't the TYPE_MODE of an array type usually be BLKmode? The function build_array_type doesn't appear to initialize the TYPE_MODE field, so it remains VOIDmode. expand_expr has plenty of code to deal with BLKmode MEMs, but rarely checks for VOIDmode. Indeed, int_mode_for_mode doesn't ICE if passed BLKmode instead of VOIDmode.
We don't call layout_type on the array type, why?
This is a C front-end problem where we don't call layout_type on the array, having it call layout_type on the type, makes this work.
Here is the patch if you need it sooner: Index: c-decl.c =============================================================== ==== RCS file: /cvs/gcc/gcc/gcc/c-decl.c,v retrieving revision 1.602 diff -u -p -r1.602 c-decl.c --- c-decl.c 14 Oct 2004 23:20:57 -0000 1.602 +++ c-decl.c 21 Oct 2004 02:10:02 -0000 @@ -4129,19 +4128,17 @@ grokdeclarator (const struct c_declarato if (size_varies) C_TYPE_VARIABLE_SIZE (type) = 1; + /* We can never complete an array type which is the + target of a pointer, so go ahead and lay it out. */ + layout_type (type); /* The GCC extension for zero-length arrays differs from ISO flexible array members in that sizeof yields zero. */ if (size && integer_zerop (size)) { - layout_type (type); TYPE_SIZE (type) = bitsize_zero_node; TYPE_SIZE_UNIT (type) = size_zero_node; } - else if (declarator->kind == cdk_pointer) - /* We can never complete an array type which is the - target of a pointer, so go ahead and lay it out. */ - layout_type (type); if (decl_context != PARM && (array_ptr_quals != TYPE_UNQUALIFIED
Patch here: <http://gcc.gnu.org/ml/gcc-patches/2004-10/msg01799.html>.
I am testing a better patch which fixes this problem in the middle-end in build_array_type instead of in the front-end where I thought the problem was. I am also fixing a C++ template related array problem which also needs this patch so I fix it for both things at the same time.
Patch here: <http://gcc.gnu.org/ml/gcc-patches/2004-10/msg01986.html> which reverts the fix for PR middle-end/12920 and fixes PR middle-end/12920 right and also fixes PR c++/18121.
Subject: Bug 17407 CVSROOT: /cvs/gcc Module name: gcc Changes by: pinskia@gcc.gnu.org 2004-10-25 13:27:33 Modified files: gcc : ChangeLog c-decl.c tree.c gcc/cp : ChangeLog decl.c gcc/testsuite : ChangeLog Added files: gcc/testsuite/g++.dg/template: array8.C gcc/testsuite/gcc.c-torture/compile: pr17407.c Log message: 2004-10-25 Andrew Pinski <pinskia@physics.uc.edu> PR middle-end/17407 * c-decl.c (grokdeclarator) <case cdk_array>: Remove the call layout_type as it is already done by build_array_type. * tree.c (build_array_type): Layout the type even 2004-10-25 Andrew Pinski <pinskia@physics.uc.edu> PR c++/18121 * decl.c (grokdeclarator) <case cdk_array>: Remove the call layout_type as it is already done by create_array_type_for_decl. 2004-10-25 Andrew Pinski <pinskia@physics.uc.edu> PR middle-end/17407 * gcc.c-torture/compile/pr17407.c: New test. PR c++/18121 * g++.dg/template/array8.C: New test. Patches: http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/ChangeLog.diff?cvsroot=gcc&r1=2.6006&r2=2.6007 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/c-decl.c.diff?cvsroot=gcc&r1=1.603&r2=1.604 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/tree.c.diff?cvsroot=gcc&r1=1.439&r2=1.440 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/cp/ChangeLog.diff?cvsroot=gcc&r1=1.4452&r2=1.4453 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/cp/decl.c.diff?cvsroot=gcc&r1=1.1317&r2=1.1318 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/ChangeLog.diff?cvsroot=gcc&r1=1.4492&r2=1.4493 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/g++.dg/template/array8.C.diff?cvsroot=gcc&r1=NONE&r2=1.1 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/gcc.c-torture/compile/pr17407.c.diff?cvsroot=gcc&r1=NONE&r2=1.1
Fixed.