Avoid assuming a VLA access specification string contains a closing bracket (PR middle-end/97189).

Resolves:
PR middle-end/97189 - ICE on redeclaration of a function with VLA argument and attribute access

gcc/ChangeLog:

	PR middle-end/97189
	* attribs.c (attr_access::array_as_string): Avoid assuming a VLA
	access specification string contains a closing bracket.

gcc/c-family/ChangeLog:

	PR middle-end/97189
	* c-attribs.c (append_access_attr): Use the function declaration
	location for a warning about an attribute access argument.

gcc/testsuite/ChangeLog:

	PR middle-end/97189
	* gcc.dg/attr-access-2.c: Adjust caret location.
	* gcc.dg/Wvla-parameter-6.c: New test.
	* gcc.dg/Wvla-parameter-7.c: New test.
This commit is contained in:
Martin Sebor 2020-09-30 12:58:09 -06:00
parent e808f3fdfa
commit 7dbc7ad524
5 changed files with 86 additions and 16 deletions

View file

@ -2270,11 +2270,11 @@ attr_access::array_as_string (tree type) const
bound is nonconstant and whose access string has "$]" in it)
extract the bound expression from SIZE. */
const char *p = end;
for ( ; *p-- != ']'; );
for ( ; p != str && *p-- != ']'; );
if (*p == '$')
index_type = build_index_type (TREE_VALUE (size));
}
else if (minsize)
else if (minsize)
index_type = build_index_type (size_int (minsize - 1));
tree arat = NULL_TREE;

View file

@ -4151,18 +4151,12 @@ append_access_attr (tree node[3], tree attrs, const char *attrstr,
"missing in previous designation",
attrstr);
else if (newa->internal_p || cura->internal_p)
{
/* Mismatch in the value of the size argument and a VLA
bound. */
location_t argloc = curloc;
if (tree arg = get_argument (node[2], newa->sizarg))
argloc = DECL_SOURCE_LOCATION (arg);
warned = warning_at (argloc, OPT_Wattributes,
"attribute %qs positional argument 2 "
"conflicts with previous designation "
"by argument %u",
attrstr, cura->sizarg + 1);
}
/* Mismatch in the value of the size argument and a VLA bound. */
warned = warning_at (curloc, OPT_Wattributes,
"attribute %qs positional argument 2 "
"conflicts with previous designation "
"by argument %u",
attrstr, cura->sizarg + 1);
else
/* Mismatch in the value of the size argument between two
explicit access attributes. */

View file

@ -0,0 +1,34 @@
/* PR middle-end/97189 - ICE on redeclaration of a function with VLA argument
and attribute access
Also verify the right arguments are underlined in the notes.
{ dg-do compile }
{ dg-options "-Wall -fdiagnostics-show-caret" } */
#define RW(...) __attribute__ ((access (read_write, __VA_ARGS__)))
RW (2, 3) void f1 (int n, int[n], int);
/* { dg-warning "attribute 'access \\(read_write, 2, 3\\)' positional argument 2 conflicts with previous designation by argument 3" "warning" { target *-*-* } .-1 }
{ dg-begin-multiline-output "" }
RW (2, 3) void f1 (int n, int[n], int);
^~
{ dg-end-multiline-output "" }
{ dg-message "designating the bound of variable length array argument 2" "note" { target *-*-* } .-6 }
{ dg-begin-multiline-output "" }
RW (2, 3) void f1 (int n, int[n], int);
~~~~^ ~~~~~~
{ dg-end-multiline-output "" } */
RW (2) void f2 (int, int[*], int);
/* { dg-message "previously declared as a variable length array 'int\\\[\\\*]'" "note" { target *-*-* } .-1 }
{ dg-begin-multiline-output "" }
RW (2, 3) void f2 (int, int[], int);
^~~~~
{ dg-end-multiline-output "" } */
RW (2, 3) void f2 (int, int[], int);
/* { dg-warning "argument 2 of type 'int\\\[]' declared as an ordinary array" "warning" { target *-*-* } .-1 }
{ dg-begin-multiline-output "" }
RW (2) void f2 (int, int[*], int);
^~~~~~
{ dg-end-multiline-output "" } */

View file

@ -0,0 +1,36 @@
/* PR middle-end/97189 - ICE on redeclaration of a function with VLA argument
and attribute access
{ dg-do compile }
{ dg-options "-Wall" } */
#define RW(...) __attribute__ ((access (read_write, __VA_ARGS__)))
RW (2, 3) void f1 (int n, int[n], int);
/* { dg-warning "attribute 'access \\(read_write, 2, 3\\)' positional argument 2 conflicts with previous designation by argument 3" "warning" { target *-*-* } .-1 }
{ dg-message "designating the bound of variable length array argument 2" "note" { target *-*-* } .-2 } */
void call_f1 (int *p)
{
/* Verify that a warning is issued. Ideally, it seems the VLA bound
should take precedence over the attribute and the warning would
reference argument 1 but since the conflict in the redeclarations
of the function is already diagnosed don't test that (and let it
be acceptable for this warning to reference argument 3). */
f1 (-1, p, -1);
// { dg-warning "argument \\d value -1 is negative" "warning" { target *-*-* } .-1 }
}
RW (2) void f2 (int, int[*], int);
// { dg-message "previously declared as a variable length array 'int\\\[\\\*]'" "note" { target *-*-* } .-1 }
RW (2, 3) void f2 (int, int[], int);
// { dg-warning "argument 2 of type 'int\\\[]' declared as an ordinary array" "warning" { target *-*-* } .-1 }
void call_f2 (int *p)
{
f2 (-1, p, 0);
/* Verify that the attribute access on the redeclaration of f2() takes
precedence over the one on the first declaration. */
f2 (0, p, -1);
// { dg-warning "argument 3 value -1 is negative" "warning" { target *-*-* } .-1 }
}

View file

@ -112,5 +112,11 @@ typedef void G1 (int n, int[n], int);
G1 g1;
RW (2, 3) void g1 (int n, int[n], int); // { dg-warning "24: attribute 'access *\\\(read_write, 2, 3\\\)' positional argument 2 conflicts with previous designation by argument 3" }
// { dg-message "designating the bound of variable length array argument 2" "note" { target *-*-* } .-1 }
/* The warning is about the attribute positional argument 2 which refers
to the last function argument. Ideally, the caret would be under
the corresponding function argument, i.e., the last one here) but
that location isn't available yet. Verify that the caret doesn't
point to function argument 1 which is the VLA bound (that's what
the caret in the note points to). */
RW (2, 3) void g1 (int n, int[n], int); // { dg-warning "16: attribute 'access *\\\(read_write, 2, 3\\\)' positional argument 2 conflicts with previous designation by argument 3" }
// { dg-message "24:designating the bound of variable length array argument 2" "note" { target *-*-* } .-1 }