diff options
author | qing zhao <qing.zhao@oracle.com> | 2024-09-30 18:29:29 +0000 |
---|---|---|
committer | Qing Zhao <qing.zhao@oracle.com> | 2024-10-07 16:02:50 +0000 |
commit | 9a17e6d03c6ed53e3b2dfd2c3ff9b1066ffa97b9 (patch) | |
tree | 647e41168fc9f2986c51d9a74f8995201a268e1f /gcc | |
parent | bc0ca75123b5996773628981a8bab865440fdf3c (diff) | |
download | gcc-9a17e6d03c6ed53e3b2dfd2c3ff9b1066ffa97b9.zip gcc-9a17e6d03c6ed53e3b2dfd2c3ff9b1066ffa97b9.tar.gz gcc-9a17e6d03c6ed53e3b2dfd2c3ff9b1066ffa97b9.tar.bz2 |
c: ICE in build_counted_by_ref [PR116735]
When handling the counted_by attribute, if the corresponding field
doesn't exit, in additiion to issue error, we should also remove
the already added non-existing "counted_by" attribute from the
field_decl.
PR c/116735
gcc/c/ChangeLog:
* c-decl.cc (verify_counted_by_attribute): Remove the attribute
when error.
gcc/testsuite/ChangeLog:
* gcc.dg/flex-array-counted-by-9.c: New test.
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/c/c-decl.cc | 32 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/flex-array-counted-by-9.c | 25 |
2 files changed, 43 insertions, 14 deletions
diff --git a/gcc/c/c-decl.cc b/gcc/c/c-decl.cc index aa7f69d..224c015 100644 --- a/gcc/c/c-decl.cc +++ b/gcc/c/c-decl.cc @@ -9502,14 +9502,17 @@ verify_counted_by_attribute (tree struct_type, tree field_decl) tree counted_by_field = lookup_field (struct_type, fieldname); - /* Error when the field is not found in the containing structure. */ + /* Error when the field is not found in the containing structure and + remove the corresponding counted_by attribute from the field_decl. */ if (!counted_by_field) - error_at (DECL_SOURCE_LOCATION (field_decl), - "argument %qE to the %qE attribute is not a field declaration" - " in the same structure as %qD", fieldname, - (get_attribute_name (attr_counted_by)), - field_decl); - + { + error_at (DECL_SOURCE_LOCATION (field_decl), + "argument %qE to the %<counted_by%> attribute" + " is not a field declaration in the same structure" + " as %qD", fieldname, field_decl); + DECL_ATTRIBUTES (field_decl) + = remove_attribute ("counted_by", DECL_ATTRIBUTES (field_decl)); + } else /* Error when the field is not with an integer type. */ { @@ -9518,14 +9521,15 @@ verify_counted_by_attribute (tree struct_type, tree field_decl) tree real_field = TREE_VALUE (counted_by_field); if (!INTEGRAL_TYPE_P (TREE_TYPE (real_field))) - error_at (DECL_SOURCE_LOCATION (field_decl), - "argument %qE to the %qE attribute is not a field declaration" - " with an integer type", fieldname, - (get_attribute_name (attr_counted_by))); - + { + error_at (DECL_SOURCE_LOCATION (field_decl), + "argument %qE to the %<counted_by%> attribute" + " is not a field declaration with an integer type", + fieldname); + DECL_ATTRIBUTES (field_decl) + = remove_attribute ("counted_by", DECL_ATTRIBUTES (field_decl)); + } } - - return; } /* TYPE is a struct or union that we're applying may_alias to after the body is diff --git a/gcc/testsuite/gcc.dg/flex-array-counted-by-9.c b/gcc/testsuite/gcc.dg/flex-array-counted-by-9.c new file mode 100644 index 0000000..5c6fedd --- /dev/null +++ b/gcc/testsuite/gcc.dg/flex-array-counted-by-9.c @@ -0,0 +1,25 @@ +/* PR c/116735 */ +/* { dg-options "-std=c99" } */ +/* { dg-do compile } */ + +struct foo { + int len; + int element[] __attribute__ ((__counted_by__ (lenx))); /* { dg-error "attribute is not a field declaration in the same structure as" } */ +}; + +struct bar { + float count; + int array[] __attribute ((counted_by (count))); /* { dg-error "attribute is not a field declaration with an integer type" } */ +}; + +int main () +{ + struct foo *p = __builtin_malloc (sizeof (struct foo) + 3 * sizeof (int)); + struct bar *q = __builtin_malloc (sizeof (struct bar) + 3 * sizeof (int)); + p->len = 3; + p->element[0] = 17; + p->element[1] = 13; + q->array[0] = 13; + q->array[2] = 17; + return 0; +} |