@@ -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
new file mode 100644
@@ -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;
+}
From: qing zhao <qing.zhao@oracle.com> Hi, this is the 2nd version of the patch. compared to the 1st version, the major changes are to address Marek and Jacub's comments. bootstrapped and regression tested on both x86 and aarch64. Okay for committing? thanks. Qing ====================== 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. --- gcc/c/c-decl.cc | 32 +++++++++++-------- .../gcc.dg/flex-array-counted-by-9.c | 25 +++++++++++++++ 2 files changed, 43 insertions(+), 14 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/flex-array-counted-by-9.c