Re: [PATCH] wrap long tree chains in a list to avoid attribute error (PR 97413)

2020-10-14 Thread Jeff Law via Gcc-patches


On 10/14/20 2:09 PM, Martin Sebor via Gcc-patches wrote:
> The attribute access implicitly added to function declarations
> with VLA parameters includes the top-level VLA bounds chained
> together similarly to other attribute arguments.  However,
> since attribute access is limited to at most 3 arguments
> including the mode, a function that takes three or more VLA
> arguments triggers an error from decl_attributes complaining
> about excess arguments.
>
> The attached patch gets around it by wrapping the VLA bound
> chain in a list.  It doesn't feel like the most elegant solution
> but it's simple and  I couldn't think of anything better.  If no
> one comes up with a suggestion for a better way of dealing with
> this I'll commit the fix sometime tomorrow as obvious.
>
> Martin
>
>
> gcc-97413.diff
>
> PR c/97413 - bogus error on function declaration with many VLA arguments
>
> gcc/ChangeLog:
>
>   PR c/97413
>   * attribs.c (init_attr_rdwr_indices): Unwrap extra list layer.
>
> gcc/c-family/ChangeLog:
>
>   PR c/97413
>   * c-attribs.c (build_attr_access_from_parms): Wrap chain of VLA
>   bounds in an extra list.
>
> gcc/testsuite/ChangeLog:
>
>   PR c/97413
>   * gcc.dg/Wvla-parameter-8.c: New test.

So as I mentioned in IRC, at the time you posted this I had just
extracted a testcase from a package build failure.  Your timing was
impeccable to get my immediate attention :-)


OK.


jeff



[PATCH] wrap long tree chains in a list to avoid attribute error (PR 97413)

2020-10-14 Thread Martin Sebor via Gcc-patches

The attribute access implicitly added to function declarations
with VLA parameters includes the top-level VLA bounds chained
together similarly to other attribute arguments.  However,
since attribute access is limited to at most 3 arguments
including the mode, a function that takes three or more VLA
arguments triggers an error from decl_attributes complaining
about excess arguments.

The attached patch gets around it by wrapping the VLA bound
chain in a list.  It doesn't feel like the most elegant solution
but it's simple and  I couldn't think of anything better.  If no
one comes up with a suggestion for a better way of dealing with
this I'll commit the fix sometime tomorrow as obvious.

Martin

PR c/97413 - bogus error on function declaration with many VLA arguments

gcc/ChangeLog:

	PR c/97413
	* attribs.c (init_attr_rdwr_indices): Unwrap extra list layer.

gcc/c-family/ChangeLog:

	PR c/97413
	* c-attribs.c (build_attr_access_from_parms): Wrap chain of VLA
	bounds in an extra list.

gcc/testsuite/ChangeLog:

	PR c/97413
	* gcc.dg/Wvla-parameter-8.c: New test.

diff --git a/gcc/attribs.c b/gcc/attribs.c
index 94b9e02699f..3bdb2ffda81 100644
--- a/gcc/attribs.c
+++ b/gcc/attribs.c
@@ -2049,6 +2049,8 @@ init_attr_rdwr_indices (rdwr_map *rwm, tree attrs)
 
   /* The (optional) list of VLA bounds.  */
   tree vblist = TREE_CHAIN (mode);
+  if (vblist)
+   vblist = TREE_VALUE (vblist);
 
   mode = TREE_VALUE (mode);
   if (TREE_CODE (mode) != STRING_CST)
diff --git a/gcc/c-family/c-attribs.c b/gcc/c-family/c-attribs.c
index c779d13f023..8283e959c89 100644
--- a/gcc/c-family/c-attribs.c
+++ b/gcc/c-family/c-attribs.c
@@ -4547,10 +4547,11 @@ handle_access_attribute (tree node[3], tree name, tree args,
result in the following attribute access:
 
  value: "+^2[*],$0$1^3[*],$1$1"
- chain: <0, x> <1, y>
+ list:  < <0, x> <1, y> >
 
-   where each  on the chain corresponds to one VLA bound for each
-   of the two parameters.  */
+   where the list has a single value which itself is is a list each
+   of whose s corresponds to one VLA bound for each of the two
+   parameters.  */
 
 tree
 build_attr_access_from_parms (tree parms, bool skip_voidptr)
@@ -4654,13 +4655,17 @@ build_attr_access_from_parms (tree parms, bool skip_voidptr)
   if (!spec.length ())
 return NULL_TREE;
 
+  /* Attribute access takes a two or three arguments.  Wrap VBLIST in
+ another list in case it has more nodes than would otherwise fit.  */
+vblist = build_tree_list (NULL_TREE, vblist);
+
   /* Build a single attribute access with the string describing all
  array arguments and an optional list of any non-parameter VLA
  bounds in order.  */
   tree str = build_string (spec.length (), spec.c_str ());
   tree attrargs = tree_cons (NULL_TREE, str, vblist);
   tree name = get_identifier ("access");
-  return tree_cons (name, attrargs, NULL_TREE);
+  return build_tree_list (name, attrargs);
 }
 
 /* Handle a "nothrow" attribute; arguments as in
diff --git a/gcc/testsuite/gcc.dg/Wvla-parameter-8.c b/gcc/testsuite/gcc.dg/Wvla-parameter-8.c
new file mode 100644
index 000..11e417df7e6
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/Wvla-parameter-8.c
@@ -0,0 +1,86 @@
+/* PR c/97413 - bogus error on function declaration with many VLA arguments:
+   wrong number of arguments specified for 'access' attribute
+   { dg-do compile }
+   { dg-options "-Wall" } */
+
+extern int n;
+
+void f1 (int[n]);
+void f2 (int[n], int[n]);
+void f3 (int[n], int[n], int[n]);
+void f4 (int[n], int[n], int[n], int[n]);
+void f5 (int[n], int[n], int[n], int[n], int[n]);
+void f6 (int[n], int[n], int[n], int[n], int[n], int[n]);
+void f7 (int[n], int[n], int[n], int[n], int[n], int[n], int[n]);
+void f8 (int[n], int[n], int[n], int[n], int[n], int[n], int[n], int[n]);
+void f9 (int[n], int[n], int[n], int[n], int[n], int[n], int[n], int[n],
+	 int[n]);
+void f10 (int[n], int[n], int[n], int[n], int[n], int[n], int[n], int[n],
+	  int[n], int[n]);
+
+
+void f1 (int[n]);
+void f2 (int[n], int[n]);
+void f3 (int[n], int[n], int[n]);
+void f4 (int[n], int[n], int[n], int[n]);
+void f5 (int[n], int[n], int[n], int[n], int[n]);
+void f6 (int[n], int[n], int[n], int[n], int[n], int[n]);
+void f7 (int[n], int[n], int[n], int[n], int[n], int[n], int[n]);
+void f8 (int[n], int[n], int[n], int[n], int[n], int[n], int[n], int[n]);
+void f9 (int[n], int[n], int[n], int[n], int[n], int[n], int[n], int[n],
+	 int[n]);
+void f10 (int[n], int[n], int[n], int[n], int[n], int[n], int[n], int[n],
+	  int[n], int[n]);
+
+
+void g (int n)
+{
+  typedef int A[n];
+
+  void g1 (A);
+  void g2 (A, A);
+  void g3 (A, A, A);
+  void g4 (A, A, A, A);
+  void g5 (A, A, A, A, A);
+  void g6 (A, A, A, A, A, A);
+  void g7 (A, A, A, A, A, A, A);
+  void g8 (A, A, A, A, A, A, A, A);
+  void g9 (A, A, A, A, A, A, A, A, A);
+  void g10 (A, A, A, A, A, A, A, A, A, A);
+
+  void g1 (A);
+  void g2 (A, A);
+  void g3 (A, A, A);
+  void g4 (A, A, A,