]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
re PR middle-end/29683 (Arg split between stack/regs can cause stack corruption)
authorJosh Conner <jconner@apple.com>
Thu, 4 Jan 2007 01:37:15 +0000 (01:37 +0000)
committerJosh Conner <jconner@gcc.gnu.org>
Thu, 4 Jan 2007 01:37:15 +0000 (01:37 +0000)
2007-03-01  Josh Conner  <jconner@apple.com>

PR middle-end/29683
* calls.c (compute_argument_addresses): Set stack and stack_slot
for partial args, too.
(store_one_arg): Use locate.size.constant for the size when
generating a save_area.

2007-03-01  Josh Conner  <jconner@apple.com>

PR middle-end/29683
* gcc.dg/pr29683.c: New.

From-SVN: r120425

gcc/ChangeLog
gcc/calls.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/pr29683.c [new file with mode: 0644]

index b59cc9a56c2e773846e7df13f78b3b14af21c3f4..be703c7f9ab4c26b19ba3892d4e6f2a4a78ebb93 100644 (file)
@@ -1,3 +1,11 @@
+2007-01-03  Josh Conner  <jconner@apple.com>
+
+       PR middle-end/29683
+       * calls.c (compute_argument_addresses): Set stack and stack_slot
+       for partial args, too.
+       (store_one_arg): Use locate.size.constant for the size when
+       generating a save_area.
+
 2007-01-03  Robert Kennedy <jimbob@google.com>
 
        * tree-cfg.c (tree_merge_blocks): Release SSA_NAME phi results
index bdb8167adeff7029004601a458ba8fc666fcbc01..c0d1f8ca75459cb525bcb403c004679af98ddc0a 100644 (file)
@@ -1355,9 +1355,13 @@ compute_argument_addresses (struct arg_data *args, rtx argblock, int num_actuals
          rtx slot_offset = ARGS_SIZE_RTX (args[i].locate.slot_offset);
          rtx addr;
          unsigned int align, boundary;
+         unsigned int units_on_stack = 0;
+         enum machine_mode partial_mode = VOIDmode;
 
          /* Skip this parm if it will not be passed on the stack.  */
-         if (! args[i].pass_on_stack && args[i].reg != 0)
+         if (! args[i].pass_on_stack
+             && args[i].reg != 0
+             && args[i].partial == 0)
            continue;
 
          if (GET_CODE (offset) == CONST_INT)
@@ -1366,9 +1370,23 @@ compute_argument_addresses (struct arg_data *args, rtx argblock, int num_actuals
            addr = gen_rtx_PLUS (Pmode, arg_reg, offset);
 
          addr = plus_constant (addr, arg_offset);
-         args[i].stack = gen_rtx_MEM (args[i].mode, addr);
-         set_mem_attributes (args[i].stack,
-                             TREE_TYPE (args[i].tree_value), 1);
+
+         if (args[i].partial != 0)
+           {
+             /* Only part of the parameter is being passed on the stack.
+                Generate a simple memory reference of the correct size.  */
+             units_on_stack = args[i].locate.size.constant;
+             partial_mode = mode_for_size (units_on_stack * BITS_PER_UNIT,
+                                           MODE_INT, 1);
+             args[i].stack = gen_rtx_MEM (partial_mode, addr);
+             set_mem_size (args[i].stack, GEN_INT (units_on_stack));
+           }
+         else
+           {
+             args[i].stack = gen_rtx_MEM (args[i].mode, addr);
+             set_mem_attributes (args[i].stack,
+                                 TREE_TYPE (args[i].tree_value), 1);
+           }
          align = BITS_PER_UNIT;
          boundary = args[i].locate.boundary;
          if (args[i].locate.where_pad != downward)
@@ -1386,9 +1404,21 @@ compute_argument_addresses (struct arg_data *args, rtx argblock, int num_actuals
            addr = gen_rtx_PLUS (Pmode, arg_reg, slot_offset);
 
          addr = plus_constant (addr, arg_offset);
-         args[i].stack_slot = gen_rtx_MEM (args[i].mode, addr);
-         set_mem_attributes (args[i].stack_slot,
-                             TREE_TYPE (args[i].tree_value), 1);
+
+         if (args[i].partial != 0)
+           {
+             /* Only part of the parameter is being passed on the stack.
+                Generate a simple memory reference of the correct size.
+              */
+             args[i].stack_slot = gen_rtx_MEM (partial_mode, addr);
+             set_mem_size (args[i].stack_slot, GEN_INT (units_on_stack));
+           }
+         else
+           {
+             args[i].stack_slot = gen_rtx_MEM (args[i].mode, addr);
+             set_mem_attributes (args[i].stack_slot,
+                                 TREE_TYPE (args[i].tree_value), 1);
+           }
          set_mem_align (args[i].stack_slot, args[i].locate.boundary);
 
          /* Function incoming arguments may overlap with sibling call
@@ -4056,7 +4086,7 @@ store_one_arg (struct arg_data *arg, rtx argblock, int flags,
                  arg->save_area = assign_temp (nt, 0, 1, 1);
                  preserve_temp_slots (arg->save_area);
                  emit_block_move (validize_mem (arg->save_area), stack_area,
-                                  expr_size (arg->tree_value),
+                                  GEN_INT (arg->locate.size.constant),
                                   BLOCK_OP_CALL_PARM);
                }
              else
index daab71d0fe0f304efb46dd121ff1d34e256d4c61..240666861916d47e3fea8d1316975c093f05abee 100644 (file)
@@ -1,3 +1,8 @@
+2007-01-03  Josh Conner  <jconner@apple.com>
+
+       PR middle-end/29683
+       * gcc.dg/pr29683.c: New.
+
 2007-01-03  Jakub Jelinek  <jakub@redhat.com>
 
        PR c++/28217
diff --git a/gcc/testsuite/gcc.dg/pr29683.c b/gcc/testsuite/gcc.dg/pr29683.c
new file mode 100644 (file)
index 0000000..4bed679
--- /dev/null
@@ -0,0 +1,43 @@
+/* { dg-do run } */
+/* { dg-options "-Os -fno-inline-functions" } */
+
+void abort (void);
+
+typedef struct {
+  int x[7];
+} agg7;
+
+typedef struct {
+  int mbr1;
+  int mbr2;
+} agg2;
+
+int expected = 31415;
+agg7 filler;
+
+int GetConst (agg7 filler, agg2 split)
+{
+  return expected;
+}
+
+void VerifyValues (agg7 filler, int last_reg, int first_stack, int second_stack)
+{
+  if (first_stack != 123 || second_stack != expected)
+    abort ();
+}
+
+void RunTest (agg2 a)
+{
+  int result;
+       
+  result = GetConst (filler, a);
+  VerifyValues (filler, 0, a.mbr1, result);
+}
+
+int main(void)
+{
+  agg2 result = {123, 456};
+  RunTest (result);
+  return 0;
+}
+