diff mbox series

Fix ubsan on mingw hosts (PR sanitizer/83014)

Message ID 20171123204036.GU14653@tucnak
State New
Headers show
Series Fix ubsan on mingw hosts (PR sanitizer/83014) | expand

Commit Message

Jakub Jelinek Nov. 23, 2017, 8:40 p.m. UTC
Hi!

From my reading of the PR and looking around, I believe the reason
ubsan ICEs on mingw hosts is that it is the only host that redefines
HOST_LONG_LONG_FORMAT to "I64" instead of the usual "ll", but "%I64"
is nothing pp_format can handle, and indeed this spot in ubsan.c is
the only place that calls pp_printf with HOST_WIDE_INT_PRINT_DEC
or similar format specifier.  Instead, other spots use
pp_unsigned_wide_integer or pp_scalar on top of which it is defined
that does:
      sprintf (pp_buffer (PP)->digit_buffer, FORMAT, SCALAR); \
      pp_string (PP, pp_buffer (PP)->digit_buffer);           \
and thus uses the host *printf which handles "I64" and appends that
as a string.

Bootstrapped/regtested on x86_64-linux and i686-linux, no way to test
on mingw.  Ok for trunk? 

2017-11-23  Jakub Jelinek  <jakub@redhat.com>

	PR sanitizer/83014
	* ubsan.c (ubsan_type_descriptor): Use pp_unsigned_wide_integer
	instead of pp_printf with HOST_WIDE_INT_PRINT_DEC.  Avoid calling
	tree_to_uhwi twice.

	* gcc.dg/ubsan/pr83014.c: New test.


	Jakub

Comments

Richard Biener Nov. 24, 2017, 8:02 a.m. UTC | #1
On Thu, 23 Nov 2017, Jakub Jelinek wrote:

> Hi!
> 
> From my reading of the PR and looking around, I believe the reason
> ubsan ICEs on mingw hosts is that it is the only host that redefines
> HOST_LONG_LONG_FORMAT to "I64" instead of the usual "ll", but "%I64"
> is nothing pp_format can handle, and indeed this spot in ubsan.c is
> the only place that calls pp_printf with HOST_WIDE_INT_PRINT_DEC
> or similar format specifier.  Instead, other spots use
> pp_unsigned_wide_integer or pp_scalar on top of which it is defined
> that does:
>       sprintf (pp_buffer (PP)->digit_buffer, FORMAT, SCALAR); \
>       pp_string (PP, pp_buffer (PP)->digit_buffer);           \
> and thus uses the host *printf which handles "I64" and appends that
> as a string.
> 
> Bootstrapped/regtested on x86_64-linux and i686-linux, no way to test
> on mingw.  Ok for trunk? 

Ok.

Richard.

> 2017-11-23  Jakub Jelinek  <jakub@redhat.com>
> 
> 	PR sanitizer/83014
> 	* ubsan.c (ubsan_type_descriptor): Use pp_unsigned_wide_integer
> 	instead of pp_printf with HOST_WIDE_INT_PRINT_DEC.  Avoid calling
> 	tree_to_uhwi twice.
> 
> 	* gcc.dg/ubsan/pr83014.c: New test.
> 
> --- gcc/ubsan.c.jj	2017-11-13 09:31:33.000000000 +0100
> +++ gcc/ubsan.c	2017-11-23 11:35:20.452162632 +0100
> @@ -436,10 +436,10 @@ ubsan_type_descriptor (tree type, enum u
>  	      && TYPE_MAX_VALUE (dom) != NULL_TREE
>  	      && TREE_CODE (TYPE_MAX_VALUE (dom)) == INTEGER_CST)
>  	    {
> +	      unsigned HOST_WIDE_INT m;
>  	      if (tree_fits_uhwi_p (TYPE_MAX_VALUE (dom))
> -		  && tree_to_uhwi (TYPE_MAX_VALUE (dom)) + 1 != 0)
> -		pp_printf (&pretty_name, HOST_WIDE_INT_PRINT_DEC,
> -			    tree_to_uhwi (TYPE_MAX_VALUE (dom)) + 1);
> +		  && (m = tree_to_uhwi (TYPE_MAX_VALUE (dom))) + 1 != 0)
> +		pp_unsigned_wide_integer (&pretty_name, m + 1);
>  	      else
>  		pp_wide_int (&pretty_name,
>  			     wi::add (wi::to_widest (TYPE_MAX_VALUE (dom)), 1),
> --- gcc/testsuite/gcc.dg/ubsan/pr83014.c.jj	2017-11-23 11:52:59.613932074 +0100
> +++ gcc/testsuite/gcc.dg/ubsan/pr83014.c	2017-11-23 11:53:30.867542456 +0100
> @@ -0,0 +1,12 @@
> +/* PR sanitizer/83014 */
> +/* { dg-do compile } */
> +/* { dg-options "-fsanitize=undefined" } */
> +
> +int
> +foo (void)
> +{
> +  int data[5];
> +  data[0] = 0;
> +  data[5] = 0;
> +  return data[0];
> +}
> 
> 	Jakub
> 
>
diff mbox series

Patch

--- gcc/ubsan.c.jj	2017-11-13 09:31:33.000000000 +0100
+++ gcc/ubsan.c	2017-11-23 11:35:20.452162632 +0100
@@ -436,10 +436,10 @@  ubsan_type_descriptor (tree type, enum u
 	      && TYPE_MAX_VALUE (dom) != NULL_TREE
 	      && TREE_CODE (TYPE_MAX_VALUE (dom)) == INTEGER_CST)
 	    {
+	      unsigned HOST_WIDE_INT m;
 	      if (tree_fits_uhwi_p (TYPE_MAX_VALUE (dom))
-		  && tree_to_uhwi (TYPE_MAX_VALUE (dom)) + 1 != 0)
-		pp_printf (&pretty_name, HOST_WIDE_INT_PRINT_DEC,
-			    tree_to_uhwi (TYPE_MAX_VALUE (dom)) + 1);
+		  && (m = tree_to_uhwi (TYPE_MAX_VALUE (dom))) + 1 != 0)
+		pp_unsigned_wide_integer (&pretty_name, m + 1);
 	      else
 		pp_wide_int (&pretty_name,
 			     wi::add (wi::to_widest (TYPE_MAX_VALUE (dom)), 1),
--- gcc/testsuite/gcc.dg/ubsan/pr83014.c.jj	2017-11-23 11:52:59.613932074 +0100
+++ gcc/testsuite/gcc.dg/ubsan/pr83014.c	2017-11-23 11:53:30.867542456 +0100
@@ -0,0 +1,12 @@ 
+/* PR sanitizer/83014 */
+/* { dg-do compile } */
+/* { dg-options "-fsanitize=undefined" } */
+
+int
+foo (void)
+{
+  int data[5];
+  data[0] = 0;
+  data[5] = 0;
+  return data[0];
+}