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

Reply via email to