re PR middle-end/82564 (ICE at -O1 and above: in assign_stack_temp_for_type, at funct...
authorJakub Jelinek <jakub@redhat.com>
Sat, 5 Jan 2019 11:14:12 +0000 (12:14 +0100)
committerJakub Jelinek <jakub@gcc.gnu.org>
Sat, 5 Jan 2019 11:14:12 +0000 (12:14 +0100)
PR middle-end/82564
PR target/88620
* expr.c (expand_assignment): For calls returning VLA structures
if to_rtx is not a MEM, force it into a stack temporary.

* gcc.dg/nested-func-12.c: New test.
* gcc.c-torture/compile/pr82564.c: New test.

From-SVN: r267595

gcc/ChangeLog
gcc/expr.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.c-torture/compile/pr82564.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/nested-func-12.c [new file with mode: 0644]

index e6992b0e982b313840ee27f17075448bd3b337e9..91c55fae6adcc29aba79e4b03360f18aa1f5f0ff 100644 (file)
@@ -1,5 +1,10 @@
 2019-01-05  Jakub Jelinek  <jakub@redhat.com>
 
+       PR middle-end/82564
+       PR target/88620
+       * expr.c (expand_assignment): For calls returning VLA structures
+       if to_rtx is not a MEM, force it into a stack temporary.
+
        PR debug/88635
        * dwarf2out.c (const_ok_for_output_1): Reject MINUS that contains
        SYMBOL_REF, CODE_LABEL or UNSPEC in subexpressions of second argument.
index 450486e24b09184ded6a258dd15892aa87375570..818ee2deaa167247849e57247fac0bdcda84b8cc 100644 (file)
@@ -5254,6 +5254,21 @@ expand_assignment (tree to, tree from, bool nontemporal)
              emit_move_insn (XEXP (to_rtx, 1), read_complex_part (temp, true));
            }
        }
+      /* For calls to functions returning variable length structures, if TO_RTX
+        is not a MEM, go through a MEM because we must not create temporaries
+        of the VLA type.  */
+      else if (!MEM_P (to_rtx)
+              && TREE_CODE (from) == CALL_EXPR
+              && COMPLETE_TYPE_P (TREE_TYPE (from))
+              && TREE_CODE (TYPE_SIZE (TREE_TYPE (from))) != INTEGER_CST)
+       {
+         rtx temp = assign_stack_temp (GET_MODE (to_rtx),
+                                       GET_MODE_SIZE (GET_MODE (to_rtx)));
+         result = store_field (temp, bitsize, bitpos, bitregion_start,
+                               bitregion_end, mode1, from, get_alias_set (to),
+                               nontemporal, reversep);
+         emit_move_insn (to_rtx, temp);
+       }
       else
        {
          if (MEM_P (to_rtx))
index af59095b05b9a9632d78bd553d60cd4149e2e7d8..0a783ce1b770588511ebaf2d90d299f4bb0fb2ca 100644 (file)
@@ -1,5 +1,10 @@
 2019-01-05  Jakub Jelinek  <jakub@redhat.com>
 
+       PR middle-end/82564
+       PR target/88620
+       * gcc.dg/nested-func-12.c: New test.
+       * gcc.c-torture/compile/pr82564.c: New test.
+
        PR debug/88635
        * gcc.dg/debug/dwarf2/pr88635.c: New test.
 
diff --git a/gcc/testsuite/gcc.c-torture/compile/pr82564.c b/gcc/testsuite/gcc.c-torture/compile/pr82564.c
new file mode 100644 (file)
index 0000000..039f55a
--- /dev/null
@@ -0,0 +1,15 @@
+/* PR middle-end/82564 */
+/* { dg-require-effective-target alloca } */
+
+int
+main ()
+{
+  int t = 8, i;
+  typedef struct { char v[t]; } B; 
+  B a, b;
+  B __attribute__ ((noinline)) f () { return b; }
+  for (i = 0; i < 8; i++)
+    b.v[i] = i;
+  a = f ();
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/nested-func-12.c b/gcc/testsuite/gcc.dg/nested-func-12.c
new file mode 100644 (file)
index 0000000..d617d7e
--- /dev/null
@@ -0,0 +1,48 @@
+/* PR target/88620 */
+/* { dg-do run } */
+/* { dg-options "-Ofast --param ipa-cp-eval-threshold=0 -fno-guess-branch-probability -fno-inline-small-functions" } */
+/* { dg-require-effective-target alloca } */
+
+void
+foo (int n)
+{
+  struct S { int a[n]; };
+
+  struct S
+  fn (void)
+  {
+    struct S s;
+    s.a[0] = 42;
+    return s;
+  }
+
+  auto struct S
+  fn2 (void)
+  {
+    return fn ();
+  }
+
+  struct S x;
+  fn ();
+  fn2 ();
+  x = fn ();
+
+  if (x.a[0] != 42)
+    __builtin_abort ();
+
+  if (fn ().a[0] != 42)
+    __builtin_abort ();
+
+  __typeof__ (fn ()) *p = &x;
+  if (p->a[0] != 42)
+    __builtin_abort ();
+
+  if (fn2 ().a[0] != 42)
+    __builtin_abort ();
+}
+
+int
+main (void)
+{
+  foo (1);
+}