Avoid -Walloca-larger-than and -Wvla-larger-than false postives and negatives.

Resolves:
PR middle-end/100425 - missing -Walloca-larger-than with -O0
PR middle-end/100510 - bogus -Wvla-large-than with -Walloca

gcc/ChangeLog:

	PR middle-end/100425
	PR middle-end/100510
	* gimple-ssa-warn-alloca.c (pass_walloca::firast_time_p): Rename...
	(pass_walloca::xlimit_certain_p): ...to this.
	(pass_walloca::gate): Execute for any kind of handled warning.
	(pass_walloca::execute): Avoid issuing "maybe" and "unbounded"
	warnings when xlimit_certain_p is set.

gcc/testsuite/ChangeLog:

	PR middle-end/100425
	PR middle-end/100510
	* c-c++-common/Walloca-larger-than.C: New test.
	* gcc.dg/Walloca-larger-than-4.c: New test.
	* gcc.dg/Wvla-larger-than-5.c: New test.
	* gcc.dg/pr79972.c: Remove unexpected warning directive.
This commit is contained in:
Martin Sebor 2021-05-10 14:00:04 -06:00
parent 51d89e61f7
commit f974b54b8a
5 changed files with 93 additions and 10 deletions

View file

@ -56,31 +56,30 @@ class pass_walloca : public gimple_opt_pass
{
public:
pass_walloca (gcc::context *ctxt)
: gimple_opt_pass(pass_data_walloca, ctxt), first_time_p (false)
: gimple_opt_pass(pass_data_walloca, ctxt), xlimit_certain_p (false)
{}
opt_pass *clone () { return new pass_walloca (m_ctxt); }
void set_pass_param (unsigned int n, bool param)
{
gcc_assert (n == 0);
first_time_p = param;
// Set to true to enable only warnings for alloca calls that
// are certainly in excess of the limit. This includes calls
// with constant arguments but excludes those in ranges (that
// can only be determined by range analysis) as well as
// the "may be too large" kind.
xlimit_certain_p = param;
}
virtual bool gate (function *);
virtual unsigned int execute (function *);
private:
// Set to TRUE the first time we run this pass on a function.
bool first_time_p;
bool xlimit_certain_p;
};
bool
pass_walloca::gate (function *fun ATTRIBUTE_UNUSED)
{
// The first time this pass is called, it is called before
// optimizations have been run and range information is unavailable,
// so we can only perform strict alloca checking.
if (first_time_p)
return warn_alloca != 0;
// Warning is disabled when its size limit is greater than PTRDIFF_MAX
// for the target maximum, which makes the limit negative since when
// represented in signed HOST_WIDE_INT.
@ -317,6 +316,9 @@ pass_walloca::execute (function *fun)
break;
case ALLOCA_BOUND_MAYBE_LARGE:
{
if (xlimit_certain_p)
break;
auto_diagnostic_group d;
if (warning_at (loc, wcode,
(is_vla
@ -354,6 +356,9 @@ pass_walloca::execute (function *fun)
}
break;
case ALLOCA_UNBOUNDED:
if (xlimit_certain_p)
break;
warning_at (loc, wcode,
(is_vla
? G_("%Gunbounded use of variable-length array")

View file

@ -0,0 +1,21 @@
/* PR middle-end/100425 - missing -Walloca-larger-than with -O0
{ dg-do compile }
{ dg-options "-O0 -Wall -Walloca-larger-than=128" } */
typedef __SIZE_TYPE__ size_t;
#if __cplusplus
extern "C"
#endif
void* alloca (size_t);
void sink (void*);
void warn_alloca_too_large (void)
{
sink (alloca (1));
sink (alloca (128));
sink (alloca (129)); // { dh-warning "\\\[-Walloca-larger-than" }
sink (alloca (1024)); // { dh-warning "\\\[-Walloca-larger-than" }
}

View file

@ -0,0 +1,18 @@
/* PR middle-end/100425 - missing -Walloca-larger-than with -O0
{ dg-do compile }
{ dg-options "-O0 -Wall -Walloca-larger-than=128" } */
typedef __SIZE_TYPE__ size_t;
void* alloca (size_t);
void sink (void*);
void warn_alloca_too_large (void)
{
sink (alloca (1));
sink (alloca (128));
sink (alloca (129)); // { dg-warning "\\\[-Walloca-larger-than" }
sink (alloca (128 + 2)); // { dg-warning "\\\[-Walloca-larger-than" }
sink (alloca (1024)); // { dg-warning "\\\[-Walloca-larger-than" }
}

View file

@ -0,0 +1,38 @@
/* PR middle-end/100510 - bogus -Wvla-large-than with -Walloca
{ dg-do compile }
{ dg-options "-O0 -Walloca -Wvla-larger-than=1000" } */
void f (void*);
#pragma GCC optimize ("0")
void nowarn_O0 (__SIZE_TYPE__ n)
{
if (n > 32)
return;
char a[n]; // { dg-bogus "\\\[-Wvla-larger-than=" }
f (a);
}
#pragma GCC optimize ("1")
void nowarn_O1 (__SIZE_TYPE__ n)
{
if (n > 33)
return;
char a[n]; // { dg-bogus "\\\[-Wvla-larger-than=" }
f (a);
}
#pragma GCC optimize ("2")
void nowarn_O2 (__SIZE_TYPE__ n)
{
if (n > 34)
return;
char a[n]; // { dg-bogus "\\\[-Wvla-larger-than=" }
f (a);
}

View file

@ -6,7 +6,8 @@
int
f (int dim, int *b, int *c)
{
int newcentroid[3][dim]; /* { dg-warning "unbounded use of variable-length array" } */
/* -Wvla-larger-than is only issued with optimization (see PR 100510). */
int newcentroid[3][dim];
int *a = newcentroid[2];
int i, dist = 0;
__builtin_memcpy (newcentroid, c, sizeof (newcentroid));