diff mbox

Fix UB in dwarf2out.c (PR debug/78587)

Message ID 20161130190242.GB3541@tucnak.redhat.com
State New
Headers show

Commit Message

Jakub Jelinek Nov. 30, 2016, 7:02 p.m. UTC
Hi!

This patch fixes 3 spots with UB in dwarf2out.c, furthermore the first spot
results in smaller/better debug info.

Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

2016-11-30  Jakub Jelinek  <jakub@redhat.com>

	PR debug/78587
	* dwarf2out.c (loc_descr_plus_const): For negative offset use
	uint_loc_descriptor instead of int_loc_descriptor and perform negation
	in unsigned HOST_WIDE_INT type.
	(scompare_loc_descriptor): Shift UINTVAL left instead of INTVAL.

	* gcc.dg/debug/pr78587.c: New test.


	Jakub

Comments

Richard Biener Dec. 1, 2016, 9:14 a.m. UTC | #1
On Wed, Nov 30, 2016 at 8:02 PM, Jakub Jelinek <jakub@redhat.com> wrote:
> Hi!
>
> This patch fixes 3 spots with UB in dwarf2out.c, furthermore the first spot
> results in smaller/better debug info.
>
> Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

Ok.

Thanks,
Richard.

> 2016-11-30  Jakub Jelinek  <jakub@redhat.com>
>
>         PR debug/78587
>         * dwarf2out.c (loc_descr_plus_const): For negative offset use
>         uint_loc_descriptor instead of int_loc_descriptor and perform negation
>         in unsigned HOST_WIDE_INT type.
>         (scompare_loc_descriptor): Shift UINTVAL left instead of INTVAL.
>
>         * gcc.dg/debug/pr78587.c: New test.
>
> --- gcc/dwarf2out.c.jj  2016-11-18 22:55:19.000000000 +0100
> +++ gcc/dwarf2out.c     2016-11-30 15:16:39.402673343 +0100
> @@ -1514,7 +1514,8 @@ loc_descr_plus_const (dw_loc_descr_ref *
>
>    else
>      {
> -      loc->dw_loc_next = int_loc_descriptor (-offset);
> +      loc->dw_loc_next
> +       = uint_loc_descriptor (-(unsigned HOST_WIDE_INT) offset);
>        add_loc_descr (&loc->dw_loc_next, new_loc_descr (DW_OP_minus, 0, 0));
>      }
>  }
> @@ -13837,7 +13838,7 @@ scompare_loc_descriptor (enum dwarf_loca
>        if (CONST_INT_P (XEXP (rtl, 1))
>           && GET_MODE_BITSIZE (op_mode) < HOST_BITS_PER_WIDE_INT
>           && (size_of_int_loc_descriptor (shift) + 1
> -             + size_of_int_loc_descriptor (INTVAL (XEXP (rtl, 1)) << shift)
> +             + size_of_int_loc_descriptor (UINTVAL (XEXP (rtl, 1)) << shift)
>               >= size_of_int_loc_descriptor (GET_MODE_MASK (op_mode)) + 1
>                  + size_of_int_loc_descriptor (INTVAL (XEXP (rtl, 1))
>                                                & GET_MODE_MASK (op_mode))))
> @@ -13852,7 +13853,7 @@ scompare_loc_descriptor (enum dwarf_loca
>    add_loc_descr (&op0, int_loc_descriptor (shift));
>    add_loc_descr (&op0, new_loc_descr (DW_OP_shl, 0, 0));
>    if (CONST_INT_P (XEXP (rtl, 1)))
> -    op1 = int_loc_descriptor (INTVAL (XEXP (rtl, 1)) << shift);
> +    op1 = int_loc_descriptor (UINTVAL (XEXP (rtl, 1)) << shift);
>    else
>      {
>        add_loc_descr (&op1, int_loc_descriptor (shift));
> --- gcc/testsuite/gcc.dg/debug/pr78587.c.jj     2016-11-30 15:01:08.855153232 +0100
> +++ gcc/testsuite/gcc.dg/debug/pr78587.c        2016-11-30 15:20:22.000000000 +0100
> @@ -0,0 +1,23 @@
> +/* PR debug/78587 */
> +/* { dg-do compile } */
> +/* { dg-additional-options "-w" } */
> +
> +extern void bar (void);
> +
> +void
> +foo (long long x)
> +{
> +  x ^= 9223372036854775808ULL;
> +  bar ();
> +}
> +
> +struct S { int w[4]; } a[1], b;
> +
> +void
> +baz ()
> +{
> +  int e = (int) baz;
> +  if (e <= -80)
> +    e = 0;
> +  b = a[e];
> +}
>
>         Jakub
diff mbox

Patch

--- gcc/dwarf2out.c.jj	2016-11-18 22:55:19.000000000 +0100
+++ gcc/dwarf2out.c	2016-11-30 15:16:39.402673343 +0100
@@ -1514,7 +1514,8 @@  loc_descr_plus_const (dw_loc_descr_ref *
 
   else
     {
-      loc->dw_loc_next = int_loc_descriptor (-offset);
+      loc->dw_loc_next
+	= uint_loc_descriptor (-(unsigned HOST_WIDE_INT) offset);
       add_loc_descr (&loc->dw_loc_next, new_loc_descr (DW_OP_minus, 0, 0));
     }
 }
@@ -13837,7 +13838,7 @@  scompare_loc_descriptor (enum dwarf_loca
       if (CONST_INT_P (XEXP (rtl, 1))
 	  && GET_MODE_BITSIZE (op_mode) < HOST_BITS_PER_WIDE_INT
 	  && (size_of_int_loc_descriptor (shift) + 1
-	      + size_of_int_loc_descriptor (INTVAL (XEXP (rtl, 1)) << shift)
+	      + size_of_int_loc_descriptor (UINTVAL (XEXP (rtl, 1)) << shift)
 	      >= size_of_int_loc_descriptor (GET_MODE_MASK (op_mode)) + 1
 		 + size_of_int_loc_descriptor (INTVAL (XEXP (rtl, 1))
 					       & GET_MODE_MASK (op_mode))))
@@ -13852,7 +13853,7 @@  scompare_loc_descriptor (enum dwarf_loca
   add_loc_descr (&op0, int_loc_descriptor (shift));
   add_loc_descr (&op0, new_loc_descr (DW_OP_shl, 0, 0));
   if (CONST_INT_P (XEXP (rtl, 1)))
-    op1 = int_loc_descriptor (INTVAL (XEXP (rtl, 1)) << shift);
+    op1 = int_loc_descriptor (UINTVAL (XEXP (rtl, 1)) << shift);
   else
     {
       add_loc_descr (&op1, int_loc_descriptor (shift));
--- gcc/testsuite/gcc.dg/debug/pr78587.c.jj	2016-11-30 15:01:08.855153232 +0100
+++ gcc/testsuite/gcc.dg/debug/pr78587.c	2016-11-30 15:20:22.000000000 +0100
@@ -0,0 +1,23 @@ 
+/* PR debug/78587 */
+/* { dg-do compile } */
+/* { dg-additional-options "-w" } */
+
+extern void bar (void);
+
+void
+foo (long long x)
+{
+  x ^= 9223372036854775808ULL;
+  bar ();
+}
+
+struct S { int w[4]; } a[1], b;
+
+void
+baz ()
+{
+  int e = (int) baz;
+  if (e <= -80)
+    e = 0;
+  b = a[e];
+}