diff mbox series

correct/improve handling of -Walloc-size-larger-than (PR 82063)

Message ID fc5530e9-2917-e4f7-08fb-84fa1a6f965a@gmail.com
State New
Headers show
Series correct/improve handling of -Walloc-size-larger-than (PR 82063) | expand

Commit Message

Martin Sebor May 18, 2018, 11:58 p.m. UTC
The -Walloc-size-larger-than= option is supposed make it possible
to disable the warning by specifying a limit that's larger than
the default of PTRDIFF_MAX (the handler for the option argument
gets around the INT_MAX maximum for numeric arguments by accepting
suffixes like MB or GB).  Unfortunately, a silly typo in the handler
prevents this from working correctly, and because there is no
-Wno-alloc-size-larger-than option it's impossible to suppress
unwanted instances of this warning.

The attached patch removes these shortcomings by:

1) fixing the typo,
2) letting the argument handler accept excessively large arguments
    (> ULLONG_MAX) and treat them as infinite,
3) adding -Wno-alloc-size-larger-than option to disable the warning

The patch also issues a warning for invalid arguments (they either
reset the limit to zero or leave it at PTRDIFF_MAX otherwise).

I'm looking for approval to commit this patch to trunk and all
release branches that support the option (8 and 7).

For trunk, as the next step, I'd like to generalize the argument
handler and move it where other similar options (for example,
-Wlarger-than, -Walloca-larger-than, -Wframe-larger-than, and
-Wstack-usage) can make use of it.

Martin

Comments

Jeff Law May 30, 2018, 11:18 p.m. UTC | #1
On 05/18/2018 05:58 PM, Martin Sebor wrote:
> The -Walloc-size-larger-than= option is supposed make it possible
> to disable the warning by specifying a limit that's larger than
> the default of PTRDIFF_MAX (the handler for the option argument
> gets around the INT_MAX maximum for numeric arguments by accepting
> suffixes like MB or GB).  Unfortunately, a silly typo in the handler
> prevents this from working correctly, and because there is no
> -Wno-alloc-size-larger-than option it's impossible to suppress
> unwanted instances of this warning.
> 
> The attached patch removes these shortcomings by:
> 
> 1) fixing the typo,
> 2) letting the argument handler accept excessively large arguments
>    (> ULLONG_MAX) and treat them as infinite,
> 3) adding -Wno-alloc-size-larger-than option to disable the warning
> 
> The patch also issues a warning for invalid arguments (they either
> reset the limit to zero or leave it at PTRDIFF_MAX otherwise).
> 
> I'm looking for approval to commit this patch to trunk and all
> release branches that support the option (8 and 7).
> 
> For trunk, as the next step, I'd like to generalize the argument
> handler and move it where other similar options (for example,
> -Wlarger-than, -Walloca-larger-than, -Wframe-larger-than, and
> -Wstack-usage) can make use of it.
> 
> Martin
> 
> gcc-82063.diff
> 
> 
> 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.
> 
> 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.
OK for the trunk.  Not sure this is really a regression, so it'd need
Richi or Jakub to approve for the release branches.

Jeff
Martin Sebor May 31, 2018, 5:07 p.m. UTC | #2
On 05/30/2018 05:18 PM, Jeff Law wrote:
> On 05/18/2018 05:58 PM, Martin Sebor wrote:
>> The -Walloc-size-larger-than= option is supposed make it possible
>> to disable the warning by specifying a limit that's larger than
>> the default of PTRDIFF_MAX (the handler for the option argument
>> gets around the INT_MAX maximum for numeric arguments by accepting
>> suffixes like MB or GB).  Unfortunately, a silly typo in the handler
>> prevents this from working correctly, and because there is no
>> -Wno-alloc-size-larger-than option it's impossible to suppress
>> unwanted instances of this warning.
>>
>> The attached patch removes these shortcomings by:
>>
>> 1) fixing the typo,
>> 2) letting the argument handler accept excessively large arguments
>>    (> ULLONG_MAX) and treat them as infinite,
>> 3) adding -Wno-alloc-size-larger-than option to disable the warning
>>
>> The patch also issues a warning for invalid arguments (they either
>> reset the limit to zero or leave it at PTRDIFF_MAX otherwise).
>>
>> I'm looking for approval to commit this patch to trunk and all
>> release branches that support the option (8 and 7).
>>
>> For trunk, as the next step, I'd like to generalize the argument
>> handler and move it where other similar options (for example,
>> -Wlarger-than, -Walloca-larger-than, -Wframe-larger-than, and
>> -Wstack-usage) can make use of it.
>>
>> Martin
>>
>> gcc-82063.diff
>>
>>
>> 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.
>>
>> 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.
> OK for the trunk.  Not sure this is really a regression, so it'd need
> Richi or Jakub to approve for the release branches.

I also updated the manual and committed r261030 to trunk.

Without the patch false positives the new warning sometimes
(if rarely) issues cannot be suppressed.  The particular false
positive that prompted me to fix this is due to C++ front end
bug 82063, and there's nothing the implementation of the warning
can do to avoid it.

Richi and/or Jakub, can you please review the patch and let me
know if it's suitable for the release branches?

Martin
diff mbox series

Patch

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.

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.

diff --git a/gcc/c-family/c.opt b/gcc/c-family/c.opt
index c48d6dc..99b0326 100644
--- a/gcc/c-family/c.opt
+++ b/gcc/c-family/c.opt
@@ -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
 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
 C ObjC C++ ObjC++ Var(warn_alloc_zero) Warning
 -Walloc-zero Warn for calls to allocation functions that specify zero bytes.
diff --git a/gcc/calls.c b/gcc/calls.c
index f0e9d3b..e00d647 100644
--- a/gcc/calls.c
+++ b/gcc/calls.c
@@ -1230,65 +1230,81 @@  static GTY(()) tree alloc_object_size_limit;
 static tree
 alloc_max_size (void)
 {
-  if (!alloc_object_size_limit)
-    {
-      alloc_object_size_limit = max_object_size ();
+  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 = max_object_size ();
 
-	  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)
-		{
-		  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);
-		}
-	    }
+  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;
 }
 
diff --git a/gcc/testsuite/gcc.dg/Walloc-size-larger-than-1.c b/gcc/testsuite/gcc.dg/Walloc-size-larger-than-1.c
new file mode 100644
index 0000000..2e0b765
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/Walloc-size-larger-than-1.c
@@ -0,0 +1,19 @@ 
+/* 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" } */
+}
diff --git a/gcc/testsuite/gcc.dg/Walloc-size-larger-than-10.c b/gcc/testsuite/gcc.dg/Walloc-size-larger-than-10.c
new file mode 100644
index 0000000..559309d
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/Walloc-size-larger-than-10.c
@@ -0,0 +1,27 @@ 
+/* 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" } */
+}
diff --git a/gcc/testsuite/gcc.dg/Walloc-size-larger-than-11.c b/gcc/testsuite/gcc.dg/Walloc-size-larger-than-11.c
new file mode 100644
index 0000000..41e523c
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/Walloc-size-larger-than-11.c
@@ -0,0 +1,27 @@ 
+/* 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" } */
+}
diff --git a/gcc/testsuite/gcc.dg/Walloc-size-larger-than-12.c b/gcc/testsuite/gcc.dg/Walloc-size-larger-than-12.c
new file mode 100644
index 0000000..24269a8
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/Walloc-size-larger-than-12.c
@@ -0,0 +1,27 @@ 
+/* 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" } */
+}
diff --git a/gcc/testsuite/gcc.dg/Walloc-size-larger-than-13.c b/gcc/testsuite/gcc.dg/Walloc-size-larger-than-13.c
new file mode 100644
index 0000000..b96e389
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/Walloc-size-larger-than-13.c
@@ -0,0 +1,27 @@ 
+/* 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" } */
+}
diff --git a/gcc/testsuite/gcc.dg/Walloc-size-larger-than-14.c b/gcc/testsuite/gcc.dg/Walloc-size-larger-than-14.c
new file mode 100644
index 0000000..e632e22
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/Walloc-size-larger-than-14.c
@@ -0,0 +1,30 @@ 
+/* 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));
+}
diff --git a/gcc/testsuite/gcc.dg/Walloc-size-larger-than-15.c b/gcc/testsuite/gcc.dg/Walloc-size-larger-than-15.c
new file mode 100644
index 0000000..b699cc0
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/Walloc-size-larger-than-15.c
@@ -0,0 +1,30 @@ 
+/* 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));
+}
diff --git a/gcc/testsuite/gcc.dg/Walloc-size-larger-than-16.c b/gcc/testsuite/gcc.dg/Walloc-size-larger-than-16.c
new file mode 100644
index 0000000..837b69a
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/Walloc-size-larger-than-16.c
@@ -0,0 +1,32 @@ 
+/* 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 } */
diff --git a/gcc/testsuite/gcc.dg/Walloc-size-larger-than-17.c b/gcc/testsuite/gcc.dg/Walloc-size-larger-than-17.c
new file mode 100644
index 0000000..752371a
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/Walloc-size-larger-than-17.c
@@ -0,0 +1,27 @@ 
+/* 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));
+}
diff --git a/gcc/testsuite/gcc.dg/Walloc-size-larger-than-2.c b/gcc/testsuite/gcc.dg/Walloc-size-larger-than-2.c
new file mode 100644
index 0000000..1ded37b
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/Walloc-size-larger-than-2.c
@@ -0,0 +1,20 @@ 
+/* 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" } */
+}
diff --git a/gcc/testsuite/gcc.dg/Walloc-size-larger-than-2.s b/gcc/testsuite/gcc.dg/Walloc-size-larger-than-2.s
new file mode 100644
index 0000000..e69de29
diff --git a/gcc/testsuite/gcc.dg/Walloc-size-larger-than-3.c b/gcc/testsuite/gcc.dg/Walloc-size-larger-than-3.c
new file mode 100644
index 0000000..500ddbf
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/Walloc-size-larger-than-3.c
@@ -0,0 +1,19 @@ 
+/* 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" } */
+}
diff --git a/gcc/testsuite/gcc.dg/Walloc-size-larger-than-4.c b/gcc/testsuite/gcc.dg/Walloc-size-larger-than-4.c
new file mode 100644
index 0000000..e4fde5a
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/Walloc-size-larger-than-4.c
@@ -0,0 +1,19 @@ 
+/* 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" } */
+}
diff --git a/gcc/testsuite/gcc.dg/Walloc-size-larger-than-5.c b/gcc/testsuite/gcc.dg/Walloc-size-larger-than-5.c
new file mode 100644
index 0000000..bfea259
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/Walloc-size-larger-than-5.c
@@ -0,0 +1,25 @@ 
+/* 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" } */
+}
diff --git a/gcc/testsuite/gcc.dg/Walloc-size-larger-than-6.c b/gcc/testsuite/gcc.dg/Walloc-size-larger-than-6.c
new file mode 100644
index 0000000..1eb83a5
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/Walloc-size-larger-than-6.c
@@ -0,0 +1,25 @@ 
+/* 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" } */
+}
diff --git a/gcc/testsuite/gcc.dg/Walloc-size-larger-than-7.c b/gcc/testsuite/gcc.dg/Walloc-size-larger-than-7.c
new file mode 100644
index 0000000..5188203
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/Walloc-size-larger-than-7.c
@@ -0,0 +1,25 @@ 
+/* 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" } */
+}
diff --git a/gcc/testsuite/gcc.dg/Walloc-size-larger-than-8.c b/gcc/testsuite/gcc.dg/Walloc-size-larger-than-8.c
new file mode 100644
index 0000000..4f84a02
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/Walloc-size-larger-than-8.c
@@ -0,0 +1,27 @@ 
+/* 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" } */
+}
diff --git a/gcc/testsuite/gcc.dg/Walloc-size-larger-than-9.c b/gcc/testsuite/gcc.dg/Walloc-size-larger-than-9.c
new file mode 100644
index 0000000..f3927f1
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/Walloc-size-larger-than-9.c
@@ -0,0 +1,27 @@ 
+/* 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" } */
+}
diff --git a/gcc/testsuite/gcc.dg/Walloc-size-larger-than.c b/gcc/testsuite/gcc.dg/Walloc-size-larger-than.c
new file mode 100644
index 0000000..8096ff1
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/Walloc-size-larger-than.c
@@ -0,0 +1,13 @@ 
+/* 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" } */
+}