Hi,

this patch changes an order of bounds params expand for vararg function.  This 
is neede for vararg function which have bounds passed for named args but these 
bounds are nor passed i nregisters.  In this case we try to load them from 
bounds table but all registers are used for vararg bounds and we have no 
register to use.  Patch delays expand of non register named bounds until vararg 
bounds are expanded.  Bootstrapped and regtested for x86_64-unknown-linux-gnu.  
Applied to trunk.  Is it OK for gcc-5-branch?

Thanks,
Ilya
--
gcc/

2015-06-18  Ilya Enkovich  <enkovich....@gmail.com>

        PR target/66569
        * function.c (assign_bounds): Add arguments assign_regs,
        assign_special, assign_bt.
        (assign_parms): For vararg functions handle bounds in BT
        and special slots after incoming vararg bounds.

gcc/testsuite/

2015-06-18  Ilya Enkovich  <enkovich....@gmail.com>

        PR target/66569
        * gcc.target/i386/mpx/chkp-vararg.c: New test.


diff --git a/gcc/function.c b/gcc/function.c
index 8baaed7..4d564fe 100644
--- a/gcc/function.c
+++ b/gcc/function.c
@@ -3490,9 +3490,11 @@ assign_parm_load_bounds (struct assign_parm_data_one 
*data,
 
 static void
 assign_bounds (vec<bounds_parm_data> &bndargs,
-              struct assign_parm_data_all &all)
+              struct assign_parm_data_all &all,
+              bool assign_regs, bool assign_special,
+              bool assign_bt)
 {
-  unsigned i, pass, handled = 0;
+  unsigned i, pass;
   bounds_parm_data *pbdata;
 
   if (!bndargs.exists ())
@@ -3506,17 +3508,20 @@ assign_bounds (vec<bounds_parm_data> &bndargs,
       {
        /* Pass 0 => regs only.  */
        if (pass == 0
-           && (!pbdata->parm_data.entry_parm
-               || GET_CODE (pbdata->parm_data.entry_parm) != REG))
+           && (!assign_regs
+               ||(!pbdata->parm_data.entry_parm
+                  || GET_CODE (pbdata->parm_data.entry_parm) != REG)))
          continue;
        /* Pass 1 => slots only.  */
        else if (pass == 1
-                && (!pbdata->parm_data.entry_parm
-                    || GET_CODE (pbdata->parm_data.entry_parm) == REG))
+                && (!assign_special
+                    || (!pbdata->parm_data.entry_parm
+                        || GET_CODE (pbdata->parm_data.entry_parm) == REG)))
          continue;
        /* Pass 2 => BT only.  */
        else if (pass == 2
-                && pbdata->parm_data.entry_parm)
+                && (!assign_bt
+                    || pbdata->parm_data.entry_parm))
          continue;
 
        if (!pbdata->parm_data.entry_parm
@@ -3537,14 +3542,7 @@ assign_bounds (vec<bounds_parm_data> &bndargs,
        else
          assign_parm_setup_stack (&all, pbdata->bounds_parm,
                                   &pbdata->parm_data);
-
-       /* Count handled bounds to make sure we miss nothing.  */
-       handled++;
       }
-
-  gcc_assert (handled == bndargs.length ());
-
-  bndargs.release ();
 }
 
 /* Assign RTL expressions to the function's parameters.  This may involve
@@ -3669,12 +3667,14 @@ assign_parms (tree fndecl)
              /* We expect this is the last parm.  Otherwise it is wrong
                 to assign bounds right now.  */
              gcc_assert (i == (fnargs.length () - 1));
-             assign_bounds (bndargs, all);
+             assign_bounds (bndargs, all, true, false, false);
              targetm.calls.setup_incoming_vararg_bounds (all.args_so_far,
                                                          data.promoted_mode,
                                                          data.passed_type,
                                                          &pretend_bytes,
                                                          false);
+             assign_bounds (bndargs, all, false, true, true);
+             bndargs.release ();
            }
        }
 
@@ -3686,7 +3686,8 @@ assign_parms (tree fndecl)
        bound_no++;
     }
 
-  assign_bounds (bndargs, all);
+  assign_bounds (bndargs, all, true, true, true);
+  bndargs.release ();
 
   if (targetm.calls.split_complex_arg)
     assign_parms_unsplit_complex (&all, fnargs);
diff --git a/gcc/testsuite/gcc.target/i386/mpx/pr66569.c 
b/gcc/testsuite/gcc.target/i386/mpx/pr66569.c
new file mode 100644
index 0000000..ba2023c
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mpx/pr66569.c
@@ -0,0 +1,14 @@
+/* { dg-do compile } */
+/* { dg-options "-fcheck-pointer-bounds -mmpx" } */
+
+struct s1 {
+  int *p;
+  int i;
+};
+
+struct s2 {
+  struct s1 s;
+  int i;
+};
+
+int test (struct s2 s, ...) { }

Reply via email to