+2018-06-18 Martin Sebor <msebor@redhat.com>
+
+ PR middle-end/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-06-14 Sebastian Huber <sebastian.huber@embedded-brains.de>
Backport from mainline
static tree
alloc_max_size (void)
{
- if (!alloc_object_size_limit)
- {
- alloc_object_size_limit = TYPE_MAX_VALUE (ssizetype);
+ if (alloc_object_size_limit)
+ return alloc_object_size_limit;
- if (warn_alloc_size_limit)
- {
- char *end = NULL;
- errno = 0;
- unsigned HOST_WIDE_INT unit = 1;
- unsigned HOST_WIDE_INT limit
- = strtoull (warn_alloc_size_limit, &end, 10);
+ alloc_object_size_limit = TYPE_MAX_VALUE (ssizetype);
- if (!errno)
- {
- if (end && *end)
- {
- /* Numeric option arguments are at most INT_MAX. Make it
- possible to specify a larger value by accepting common
- suffixes. */
- if (!strcmp (end, "kB"))
- unit = 1000;
- else if (!strcasecmp (end, "KiB") || strcmp (end, "KB"))
- unit = 1024;
- else if (!strcmp (end, "MB"))
- unit = HOST_WIDE_INT_UC (1000) * 1000;
- else if (!strcasecmp (end, "MiB"))
- unit = HOST_WIDE_INT_UC (1024) * 1024;
- else if (!strcasecmp (end, "GB"))
- unit = HOST_WIDE_INT_UC (1000) * 1000 * 1000;
- else if (!strcasecmp (end, "GiB"))
- unit = HOST_WIDE_INT_UC (1024) * 1024 * 1024;
- else if (!strcasecmp (end, "TB"))
- unit = HOST_WIDE_INT_UC (1000) * 1000 * 1000 * 1000;
- else if (!strcasecmp (end, "TiB"))
- unit = HOST_WIDE_INT_UC (1024) * 1024 * 1024 * 1024;
- else if (!strcasecmp (end, "PB"))
- unit = HOST_WIDE_INT_UC (1000) * 1000 * 1000 * 1000 * 1000;
- else if (!strcasecmp (end, "PiB"))
- unit = HOST_WIDE_INT_UC (1024) * 1024 * 1024 * 1024 * 1024;
- else if (!strcasecmp (end, "EB"))
- unit = HOST_WIDE_INT_UC (1000) * 1000 * 1000 * 1000 * 1000
- * 1000;
- else if (!strcasecmp (end, "EiB"))
- unit = HOST_WIDE_INT_UC (1024) * 1024 * 1024 * 1024 * 1024
- * 1024;
- else
- unit = 0;
- }
+ if (!warn_alloc_size_limit)
+ return alloc_object_size_limit;
- if (unit)
- {
- wide_int w = wi::uhwi (limit, HOST_BITS_PER_WIDE_INT + 64);
- w *= unit;
- if (wi::ltu_p (w, alloc_object_size_limit))
- alloc_object_size_limit = wide_int_to_tree (ssizetype, w);
- }
- }
+ const char *optname = "-Walloc-size-larger-than=";
+
+ char *end = NULL;
+ errno = 0;
+ unsigned HOST_WIDE_INT unit = 1;
+ unsigned HOST_WIDE_INT limit
+ = strtoull (warn_alloc_size_limit, &end, 10);
+
+ /* 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)
+ {
+ /* Numeric option arguments are at most INT_MAX. Make it
+ possible to specify a larger value by accepting common
+ suffixes. */
+ if (!strcmp (end, "kB"))
+ unit = 1000;
+ else if (!strcasecmp (end, "KiB") || !strcmp (end, "KB"))
+ unit = 1024;
+ else if (!strcmp (end, "MB"))
+ unit = HOST_WIDE_INT_UC (1000) * 1000;
+ else if (!strcasecmp (end, "MiB"))
+ unit = HOST_WIDE_INT_UC (1024) * 1024;
+ else if (!strcasecmp (end, "GB"))
+ unit = HOST_WIDE_INT_UC (1000) * 1000 * 1000;
+ else if (!strcasecmp (end, "GiB"))
+ unit = HOST_WIDE_INT_UC (1024) * 1024 * 1024;
+ else if (!strcasecmp (end, "TB"))
+ unit = HOST_WIDE_INT_UC (1000) * 1000 * 1000 * 1000;
+ else if (!strcasecmp (end, "TiB"))
+ unit = HOST_WIDE_INT_UC (1024) * 1024 * 1024 * 1024;
+ else if (!strcasecmp (end, "PB"))
+ unit = HOST_WIDE_INT_UC (1000) * 1000 * 1000 * 1000 * 1000;
+ else if (!strcasecmp (end, "PiB"))
+ unit = HOST_WIDE_INT_UC (1024) * 1024 * 1024 * 1024 * 1024;
+ else if (!strcasecmp (end, "EB"))
+ unit = HOST_WIDE_INT_UC (1000) * 1000 * 1000 * 1000 * 1000
+ * 1000;
+ else if (!strcasecmp (end, "EiB"))
+ unit = HOST_WIDE_INT_UC (1024) * 1024 * 1024 * 1024 * 1024
+ * 1024;
+ 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;
}
}
+
+ if (unit)
+ {
+ widest_int w = wi::mul (limit, unit);
+ if (w < wi::to_widest (alloc_object_size_limit))
+ alloc_object_size_limit
+ = 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;
}
may end in one of the standard suffixes designating a multiple of bytes
such as @code{kB} and @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 by specifying @var{n}
+of @var{SIZE_MAX} or more.
@xref{Function Attributes}.
@item -Walloca
+2018-06-18 Martin Sebor <msebor@redhat.com>
+
+ PR middle-end/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-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-06-13 Steven G. Kargl <kargl@gcc.gnu.org>
PR fortran/86110
--- /dev/null
+/* 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" } */
+}
--- /dev/null
+/* 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" } */
+}
--- /dev/null
+/* 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" } */
+}
--- /dev/null
+/* 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" } */
+}
--- /dev/null
+/* 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" } */
+}
--- /dev/null
+/* 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));
+}
--- /dev/null
+/* 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));
+}
--- /dev/null
+/* 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 } */
--- /dev/null
+/* 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" } */
+}
--- /dev/null
+/* 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" } */
+}
--- /dev/null
+/* 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" } */
+}
--- /dev/null
+/* 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" } */
+}
--- /dev/null
+/* 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" } */
+}
--- /dev/null
+/* 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" } */
+}
--- /dev/null
+/* 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" } */
+}
--- /dev/null
+/* 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" } */
+}
--- /dev/null
+/* 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" } */
+}