From eb2a917fa0779b689f09ac8d8c41b0456facbe62 Mon Sep 17 00:00:00 2001 From: Martin Sebor Date: Wed, 19 May 2021 16:13:13 -0600 Subject: [PATCH] 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. --- gcc/c-family/c-attribs.c | 36 +++++++++++++++++++++++---------- gcc/testsuite/gcc.dg/pr100619.c | 24 ++++++++++++++++++++++ 2 files changed, 49 insertions(+), 11 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/pr100619.c diff --git a/gcc/c-family/c-attribs.c b/gcc/c-family/c-attribs.c index ecb32c70172..ccf9e4ccf0b 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); + { + size_t specend = spec.length (); + if (!specend) + { + spec = '+'; + specend = 1; + } - if (!spec.length ()) - spec += '+'; - - 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 [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 00000000000..5df02bdb820 --- /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" }