public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [patch] Fix segfault caused by spurious constant overflow
@ 2019-05-31 10:31 Eric Botcazou
  2019-05-31 11:44 ` Richard Biener
  0 siblings, 1 reply; 5+ messages in thread
From: Eric Botcazou @ 2019-05-31 10:31 UTC (permalink / raw)
  To: gcc-patches

[-- Attachment #1: Type: text/plain, Size: 2057 bytes --]

Hi,

this is a regression present for 32-bit targets on mainline and 9 branch only, 
but the underlying issue dates back from the removal of the TYPE_IS_SIZETYPE 
machinery.  Since the removal of this machinery, there is an internal conflict 
for sizetype: it's an unsigned type so with wrap-around semantics on overflow 
but overflow nevertheless needs to be tracked for it in order to avoid buffer 
overflows for large objects.

The constant folder contains various tricks to that effect and the Ada front-
end even more so, because VLAs are first-class citizens in the language and 
their lower bound is not necessarily 0.  In particular, you need to be able to 
distinguish large constants in sizetype from small negative constants turned 
into even larger constants, because the latter appear in the length of e.g.:

  type Arr is array (2 .. N) of Long_Long_Integer;

This works when the expressions haven't been too much mangled by the constant 
folder and here we have a counter-example for 32-bit targets.  Starting with:

  (N + 4294967295) * 8

which is the sizetype expression of the size of Arr in bytes, extract_muldiv_1 
distributes the multiplication:

  N * 8 + 4294967288

and, immediately after, fold_plusminus_mult_expr factors it back:

  (N + 536870911) * 8

At this point, there is no way for gigi to tell that it's the expression of a 
simple array with no overflow in sight because the 536870911 constant is large 
but not large enough, so gigi flags it as overflowing for small values of N.

I don't see any other way out than disabling the back-and-forth mathematical 
game played by the constant folder in this case, which very likely brings no 
benefit in practice, hence the proposed fix.

Tested on x86_64-suse-linux, OK for the mainline and 9 branch?


2019-05-31  Eric Botcazou  <ebotcazou@adacore.com>

	* fold-const.c (extract_muldiv_1) <PLUS_EXPR>: Do not distribute a
	multiplication by a power-of-two value.


2019-05-31  Eric Botcazou  <ebotcazou@adacore.com>

	* gnat.dg/specs/discr6.ads: New test.

-- 
Eric Botcazou

[-- Attachment #2: p.diff --]
[-- Type: text/x-patch, Size: 980 bytes --]

Index: fold-const.c
===================================================================
--- fold-const.c	(revision 271694)
+++ fold-const.c	(working copy)
@@ -6475,8 +6475,13 @@ extract_muldiv_1 (tree t, tree c, enum t
 	 apply the distributive law to commute the multiply and addition
 	 if the multiplication of the constants doesn't overflow
 	 and overflow is defined.  With undefined overflow
-	 op0 * c might overflow, while (op0 + orig_op1) * c doesn't.  */
-      if (code == MULT_EXPR && TYPE_OVERFLOW_WRAPS (ctype))
+	 op0 * c might overflow, while (op0 + orig_op1) * c doesn't.
+	 But fold_plusminus_mult_expr would factor back any power-of-two
+	 value so do not distribute in the first place in this case.  */
+      if (code == MULT_EXPR
+	  && TYPE_OVERFLOW_WRAPS (ctype)
+	  && !(tree_fits_shwi_p (c)
+	       && exact_log2 (absu_hwi (tree_to_shwi (c))) > 0))
 	return fold_build2 (tcode, ctype,
 			    fold_build2 (code, ctype,
 					 fold_convert (ctype, op0),

[-- Attachment #3: discr6.ads --]
[-- Type: text/x-adasrc, Size: 404 bytes --]

-- { dg-do compile }

package Discr6 is

  subtype Index_T is Integer range 0 .. 15;

  type Arr is array (Index_T range <> ) of Long_Long_Integer;

  type Rec2 (Size : Index_T := 2) is record
    A : Arr (2 .. Size);
  end record;

  type Rec3 (D : Boolean := False) is record
    R : Rec2;
    case D is
      when False=> null;
      when True => I : Integer;
    end case;
  end record;

end Discr6;

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2019-06-04 15:06 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-05-31 10:31 [patch] Fix segfault caused by spurious constant overflow Eric Botcazou
2019-05-31 11:44 ` Richard Biener
2019-05-31 16:17   ` Eric Botcazou
2019-06-03 10:38   ` Eric Botcazou
2019-06-04 15:06     ` Richard Biener

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).