diff mbox series

[v2] c: ICE in build_counted_by_ref [PR116735]

Message ID 20241002222219.1609430-1-qing.zhao@oracle.com
State New
Headers show
Series [v2] c: ICE in build_counted_by_ref [PR116735] | expand

Commit Message

Qing Zhao Oct. 2, 2024, 10:20 p.m. UTC
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
diff mbox series

Patch

diff --git a/gcc/c/c-decl.cc b/gcc/c/c-decl.cc
index aa7f69d1b7b..224c015cd6d 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 00000000000..5c6fedd0d3d
--- /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;
+}