aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2014-01-16 20:54:23 +0100
committerJakub Jelinek <jakub@gcc.gnu.org>2014-01-16 20:54:23 +0100
commit42ed6cde4bd468d169ac198ef593aa4c686e7117 (patch)
tree4658ec6993cb1ef20e3a955c89af2533c00fed1c /gcc
parenta611d7cb08d5b44fd0f2f8118f8083263a6a06df (diff)
downloadgcc-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/ChangeLog3
-rw-r--r--gcc/expr.c20
-rw-r--r--gcc/testsuite/ChangeLog3
-rw-r--r--gcc/testsuite/gcc.c-torture/compile/pr58344.c12
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
diff --git a/gcc/expr.c b/gcc/expr.c
index 400a152..878a51b 100644
--- a/gcc/expr.c
+++ b/gcc/expr.c
@@ -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]);
+}