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" }