diff mbox

Pointer Bounds Checker and trailing arrays (PR68270)

Message ID CACysShhYhEUkcYOMpX33CtoSKELoq+GioaWEKsWq4ycYYeTEkQ@mail.gmail.com
State New
Headers show

Commit Message

Alexander Ivchenko Dec. 21, 2016, 7:18 p.m. UTC
Right.. here is this updated chunk (otherwise no difference in the patch)


2016-12-21 21:00 GMT+03:00 Ilya Enkovich <enkovich.gnu@gmail.com>:
> 2016-12-20 17:44 GMT+03:00 Alexander Ivchenko <aivchenk@gmail.com>:
>> 2016-11-26 0:28 GMT+03:00 Ilya Enkovich <enkovich.gnu@gmail.com>:
>>> 2016-11-25 15:47 GMT+03:00 Alexander Ivchenko <aivchenk@gmail.com>:
>>>> Hi,
>>>>
>>>> The patch below addresses PR68270. could you please take a look?
>>>>
>>>> 2016-11-25  Alexander Ivchenko  <aivchenk@gmail.com>
>>>>
>>>>        * c-family/c.opt (flag_chkp_flexible_struct_trailing_arrays):
>>>>        Add new option.
>>>>        * tree-chkp.c (chkp_parse_array_and_component_ref): Forbid
>>>>        narrowing when chkp_parse_array_and_component_ref is used and
>>>>        the ARRAY_REF points to an array in the end of the struct.
>>>>
>>>>
>>>>
>>>> diff --git a/gcc/c-family/c.opt b/gcc/c-family/c.opt
>>>> index 7d8a726..e45d6a2 100644
>>>> --- a/gcc/c-family/c.opt
>>>> +++ b/gcc/c-family/c.opt
>>>> @@ -1166,6 +1166,11 @@ C ObjC C++ ObjC++ LTO RejectNegative Report
>>>> Var(flag_chkp_narrow_to_innermost_ar
>>>>  Forces Pointer Bounds Checker to use bounds of the innermost arrays in case of
>>>>  nested static arryas access.  By default outermost array is used.
>>>>
>>>> +fchkp-flexible-struct-trailing-arrays
>>>> +C ObjC C++ ObjC++ LTO RejectNegative Report
>>>> Var(flag_chkp_flexible_struct_trailing_arrays)
>>>> +Allow Pointer Bounds Checker to treat all trailing arrays in structures as
>>>> +possibly flexible.
>>>
>>> Words 'allow' and 'possibly' are confusing here. This option is about to force
>>> checker to do something, not to give him a choice.
>>
>> Fixed
>>
>>> New option has to be documented in invoke.texi. It would also be nice to reflect
>>> changes on GCC MPX wiki page.
>>
>> Done
>>> We have an attribute to change compiler behavior when this option is not set.
>>> But we have no way to make exceptions when this option is used. Should we
>>> add one?
>> Something like "bnd_fixed_size" ? Could work. Although the customer
>> request did not mention the need for that.
>> Can I add it in a separate patch?
>>
>
> Yes.
>
>>
>>>> +
>>>>  fchkp-optimize
>>>>  C ObjC C++ ObjC++ LTO Report Var(flag_chkp_optimize) Init(-1)
>>>>  Allow Pointer Bounds Checker optimizations.  By default allowed
>>>> diff --git a/gcc/tree-chkp.c b/gcc/tree-chkp.c
>>>> index 2769682..40f99c3 100644
>>>> --- a/gcc/tree-chkp.c
>>>> +++ b/gcc/tree-chkp.c
>>>> @@ -3425,7 +3425,9 @@ chkp_parse_array_and_component_ref (tree node, tree *ptr,
>>>>    if (flag_chkp_narrow_bounds
>>>>        && !flag_chkp_narrow_to_innermost_arrray
>>>>        && (!last_comp
>>>> -  || chkp_may_narrow_to_field (TREE_OPERAND (last_comp, 1))))
>>>> +  || (chkp_may_narrow_to_field (TREE_OPERAND (last_comp, 1))
>>>> +      && !(flag_chkp_flexible_struct_trailing_arrays
>>>> +   && array_at_struct_end_p (var)))))
>>>
>>> This is incorrect place for fix. Consider code
>>>
>>> struct S {
>>>   int a;
>>>   int b[10];
>>> };
>>>
>>> struct S s;
>>> int *p = s.b;
>>>
>>> Here you need to compute bounds for p and you want your option to take effect
>>> but in this case you won't event reach your new check because there is no
>>> ARRAY_REF. And even if we change it to
>>>
>>> int *p = s.b[5];
>>>
>>> then it still would be narrowed because s.b would still be written
>>> into 'comp_to_narrow'
>>> variable. Correct place for fix is in chkp_may_narrow_to_field.
>>
>> Done
>>
>>> Also you should consider fchkp-narrow-to-innermost-arrray option. Should it
>>> be more powerfull or not? I think fchkp-narrow-to-innermost-arrray shouldn't
>>> narrow to variable sized fields. BTW looks like right now bnd_variable_size
>>> attribute is ignored by fchkp-narrow-to-innermost-arrray. This is another
>>> problem and may be fixed in another patch though.
>> The way code works in chkp_parse_array_and_component_ref seems to be
>> exactly like you say:  fchkp-narrow-to-innermost-arrray won't narrow
>> to variable sized fields. I will create a separate bug for
>> bnd_variable_size+ fchkp-narrow-to-innermost-arrray.
>>
>>> Also patch lacks tests for various situations (with option and without, with
>>> ARRAY_REF and without). In case of new attribute and fix for
>>> fchkp-narrow-to-innermost-arrray behavior additional tests are required.
>> I added three tests for flag_chkp_flexible_struct_trailing_arrays
>>
>>
>>
>> The patch is below:
>>
>> diff --git a/gcc/c-family/c.opt b/gcc/c-family/c.opt
>> index 2d47d54..21ad6aa 100644
>> --- a/gcc/c-family/c.opt
>> +++ b/gcc/c-family/c.opt
>> @@ -1188,7 +1188,13 @@ narrowing is on, field bounds are used.
>> Otherwise full object bounds are used.
>>  fchkp-narrow-to-innermost-array
>>  C ObjC C++ ObjC++ LTO RejectNegative Report
>> Var(flag_chkp_narrow_to_innermost_arrray)
>>  Forces Pointer Bounds Checker to use bounds of the innermost arrays in case of
>> -nested static arryas access.  By default outermost array is used.
>> +nested static arrays access.  By default outermost array is used.
>> +
>> +fchkp-flexible-struct-trailing-arrays
>> +C ObjC C++ ObjC++ LTO RejectNegative Report
>> Var(flag_chkp_flexible_struct_trailing_arrays)
>> +Forces Pointer Bounds Checker to treat all trailing arrays in structures as
>> +possibly flexible.  By default only arrays fields with zero length or that are
>> +marked with attribute bnd_variable_size are treated as flexible.
>>
>>  fchkp-optimize
>>  C ObjC C++ ObjC++ LTO Report Var(flag_chkp_optimize) Init(-1)
>> diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
>> index 034ae98..2372c22a 100644
>> --- a/gcc/doc/invoke.texi
>> +++ b/gcc/doc/invoke.texi
>> @@ -10886,6 +10886,13 @@ Forces Pointer Bounds Checker to use narrowed
>> bounds for the address of the
>>  first field in the structure.  By default a pointer to the first field has
>>  the same bounds as a pointer to the whole structure.
>>
>> +@item -fchkp-flexible-struct-trailing-arrays
>> +@opindex fchkp-flexible-struct-trailing-arrays
>> +@opindex fno-chkp-flexible-struct-trailing-arrays
>> +Forces Pointer Bounds Checker to treat all trailing arrays in structures as
>> +possibly flexible.  By default only arrays fields with zero length or that are
>> +marked with attribute bnd_variable_size are treated as flexible.
>> +
>>  @item -fchkp-narrow-to-innermost-array
>>  @opindex fchkp-narrow-to-innermost-array
>>  @opindex fno-chkp-narrow-to-innermost-array
>> diff --git a/gcc/testsuite/gcc.target/i386/mpx/vla-trailing-1-lbv.c
>> b/gcc/testsuite/gcc.target/i386/mpx/vla-trailing-1-lbv.c
>> new file mode 100644
>> index 0000000..9739920
>> --- /dev/null
>> +++ b/gcc/testsuite/gcc.target/i386/mpx/vla-trailing-1-lbv.c
>> @@ -0,0 +1,29 @@
>> +/* { dg-do run } */
>> +/* { dg-shouldfail "bounds violation" } */
>> +/* { dg-options "-fcheck-pointer-bounds -mmpx
>> -fchkp-flexible-struct-trailing-arrays" } */
>> +
>> +
>> +#define SHOULDFAIL
>> +
>> +#include "mpx-check.h"
>> +
>> +struct S
>> +{
>> +  int a;
>> +  int p[10];
>> +};
>> +
>> +int rd (int *p, int i)
>> +{
>> +  int res = p[i];
>> +  printf ("%d\n", res);
>> +  return res;
>> +}
>> +
>> +int mpx_test (int argc, const char **argv)
>> +{
>> +  struct S *s = (struct S *)alloca (sizeof(struct S) + sizeof (int)*100);
>> +  rd (s->p, -2);
>> +
>> +  return 0;
>> +}
>> diff --git a/gcc/testsuite/gcc.target/i386/mpx/vla-trailing-1-nov.c
>> b/gcc/testsuite/gcc.target/i386/mpx/vla-trailing-1-nov.c
>> new file mode 100644
>> index 0000000..f5c8f95
>> --- /dev/null
>> +++ b/gcc/testsuite/gcc.target/i386/mpx/vla-trailing-1-nov.c
>> @@ -0,0 +1,29 @@
>> +/* { dg-do run } */
>> +/* { dg-options "-fcheck-pointer-bounds -mmpx
>> -fchkp-flexible-struct-trailing-arrays" } */
>> +
>> +
>> +#include "mpx-check.h"
>> +
>> +struct S
>> +{
>> +  int a;
>> +  int p[10];
>> +};
>> +
>> +int rd (int *p, int i)
>> +{
>> +  int res = p[i];
>> +  printf ("%d\n", res);
>> +  return res;
>> +}
>> +
>> +int mpx_test (int argc, const char **argv)
>> +{
>> +  struct S *s = (struct S *)alloca (sizeof(struct S) + sizeof (int)*100);
>> +  rd (s->p, 0);
>> +  rd (s->p, 99);
>> +  s->p[0];
>> +  s->p[99];
>> +
>> +  return 0;
>> +}
>> diff --git a/gcc/testsuite/gcc.target/i386/mpx/vla-trailing-1-ubv.c
>> b/gcc/testsuite/gcc.target/i386/mpx/vla-trailing-1-ubv.c
>> new file mode 100644
>> index 0000000..8385a5a
>> --- /dev/null
>> +++ b/gcc/testsuite/gcc.target/i386/mpx/vla-trailing-1-ubv.c
>> @@ -0,0 +1,29 @@
>> +/* { dg-do run } */
>> +/* { dg-shouldfail "bounds violation" } */
>> +/* { dg-options "-fcheck-pointer-bounds -mmpx
>> -fchkp-flexible-struct-trailing-arrays" } */
>> +
>> +
>> +#define SHOULDFAIL
>> +
>> +#include "mpx-check.h"
>> +
>> +struct S
>> +{
>> +  int a;
>> +  int p[10];
>> +};
>> +
>> +int rd (int *p, int i)
>> +{
>> +  int res = p[i];
>> +  printf ("%d\n", res);
>> +  return res;
>> +}
>> +
>> +int mpx_test (int argc, const char **argv)
>> +{
>> +  struct S *s = (struct S *)alloca (sizeof(struct S) + sizeof (int)*100);
>> +  rd (s->p, 110);
>> +
>> +  return 0;
>> +}
>> diff --git a/gcc/tree-chkp.c b/gcc/tree-chkp.c
>> index 2769682..6c5e541 100644
>> --- a/gcc/tree-chkp.c
>> +++ b/gcc/tree-chkp.c
>> @@ -3272,6 +3272,8 @@ chkp_may_narrow_to_field (tree field)
>>  {
>>    return DECL_SIZE (field) && TREE_CODE (DECL_SIZE (field)) == INTEGER_CST
>>      && tree_to_uhwi (DECL_SIZE (field)) != 0
>> +    && (!flag_chkp_flexible_struct_trailing_arrays
>> + || DECL_CHAIN (field))
>
> What if it's not array?
>
> Thanks,
> Ilya
>
>>      && (!DECL_FIELD_OFFSET (field)
>>   || TREE_CODE (DECL_FIELD_OFFSET (field)) == INTEGER_CST)
>>      && (!DECL_FIELD_BIT_OFFSET (field)

Comments

Ilya Enkovich Dec. 21, 2016, 11:47 p.m. UTC | #1
2016-12-21 22:18 GMT+03:00 Alexander Ivchenko <aivchenk@gmail.com>:
> Right.. here is this updated chunk (otherwise no difference in the patch)
>
> diff --git a/gcc/tree-chkp.c b/gcc/tree-chkp.c
> index 2769682..6c7862c 100644
> --- a/gcc/tree-chkp.c
> +++ b/gcc/tree-chkp.c
> @@ -3272,6 +3272,9 @@ chkp_may_narrow_to_field (tree field)
>  {
>    return DECL_SIZE (field) && TREE_CODE (DECL_SIZE (field)) == INTEGER_CST
>      && tree_to_uhwi (DECL_SIZE (field)) != 0
> +    && !(flag_chkp_flexible_struct_trailing_arrays
> + && TREE_CODE(TREE_TYPE(field)) == ARRAY_TYPE
> + && !DECL_CHAIN (field))
>      && (!DECL_FIELD_OFFSET (field)
>   || TREE_CODE (DECL_FIELD_OFFSET (field)) == INTEGER_CST)
>      && (!DECL_FIELD_BIT_OFFSET (field)

OK.

>
> 2016-12-21 21:00 GMT+03:00 Ilya Enkovich <enkovich.gnu@gmail.com>:
>> 2016-12-20 17:44 GMT+03:00 Alexander Ivchenko <aivchenk@gmail.com>:
>>> 2016-11-26 0:28 GMT+03:00 Ilya Enkovich <enkovich.gnu@gmail.com>:
>>>> 2016-11-25 15:47 GMT+03:00 Alexander Ivchenko <aivchenk@gmail.com>:
>>>>> Hi,
>>>>>
>>>>> The patch below addresses PR68270. could you please take a look?
>>>>>
>>>>> 2016-11-25  Alexander Ivchenko  <aivchenk@gmail.com>
>>>>>
>>>>>        * c-family/c.opt (flag_chkp_flexible_struct_trailing_arrays):
>>>>>        Add new option.
>>>>>        * tree-chkp.c (chkp_parse_array_and_component_ref): Forbid
>>>>>        narrowing when chkp_parse_array_and_component_ref is used and
>>>>>        the ARRAY_REF points to an array in the end of the struct.
>>>>>
>>>>>
>>>>>
>>>>> diff --git a/gcc/c-family/c.opt b/gcc/c-family/c.opt
>>>>> index 7d8a726..e45d6a2 100644
>>>>> --- a/gcc/c-family/c.opt
>>>>> +++ b/gcc/c-family/c.opt
>>>>> @@ -1166,6 +1166,11 @@ C ObjC C++ ObjC++ LTO RejectNegative Report
>>>>> Var(flag_chkp_narrow_to_innermost_ar
>>>>>  Forces Pointer Bounds Checker to use bounds of the innermost arrays in case of
>>>>>  nested static arryas access.  By default outermost array is used.
>>>>>
>>>>> +fchkp-flexible-struct-trailing-arrays
>>>>> +C ObjC C++ ObjC++ LTO RejectNegative Report
>>>>> Var(flag_chkp_flexible_struct_trailing_arrays)
>>>>> +Allow Pointer Bounds Checker to treat all trailing arrays in structures as
>>>>> +possibly flexible.
>>>>
>>>> Words 'allow' and 'possibly' are confusing here. This option is about to force
>>>> checker to do something, not to give him a choice.
>>>
>>> Fixed
>>>
>>>> New option has to be documented in invoke.texi. It would also be nice to reflect
>>>> changes on GCC MPX wiki page.
>>>
>>> Done
>>>> We have an attribute to change compiler behavior when this option is not set.
>>>> But we have no way to make exceptions when this option is used. Should we
>>>> add one?
>>> Something like "bnd_fixed_size" ? Could work. Although the customer
>>> request did not mention the need for that.
>>> Can I add it in a separate patch?
>>>
>>
>> Yes.
>>
>>>
>>>>> +
>>>>>  fchkp-optimize
>>>>>  C ObjC C++ ObjC++ LTO Report Var(flag_chkp_optimize) Init(-1)
>>>>>  Allow Pointer Bounds Checker optimizations.  By default allowed
>>>>> diff --git a/gcc/tree-chkp.c b/gcc/tree-chkp.c
>>>>> index 2769682..40f99c3 100644
>>>>> --- a/gcc/tree-chkp.c
>>>>> +++ b/gcc/tree-chkp.c
>>>>> @@ -3425,7 +3425,9 @@ chkp_parse_array_and_component_ref (tree node, tree *ptr,
>>>>>    if (flag_chkp_narrow_bounds
>>>>>        && !flag_chkp_narrow_to_innermost_arrray
>>>>>        && (!last_comp
>>>>> -  || chkp_may_narrow_to_field (TREE_OPERAND (last_comp, 1))))
>>>>> +  || (chkp_may_narrow_to_field (TREE_OPERAND (last_comp, 1))
>>>>> +      && !(flag_chkp_flexible_struct_trailing_arrays
>>>>> +   && array_at_struct_end_p (var)))))
>>>>
>>>> This is incorrect place for fix. Consider code
>>>>
>>>> struct S {
>>>>   int a;
>>>>   int b[10];
>>>> };
>>>>
>>>> struct S s;
>>>> int *p = s.b;
>>>>
>>>> Here you need to compute bounds for p and you want your option to take effect
>>>> but in this case you won't event reach your new check because there is no
>>>> ARRAY_REF. And even if we change it to
>>>>
>>>> int *p = s.b[5];
>>>>
>>>> then it still would be narrowed because s.b would still be written
>>>> into 'comp_to_narrow'
>>>> variable. Correct place for fix is in chkp_may_narrow_to_field.
>>>
>>> Done
>>>
>>>> Also you should consider fchkp-narrow-to-innermost-arrray option. Should it
>>>> be more powerfull or not? I think fchkp-narrow-to-innermost-arrray shouldn't
>>>> narrow to variable sized fields. BTW looks like right now bnd_variable_size
>>>> attribute is ignored by fchkp-narrow-to-innermost-arrray. This is another
>>>> problem and may be fixed in another patch though.
>>> The way code works in chkp_parse_array_and_component_ref seems to be
>>> exactly like you say:  fchkp-narrow-to-innermost-arrray won't narrow
>>> to variable sized fields. I will create a separate bug for
>>> bnd_variable_size+ fchkp-narrow-to-innermost-arrray.
>>>
>>>> Also patch lacks tests for various situations (with option and without, with
>>>> ARRAY_REF and without). In case of new attribute and fix for
>>>> fchkp-narrow-to-innermost-arrray behavior additional tests are required.
>>> I added three tests for flag_chkp_flexible_struct_trailing_arrays
>>>
>>>
>>>
>>> The patch is below:
>>>
>>> diff --git a/gcc/c-family/c.opt b/gcc/c-family/c.opt
>>> index 2d47d54..21ad6aa 100644
>>> --- a/gcc/c-family/c.opt
>>> +++ b/gcc/c-family/c.opt
>>> @@ -1188,7 +1188,13 @@ narrowing is on, field bounds are used.
>>> Otherwise full object bounds are used.
>>>  fchkp-narrow-to-innermost-array
>>>  C ObjC C++ ObjC++ LTO RejectNegative Report
>>> Var(flag_chkp_narrow_to_innermost_arrray)
>>>  Forces Pointer Bounds Checker to use bounds of the innermost arrays in case of
>>> -nested static arryas access.  By default outermost array is used.
>>> +nested static arrays access.  By default outermost array is used.
>>> +
>>> +fchkp-flexible-struct-trailing-arrays
>>> +C ObjC C++ ObjC++ LTO RejectNegative Report

I also noticed this part conflicts with documentation which describes
both positive and negative flag versions. I think we should allow
negative version.

Patch is OK with that change and proper testing.

Thanks,
Ilya

>>> Var(flag_chkp_flexible_struct_trailing_arrays)
>>> +Forces Pointer Bounds Checker to treat all trailing arrays in structures as
>>> +possibly flexible.  By default only arrays fields with zero length or that are
>>> +marked with attribute bnd_variable_size are treated as flexible.
>>>
>>>  fchkp-optimize
>>>  C ObjC C++ ObjC++ LTO Report Var(flag_chkp_optimize) Init(-1)
>>> diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
>>> index 034ae98..2372c22a 100644
>>> --- a/gcc/doc/invoke.texi
>>> +++ b/gcc/doc/invoke.texi
>>> @@ -10886,6 +10886,13 @@ Forces Pointer Bounds Checker to use narrowed
>>> bounds for the address of the
>>>  first field in the structure.  By default a pointer to the first field has
>>>  the same bounds as a pointer to the whole structure.
>>>
>>> +@item -fchkp-flexible-struct-trailing-arrays
>>> +@opindex fchkp-flexible-struct-trailing-arrays
>>> +@opindex fno-chkp-flexible-struct-trailing-arrays
>>> +Forces Pointer Bounds Checker to treat all trailing arrays in structures as
>>> +possibly flexible.  By default only arrays fields with zero length or that are
>>> +marked with attribute bnd_variable_size are treated as flexible.
>>> +
>>>  @item -fchkp-narrow-to-innermost-array
>>>  @opindex fchkp-narrow-to-innermost-array
>>>  @opindex fno-chkp-narrow-to-innermost-array
>>> diff --git a/gcc/testsuite/gcc.target/i386/mpx/vla-trailing-1-lbv.c
>>> b/gcc/testsuite/gcc.target/i386/mpx/vla-trailing-1-lbv.c
>>> new file mode 100644
>>> index 0000000..9739920
>>> --- /dev/null
>>> +++ b/gcc/testsuite/gcc.target/i386/mpx/vla-trailing-1-lbv.c
>>> @@ -0,0 +1,29 @@
>>> +/* { dg-do run } */
>>> +/* { dg-shouldfail "bounds violation" } */
>>> +/* { dg-options "-fcheck-pointer-bounds -mmpx
>>> -fchkp-flexible-struct-trailing-arrays" } */
>>> +
>>> +
>>> +#define SHOULDFAIL
>>> +
>>> +#include "mpx-check.h"
>>> +
>>> +struct S
>>> +{
>>> +  int a;
>>> +  int p[10];
>>> +};
>>> +
>>> +int rd (int *p, int i)
>>> +{
>>> +  int res = p[i];
>>> +  printf ("%d\n", res);
>>> +  return res;
>>> +}
>>> +
>>> +int mpx_test (int argc, const char **argv)
>>> +{
>>> +  struct S *s = (struct S *)alloca (sizeof(struct S) + sizeof (int)*100);
>>> +  rd (s->p, -2);
>>> +
>>> +  return 0;
>>> +}
>>> diff --git a/gcc/testsuite/gcc.target/i386/mpx/vla-trailing-1-nov.c
>>> b/gcc/testsuite/gcc.target/i386/mpx/vla-trailing-1-nov.c
>>> new file mode 100644
>>> index 0000000..f5c8f95
>>> --- /dev/null
>>> +++ b/gcc/testsuite/gcc.target/i386/mpx/vla-trailing-1-nov.c
>>> @@ -0,0 +1,29 @@
>>> +/* { dg-do run } */
>>> +/* { dg-options "-fcheck-pointer-bounds -mmpx
>>> -fchkp-flexible-struct-trailing-arrays" } */
>>> +
>>> +
>>> +#include "mpx-check.h"
>>> +
>>> +struct S
>>> +{
>>> +  int a;
>>> +  int p[10];
>>> +};
>>> +
>>> +int rd (int *p, int i)
>>> +{
>>> +  int res = p[i];
>>> +  printf ("%d\n", res);
>>> +  return res;
>>> +}
>>> +
>>> +int mpx_test (int argc, const char **argv)
>>> +{
>>> +  struct S *s = (struct S *)alloca (sizeof(struct S) + sizeof (int)*100);
>>> +  rd (s->p, 0);
>>> +  rd (s->p, 99);
>>> +  s->p[0];
>>> +  s->p[99];
>>> +
>>> +  return 0;
>>> +}
>>> diff --git a/gcc/testsuite/gcc.target/i386/mpx/vla-trailing-1-ubv.c
>>> b/gcc/testsuite/gcc.target/i386/mpx/vla-trailing-1-ubv.c
>>> new file mode 100644
>>> index 0000000..8385a5a
>>> --- /dev/null
>>> +++ b/gcc/testsuite/gcc.target/i386/mpx/vla-trailing-1-ubv.c
>>> @@ -0,0 +1,29 @@
>>> +/* { dg-do run } */
>>> +/* { dg-shouldfail "bounds violation" } */
>>> +/* { dg-options "-fcheck-pointer-bounds -mmpx
>>> -fchkp-flexible-struct-trailing-arrays" } */
>>> +
>>> +
>>> +#define SHOULDFAIL
>>> +
>>> +#include "mpx-check.h"
>>> +
>>> +struct S
>>> +{
>>> +  int a;
>>> +  int p[10];
>>> +};
>>> +
>>> +int rd (int *p, int i)
>>> +{
>>> +  int res = p[i];
>>> +  printf ("%d\n", res);
>>> +  return res;
>>> +}
>>> +
>>> +int mpx_test (int argc, const char **argv)
>>> +{
>>> +  struct S *s = (struct S *)alloca (sizeof(struct S) + sizeof (int)*100);
>>> +  rd (s->p, 110);
>>> +
>>> +  return 0;
>>> +}
>>> diff --git a/gcc/tree-chkp.c b/gcc/tree-chkp.c
>>> index 2769682..6c5e541 100644
>>> --- a/gcc/tree-chkp.c
>>> +++ b/gcc/tree-chkp.c
>>> @@ -3272,6 +3272,8 @@ chkp_may_narrow_to_field (tree field)
>>>  {
>>>    return DECL_SIZE (field) && TREE_CODE (DECL_SIZE (field)) == INTEGER_CST
>>>      && tree_to_uhwi (DECL_SIZE (field)) != 0
>>> +    && (!flag_chkp_flexible_struct_trailing_arrays
>>> + || DECL_CHAIN (field))
>>
>> What if it's not array?
>>
>> Thanks,
>> Ilya
>>
>>>      && (!DECL_FIELD_OFFSET (field)
>>>   || TREE_CODE (DECL_FIELD_OFFSET (field)) == INTEGER_CST)
>>>      && (!DECL_FIELD_BIT_OFFSET (field)
Alexander Ivchenko Dec. 27, 2016, 1:42 p.m. UTC | #2
Committed as r243936.

Thank you,
Alexander

2016-12-22 2:47 GMT+03:00 Ilya Enkovich <enkovich.gnu@gmail.com>:
> 2016-12-21 22:18 GMT+03:00 Alexander Ivchenko <aivchenk@gmail.com>:
>> Right.. here is this updated chunk (otherwise no difference in the patch)
>>
>> diff --git a/gcc/tree-chkp.c b/gcc/tree-chkp.c
>> index 2769682..6c7862c 100644
>> --- a/gcc/tree-chkp.c
>> +++ b/gcc/tree-chkp.c
>> @@ -3272,6 +3272,9 @@ chkp_may_narrow_to_field (tree field)
>>  {
>>    return DECL_SIZE (field) && TREE_CODE (DECL_SIZE (field)) == INTEGER_CST
>>      && tree_to_uhwi (DECL_SIZE (field)) != 0
>> +    && !(flag_chkp_flexible_struct_trailing_arrays
>> + && TREE_CODE(TREE_TYPE(field)) == ARRAY_TYPE
>> + && !DECL_CHAIN (field))
>>      && (!DECL_FIELD_OFFSET (field)
>>   || TREE_CODE (DECL_FIELD_OFFSET (field)) == INTEGER_CST)
>>      && (!DECL_FIELD_BIT_OFFSET (field)
>
> OK.
>
>>
>> 2016-12-21 21:00 GMT+03:00 Ilya Enkovich <enkovich.gnu@gmail.com>:
>>> 2016-12-20 17:44 GMT+03:00 Alexander Ivchenko <aivchenk@gmail.com>:
>>>> 2016-11-26 0:28 GMT+03:00 Ilya Enkovich <enkovich.gnu@gmail.com>:
>>>>> 2016-11-25 15:47 GMT+03:00 Alexander Ivchenko <aivchenk@gmail.com>:
>>>>>> Hi,
>>>>>>
>>>>>> The patch below addresses PR68270. could you please take a look?
>>>>>>
>>>>>> 2016-11-25  Alexander Ivchenko  <aivchenk@gmail.com>
>>>>>>
>>>>>>        * c-family/c.opt (flag_chkp_flexible_struct_trailing_arrays):
>>>>>>        Add new option.
>>>>>>        * tree-chkp.c (chkp_parse_array_and_component_ref): Forbid
>>>>>>        narrowing when chkp_parse_array_and_component_ref is used and
>>>>>>        the ARRAY_REF points to an array in the end of the struct.
>>>>>>
>>>>>>
>>>>>>
>>>>>> diff --git a/gcc/c-family/c.opt b/gcc/c-family/c.opt
>>>>>> index 7d8a726..e45d6a2 100644
>>>>>> --- a/gcc/c-family/c.opt
>>>>>> +++ b/gcc/c-family/c.opt
>>>>>> @@ -1166,6 +1166,11 @@ C ObjC C++ ObjC++ LTO RejectNegative Report
>>>>>> Var(flag_chkp_narrow_to_innermost_ar
>>>>>>  Forces Pointer Bounds Checker to use bounds of the innermost arrays in case of
>>>>>>  nested static arryas access.  By default outermost array is used.
>>>>>>
>>>>>> +fchkp-flexible-struct-trailing-arrays
>>>>>> +C ObjC C++ ObjC++ LTO RejectNegative Report
>>>>>> Var(flag_chkp_flexible_struct_trailing_arrays)
>>>>>> +Allow Pointer Bounds Checker to treat all trailing arrays in structures as
>>>>>> +possibly flexible.
>>>>>
>>>>> Words 'allow' and 'possibly' are confusing here. This option is about to force
>>>>> checker to do something, not to give him a choice.
>>>>
>>>> Fixed
>>>>
>>>>> New option has to be documented in invoke.texi. It would also be nice to reflect
>>>>> changes on GCC MPX wiki page.
>>>>
>>>> Done
>>>>> We have an attribute to change compiler behavior when this option is not set.
>>>>> But we have no way to make exceptions when this option is used. Should we
>>>>> add one?
>>>> Something like "bnd_fixed_size" ? Could work. Although the customer
>>>> request did not mention the need for that.
>>>> Can I add it in a separate patch?
>>>>
>>>
>>> Yes.
>>>
>>>>
>>>>>> +
>>>>>>  fchkp-optimize
>>>>>>  C ObjC C++ ObjC++ LTO Report Var(flag_chkp_optimize) Init(-1)
>>>>>>  Allow Pointer Bounds Checker optimizations.  By default allowed
>>>>>> diff --git a/gcc/tree-chkp.c b/gcc/tree-chkp.c
>>>>>> index 2769682..40f99c3 100644
>>>>>> --- a/gcc/tree-chkp.c
>>>>>> +++ b/gcc/tree-chkp.c
>>>>>> @@ -3425,7 +3425,9 @@ chkp_parse_array_and_component_ref (tree node, tree *ptr,
>>>>>>    if (flag_chkp_narrow_bounds
>>>>>>        && !flag_chkp_narrow_to_innermost_arrray
>>>>>>        && (!last_comp
>>>>>> -  || chkp_may_narrow_to_field (TREE_OPERAND (last_comp, 1))))
>>>>>> +  || (chkp_may_narrow_to_field (TREE_OPERAND (last_comp, 1))
>>>>>> +      && !(flag_chkp_flexible_struct_trailing_arrays
>>>>>> +   && array_at_struct_end_p (var)))))
>>>>>
>>>>> This is incorrect place for fix. Consider code
>>>>>
>>>>> struct S {
>>>>>   int a;
>>>>>   int b[10];
>>>>> };
>>>>>
>>>>> struct S s;
>>>>> int *p = s.b;
>>>>>
>>>>> Here you need to compute bounds for p and you want your option to take effect
>>>>> but in this case you won't event reach your new check because there is no
>>>>> ARRAY_REF. And even if we change it to
>>>>>
>>>>> int *p = s.b[5];
>>>>>
>>>>> then it still would be narrowed because s.b would still be written
>>>>> into 'comp_to_narrow'
>>>>> variable. Correct place for fix is in chkp_may_narrow_to_field.
>>>>
>>>> Done
>>>>
>>>>> Also you should consider fchkp-narrow-to-innermost-arrray option. Should it
>>>>> be more powerfull or not? I think fchkp-narrow-to-innermost-arrray shouldn't
>>>>> narrow to variable sized fields. BTW looks like right now bnd_variable_size
>>>>> attribute is ignored by fchkp-narrow-to-innermost-arrray. This is another
>>>>> problem and may be fixed in another patch though.
>>>> The way code works in chkp_parse_array_and_component_ref seems to be
>>>> exactly like you say:  fchkp-narrow-to-innermost-arrray won't narrow
>>>> to variable sized fields. I will create a separate bug for
>>>> bnd_variable_size+ fchkp-narrow-to-innermost-arrray.
>>>>
>>>>> Also patch lacks tests for various situations (with option and without, with
>>>>> ARRAY_REF and without). In case of new attribute and fix for
>>>>> fchkp-narrow-to-innermost-arrray behavior additional tests are required.
>>>> I added three tests for flag_chkp_flexible_struct_trailing_arrays
>>>>
>>>>
>>>>
>>>> The patch is below:
>>>>
>>>> diff --git a/gcc/c-family/c.opt b/gcc/c-family/c.opt
>>>> index 2d47d54..21ad6aa 100644
>>>> --- a/gcc/c-family/c.opt
>>>> +++ b/gcc/c-family/c.opt
>>>> @@ -1188,7 +1188,13 @@ narrowing is on, field bounds are used.
>>>> Otherwise full object bounds are used.
>>>>  fchkp-narrow-to-innermost-array
>>>>  C ObjC C++ ObjC++ LTO RejectNegative Report
>>>> Var(flag_chkp_narrow_to_innermost_arrray)
>>>>  Forces Pointer Bounds Checker to use bounds of the innermost arrays in case of
>>>> -nested static arryas access.  By default outermost array is used.
>>>> +nested static arrays access.  By default outermost array is used.
>>>> +
>>>> +fchkp-flexible-struct-trailing-arrays
>>>> +C ObjC C++ ObjC++ LTO RejectNegative Report
>
> I also noticed this part conflicts with documentation which describes
> both positive and negative flag versions. I think we should allow
> negative version.
>
> Patch is OK with that change and proper testing.
>
> Thanks,
> Ilya
>
>>>> Var(flag_chkp_flexible_struct_trailing_arrays)
>>>> +Forces Pointer Bounds Checker to treat all trailing arrays in structures as
>>>> +possibly flexible.  By default only arrays fields with zero length or that are
>>>> +marked with attribute bnd_variable_size are treated as flexible.
>>>>
>>>>  fchkp-optimize
>>>>  C ObjC C++ ObjC++ LTO Report Var(flag_chkp_optimize) Init(-1)
>>>> diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
>>>> index 034ae98..2372c22a 100644
>>>> --- a/gcc/doc/invoke.texi
>>>> +++ b/gcc/doc/invoke.texi
>>>> @@ -10886,6 +10886,13 @@ Forces Pointer Bounds Checker to use narrowed
>>>> bounds for the address of the
>>>>  first field in the structure.  By default a pointer to the first field has
>>>>  the same bounds as a pointer to the whole structure.
>>>>
>>>> +@item -fchkp-flexible-struct-trailing-arrays
>>>> +@opindex fchkp-flexible-struct-trailing-arrays
>>>> +@opindex fno-chkp-flexible-struct-trailing-arrays
>>>> +Forces Pointer Bounds Checker to treat all trailing arrays in structures as
>>>> +possibly flexible.  By default only arrays fields with zero length or that are
>>>> +marked with attribute bnd_variable_size are treated as flexible.
>>>> +
>>>>  @item -fchkp-narrow-to-innermost-array
>>>>  @opindex fchkp-narrow-to-innermost-array
>>>>  @opindex fno-chkp-narrow-to-innermost-array
>>>> diff --git a/gcc/testsuite/gcc.target/i386/mpx/vla-trailing-1-lbv.c
>>>> b/gcc/testsuite/gcc.target/i386/mpx/vla-trailing-1-lbv.c
>>>> new file mode 100644
>>>> index 0000000..9739920
>>>> --- /dev/null
>>>> +++ b/gcc/testsuite/gcc.target/i386/mpx/vla-trailing-1-lbv.c
>>>> @@ -0,0 +1,29 @@
>>>> +/* { dg-do run } */
>>>> +/* { dg-shouldfail "bounds violation" } */
>>>> +/* { dg-options "-fcheck-pointer-bounds -mmpx
>>>> -fchkp-flexible-struct-trailing-arrays" } */
>>>> +
>>>> +
>>>> +#define SHOULDFAIL
>>>> +
>>>> +#include "mpx-check.h"
>>>> +
>>>> +struct S
>>>> +{
>>>> +  int a;
>>>> +  int p[10];
>>>> +};
>>>> +
>>>> +int rd (int *p, int i)
>>>> +{
>>>> +  int res = p[i];
>>>> +  printf ("%d\n", res);
>>>> +  return res;
>>>> +}
>>>> +
>>>> +int mpx_test (int argc, const char **argv)
>>>> +{
>>>> +  struct S *s = (struct S *)alloca (sizeof(struct S) + sizeof (int)*100);
>>>> +  rd (s->p, -2);
>>>> +
>>>> +  return 0;
>>>> +}
>>>> diff --git a/gcc/testsuite/gcc.target/i386/mpx/vla-trailing-1-nov.c
>>>> b/gcc/testsuite/gcc.target/i386/mpx/vla-trailing-1-nov.c
>>>> new file mode 100644
>>>> index 0000000..f5c8f95
>>>> --- /dev/null
>>>> +++ b/gcc/testsuite/gcc.target/i386/mpx/vla-trailing-1-nov.c
>>>> @@ -0,0 +1,29 @@
>>>> +/* { dg-do run } */
>>>> +/* { dg-options "-fcheck-pointer-bounds -mmpx
>>>> -fchkp-flexible-struct-trailing-arrays" } */
>>>> +
>>>> +
>>>> +#include "mpx-check.h"
>>>> +
>>>> +struct S
>>>> +{
>>>> +  int a;
>>>> +  int p[10];
>>>> +};
>>>> +
>>>> +int rd (int *p, int i)
>>>> +{
>>>> +  int res = p[i];
>>>> +  printf ("%d\n", res);
>>>> +  return res;
>>>> +}
>>>> +
>>>> +int mpx_test (int argc, const char **argv)
>>>> +{
>>>> +  struct S *s = (struct S *)alloca (sizeof(struct S) + sizeof (int)*100);
>>>> +  rd (s->p, 0);
>>>> +  rd (s->p, 99);
>>>> +  s->p[0];
>>>> +  s->p[99];
>>>> +
>>>> +  return 0;
>>>> +}
>>>> diff --git a/gcc/testsuite/gcc.target/i386/mpx/vla-trailing-1-ubv.c
>>>> b/gcc/testsuite/gcc.target/i386/mpx/vla-trailing-1-ubv.c
>>>> new file mode 100644
>>>> index 0000000..8385a5a
>>>> --- /dev/null
>>>> +++ b/gcc/testsuite/gcc.target/i386/mpx/vla-trailing-1-ubv.c
>>>> @@ -0,0 +1,29 @@
>>>> +/* { dg-do run } */
>>>> +/* { dg-shouldfail "bounds violation" } */
>>>> +/* { dg-options "-fcheck-pointer-bounds -mmpx
>>>> -fchkp-flexible-struct-trailing-arrays" } */
>>>> +
>>>> +
>>>> +#define SHOULDFAIL
>>>> +
>>>> +#include "mpx-check.h"
>>>> +
>>>> +struct S
>>>> +{
>>>> +  int a;
>>>> +  int p[10];
>>>> +};
>>>> +
>>>> +int rd (int *p, int i)
>>>> +{
>>>> +  int res = p[i];
>>>> +  printf ("%d\n", res);
>>>> +  return res;
>>>> +}
>>>> +
>>>> +int mpx_test (int argc, const char **argv)
>>>> +{
>>>> +  struct S *s = (struct S *)alloca (sizeof(struct S) + sizeof (int)*100);
>>>> +  rd (s->p, 110);
>>>> +
>>>> +  return 0;
>>>> +}
>>>> diff --git a/gcc/tree-chkp.c b/gcc/tree-chkp.c
>>>> index 2769682..6c5e541 100644
>>>> --- a/gcc/tree-chkp.c
>>>> +++ b/gcc/tree-chkp.c
>>>> @@ -3272,6 +3272,8 @@ chkp_may_narrow_to_field (tree field)
>>>>  {
>>>>    return DECL_SIZE (field) && TREE_CODE (DECL_SIZE (field)) == INTEGER_CST
>>>>      && tree_to_uhwi (DECL_SIZE (field)) != 0
>>>> +    && (!flag_chkp_flexible_struct_trailing_arrays
>>>> + || DECL_CHAIN (field))
>>>
>>> What if it's not array?
>>>
>>> Thanks,
>>> Ilya
>>>
>>>>      && (!DECL_FIELD_OFFSET (field)
>>>>   || TREE_CODE (DECL_FIELD_OFFSET (field)) == INTEGER_CST)
>>>>      && (!DECL_FIELD_BIT_OFFSET (field)
Richard Biener Jan. 4, 2017, 10:25 a.m. UTC | #3
On Thu, Dec 22, 2016 at 12:47 AM, Ilya Enkovich <enkovich.gnu@gmail.com> wrote:
> 2016-12-21 22:18 GMT+03:00 Alexander Ivchenko <aivchenk@gmail.com>:
>> Right.. here is this updated chunk (otherwise no difference in the patch)
>>
>> diff --git a/gcc/tree-chkp.c b/gcc/tree-chkp.c
>> index 2769682..6c7862c 100644
>> --- a/gcc/tree-chkp.c
>> +++ b/gcc/tree-chkp.c
>> @@ -3272,6 +3272,9 @@ chkp_may_narrow_to_field (tree field)
>>  {
>>    return DECL_SIZE (field) && TREE_CODE (DECL_SIZE (field)) == INTEGER_CST
>>      && tree_to_uhwi (DECL_SIZE (field)) != 0
>> +    && !(flag_chkp_flexible_struct_trailing_arrays
>> + && TREE_CODE(TREE_TYPE(field)) == ARRAY_TYPE
>> + && !DECL_CHAIN (field))
>>      && (!DECL_FIELD_OFFSET (field)
>>   || TREE_CODE (DECL_FIELD_OFFSET (field)) == INTEGER_CST)
>>      && (!DECL_FIELD_BIT_OFFSET (field)
>
> OK.

There is array_at_struct_end_p which has a better implementation for
this (the above
considers a TYPE_DECL after the array a field).

Richard.

>>
>> 2016-12-21 21:00 GMT+03:00 Ilya Enkovich <enkovich.gnu@gmail.com>:
>>> 2016-12-20 17:44 GMT+03:00 Alexander Ivchenko <aivchenk@gmail.com>:
>>>> 2016-11-26 0:28 GMT+03:00 Ilya Enkovich <enkovich.gnu@gmail.com>:
>>>>> 2016-11-25 15:47 GMT+03:00 Alexander Ivchenko <aivchenk@gmail.com>:
>>>>>> Hi,
>>>>>>
>>>>>> The patch below addresses PR68270. could you please take a look?
>>>>>>
>>>>>> 2016-11-25  Alexander Ivchenko  <aivchenk@gmail.com>
>>>>>>
>>>>>>        * c-family/c.opt (flag_chkp_flexible_struct_trailing_arrays):
>>>>>>        Add new option.
>>>>>>        * tree-chkp.c (chkp_parse_array_and_component_ref): Forbid
>>>>>>        narrowing when chkp_parse_array_and_component_ref is used and
>>>>>>        the ARRAY_REF points to an array in the end of the struct.
>>>>>>
>>>>>>
>>>>>>
>>>>>> diff --git a/gcc/c-family/c.opt b/gcc/c-family/c.opt
>>>>>> index 7d8a726..e45d6a2 100644
>>>>>> --- a/gcc/c-family/c.opt
>>>>>> +++ b/gcc/c-family/c.opt
>>>>>> @@ -1166,6 +1166,11 @@ C ObjC C++ ObjC++ LTO RejectNegative Report
>>>>>> Var(flag_chkp_narrow_to_innermost_ar
>>>>>>  Forces Pointer Bounds Checker to use bounds of the innermost arrays in case of
>>>>>>  nested static arryas access.  By default outermost array is used.
>>>>>>
>>>>>> +fchkp-flexible-struct-trailing-arrays
>>>>>> +C ObjC C++ ObjC++ LTO RejectNegative Report
>>>>>> Var(flag_chkp_flexible_struct_trailing_arrays)
>>>>>> +Allow Pointer Bounds Checker to treat all trailing arrays in structures as
>>>>>> +possibly flexible.
>>>>>
>>>>> Words 'allow' and 'possibly' are confusing here. This option is about to force
>>>>> checker to do something, not to give him a choice.
>>>>
>>>> Fixed
>>>>
>>>>> New option has to be documented in invoke.texi. It would also be nice to reflect
>>>>> changes on GCC MPX wiki page.
>>>>
>>>> Done
>>>>> We have an attribute to change compiler behavior when this option is not set.
>>>>> But we have no way to make exceptions when this option is used. Should we
>>>>> add one?
>>>> Something like "bnd_fixed_size" ? Could work. Although the customer
>>>> request did not mention the need for that.
>>>> Can I add it in a separate patch?
>>>>
>>>
>>> Yes.
>>>
>>>>
>>>>>> +
>>>>>>  fchkp-optimize
>>>>>>  C ObjC C++ ObjC++ LTO Report Var(flag_chkp_optimize) Init(-1)
>>>>>>  Allow Pointer Bounds Checker optimizations.  By default allowed
>>>>>> diff --git a/gcc/tree-chkp.c b/gcc/tree-chkp.c
>>>>>> index 2769682..40f99c3 100644
>>>>>> --- a/gcc/tree-chkp.c
>>>>>> +++ b/gcc/tree-chkp.c
>>>>>> @@ -3425,7 +3425,9 @@ chkp_parse_array_and_component_ref (tree node, tree *ptr,
>>>>>>    if (flag_chkp_narrow_bounds
>>>>>>        && !flag_chkp_narrow_to_innermost_arrray
>>>>>>        && (!last_comp
>>>>>> -  || chkp_may_narrow_to_field (TREE_OPERAND (last_comp, 1))))
>>>>>> +  || (chkp_may_narrow_to_field (TREE_OPERAND (last_comp, 1))
>>>>>> +      && !(flag_chkp_flexible_struct_trailing_arrays
>>>>>> +   && array_at_struct_end_p (var)))))
>>>>>
>>>>> This is incorrect place for fix. Consider code
>>>>>
>>>>> struct S {
>>>>>   int a;
>>>>>   int b[10];
>>>>> };
>>>>>
>>>>> struct S s;
>>>>> int *p = s.b;
>>>>>
>>>>> Here you need to compute bounds for p and you want your option to take effect
>>>>> but in this case you won't event reach your new check because there is no
>>>>> ARRAY_REF. And even if we change it to
>>>>>
>>>>> int *p = s.b[5];
>>>>>
>>>>> then it still would be narrowed because s.b would still be written
>>>>> into 'comp_to_narrow'
>>>>> variable. Correct place for fix is in chkp_may_narrow_to_field.
>>>>
>>>> Done
>>>>
>>>>> Also you should consider fchkp-narrow-to-innermost-arrray option. Should it
>>>>> be more powerfull or not? I think fchkp-narrow-to-innermost-arrray shouldn't
>>>>> narrow to variable sized fields. BTW looks like right now bnd_variable_size
>>>>> attribute is ignored by fchkp-narrow-to-innermost-arrray. This is another
>>>>> problem and may be fixed in another patch though.
>>>> The way code works in chkp_parse_array_and_component_ref seems to be
>>>> exactly like you say:  fchkp-narrow-to-innermost-arrray won't narrow
>>>> to variable sized fields. I will create a separate bug for
>>>> bnd_variable_size+ fchkp-narrow-to-innermost-arrray.
>>>>
>>>>> Also patch lacks tests for various situations (with option and without, with
>>>>> ARRAY_REF and without). In case of new attribute and fix for
>>>>> fchkp-narrow-to-innermost-arrray behavior additional tests are required.
>>>> I added three tests for flag_chkp_flexible_struct_trailing_arrays
>>>>
>>>>
>>>>
>>>> The patch is below:
>>>>
>>>> diff --git a/gcc/c-family/c.opt b/gcc/c-family/c.opt
>>>> index 2d47d54..21ad6aa 100644
>>>> --- a/gcc/c-family/c.opt
>>>> +++ b/gcc/c-family/c.opt
>>>> @@ -1188,7 +1188,13 @@ narrowing is on, field bounds are used.
>>>> Otherwise full object bounds are used.
>>>>  fchkp-narrow-to-innermost-array
>>>>  C ObjC C++ ObjC++ LTO RejectNegative Report
>>>> Var(flag_chkp_narrow_to_innermost_arrray)
>>>>  Forces Pointer Bounds Checker to use bounds of the innermost arrays in case of
>>>> -nested static arryas access.  By default outermost array is used.
>>>> +nested static arrays access.  By default outermost array is used.
>>>> +
>>>> +fchkp-flexible-struct-trailing-arrays
>>>> +C ObjC C++ ObjC++ LTO RejectNegative Report
>
> I also noticed this part conflicts with documentation which describes
> both positive and negative flag versions. I think we should allow
> negative version.
>
> Patch is OK with that change and proper testing.
>
> Thanks,
> Ilya
>
>>>> Var(flag_chkp_flexible_struct_trailing_arrays)
>>>> +Forces Pointer Bounds Checker to treat all trailing arrays in structures as
>>>> +possibly flexible.  By default only arrays fields with zero length or that are
>>>> +marked with attribute bnd_variable_size are treated as flexible.
>>>>
>>>>  fchkp-optimize
>>>>  C ObjC C++ ObjC++ LTO Report Var(flag_chkp_optimize) Init(-1)
>>>> diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
>>>> index 034ae98..2372c22a 100644
>>>> --- a/gcc/doc/invoke.texi
>>>> +++ b/gcc/doc/invoke.texi
>>>> @@ -10886,6 +10886,13 @@ Forces Pointer Bounds Checker to use narrowed
>>>> bounds for the address of the
>>>>  first field in the structure.  By default a pointer to the first field has
>>>>  the same bounds as a pointer to the whole structure.
>>>>
>>>> +@item -fchkp-flexible-struct-trailing-arrays
>>>> +@opindex fchkp-flexible-struct-trailing-arrays
>>>> +@opindex fno-chkp-flexible-struct-trailing-arrays
>>>> +Forces Pointer Bounds Checker to treat all trailing arrays in structures as
>>>> +possibly flexible.  By default only arrays fields with zero length or that are
>>>> +marked with attribute bnd_variable_size are treated as flexible.
>>>> +
>>>>  @item -fchkp-narrow-to-innermost-array
>>>>  @opindex fchkp-narrow-to-innermost-array
>>>>  @opindex fno-chkp-narrow-to-innermost-array
>>>> diff --git a/gcc/testsuite/gcc.target/i386/mpx/vla-trailing-1-lbv.c
>>>> b/gcc/testsuite/gcc.target/i386/mpx/vla-trailing-1-lbv.c
>>>> new file mode 100644
>>>> index 0000000..9739920
>>>> --- /dev/null
>>>> +++ b/gcc/testsuite/gcc.target/i386/mpx/vla-trailing-1-lbv.c
>>>> @@ -0,0 +1,29 @@
>>>> +/* { dg-do run } */
>>>> +/* { dg-shouldfail "bounds violation" } */
>>>> +/* { dg-options "-fcheck-pointer-bounds -mmpx
>>>> -fchkp-flexible-struct-trailing-arrays" } */
>>>> +
>>>> +
>>>> +#define SHOULDFAIL
>>>> +
>>>> +#include "mpx-check.h"
>>>> +
>>>> +struct S
>>>> +{
>>>> +  int a;
>>>> +  int p[10];
>>>> +};
>>>> +
>>>> +int rd (int *p, int i)
>>>> +{
>>>> +  int res = p[i];
>>>> +  printf ("%d\n", res);
>>>> +  return res;
>>>> +}
>>>> +
>>>> +int mpx_test (int argc, const char **argv)
>>>> +{
>>>> +  struct S *s = (struct S *)alloca (sizeof(struct S) + sizeof (int)*100);
>>>> +  rd (s->p, -2);
>>>> +
>>>> +  return 0;
>>>> +}
>>>> diff --git a/gcc/testsuite/gcc.target/i386/mpx/vla-trailing-1-nov.c
>>>> b/gcc/testsuite/gcc.target/i386/mpx/vla-trailing-1-nov.c
>>>> new file mode 100644
>>>> index 0000000..f5c8f95
>>>> --- /dev/null
>>>> +++ b/gcc/testsuite/gcc.target/i386/mpx/vla-trailing-1-nov.c
>>>> @@ -0,0 +1,29 @@
>>>> +/* { dg-do run } */
>>>> +/* { dg-options "-fcheck-pointer-bounds -mmpx
>>>> -fchkp-flexible-struct-trailing-arrays" } */
>>>> +
>>>> +
>>>> +#include "mpx-check.h"
>>>> +
>>>> +struct S
>>>> +{
>>>> +  int a;
>>>> +  int p[10];
>>>> +};
>>>> +
>>>> +int rd (int *p, int i)
>>>> +{
>>>> +  int res = p[i];
>>>> +  printf ("%d\n", res);
>>>> +  return res;
>>>> +}
>>>> +
>>>> +int mpx_test (int argc, const char **argv)
>>>> +{
>>>> +  struct S *s = (struct S *)alloca (sizeof(struct S) + sizeof (int)*100);
>>>> +  rd (s->p, 0);
>>>> +  rd (s->p, 99);
>>>> +  s->p[0];
>>>> +  s->p[99];
>>>> +
>>>> +  return 0;
>>>> +}
>>>> diff --git a/gcc/testsuite/gcc.target/i386/mpx/vla-trailing-1-ubv.c
>>>> b/gcc/testsuite/gcc.target/i386/mpx/vla-trailing-1-ubv.c
>>>> new file mode 100644
>>>> index 0000000..8385a5a
>>>> --- /dev/null
>>>> +++ b/gcc/testsuite/gcc.target/i386/mpx/vla-trailing-1-ubv.c
>>>> @@ -0,0 +1,29 @@
>>>> +/* { dg-do run } */
>>>> +/* { dg-shouldfail "bounds violation" } */
>>>> +/* { dg-options "-fcheck-pointer-bounds -mmpx
>>>> -fchkp-flexible-struct-trailing-arrays" } */
>>>> +
>>>> +
>>>> +#define SHOULDFAIL
>>>> +
>>>> +#include "mpx-check.h"
>>>> +
>>>> +struct S
>>>> +{
>>>> +  int a;
>>>> +  int p[10];
>>>> +};
>>>> +
>>>> +int rd (int *p, int i)
>>>> +{
>>>> +  int res = p[i];
>>>> +  printf ("%d\n", res);
>>>> +  return res;
>>>> +}
>>>> +
>>>> +int mpx_test (int argc, const char **argv)
>>>> +{
>>>> +  struct S *s = (struct S *)alloca (sizeof(struct S) + sizeof (int)*100);
>>>> +  rd (s->p, 110);
>>>> +
>>>> +  return 0;
>>>> +}
>>>> diff --git a/gcc/tree-chkp.c b/gcc/tree-chkp.c
>>>> index 2769682..6c5e541 100644
>>>> --- a/gcc/tree-chkp.c
>>>> +++ b/gcc/tree-chkp.c
>>>> @@ -3272,6 +3272,8 @@ chkp_may_narrow_to_field (tree field)
>>>>  {
>>>>    return DECL_SIZE (field) && TREE_CODE (DECL_SIZE (field)) == INTEGER_CST
>>>>      && tree_to_uhwi (DECL_SIZE (field)) != 0
>>>> +    && (!flag_chkp_flexible_struct_trailing_arrays
>>>> + || DECL_CHAIN (field))
>>>
>>> What if it's not array?
>>>
>>> Thanks,
>>> Ilya
>>>
>>>>      && (!DECL_FIELD_OFFSET (field)
>>>>   || TREE_CODE (DECL_FIELD_OFFSET (field)) == INTEGER_CST)
>>>>      && (!DECL_FIELD_BIT_OFFSET (field)
diff mbox

Patch

diff --git a/gcc/tree-chkp.c b/gcc/tree-chkp.c
index 2769682..6c7862c 100644
--- a/gcc/tree-chkp.c
+++ b/gcc/tree-chkp.c
@@ -3272,6 +3272,9 @@  chkp_may_narrow_to_field (tree field)
 {
   return DECL_SIZE (field) && TREE_CODE (DECL_SIZE (field)) == INTEGER_CST
     && tree_to_uhwi (DECL_SIZE (field)) != 0
+    && !(flag_chkp_flexible_struct_trailing_arrays
+ && TREE_CODE(TREE_TYPE(field)) == ARRAY_TYPE
+ && !DECL_CHAIN (field))
     && (!DECL_FIELD_OFFSET (field)
  || TREE_CODE (DECL_FIELD_OFFSET (field)) == INTEGER_CST)
     && (!DECL_FIELD_BIT_OFFSET (field)