aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorqing zhao <qing.zhao@oracle.com>2024-09-30 18:29:29 +0000
committerQing Zhao <qing.zhao@oracle.com>2024-10-07 16:02:50 +0000
commit9a17e6d03c6ed53e3b2dfd2c3ff9b1066ffa97b9 (patch)
tree647e41168fc9f2986c51d9a74f8995201a268e1f /gcc
parentbc0ca75123b5996773628981a8bab865440fdf3c (diff)
downloadgcc-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.cc32
-rw-r--r--gcc/testsuite/gcc.dg/flex-array-counted-by-9.c25
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;
+}