[PATCH][C-family] Fix PR61184

Richard Biener rguenther@suse.de
Wed May 14 09:08:00 GMT 2014


The following fixes pre/post-inc/dec gimplification of promoted
integer types.  There is the issue with the way TYPE_OVERFLOW_UNDEFINED
is related to TYPE_OVERFLOW_WRAPS and the (non-)semantics of
-fno-strict-overflow.

In this case, with -On -fno-strict-overflow for a variable of
type short we have !TYPE_OVERFLOW_WRAPS _and_ !TYPE_OVERFLOW_UNDEFINED
(so we're in an "undefined" area).  Which means that
!TYPE_OVERFLOW_UNDEFINED doesn't imply that overflow wraps.

Thus the gimplification has to play on the safe side and
always use an unsigned type unless the user specifies -fwrapv
(the flag with a proper semantic meaning).

That is, it seems to be the case that what predicate to use
(TYPE_OVERFLOW_WRAPS or TYPE_OVERFLOW_UNDEFINED, independent
on whether you invert it), depends on the use-case in a very
awkward (and error-prone) way.

Bootstrap and regtest pending on x86_64-unknown-linux-gnu, ok
if that succeeds (I expect to have to adjust some testcases)?

Thanks,
Richard.

2014-05-14  Richard Biener  <rguenther@suse.de>

	c-family/
	* c-gimplify.c (c_gimplify_expr): Gimplify self-modify expressions
	using unsigned arithmetic if overflow does not wrap instead of
	if overflow is undefined.

	* c-c++-common/torture/pr61184.c: New testcase.

Index: gcc/c-family/c-gimplify.c
===================================================================
*** gcc/c-family/c-gimplify.c	(revision 210354)
--- gcc/c-family/c-gimplify.c	(working copy)
*************** c_gimplify_expr (tree *expr_p, gimple_se
*** 199,207 ****
  	tree type = TREE_TYPE (TREE_OPERAND (*expr_p, 0));
  	if (INTEGRAL_TYPE_P (type) && c_promoting_integer_type_p (type))
  	  {
! 	    if (TYPE_OVERFLOW_UNDEFINED (type)
! 		|| ((flag_sanitize & SANITIZE_SI_OVERFLOW)
! 		    && !TYPE_OVERFLOW_WRAPS (type)))
  	      type = unsigned_type_for (type);
  	    return gimplify_self_mod_expr (expr_p, pre_p, post_p, 1, type);
  	  }
--- 199,205 ----
  	tree type = TREE_TYPE (TREE_OPERAND (*expr_p, 0));
  	if (INTEGRAL_TYPE_P (type) && c_promoting_integer_type_p (type))
  	  {
! 	    if (!TYPE_OVERFLOW_WRAPS (type))
  	      type = unsigned_type_for (type);
  	    return gimplify_self_mod_expr (expr_p, pre_p, post_p, 1, type);
  	  }
Index: gcc/testsuite/c-c++-common/torture/pr61184.c
===================================================================
*** gcc/testsuite/c-c++-common/torture/pr61184.c	(revision 0)
--- gcc/testsuite/c-c++-common/torture/pr61184.c	(working copy)
***************
*** 0 ****
--- 1,18 ----
+ /* { dg-do run } */
+ /* { dg-additional-options "-fno-strict-overflow" } */
+ 
+ short a; 
+ 
+ void
+ foo (void)
+ {
+   for (a = 0; a >= 0; a++)
+     ;
+ }
+ 
+ int
+ main ()
+ {
+   foo ();
+   return 0;
+ }



More information about the Gcc-patches mailing list