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/
20251021095447.GL3245006@noisy.programming.kicks-ass.net/
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.
" 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
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),
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
--- /dev/null
+/* 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" } */
+};
--- /dev/null
+/* 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"
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 {