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.
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))
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.
--- /dev/null
+/* 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;
+}
--- /dev/null
+/* 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);
+}