Message ID | 20140116191133.GW892@tucnak.redhat.com |
---|---|
State | New |
Headers | show |
Jakub Jelinek <jakub@redhat.com> wrote: >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? Ok. Thanks, Richard. >2014-01-16 Jakub Jelinek <jakub@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
--- 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]); +}