PR c/100619 - ICE on a VLA parameter with too many dimensions
authorMartin Sebor <msebor@redhat.com>
Wed, 19 May 2021 22:13:13 +0000 (16:13 -0600)
committerMartin Sebor <msebor@redhat.com>
Wed, 19 May 2021 22:13:13 +0000 (16:13 -0600)
gcc/c-family/ChangeLog:

PR c/100619
* c-attribs.c (build_attr_access_from_parms): Handle arbitrarily many
bounds.

gcc/testsuite/ChangeLog:

PR c/100619
* gcc.dg/pr100619.c: New test.

gcc/c-family/c-attribs.c
gcc/testsuite/gcc.dg/pr100619.c [new file with mode: 0644]

index ecb32c7..ccf9e4c 100644 (file)
@@ -5043,16 +5043,25 @@ build_attr_access_from_parms (tree parms, bool skip_voidptr)
       /* Create the attribute access string from the arg spec string,
         optionally followed by position of the VLA bound argument if
         it is one.  */
-      char specbuf[80];
-      int len = snprintf (specbuf, sizeof specbuf, "%c%u%s",
-                         attr_access::mode_chars[access_deferred],
-                         argpos, s);
-      gcc_assert ((size_t) len < sizeof specbuf);
-
-      if (!spec.length ())
-       spec += '+';
+      {
+       size_t specend = spec.length ();
+       if (!specend)
+         {
+           spec = '+';
+           specend = 1;
+         }
 
-      spec += specbuf;
+       /* Format the access string in place.  */
+       int len = snprintf (NULL, 0, "%c%u%s",
+                           attr_access::mode_chars[access_deferred],
+                           argpos, s);
+       spec.resize (specend + len + 1);
+       sprintf (&spec[specend], "%c%u%s",
+                attr_access::mode_chars[access_deferred],
+                argpos, s);
+       /* Trim the trailing NUL.  */
+       spec.resize (specend + len);
+      }
 
       /* The (optional) list of expressions denoting the VLA bounds
         N in ARGTYPE <arg>[Ni]...[Nj]...[Nk].  */
@@ -5077,8 +5086,13 @@ build_attr_access_from_parms (tree parms, bool skip_voidptr)
                {
                  /* BOUND previously seen in the parameter list.  */
                  TREE_PURPOSE (vb) = size_int (*psizpos);
-                 sprintf (specbuf, "$%u", *psizpos);
-                 spec += specbuf;
+                 /* Format the position string in place.  */
+                 int len = snprintf (NULL, 0, "$%u", *psizpos);
+                 size_t specend = spec.length ();
+                 spec.resize (specend + len + 1);
+                 sprintf (&spec[specend], "$%u", *psizpos);
+                 /* Trim the trailing NUL.  */
+                 spec.resize (specend + len);
                }
              else
                {
diff --git a/gcc/testsuite/gcc.dg/pr100619.c b/gcc/testsuite/gcc.dg/pr100619.c
new file mode 100644 (file)
index 0000000..5df02bd
--- /dev/null
@@ -0,0 +1,24 @@
+/* PR c/100619 - ICE on a VLA parameter with too many dimensions
+   { dg-do compile }
+   { dg-options "-Wall" } */
+
+extern int n;
+
+#define A10     [n][n][n][n][n][n][n][n][n][n]
+#define A100    A10 A10 A10 A10 A10 A10 A10 A10 A10 A10 A10
+#define A1000   A100 A100 A100 A100 A100 A100 A100 A100 A100 A100 A100
+
+void f10 (int A10);
+void f10 (int A10);
+
+void f100 (int A100);
+void f100 (int A100);
+
+void f1000 (int A1000);
+void f1000 (int A1000);
+
+void fx_1000 (int [ ]A1000);
+void fx_1000 (int [1]A1000);        // { dg-warning "-Warray-parameter" }
+
+void fn_1000 (int [n    ]A1000);
+void fn_1000 (int [n + 1]A1000);    // { dg-warning "-Wvla-parameter" }