Hi, this is the 2nd version of the patch. compared to the first version, the major change is the update based on Joseph's comments:
support ???counted_by??? for VOID pointer by default, but issue warnings when -Wpointer-arith is presenting. the patch has been bootstrapped and regression tested on both x86 and aarch64. Okay for committing? thanks. Qing ================================= This extension is requested by linux kernel to ease the adoption of counted_by attribute into linux kernel. Please refer to https://lore.kernel.org/lkml/[email protected]/ for the initial request for this feature. The attribute is allowed for a pointer to void, However, Warnings will be issued for such cases when -Wpointer-arith is specified. When this attribute is applied on a pointer to void, the size of each element of this pointer array is treated as 1. gcc/c-family/ChangeLog: * c-attribs.cc (handle_counted_by_attribute): Allow counted_by for void pointer. Issue warnings when -Wpointer-arith is present. gcc/c/ChangeLog: * c-typeck.cc (build_access_with_size_for_counted_by): When the element type is void, assign size one as the element_size. gcc/ChangeLog: * doc/extend.texi: Clarification when the counted_by attribute is applied on a void pointer. gcc/testsuite/ChangeLog: * gcc.dg/pointer-counted-by.c: Update for void pointers. * gcc.dg/pointer-counted-by-10.c: New test. * gcc.dg/pointer-counted-by-4-void.c: New test. --- gcc/c-family/c-attribs.cc | 12 +++++++----- gcc/c/c-typeck.cc | 5 ++++- gcc/doc/extend.texi | 15 ++++++++++----- gcc/testsuite/gcc.dg/pointer-counted-by-10.c | 8 ++++++++ gcc/testsuite/gcc.dg/pointer-counted-by-4-void.c | 6 ++++++ gcc/testsuite/gcc.dg/pointer-counted-by.c | 3 ++- 6 files changed, 37 insertions(+), 12 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/pointer-counted-by-10.c create mode 100644 gcc/testsuite/gcc.dg/pointer-counted-by-4-void.c diff --git a/gcc/c-family/c-attribs.cc b/gcc/c-family/c-attribs.cc index 8ca767abbeb..28a034f6c06 100644 --- a/gcc/c-family/c-attribs.cc +++ b/gcc/c-family/c-attribs.cc @@ -2963,14 +2963,16 @@ handle_counted_by_attribute (tree *node, tree name, " array member field", name); *no_add_attrs = true; } - /* This attribute cannot be applied to a pointer to void type. */ + /* This attribute can be applied to a pointer to void type, but issue + warning when -Wpointer-arith is presenting. */ else if (TREE_CODE (TREE_TYPE (decl)) == POINTER_TYPE && TREE_CODE (TREE_TYPE (TREE_TYPE (decl))) == VOID_TYPE) { - error_at (DECL_SOURCE_LOCATION (decl), - "%qE attribute is not allowed for a pointer to void", - name); - *no_add_attrs = true; + if (warn_pointer_arith) + warning_at (DECL_SOURCE_LOCATION (decl), + OPT_Wpointer_arith, + "%qE attribute is used for a pointer to void", + name); } /* This attribute cannot be applied to a pointer to function type. */ else if (TREE_CODE (TREE_TYPE (decl)) == POINTER_TYPE diff --git a/gcc/c/c-typeck.cc b/gcc/c/c-typeck.cc index 371583bd64e..bc0fb6b59e5 100644 --- a/gcc/c/c-typeck.cc +++ b/gcc/c/c-typeck.cc @@ -3179,7 +3179,10 @@ build_access_with_size_for_counted_by (location_t loc, tree ref, tree result_type = is_fam ? c_build_pointer_type (TREE_TYPE (ref)) : TREE_TYPE (ref); - tree element_size = TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (ref))); + tree element_type = TREE_TYPE (TREE_TYPE (ref)); + tree element_size = VOID_TYPE_P (element_type) + ? build_one_cst (size_type_node) + : TYPE_SIZE_UNIT (element_type); tree first_param = is_fam ? c_fully_fold (array_to_pointer_conversion (loc, ref), diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi index 94b76b75565..3a8a2e49a44 100644 --- a/gcc/doc/extend.texi +++ b/gcc/doc/extend.texi @@ -7312,11 +7312,16 @@ the attribute. When the field that represents the number of the elements is assigned a negative integer value, the compiler treats the value as zero. -The @code{counted_by} attribute is not allowed for a pointer to @code{void}, -a pointer to function, or a pointer to a structure or union that includes -a flexible array member. However, it is allowed for a pointer to -non-void incomplete structure or union types, as long as the type could -be completed before the first reference to the pointer. +The @code{counted_by} attribute is not allowed for a pointer to function, +or a pointer to a structure or union that includes a flexible array member. +However, it is allowed for a pointer to non-void incomplete structure +or union types, as long as the type could be completed before the first +reference to the pointer. + +The attribute is allowed for a pointer to @code{void}. However, +warnings will be issued for such cases when @option{-Wpointer-arith} is +specified. When this attribute is applied on a pointer to @code{void}, +the size of each element of this pointer array is treated as 1. An explicit @code{counted_by} annotation defines a relationship between two objects, @code{p->array} and @code{p->count}, and there are the diff --git a/gcc/testsuite/gcc.dg/pointer-counted-by-10.c b/gcc/testsuite/gcc.dg/pointer-counted-by-10.c new file mode 100644 index 00000000000..e2bd018a90b --- /dev/null +++ b/gcc/testsuite/gcc.dg/pointer-counted-by-10.c @@ -0,0 +1,8 @@ +/* Testing the correct usage of attribute counted_by for pointer to void. */ +/* { dg-do compile } */ +/* { dg-options "-O0 -Wpointer-arith" } */ + +struct pointer_array { + int count; + void *array __attribute__ ((counted_by (count))); /* { dg-warning "attribute is used for a pointer to void" } */ +}; diff --git a/gcc/testsuite/gcc.dg/pointer-counted-by-4-void.c b/gcc/testsuite/gcc.dg/pointer-counted-by-4-void.c new file mode 100644 index 00000000000..71bac95dfb2 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pointer-counted-by-4-void.c @@ -0,0 +1,6 @@ +/* Test the attribute counted_by for pointer field and its usage in + * __builtin_dynamic_object_size. */ +/* { dg-do run } */ +/* { dg-options "-O2" } */ +#define PTR_TYPE void +#include "pointer-counted-by-4.c" diff --git a/gcc/testsuite/gcc.dg/pointer-counted-by.c b/gcc/testsuite/gcc.dg/pointer-counted-by.c index 0f18828ac11..5e9ebef4ce5 100644 --- a/gcc/testsuite/gcc.dg/pointer-counted-by.c +++ b/gcc/testsuite/gcc.dg/pointer-counted-by.c @@ -49,9 +49,10 @@ struct pointer_array_6 { int *array_6 __attribute__ ((counted_by (days))); }; +/* counted_by is allowed for pointer to void when GNU extension is enabled. */ struct pointer_array_7 { int count; - void *array_7 __attribute__ ((counted_by (count))); /* { dg-error "attribute is not allowed for a pointer to void" } */ + void *array_7 __attribute__ ((counted_by (count))); }; struct pointer_array_8 { -- 2.31.1
