Commit d258f4aa by Martin Sebor Committed by Martin Sebor

PR c/82063 - issues with arguments enabled by -Wall

gcc/c-family/ChangeLog:

	PR c/82063
	* c.opt (-Wno-alloc-size-larger-than): New option.
	* doc/invoke.texi (-Walloc-size-larger-than): Update.

gcc/ChangeLog:

	PR c/82063
	* calls.c (alloc_max_size): Correct a logic error/typo.
	Treat excessive arguments as infinite.  Warn for invalid arguments.

gcc/testsuite/ChangeLog:

	PR c/82063
	* gcc.dg/Walloc-size-larger-than-1.c: New test.
	* gcc.dg/Walloc-size-larger-than-10.c: New test.
	* gcc.dg/Walloc-size-larger-than-11.c: New test.
	* gcc.dg/Walloc-size-larger-than-12.c: New test.
	* gcc.dg/Walloc-size-larger-than-13.c: New test.
	* gcc.dg/Walloc-size-larger-than-14.c: New test.
	* gcc.dg/Walloc-size-larger-than-15.c: New test.
	* gcc.dg/Walloc-size-larger-than-16.c: New test.
	* gcc.dg/Walloc-size-larger-than-17.c: New test.
	* gcc.dg/Walloc-size-larger-than-2.c: New test.
	* gcc.dg/Walloc-size-larger-than-3.c: New test.
	* gcc.dg/Walloc-size-larger-than-4.c: New test.
	* gcc.dg/Walloc-size-larger-than-5.c: New test.
	* gcc.dg/Walloc-size-larger-than-6.c: New test.
	* gcc.dg/Walloc-size-larger-than-7.c: New test.
	* gcc.dg/Walloc-size-larger-than-8.c: New test.
	* gcc.dg/Walloc-size-larger-than-9.c: New test.
	* gcc.dg/Walloc-size-larger-than.c: New test.

From-SVN: r261030
parent 3217e694
2018-05-31 Martin Sebor <msebor@redhat.com>
PR c/82063
* calls.c (alloc_max_size): Correct a logic error/typo.
Treat excessive arguments as infinite. Warn for invalid arguments.
* doc/invoke.texi (-Walloc-size-larger-than): Update.
2018-05-31 H.J. Lu <hongjiu.lu@intel.com> 2018-05-31 H.J. Lu <hongjiu.lu@intel.com>
PR target/85829 PR target/85829
......
2018-05-31 Martin Sebor <msebor@redhat.com>
PR c/82063
* c.opt (-Wno-alloc-size-larger-than): New option.
2018-04-22 David Pagan <dave.pagan@oracle.com> 2018-04-22 David Pagan <dave.pagan@oracle.com>
PR c/55976 PR c/55976
......
...@@ -308,6 +308,10 @@ C ObjC C++ LTO ObjC++ Var(warn_alloc_size_limit) Warning Joined LangEnabledBy(C ...@@ -308,6 +308,10 @@ C ObjC C++ LTO ObjC++ Var(warn_alloc_size_limit) Warning Joined LangEnabledBy(C
-Walloc-size-larger-than=<bytes> Warn for calls to allocation functions that -Walloc-size-larger-than=<bytes> Warn for calls to allocation functions that
attempt to allocate objects larger than the specified number of bytes. attempt to allocate objects larger than the specified number of bytes.
Wno-alloc-size-larger-than
C ObjC C++ LTO ObjC++ Alias(Walloc-size-larger-than=, 18446744073709551615EiB,none) Warning
-Wno-alloc-size-larger-than Disable Walloc-size-larger-than= warning. Equivalent to Walloc-size-larger-than=<SIZE_MAX> or larger.
Walloc-zero Walloc-zero
C ObjC C++ ObjC++ Var(warn_alloc_zero) Warning C ObjC C++ ObjC++ Var(warn_alloc_zero) Warning
-Walloc-zero Warn for calls to allocation functions that specify zero bytes. -Walloc-zero Warn for calls to allocation functions that specify zero bytes.
......
...@@ -1231,20 +1231,26 @@ static GTY(()) tree alloc_object_size_limit; ...@@ -1231,20 +1231,26 @@ static GTY(()) tree alloc_object_size_limit;
static tree static tree
alloc_max_size (void) alloc_max_size (void)
{ {
if (!alloc_object_size_limit) if (alloc_object_size_limit)
{ return alloc_object_size_limit;
alloc_object_size_limit = max_object_size (); alloc_object_size_limit = max_object_size ();
if (warn_alloc_size_limit) if (!warn_alloc_size_limit)
{ return alloc_object_size_limit;
const char *optname = "-Walloc-size-larger-than=";
char *end = NULL; char *end = NULL;
errno = 0; errno = 0;
unsigned HOST_WIDE_INT unit = 1; unsigned HOST_WIDE_INT unit = 1;
unsigned HOST_WIDE_INT limit unsigned HOST_WIDE_INT limit
= strtoull (warn_alloc_size_limit, &end, 10); = strtoull (warn_alloc_size_limit, &end, 10);
if (!errno) /* If the value is too large to be represented use the maximum
{ representable value that strtoull sets limit to (setting
errno to ERANGE). */
if (end && *end) if (end && *end)
{ {
/* Numeric option arguments are at most INT_MAX. Make it /* Numeric option arguments are at most INT_MAX. Make it
...@@ -1252,7 +1258,7 @@ alloc_max_size (void) ...@@ -1252,7 +1258,7 @@ alloc_max_size (void)
suffixes. */ suffixes. */
if (!strcmp (end, "kB")) if (!strcmp (end, "kB"))
unit = 1000; unit = 1000;
else if (!strcasecmp (end, "KiB") || strcmp (end, "KB")) else if (!strcasecmp (end, "KiB") || !strcmp (end, "KB"))
unit = 1024; unit = 1024;
else if (!strcmp (end, "MB")) else if (!strcmp (end, "MB"))
unit = HOST_WIDE_INT_UC (1000) * 1000; unit = HOST_WIDE_INT_UC (1000) * 1000;
...@@ -1277,8 +1283,17 @@ alloc_max_size (void) ...@@ -1277,8 +1283,17 @@ alloc_max_size (void)
unit = HOST_WIDE_INT_UC (1024) * 1024 * 1024 * 1024 * 1024 unit = HOST_WIDE_INT_UC (1024) * 1024 * 1024 * 1024 * 1024
* 1024; * 1024;
else else
{
/* This could mean an unknown suffix or a bad prefix, like
"+-1". */
warning_at (UNKNOWN_LOCATION, 0,
"invalid argument %qs to %qs",
warn_alloc_size_limit, optname);
/* Ignore the limit extracted by strtoull. */
unit = 0; unit = 0;
} }
}
if (unit) if (unit)
{ {
...@@ -1286,10 +1301,11 @@ alloc_max_size (void) ...@@ -1286,10 +1301,11 @@ alloc_max_size (void)
if (w < wi::to_widest (alloc_object_size_limit)) if (w < wi::to_widest (alloc_object_size_limit))
alloc_object_size_limit alloc_object_size_limit
= wide_int_to_tree (ptrdiff_type_node, w); = wide_int_to_tree (ptrdiff_type_node, w);
else
alloc_object_size_limit = build_all_ones_cst (size_type_node);
} }
}
}
}
return alloc_object_size_limit; return alloc_object_size_limit;
} }
......
...@@ -5510,10 +5510,14 @@ portability bugs and should be avoided. ...@@ -5510,10 +5510,14 @@ portability bugs and should be avoided.
Warn about calls to functions decorated with attribute @code{alloc_size} Warn about calls to functions decorated with attribute @code{alloc_size}
that attempt to allocate objects larger than the specified number of bytes, that attempt to allocate objects larger than the specified number of bytes,
or where the result of the size computation in an integer type with infinite or where the result of the size computation in an integer type with infinite
precision would exceed @code{SIZE_MAX / 2}. The option argument @var{n} precision would exceed @code{SIZE_MAX / 2}. The option argument @var{n} is
may end in one of the standard suffixes designating a multiple of bytes treated as an integer with infinite precision and may end in one of
such as @code{kB} and @code{KiB} for kilobyte and kibibyte, respectively, the standard suffixes designating a multiple of bytes such as @code{kB} and
@code{MB} and @code{MiB} for megabyte and mebibyte, and so on. @code{KiB} for kilobyte and kibibyte, respectively, @code{MB} and @code{MiB}
for megabyte and mebibyte, and so on.
@option{-Walloc-size-larger-than=}@var{PTRDIFF_MAX} is enabled by default.
Warnings controlled by the option can be disabled either by specifying
@var{n} of @var{SIZE_MAX} or more or by @option{-Wno-alloc-size-larger-than}.
@xref{Function Attributes}. @xref{Function Attributes}.
@item -Walloca @item -Walloca
2018-05-31 Martin Sebor <msebor@redhat.com>
PR c/82063
* gcc.dg/Walloc-size-larger-than-1.c: New test.
* gcc.dg/Walloc-size-larger-than-10.c: New test.
* gcc.dg/Walloc-size-larger-than-11.c: New test.
* gcc.dg/Walloc-size-larger-than-12.c: New test.
* gcc.dg/Walloc-size-larger-than-13.c: New test.
* gcc.dg/Walloc-size-larger-than-14.c: New test.
* gcc.dg/Walloc-size-larger-than-15.c: New test.
* gcc.dg/Walloc-size-larger-than-16.c: New test.
* gcc.dg/Walloc-size-larger-than-17.c: New test.
* gcc.dg/Walloc-size-larger-than-2.c: New test.
* gcc.dg/Walloc-size-larger-than-3.c: New test.
* gcc.dg/Walloc-size-larger-than-4.c: New test.
* gcc.dg/Walloc-size-larger-than-5.c: New test.
* gcc.dg/Walloc-size-larger-than-6.c: New test.
* gcc.dg/Walloc-size-larger-than-7.c: New test.
* gcc.dg/Walloc-size-larger-than-8.c: New test.
* gcc.dg/Walloc-size-larger-than-9.c: New test.
* gcc.dg/Walloc-size-larger-than.c: New test.
2018-05-31 Chung-Lin Tang <cltang@codesourcery.com> 2018-05-31 Chung-Lin Tang <cltang@codesourcery.com>
Cesar Philippidis <cesar@codesourcery.com> Cesar Philippidis <cesar@codesourcery.com>
......
/* PR middle-end/82063 - issues with arguments enabled by -Wall
{ dg-do compile }
{ dg-options "-O -Walloc-size-larger-than=1KB -ftrack-macro-expansion=0" } */
void sink (void*);
#define T(x) sink (x)
void f (void)
{
unsigned n = 0;
T (__builtin_malloc (n));
n = 1024; /* 1 kibibyte (KB or KiB) */
T (__builtin_malloc (n));
n = 1025;
T (__builtin_malloc (n)); /* { dg-warning "argument 1 value .1025. exceeds maximum object size 1024" } */
}
/* PR middle-end/82063 - issues with arguments enabled by -Wall
{ dg-do compile { target lp64 } }
{ dg-options "-O -Walloc-size-larger-than=1PiB -ftrack-macro-expansion=0" } */
typedef __SIZE_TYPE__ size_t;
void sink (void*);
#define T(x) sink (x)
void f (void)
{
size_t n = 0;
T (__builtin_malloc (n));
n = (size_t)1024 * 1024 * 1024 * 1024 * 1024; /* 1 pebibyte (PiB) */
T (__builtin_malloc (n));
n += 1;
T (__builtin_malloc (n)); /* { dg-warning "argument 1 value .1125899906842625. exceeds maximum object size 1125899906842624" } */
n = __PTRDIFF_MAX__;
T (__builtin_malloc (n)); /* { dg-warning "exceeds maximum object size" } */
n = __SIZE_MAX__;
T (__builtin_malloc (n)); /* { dg-warning "exceeds maximum object size" } */
}
/* PR middle-end/82063 - issues with arguments enabled by -Wall
{ dg-do compile { target lp64 } }
{ dg-options "-O -Walloc-size-larger-than=1PB -ftrack-macro-expansion=0" } */
typedef __SIZE_TYPE__ size_t;
void sink (void*);
#define T(x) sink (x)
void f (void)
{
size_t n = 0;
T (__builtin_malloc (n));
n = (size_t)1000 * 1000 * 1000 * 1000 * 1000; /* 1 petabyte (PB) */
T (__builtin_malloc (n));
n += 1;
T (__builtin_malloc (n)); /* { dg-warning "argument 1 value .1000000000000001. exceeds maximum object size 1000000000000000" } */
n = __PTRDIFF_MAX__;
T (__builtin_malloc (n)); /* { dg-warning "exceeds maximum object size" } */
n = __SIZE_MAX__;
T (__builtin_malloc (n)); /* { dg-warning "exceeds maximum object size" } */
}
/* PR middle-end/82063 - issues with arguments enabled by -Wall
{ dg-do compile { target lp64 } }
{ dg-options "-O -Walloc-size-larger-than=1EiB -ftrack-macro-expansion=0" } */
typedef __SIZE_TYPE__ size_t;
void sink (void*);
#define T(x) sink (x)
void f (void)
{
size_t n = 0;
T (__builtin_malloc (n));
n = (size_t)1024 * 1024 * 1024 * 1024 * 1024 * 1024; /* 1 exbibyte (EiB) */
T (__builtin_malloc (n));
n += 1;
T (__builtin_malloc (n)); /* { dg-warning "argument 1 value .1152921504606846977. exceeds maximum object size 1152921504606846976" } */
n = __PTRDIFF_MAX__;
T (__builtin_malloc (n)); /* { dg-warning "exceeds maximum object size" } */
n = __SIZE_MAX__;
T (__builtin_malloc (n)); /* { dg-warning "exceeds maximum object size" } */
}
/* PR middle-end/82063 - issues with arguments enabled by -Wall
{ dg-do compile { target lp64 } }
{ dg-options "-O -Walloc-size-larger-than=1EB -ftrack-macro-expansion=0" } */
typedef __SIZE_TYPE__ size_t;
void sink (void*);
#define T(x) sink (x)
void f (void)
{
size_t n = 0;
T (__builtin_malloc (n));
n = (size_t)1000 * 1000 * 1000 * 1000 * 1000 * 1000; /* 1 exabyte (EB) */
T (__builtin_malloc (n));
n += 1;
T (__builtin_malloc (n)); /* { dg-warning "argument 1 value .1000000000000000001. exceeds maximum object size 1000000000000000000" } */
n = __PTRDIFF_MAX__;
T (__builtin_malloc (n)); /* { dg-warning "exceeds maximum object size" } */
n = __SIZE_MAX__;
T (__builtin_malloc (n)); /* { dg-warning "exceeds maximum object size" } */
}
/* PR middle-end/82063 - issues with arguments enabled by -Wall
{ dg-do compile }
{ dg-options "-O -Walloc-size-larger-than=123456789123456789123456789123456789 -ftrack-macro-expansion=0" } */
typedef __SIZE_TYPE__ size_t;
void sink (void*);
#define T(x) sink (x)
/* Verify that an exceedingly large -Walloc-size-larger-than argument
with no suffix is accepted and treated as infinite. */
void f (void)
{
size_t n = 0;
T (__builtin_malloc (n));
n = __PTRDIFF_MAX__;
T (__builtin_malloc (n));
n += 1;
T (__builtin_malloc (n));
n = __SIZE_MAX__ - 1;
T (__builtin_malloc (n));
n = __SIZE_MAX__;
T (__builtin_malloc (n));
}
/* PR middle-end/82063 - issues with arguments enabled by -Wall
{ dg-do compile }
{ dg-options "-O -Walloc-size-larger-than=123456789123456789123456789123456789gb -ftrack-macro-expansion=0" } */
typedef __SIZE_TYPE__ size_t;
void sink (void*);
#define T(x) sink (x)
/* Verify that an exceeingly large -Walloc-size-larger-than argument
with a valid suffic is accepted and treated as infinite. */
void f (void)
{
size_t n = 0;
T (__builtin_malloc (n));
n = __PTRDIFF_MAX__;
T (__builtin_malloc (n));
n += 1;
T (__builtin_malloc (n));
n = __SIZE_MAX__ - 1;
T (__builtin_malloc (n));
n = __SIZE_MAX__;
T (__builtin_malloc (n));
}
/* PR middle-end/82063 - issues with arguments enabled by -Wall
{ dg-do compile }
{ dg-options "-O -Walloc-size-larger-than=1zb -ftrack-macro-expansion=0" } */
typedef __SIZE_TYPE__ size_t;
void sink (void*);
#define T(x) sink (x)
/* Verify that an invalid -Walloc-size-larger-than argument is diagnosed
and rejected without changing the default setting of PTRDIFF_MAX. */
void f (void)
{
size_t n = 0;
T (__builtin_malloc (n));
n = __PTRDIFF_MAX__;
T (__builtin_malloc (n));
n += 1;
T (__builtin_malloc (n)); /* { dg-warning "exceeds maximum object size" } */
n = __SIZE_MAX__ - 1;
T (__builtin_malloc (n)); /* { dg-warning "exceeds maximum object size" } */
n = __SIZE_MAX__;
T (__builtin_malloc (n)); /* { dg-warning "exceeds maximum object size" } */
}
/* { dg-warning "invalid argument .1zb. to .-Walloc-size-larger-than=." "" { target *-*-* } 0 } */
/* PR middle-end/82063 - issues with arguments enabled by -Wall
{ dg-do compile }
{ dg-options "-O -Wno-alloc-size-larger-than -ftrack-macro-expansion=0" } */
typedef __SIZE_TYPE__ size_t;
void sink (void*);
#define T(x) sink (x)
void f (void)
{
size_t n = 0;
T (__builtin_malloc (n));
n = __PTRDIFF_MAX__;
T (__builtin_malloc (n));
n += 1;
T (__builtin_malloc (n));
n = __SIZE_MAX__ - 1;
T (__builtin_malloc (n));
n = __SIZE_MAX__;
T (__builtin_malloc (n));
}
/* PR middle-end/82063 - issues with arguments enabled by -Wall
{ dg-do compile }
{ dg-options "-O -Walloc-size-larger-than=1KiB -ftrack-macro-expansion=0" }
*/
void sink (void*);
#define T(x) sink (x)
void f (void)
{
unsigned n = 0;
T (__builtin_malloc (n));
n = 1024; /* 1 kibibyte (KB or KiB) */
T (__builtin_malloc (n));
n = 1025;
T (__builtin_malloc (n)); /* { dg-warning "argument 1 value .1025. exceeds maximum object size 1024" } */
}
/* PR middle-end/82063 - issues with arguments enabled by -Wall
{ dg-do compile }
{ dg-options "-O -Walloc-size-larger-than=1kB -ftrack-macro-expansion=0" } */
void sink (void*);
#define T(x) sink (x)
void f (void)
{
unsigned n = 0;
T (__builtin_malloc (n));
n = 1000; /* 1 kilobyte (kB, not to be confused with KB or KiB) */
T (__builtin_malloc (n));
n = 1001;
T (__builtin_malloc (n)); /* { dg-warning "argument 1 value .1001. exceeds maximum object size 1000" } */
}
/* PR middle-end/82063 - issues with arguments enabled by -Wall
{ dg-do compile }
{ dg-options "-O -Walloc-size-larger-than=1MiB -ftrack-macro-expansion=0" } */
void sink (void*);
#define T(x) sink (x)
void f (void)
{
unsigned n = 0;
T (__builtin_malloc (n));
n = 1024 * 1024; /* 1 mebibyte (MiB) */
T (__builtin_malloc (n));
n += 1;
T (__builtin_malloc (n)); /* { dg-warning "argument 1 value .1048577. exceeds maximum object size 1048576" } */
}
/* PR middle-end/82063 - issues with arguments enabled by -Wall
{ dg-do compile }
{ dg-options "-O -Walloc-size-larger-than=1MB -ftrack-macro-expansion=0" } */
void sink (void*);
#define T(x) sink (x)
void f (void)
{
__SIZE_TYPE__ n = 0;
T (__builtin_malloc (n));
n = 1000 * 1000; /* 1 megabyte (MB) */
T (__builtin_malloc (n));
n += 1;
T (__builtin_malloc (n)); /* { dg-warning "argument 1 value .1000001. exceeds maximum object size 1000000" } */
n = __PTRDIFF_MAX__;
T (__builtin_malloc (n)); /* { dg-warning "exceeds maximum object size 1000000" } */
n = __SIZE_MAX__;
T (__builtin_malloc (n)); /* { dg-warning "exceeds maximum object size 1000000" } */
}
/* PR middle-end/82063 - issues with arguments enabled by -Wall
{ dg-do compile }
{ dg-options "-O -Walloc-size-larger-than=1GiB -ftrack-macro-expansion=0" } */
void sink (void*);
#define T(x) sink (x)
void f (void)
{
__SIZE_TYPE__ n = 0;
T (__builtin_malloc (n));
n = 1024 * 1024 * 1024; /* 1 gigibyte (GiB) */
T (__builtin_malloc (n));
n += 1;
T (__builtin_malloc (n)); /* { dg-warning "argument 1 value .1073741825. exceeds maximum object size 1073741824" } */
n = __PTRDIFF_MAX__;
T (__builtin_malloc (n)); /* { dg-warning "exceeds maximum object size" } */
n = __SIZE_MAX__;
T (__builtin_malloc (n)); /* { dg-warning "exceeds maximum object size" } */
}
/* PR middle-end/82063 - issues with arguments enabled by -Wall
{ dg-do compile }
{ dg-options "-O -Walloc-size-larger-than=1GB -ftrack-macro-expansion=0" } */
void sink (void*);
#define T(x) sink (x)
void f (void)
{
__SIZE_TYPE__ n = 0;
T (__builtin_malloc (n));
n = 1000 * 1000 * 1000; /* 1 gigabyte (GB) */
T (__builtin_malloc (n));
n += 1;
T (__builtin_malloc (n)); /* { dg-warning "argument 1 value .1000000001. exceeds maximum object size 1000000000" } */
n = __PTRDIFF_MAX__;
T (__builtin_malloc (n)); /* { dg-warning "exceeds maximum object size" } */
n = __SIZE_MAX__;
T (__builtin_malloc (n)); /* { dg-warning "exceeds maximum object size" } */
}
/* PR middle-end/82063 - issues with arguments enabled by -Wall
{ dg-do compile { target lp64 } }
{ dg-options "-O -Walloc-size-larger-than=1TiB -ftrack-macro-expansion=0" } */
typedef __SIZE_TYPE__ size_t;
void sink (void*);
#define T(x) sink (x)
void f (void)
{
size_t n = 0;
T (__builtin_malloc (n));
n = (size_t)1024 * 1024 * 1024 * 1024; /* 1 tebibyte (TiB) */
T (__builtin_malloc (n));
n += 1;
T (__builtin_malloc (n)); /* { dg-warning "argument 1 value .1099511627777. exceeds maximum object size 1099511627776" } */
n = __PTRDIFF_MAX__;
T (__builtin_malloc (n)); /* { dg-warning "exceeds maximum object size" } */
n = __SIZE_MAX__;
T (__builtin_malloc (n)); /* { dg-warning "exceeds maximum object size" } */
}
/* PR middle-end/82063 - issues with arguments enabled by -Wall
{ dg-do compile { target lp64 } }
{ dg-options "-O -Walloc-size-larger-than=1TB -ftrack-macro-expansion=0" } */
typedef __SIZE_TYPE__ size_t;
void sink (void*);
#define T(x) sink (x)
void f (void)
{
size_t n = 0;
T (__builtin_malloc (n));
n = (size_t)1000 * 1000 * 1000 * 1000; /* 1 terabyte (TB) */
T (__builtin_malloc (n));
n += 1;
T (__builtin_malloc (n)); /* { dg-warning "argument 1 value .1000000000001. exceeds maximum object size 1000000000000" } */
n = __PTRDIFF_MAX__;
T (__builtin_malloc (n)); /* { dg-warning "exceeds maximum object size" } */
n = __SIZE_MAX__;
T (__builtin_malloc (n)); /* { dg-warning "exceeds maximum object size" } */
}
/* PR middle-end/82063 - issues with arguments enabled by -Wall
{ dg-do compile }
{ dg-options "-Walloc-size-larger-than=0 -ftrack-macro-expansion=0" } */
void sink (void*);
#define T(x) sink (x)
void f (void)
{
T (__builtin_malloc (0));
T (__builtin_malloc (1)); /* { dg-warning "argument 1 value .1. exceeds maximum object size 0" } */
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment