Message ID | 20170803084300.GS2123@tucnak |
---|---|
State | New |
Headers | show |
On Thu, 3 Aug 2017, Jakub Jelinek wrote: > 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. Ok. Richard. > 2017-08-03 Jakub Jelinek <jakub@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 > >
--- 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); +}