aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Sebor <msebor@redhat.com>2021-05-19 16:13:13 -0600
committerMartin Sebor <msebor@redhat.com>2021-05-19 16:13:13 -0600
commiteb2a917fa0779b689f09ac8d8c41b0456facbe62 (patch)
tree6bfff1209e0215811ca4c0c230bc7c2c684d1b24
parentdc6758f03effbf7d6946d8c314576c7a6c0003af (diff)
downloadgcc-eb2a917fa0779b689f09ac8d8c41b0456facbe62.zip
gcc-eb2a917fa0779b689f09ac8d8c41b0456facbe62.tar.gz
gcc-eb2a917fa0779b689f09ac8d8c41b0456facbe62.tar.bz2
PR c/100619 - ICE on a VLA parameter with too many dimensions
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.
-rw-r--r--gcc/c-family/c-attribs.c36
-rw-r--r--gcc/testsuite/gcc.dg/pr100619.c24
2 files changed, 49 insertions, 11 deletions
diff --git a/gcc/c-family/c-attribs.c b/gcc/c-family/c-attribs.c
index ecb32c7..ccf9e4c 100644
--- a/gcc/c-family/c-attribs.c
+++ b/gcc/c-family/c-attribs.c
@@ -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
index 0000000..5df02bd
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr100619.c
@@ -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" }