+2005-07-25 Jakub Jelinek <jakub@redhat.com>
+
+ * calls.c (store_one_arg): Check for sibling call MEM arguments
+ from already clobbered incoming argument area.
+
2005-07-24 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
* c-common.c (check_missing_format_attribute): New.
stack_arg_under_construction--;
}
+ /* Check for overlap with already clobbered argument area. */
+ if ((flags & ECF_SIBCALL) && MEM_P (arg->value))
+ {
+ int i = -1;
+ unsigned int k;
+ rtx x = arg->value;
+
+ if (XEXP (x, 0) == current_function_internal_arg_pointer)
+ i = 0;
+ else if (GET_CODE (XEXP (x, 0)) == PLUS
+ && XEXP (XEXP (x, 0), 0) ==
+ current_function_internal_arg_pointer
+ && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT)
+ i = INTVAL (XEXP (XEXP (x, 0), 1));
+ else
+ i = -1;
+
+ if (i >= 0)
+ {
+#ifdef ARGS_GROW_DOWNWARD
+ i = -i - arg->locate.size.constant;
+#endif
+ for (k = 0; k < arg->locate.size.constant; k++)
+ if (i + k < stored_args_map->n_bits
+ && TEST_BIT (stored_args_map, i + k))
+ {
+ sibcall_failure = 1;
+ break;
+ }
+ }
+ }
+
/* Don't allow anything left on stack from computation
of argument to alloca. */
if (flags & ECF_MAY_BE_ALLOCA)
2005-07-25 Jakub Jelinek <jakub@redhat.com>
+ * gcc.c-torture/execute/20050713-1.c: New test.
+
PR fortran/20063
* gfortran.fortran-torture/execute/data_4.f90: New test.
--- /dev/null
+/* Test that sibling call is not used if there is an argument overlap. */
+
+extern void abort (void);
+
+struct S
+{
+ int a, b, c;
+};
+
+int
+foo2 (struct S x, struct S y)
+{
+ if (x.a != 3 || x.b != 4 || x.c != 5)
+ abort ();
+ if (y.a != 6 || y.b != 7 || y.c != 8)
+ abort ();
+ return 0;
+}
+
+int
+foo3 (struct S x, struct S y, struct S z)
+{
+ foo2 (x, y);
+ if (z.a != 9 || z.b != 10 || z.c != 11)
+ abort ();
+ return 0;
+}
+
+int
+bar2 (struct S x, struct S y)
+{
+ return foo2 (y, x);
+}
+
+int
+bar3 (struct S x, struct S y, struct S z)
+{
+ return foo3 (y, x, z);
+}
+
+int
+baz3 (struct S x, struct S y, struct S z)
+{
+ return foo3 (y, z, x);
+}
+
+int
+main (void)
+{
+ struct S a = { 3, 4, 5 }, b = { 6, 7, 8 }, c = { 9, 10, 11 };
+
+ bar2 (b, a);
+ bar3 (b, a, c);
+ baz3 (c, a, b);
+ return 0;
+}