diff options
author | Jakub Jelinek <jakub@redhat.com> | 2014-01-16 20:54:23 +0100 |
---|---|---|
committer | Jakub Jelinek <jakub@gcc.gnu.org> | 2014-01-16 20:54:23 +0100 |
commit | 42ed6cde4bd468d169ac198ef593aa4c686e7117 (patch) | |
tree | 4658ec6993cb1ef20e3a955c89af2533c00fed1c /gcc | |
parent | a611d7cb08d5b44fd0f2f8118f8083263a6a06df (diff) | |
download | gcc-42ed6cde4bd468d169ac198ef593aa4c686e7117.zip gcc-42ed6cde4bd468d169ac198ef593aa4c686e7117.tar.gz gcc-42ed6cde4bd468d169ac198ef593aa4c686e7117.tar.bz2 |
re PR middle-end/58344 (ICE with segfault at -O1 and above on x86_64-linux-gnu)
PR middle-end/58344
* expr.c (expand_expr_real_1): Handle init == NULL_TREE.
* gcc.c-torture/compile/pr58344.c: New test.
From-SVN: r206685
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 3 | ||||
-rw-r--r-- | gcc/expr.c | 20 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 3 | ||||
-rw-r--r-- | gcc/testsuite/gcc.c-torture/compile/pr58344.c | 12 |
4 files changed, 37 insertions, 1 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 098e0c1..f7a764f 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,8 @@ 2014-01-16 Jakub Jelinek <jakub@redhat.com> + PR middle-end/58344 + * expr.c (expand_expr_real_1): Handle init == NULL_TREE. + PR target/59839 * config/i386/i386.c (ix86_expand_builtin): If target doesn't satisfy operand 0 predicate for gathers, use a new pseudo as @@ -9832,7 +9832,25 @@ expand_expr_real_1 (tree exp, rtx target, enum machine_mode tmode, || 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; diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 6482650..fa17276 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,5 +1,8 @@ 2014-01-16 Jakub Jelinek <jakub@redhat.com> + PR middle-end/58344 + * gcc.c-torture/compile/pr58344.c: New test. + PR target/59839 * gcc.target/i386/pr59839.c: New test. diff --git a/gcc/testsuite/gcc.c-torture/compile/pr58344.c b/gcc/testsuite/gcc.c-torture/compile/pr58344.c new file mode 100644 index 0000000..42b646f --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/compile/pr58344.c @@ -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]); +} |