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
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" } */
+}

Reply via email to