diff mbox series

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

Message ID 398ec06f-d735-36a8-a3d7-3903d16d4e10@gmail.com
State New
Headers show
Series wrap long tree chains in a list to avoid attribute error (PR 97413) | expand

Commit Message

Martin Sebor Oct. 14, 2020, 8:09 p.m. UTC
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

Comments

Jeff Law Oct. 14, 2020, 8:31 p.m. UTC | #1
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
diff mbox series

Patch

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 <node> 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 <node>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 00000000000..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, 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);
+
+
+  typedef int B[n][n + 1][n + 2][n + 3][n + 4][n + 5][n + 7];
+
+  void h1 (B);
+  void h2 (B, B);
+  void h3 (B, B, B);
+  void h4 (B, B, B, B);
+  void h5 (B, B, B, B, B);
+  void h6 (B, B, B, B, B, B);
+  void h7 (B, B, B, B, B, B, B);
+  void h8 (B, B, B, B, B, B, B, B);
+  void h9 (B, B, B, B, B, B, B, B, B);
+  void h10 (B, B, B, B, B, B, B, B, B, B);
+
+  void h1 (B);
+  void h2 (B, B);
+  void h3 (B, B, B);
+  void h4 (B, B, B, B);
+  void h5 (B, B, B, B, B);
+  void h6 (B, B, B, B, B, B);
+  void h7 (B, B, B, B, B, B, B);
+  void h8 (B, B, B, B, B, B, B, B);
+  void h9 (B, B, B, B, B, B, B, B, B);
+  void h10 (B, B, B, B, B, B, B, B, B, B);
+}