https://gcc.gnu.org/g:6951e953e01a91333bacecb9609ca12f7d83af0a

commit r16-4743-g6951e953e01a91333bacecb9609ca12f7d83af0a
Author: Qing Zhao <[email protected]>
Date:   Fri Oct 24 18:02:06 2025 +0000

    Extend the attribute "counted_by" to support VOID pointer under GNU 
extension.
    
    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.

Diff:
---
 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(-)

diff --git a/gcc/c-family/c-attribs.cc b/gcc/c-family/c-attribs.cc
index 8ca767abbeba..28a034f6c065 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 371583bd64ed..bc0fb6b59e55 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 882c0820a6e6..8aaedaeb3b30 100644
--- a/gcc/doc/extend.texi
+++ b/gcc/doc/extend.texi
@@ -7311,11 +7311,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 000000000000..e2bd018a90b7
--- /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 000000000000..71bac95dfb24
--- /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 0f18828ac113..5e9ebef4ce5b 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 {

Reply via email to