Hi!

This patch attempts to fix some overflows during computation of the size
and then effectively uses MIN (SSIZE_MAX, user_specified_value) as the
bound.

Not really sure what exact behavior we want, whether that, or default
to SSIZE_MAX (note the documentation mistakenly talks about SIZE_MAX / 2
instead) and use MIN (SIZE_MAX, user_specified_value) for user specified
value, or error out if user_specified_value is larger than
SSIZE_MAX or larger than SIZE_MAX.  Also the else unit = 0; case
probably should get diagnostics.  Another issue is if we want to diagnose,
that right now it will be diagnosed only if some allocation routine is seen,
diagnosing stuff during option processing is unfortunately too early because
we don't have sizetype/ssizetype built yet.

Anyway, the following has been bootstrapped/regtested on x86_64-linux and
i686-linux.

2017-08-03  Jakub Jelinek  <ja...@redhat.com>

        PR driver/81650
        * calls.c (alloc_max_size): Use HOST_WIDE_INT_UC (10??)
        instead of 10??LU, perform unit multiplication in wide_int,
        don't change alloc_object_size_limit if the limit is larger
        than SSIZE_MAX.

        * gcc.dg/pr81650.c: New test.

--- gcc/calls.c.jj      2017-06-12 12:42:01.000000000 +0200
+++ gcc/calls.c 2017-08-02 13:41:00.887324420 +0200
@@ -1222,32 +1222,38 @@ alloc_max_size (void)
                  else if (!strcasecmp (end, "KiB") || strcmp (end, "KB"))
                    unit = 1024;
                  else if (!strcmp (end, "MB"))
-                   unit = 1000LU * 1000;
+                   unit = HOST_WIDE_INT_UC (1000) * 1000;
                  else if (!strcasecmp (end, "MiB"))
-                   unit = 1024LU * 1024;
+                   unit = HOST_WIDE_INT_UC (1024) * 1024;
                  else if (!strcasecmp (end, "GB"))
-                   unit = 1000LU * 1000 * 1000;
+                   unit = HOST_WIDE_INT_UC (1000) * 1000 * 1000;
                  else if (!strcasecmp (end, "GiB"))
-                   unit = 1024LU * 1024 * 1024;
+                   unit = HOST_WIDE_INT_UC (1024) * 1024 * 1024;
                  else if (!strcasecmp (end, "TB"))
-                   unit = 1000LU * 1000 * 1000 * 1000;
+                   unit = HOST_WIDE_INT_UC (1000) * 1000 * 1000 * 1000;
                  else if (!strcasecmp (end, "TiB"))
-                   unit = 1024LU * 1024 * 1024 * 1024;
+                   unit = HOST_WIDE_INT_UC (1024) * 1024 * 1024 * 1024;
                  else if (!strcasecmp (end, "PB"))
-                   unit = 1000LU * 1000 * 1000 * 1000 * 1000;
+                   unit = HOST_WIDE_INT_UC (1000) * 1000 * 1000 * 1000 * 1000;
                  else if (!strcasecmp (end, "PiB"))
-                   unit = 1024LU * 1024 * 1024 * 1024 * 1024;
+                   unit = HOST_WIDE_INT_UC (1024) * 1024 * 1024 * 1024 * 1024;
                  else if (!strcasecmp (end, "EB"))
-                   unit = 1000LU * 1000 * 1000 * 1000 * 1000 * 1000;
+                   unit = HOST_WIDE_INT_UC (1000) * 1000 * 1000 * 1000 * 1000
+                          * 1000;
                  else if (!strcasecmp (end, "EiB"))
-                   unit = 1024LU * 1024 * 1024 * 1024 * 1024 * 1024;
+                   unit = HOST_WIDE_INT_UC (1024) * 1024 * 1024 * 1024 * 1024
+                          * 1024;
                  else
                    unit = 0;
                }
 
              if (unit)
-               alloc_object_size_limit
-                 = build_int_cst (ssizetype, limit * 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);
+               }
            }
        }
     }
--- gcc/testsuite/gcc.dg/pr81650.c.jj   2017-08-02 14:52:22.864787221 +0200
+++ gcc/testsuite/gcc.dg/pr81650.c      2017-08-02 14:21:11.000000000 +0200
@@ -0,0 +1,9 @@
+/* PR driver/81650 */
+/* { dg-do compile } */
+/* { dg-options "-Walloc-size-larger-than=9223372036854775807" } */
+
+void *
+foo (void)
+{
+  return __builtin_malloc (5);
+}

        Jakub

Reply via email to