diff mbox

Some -Walloc-size-larger-than= warning fixes (PR driver/81650)

Message ID 20170803084300.GS2123@tucnak
State New
Headers show

Commit Message

Jakub Jelinek Aug. 3, 2017, 8:43 a.m. UTC
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  <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.


	Jakub

Comments

Richard Biener Aug. 3, 2017, 8:59 a.m. UTC | #1
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
> 
>
diff mbox

Patch

--- 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);
+}