Hi! Before r200211 expand_expr_real_1 (and other places) used const_value_known_p which just returned a bool whether the DECL_INITIAL is usable, but now it has 3 possible return values, error_mark_node for unusable initial, NULL_TREE for no DECL_INITIAL, but const var (so, assuming zero initialization) and some other tree otherwise, while the new error_mark_node/NULL_TREE cases were both rejected previously. Because of that we can end up with NULL init now and crash on it.
The following patch handles this case as zero initialization. Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk? 2014-01-16 Jakub Jelinek <ja...@redhat.com> PR middle-end/58344 * expr.c (expand_expr_real_1): Handle init == NULL_TREE. * gcc.c-torture/compile/pr58344.c: New test. --- gcc/expr.c.jj 2014-01-08 19:37:33.000000000 +0100 +++ gcc/expr.c 2014-01-16 15:08:10.451913525 +0100 @@ -9832,7 +9832,25 @@ expand_expr_real_1 (tree exp, rtx target || TREE_CODE (array) == CONST_DECL) && (init = ctor_for_folding (array)) != error_mark_node) { - if (TREE_CODE (init) == CONSTRUCTOR) + if (init == NULL_TREE) + { + tree value = build_zero_cst (type); + if (TREE_CODE (value) == CONSTRUCTOR) + { + /* If VALUE is a CONSTRUCTOR, this optimization is only + useful if this doesn't store the CONSTRUCTOR into + memory. If it does, it is more efficient to just + load the data from the array directly. */ + rtx ret = expand_constructor (value, target, + modifier, true); + if (ret == NULL_RTX) + value = NULL_TREE; + } + + if (value) + return expand_expr (value, target, tmode, modifier); + } + else if (TREE_CODE (init) == CONSTRUCTOR) { unsigned HOST_WIDE_INT ix; tree field, value; --- gcc/testsuite/gcc.c-torture/compile/pr58344.c.jj 2014-01-16 15:13:45.875197932 +0100 +++ gcc/testsuite/gcc.c-torture/compile/pr58344.c 2014-01-16 15:13:07.000000000 +0100 @@ -0,0 +1,12 @@ +/* PR middle-end/58344 */ +/* { dg-do compile } */ + +struct U {}; +static struct U a[1]; +extern void bar (struct U); + +void +foo (void) +{ + bar (a[0]); +} Jakub