Hi folks!

Calling print_hex() on a widest_int with the most significant bit turned on can lead to a leading zero being printed (0x0ffff....). This produces confusing dumps to say the least, especially when you incorrectly assume an integer is NOT signed :).

OK for trunk?
gcc/

	* wide-int-print.cc (print_hex): Avoid printing a leading zero.
	* wide-int.cc (test_printing): Add test for hex dumping of
	a widest_int conversion.

diff --git a/gcc/wide-int-print.cc b/gcc/wide-int-print.cc
index 36d8ad863f5..36a681d4b73 100644
--- a/gcc/wide-int-print.cc
+++ b/gcc/wide-int-print.cc
@@ -123,7 +123,13 @@ print_hex (const wide_int_ref &wi, char *buf)
 
 	}
       else
-	buf += sprintf (buf, "0x" HOST_WIDE_INT_PRINT_HEX_PURE, wi.elt (--i));
+	{
+	  buf += sprintf (buf, "0x");
+	  --i;
+	  /* Avoid printing a leading zero.  */
+	  if (wi.elt (i))
+	    buf += sprintf (buf, HOST_WIDE_INT_PRINT_HEX_PURE, wi.elt (i));
+	}
 
       while (--i >= 0)
 	buf += sprintf (buf, HOST_WIDE_INT_PRINT_PADDED_HEX, wi.elt (i));
diff --git a/gcc/wide-int.cc b/gcc/wide-int.cc
index 71e24ec22af..123a70fa9b8 100644
--- a/gcc/wide-int.cc
+++ b/gcc/wide-int.cc
@@ -2220,6 +2220,14 @@ test_printing ()
   VALUE_TYPE a = from_int<VALUE_TYPE> (42);
   assert_deceq ("42", a, SIGNED);
   assert_hexeq ("0x2a", a);
+
+  /* Test that converting to widest_int still produces a sane hex
+     representation.  */
+  VALUE_TYPE big = from_int<VALUE_TYPE> (0xffffffff);
+  widest_int huge = widest_int::from (big, UNSIGNED);
+  char buf[WIDE_INT_PRINT_BUFFER_SIZE];
+  print_hex (huge, buf);
+  ASSERT_TRUE (buf[0] == '0' && buf[1] == 'x' && buf[2] == 'f');
 }
 
 /* Verify that various operations work correctly for VALUE_TYPE,

Reply via email to