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, ...) { }