Hi,

This is the 4th version of the patch set to extend "counted_by" attribute
 to pointer fields of structures.

compared to the 3rd version:

https://gcc.gnu.org/pipermail/gcc-patches/2025-April/682310.html
https://gcc.gnu.org/pipermail/gcc-patches/2025-April/682312.html
https://gcc.gnu.org/pipermail/gcc-patches/2025-April/682311.html
https://gcc.gnu.org/pipermail/gcc-patches/2025-April/682313.html

The major change are:

A. Explicitly disallow counted_by attribute for a void * field. Report error
for such cases. Delete the support for void * from both __bdos and bound
sanitizer.

B. Some refactoring on the 3rd patch, bound santizer to make it easierly to
be understood.

C. Bug fixes on the 3rd patch to fix a bug in bound santizer Kees reported 
when he run the 3rd version on his testing suites.


This patch set includes 3 parts:

1.Extend "counted_by" attribute to pointer fields of structures. 
2.Convert a pointer reference with counted_by attribute to .ACCESS_WITH_SIZE
    and use it in builtinin-object-size.
3.Use the counted_by attribute of pointers in array bound checker.

In which, the patch 1 and 2 are simple and straightforward, however, the patch 
3  
is a little complicate due to the following reason:

    Current array bound checker only instruments ARRAY_REF, and the INDEX
    information is the 2nd operand of the ARRAY_REF.
    
    When extending the array bound checker to pointer references with
    counted_by attributes, the hardest part is to get the INDEX of the
    corresponding array ref from the offset computation expression of
    the pointer ref. 

I have done some study on the other appraoch I thought previously, and realized
that the current implementation might be better. Please see the following
https://gcc.gnu.org/pipermail/gcc-patches/2025-May/683136.html
for details.

The whole patch set has been bootstrapped and regression tested on both
 aarch64 and x86.

Okay for trunk?
 
Thanks a lot.

Qing

========================================================


the first version was submitted 4 months ago on 1/16/2025, and triggered
a lot of discussion on whether we need a new syntax for counted_by
attribute.

https://gcc.gnu.org/pipermail/gcc-patches/2025-January/673837.html

After a long discussion since then: 
(https://gcc.gnu.org/pipermail/gcc-patches/2025-March/677024.html)

We agreed to the following compromised solution:

1. Keep the current syntax of counted_by for lone identifier;
2. Add a new attribute "counted_by_exp" for expressions.

Although there are still some discussion going on for the new 
counted_by_exp attribute (In Clang community) 
https://discourse.llvm.org/t/rfc-bounds-safety-in-c-syntax-compatibility-with-gcc/85885

The syntax for the lone identifier is kept the same as before.

So, I'd like to resubmit my previous patch of extending "counted_by"
to pointer fields of structures. 

The whole patch set has been rebased on the latest trunk, some testing case
adjustment,  bootstrapped  and regression tested on both aarch64 and x86.

There will be a seperate patch set for the new "counted_by_exp" 
attribute later to cover the expressions cases.

The following are more details on this patch set:

For example:

struct PP {
  size_t count2;
  char other1;
  char *array2 __attribute__ ((counted_by (count2)));
  int other2;
} *pp;

specifies that the "array2" is an array that is pointed by the
pointer field, and its number of elements is given by the field
"count2" in the same structure.

There are the following important facts about "counted_by" on pointer
fields compared to the "counted_by" on FAM fields:

1. one more new requirement for pointer fields with "counted_by" attribute:
   pp->array2 and pp->count2 can ONLY be changed by changing the whole structure
   at the same time.

2. the following feature for FAM field with "counted_by" attribute is NOT
   valid for the pointer field any more:

    " One important feature of the attribute is, a reference to the
     flexible array member field uses the latest value assigned to the
     field that represents the number of the elements before that
     reference.  For example,

            p->count = val1;
            p->array[20] = 0;  // ref1 to p->array
            p->count = val2;
            p->array[30] = 0;  // ref2 to p->array

     in the above, 'ref1' uses 'val1' as the number of the elements in
     'p->array', and 'ref2' uses 'val2' as the number of elements in
     'p->array'. "

Reply via email to