aboutsummaryrefslogtreecommitdiff
path: root/libjava/java
diff options
context:
space:
mode:
authorQing Zhao <qing.zhao@oracle.com>2025-08-14 20:22:20 +0000
committerQing Zhao <qing.zhao@oracle.com>2025-08-15 15:27:41 +0000
commitbddb7b252896906056345b7db87f8d01eb2d1ac1 (patch)
tree07d5996aaa8bb72e27f45ded48b2cb42370212eb /libjava/java
parentef5f0e9c510231d56aebdaa1a3db9b41a962d23c (diff)
downloadgcc-bddb7b252896906056345b7db87f8d01eb2d1ac1.zip
gcc-bddb7b252896906056345b7db87f8d01eb2d1ac1.tar.gz
gcc-bddb7b252896906056345b7db87f8d01eb2d1ac1.tar.bz2
Extend "counted_by" attribute to pointer fields of structures. Convert a pointer reference with counted_by attribute to .ACCESS_WITH_SIZE. Fix PR120929.
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. In order to fix PR120929, we agreed on the following solution: for a pointer field with counted_by attribute: struct S { int n; int *p __attribute__((counted_by(n))); } *f; when generating call to .ACCESS_WITH_SIZE for f->p, instead of generating *.ACCESS_WITH_SIZE (&f->p, &f->n,...) We should generate .ACCESS_WITH_SIZE (f->p, &f->n,...) i.e., the return type and the type of the first argument of the call is the original pointer type in this version. However, this code generation might bring undefined behavior into the applicaiton if the call to .ACCESS_WITH_SIZE is generated for a pointer field reference when this refernece is written to. For example: f->p = malloc (size); ***** the IL for the above is: tmp1 = f->p; tmp2 = &f->n; tmp3 = .ACCESS_WITH_SIZE (tmp1, tmp2, ...); tmp4 = malloc (size); tmp3 = tmp4; In the above, in order to generate a call to .ACCESS_WITH_SIZE for the pointer reference f->p, the new GIMPLE tmp1 = f->p is necessary to pass the value of the pointer f->p to the call to .ACCESS_WITH_SIZE. However, this new GIMPLE is the one that brings UB into the application since the value of f->p is not initialized yet when it is assigned to "tmp1". the above IL will be expanded to the following when .ACCESS_WITH_SIZE is expanded to its first argument: tmp1 = f->p; tmp2 = &f->n; tmp3 = tmp1; tmp4 = malloc (size); tmp3 = tmp4; the final optimized IL will be: tmp3 = f->p; tmp3 = malloc (size);; As a result, the f->p will NOT be set correctly to the pointer returned by malloc (size). Due to this potential issue, We will need to selectively generate the call to .ACCESS_WITH_SIZE for f->p according to whether it's a read or a write. We will only generate call to .ACCESS_WITH_SIZE for f->p when it's a read in C FE. gcc/c-family/ChangeLog: * c-attribs.cc (handle_counted_by_attribute): Accept counted_by attribute for pointer fields. gcc/c/ChangeLog: * c-decl.cc (verify_counted_by_attribute): Change the 2nd argument to a vector of fields with counted_by attribute. Verify all fields in this vector. (finish_struct): Collect all the fields with counted_by attribute to a vector and pass this vector to verify_counted_by_attribute. * c-tree.h (handle_counted_by_for_component_ref): New prototype of handle_counted_by_form_component_ref. * c-parser.cc (c_parser_postfix_expression): Call the new prototype of handle_counted_by_for_component_ref. * c-typeck.cc (default_function_array_read_conversion): Only generate call to .ACCESS_WITH_SIZE for a pointer field when it's a read. (convert_lvalue_to_rvalue): Likewise. (default_conversion): Likewise. (handle_counted_by_p): New routine. (check_counted_by_attribute): New routine. (build_counted_by_ref): Handle pointers with counted_by. (build_access_with_size_for_counted_by): Handle pointers with counted_by. (handle_counted_by_for_component_ref): Add one more argument. (build_component_ref): Call the new prototype of handle_counted_by_for_component_ref. gcc/ChangeLog: * doc/extend.texi: Extend counted_by attribute to pointer fields in structures. Add one more requirement to pointers with counted_by attribute. gcc/testsuite/ChangeLog: * gcc.dg/flex-array-counted-by.c: Update test. * gcc.dg/pointer-counted-by-1.c: New test. * gcc.dg/pointer-counted-by-2.c: New test. * gcc.dg/pointer-counted-by-3.c: New test. * gcc.dg/pointer-counted-by-8.c: New test. * gcc.dg/pointer-counted-by-9.c: New test. * gcc.dg/pointer-counted-by.c: New test.
Diffstat (limited to 'libjava/java')
0 files changed, 0 insertions, 0 deletions