PR c/100719 - missing -Wvla-parameter on a mismatch in second parameter

gcc/ChangeLog:

	* attribs.c (init_attr_rdwr_indices): Use VLA bounds in the expected
	order.
	(attr_access::vla_bounds): Also handle VLA bounds.

gcc/c-family/ChangeLog:

	* c-warn.c (warn_parm_array_mismatch): Check TREE_PURPOSE to test
	for element presence.

gcc/testsuite/ChangeLog:

	* gcc.dg/Wvla-parameter-10.c: New test.
	* gcc.dg/Wvla-parameter-11.c: New test.
This commit is contained in:
Martin Sebor 2021-06-04 10:35:27 -06:00
parent 1b51f038cf
commit c6503fa93b
4 changed files with 153 additions and 8 deletions

View File

@ -2126,14 +2126,14 @@ init_attr_rdwr_indices (rdwr_map *rwm, tree attrs)
/* The (optional) list of VLA bounds. */
tree vblist = TREE_CHAIN (mode);
if (vblist)
vblist = TREE_VALUE (vblist);
mode = TREE_VALUE (mode);
if (TREE_CODE (mode) != STRING_CST)
continue;
gcc_assert (TREE_CODE (mode) == STRING_CST);
if (vblist)
vblist = nreverse (copy_list (TREE_VALUE (vblist)));
for (const char *m = TREE_STRING_POINTER (mode); *m; )
{
attr_access acc = { };
@ -2308,11 +2308,18 @@ attr_access::to_external_string () const
unsigned
attr_access::vla_bounds (unsigned *nunspec) const
{
unsigned nbounds = 0;
*nunspec = 0;
for (const char* p = strrchr (str, ']'); p && *p != '['; --p)
if (*p == '*')
++*nunspec;
return list_length (size);
/* STR points to the beginning of the specified string for the current
argument that may be followed by the string for the next argument. */
for (const char* p = strchr (str, ']'); p && *p != '['; --p)
{
if (*p == '*')
++*nunspec;
else if (*p == '$')
++nbounds;
}
return nbounds;
}
/* Reset front end-specific attribute access data from ATTRS.

View File

@ -3511,7 +3511,7 @@ warn_parm_array_mismatch (location_t origloc, tree fndecl, tree newparms)
&& newa->sizarg != UINT_MAX
&& newa->sizarg == cura->sizarg
&& newa->minsize == cura->minsize
&& !TREE_CHAIN (newa->size) && !TREE_CHAIN (cura->size))
&& !TREE_PURPOSE (newa->size) && !TREE_PURPOSE (cura->size))
continue;
if (newa->size || cura->size)

View File

@ -0,0 +1,68 @@
/* PR c/100719 - missing -Wvla-parameter on a mismatch in second parameter
{ dg-do compile }
{ dg-options "-Wall" } */
typedef struct A1 { int i; } A1;
typedef struct A2 { int i; } A2;
typedef struct A3 { int i; } A3;
void f2 (int n, A1[n], A2[n]);
void f2 (int n, A1[n], A2[n]);
void f2_x1 (int n, A1[n], A2[n]); // { dg-note "previously declared as 'A1\\\[n]' with bound argument 1" }
void f2_x1 (int n, A1[n + 1], A2[n]); // { dg-warning "argument 2 of type 'A1\\\[n \\+ 1]' declared with mismatched bound 'n \\+ 1'" }
void f2_x2 (int n, A1[n], A2[n]); // { dg-note "previously declared as 'A2\\\[n]' with bound argument 1" }
void f2_x2 (int n, A1[n], A2[n + 2]); // { dg-warning "argument 3 of type 'A2\\\[n \\+ 2]' declared with mismatched bound 'n \\+ 2'" }
void f3 (int n, A1[n], A2[n], A3[n]);
void f3 (int n, A1[n], A2[n], A3[n]);
void f3_x1 (int n, A1[n], A2[n], A3[n]);
// { dg-note "previously declared as 'A1\\\[n]' with bound argument 1" "note" { target *-*-* } .-1 }
void f3_x1 (int n, A1[n + 1], A2[n], A3[n]);
// { dg-warning "argument 2 of type 'A1\\\[n \\+ 1]' declared with mismatched bound 'n \\+ 1'" "" { target *-*-* } .-1 }
void f3_x2 (int n, A1[n], A2[n], A3[n]);
// { dg-note "previously declared as 'A2\\\[n]' with bound argument 1" "note" { target *-*-* } .-1 }
void f3_x2 (int n, A1[n], A2[n + 2], A3[n]);
// { dg-warning "argument 3 of type 'A2\\\[n \\+ 2]' declared with mismatched bound 'n \\+ 2'" "" { target *-*-* } .-1 }
void f3_x3 (int n, A1[n], A2[n], A3[n]);
// { dg-note "previously declared as 'A3\\\[n]' with bound argument 1" "note" { target *-*-* } .-1 }
void f3_x3 (int n, A1[n], A2[n], A3[n + 3]);
// { dg-warning "argument 4 of type 'A3\\\[n \\+ 3]' declared with mismatched bound 'n \\+ 3'" "" { target *-*-* } .-1 }
void g3_x1 (int n, A1[n], A2[*], A3[n]);
// { dg-note "previously declared as 'A1\\\[n]' with bound argument 1" "note" { target *-*-* } .-1 }
void g3_x1 (int n, A1[n + 1], A2[*], A3[n]);
// { dg-warning "argument 2 of type 'A1\\\[n \\+ 1]' declared with mismatched bound 'n \\+ 1'" "" { target *-*-* } .-1 }
void g3_x2 (int n, A1[*], A2[n], A3[n]);
// { dg-note "previously declared as 'A2\\\[n]' with bound argument 1" "note" { target *-*-* } .-1 }
void g3_x2 (int n, A1[*], A2[n + 2], A3[n]);
// { dg-warning "argument 3 of type 'A2\\\[n \\+ 2]' declared with mismatched bound 'n \\+ 2'" "" { target *-*-* } .-1 }
void g3_x3 (int n, A1[*], A2[*], A3[n]);
// { dg-note "previously declared as 'A3\\\[n]' with bound argument 1" "note" { target *-*-* } .-1 }
void g3_x3 (int n, A1[*], A2[*], A3[n + 3]);
// { dg-warning "argument 4 of type 'A3\\\[n \\+ 3]' declared with mismatched bound 'n \\+ 3'" "" { target *-*-* } .-1 }
void h3_x1 (int n, A1[n], A2[ ], A3[n]);
// { dg-note "previously declared as 'A1\\\[n]' with bound argument 1" "note" { target *-*-* } .-1 }
void h3_x1 (int n, A1[n + 1], A2[ ], A3[n]);
// { dg-warning "argument 2 of type 'A1\\\[n \\+ 1]' declared with mismatched bound 'n \\+ 1'" "" { target *-*-* } .-1 }
void h3_x2 (int n, A1[ ], A2[n], A3[n]);
// { dg-note "previously declared as 'A2\\\[n]' with bound argument 1" "note" { target *-*-* } .-1 }
void h3_x2 (int n, A1[ ], A2[n + 2], A3[n]);
// { dg-warning "argument 3 of type 'A2\\\[n \\+ 2]' declared with mismatched bound 'n \\+ 2'" "" { target *-*-* } .-1 }
void h3_x3 (int n, A1[ ], A2[ ], A3[n]);
// { dg-note "previously declared as 'A3\\\[n]' with bound argument 1" "note" { target *-*-* } .-1 }
void h3_x3 (int n, A1[ ], A2[ ], A3[n + 3]);
// { dg-warning "argument 4 of type 'A3\\\[n \\+ 3]' declared with mismatched bound 'n \\+ 3'" "" { target *-*-* } .-1 }

View File

@ -0,0 +1,70 @@
/* PR c/100719 - missing -Wvla-parameter on a mismatch in second parameter
{ dg-do compile }
{ dg-options "-Wall" } */
typedef struct A1 { int i; } A1;
typedef struct A2 { int i; } A2;
typedef struct A3 { int i; } A3;
extern int n, n1, n2, n3;
void f2 (int, A1[n], A2[n]);
void f2 (int, A1[n], A2[n]);
void f2_x1 (int, A1[n], A2[n]); // { dg-note "previously declared as 'A1\\\[n]'" }
void f2_x1 (int, A1[n1], A2[n]); // { dg-warning "argument 2 of type 'A1\\\[n1]' declared with mismatched bound 'n1'" }
void f2_x2 (int, A1[n], A2[n]); // { dg-note "previously declared as 'A2\\\[n]'" }
void f2_x2 (int, A1[n], A2[n2]); // { dg-warning "argument 3 of type 'A2\\\[n2]' declared with mismatched bound 'n2'" }
void f3 (int, A1[n], A2[n], A3[n]);
void f3 (int, A1[n], A2[n], A3[n]);
void f3_x1 (int, A1[n], A2[n], A3[n]);
// { dg-note "previously declared as 'A1\\\[n]'" "note" { target *-*-* } .-1 }
void f3_x1 (int, A1[n1], A2[n], A3[n]);
// { dg-warning "argument 2 of type 'A1\\\[n1]' declared with mismatched bound 'n1'" "" { target *-*-* } .-1 }
void f3_x2 (int, A1[n], A2[n], A3[n]);
// { dg-note "previously declared as 'A2\\\[n]'" "note" { target *-*-* } .-1 }
void f3_x2 (int, A1[n], A2[n2], A3[n]);
// { dg-warning "argument 3 of type 'A2\\\[n2]' declared with mismatched bound 'n2'" "" { target *-*-* } .-1 }
void f3_x3 (int, A1[n], A2[n], A3[n]);
// { dg-note "previously declared as 'A3\\\[n]'" "note" { target *-*-* } .-1 }
void f3_x3 (int, A1[n], A2[n], A3[n3]);
// { dg-warning "argument 4 of type 'A3\\\[n3]' declared with mismatched bound 'n3'" "" { target *-*-* } .-1 }
void g3_x1 (int, A1[n], A2[*], A3[n]);
// { dg-note "previously declared as 'A1\\\[n]'" "note" { target *-*-* } .-1 }
void g3_x1 (int, A1[n1], A2[*], A3[n]);
// { dg-warning "argument 2 of type 'A1\\\[n1]' declared with mismatched bound 'n1'" "" { target *-*-* } .-1 }
void g3_x2 (int, A1[*], A2[n], A3[n]);
// { dg-note "previously declared as 'A2\\\[n]'" "note" { target *-*-* } .-1 }
void g3_x2 (int, A1[*], A2[n2], A3[n]);
// { dg-warning "argument 3 of type 'A2\\\[n2]' declared with mismatched bound 'n2'" "" { target *-*-* } .-1 }
void g3_x3 (int, A1[*], A2[*], A3[n]);
// { dg-note "previously declared as 'A3\\\[n]'" "note" { target *-*-* } .-1 }
void g3_x3 (int, A1[*], A2[*], A3[n3]);
// { dg-warning "argument 4 of type 'A3\\\[n3]' declared with mismatched bound 'n3'" "" { target *-*-* } .-1 }
void h3_x1 (int, A1[n], A2[ ], A3[n]);
// { dg-note "previously declared as 'A1\\\[n]'" "note" { target *-*-* } .-1 }
void h3_x1 (int, A1[n1], A2[ ], A3[n]);
// { dg-warning "argument 2 of type 'A1\\\[n1]' declared with mismatched bound 'n1'" "" { target *-*-* } .-1 }
void h3_x2 (int, A1[ ], A2[n], A3[n]);
// { dg-note "previously declared as 'A2\\\[n]'" "note" { target *-*-* } .-1 }
void h3_x2 (int, A1[ ], A2[n2], A3[n]);
// { dg-warning "argument 3 of type 'A2\\\[n2]' declared with mismatched bound 'n2'" "" { target *-*-* } .-1 }
void h3_x3 (int, A1[ ], A2[ ], A3[n]);
// { dg-note "previously declared as 'A3\\\[n]'" "note" { target *-*-* } .-1 }
void h3_x3 (int, A1[ ], A2[ ], A3[n3]);
// { dg-warning "argument 4 of type 'A3\\\[n3]' declared with mismatched bound 'n3'" "" { target *-*-* } .-1 }