This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] Fix PR81088


The associate case in folding ignores overflow when one of the literals
involved has TREE_OVERFLOW set.  That is obviously wrong as TREE_OVERFLOW
doesn't necessarily mean sth undefined happened (and thus GIGO) as we
are setting TREE_OVERFLOW also on implementation-defined unsigned->int
conversions.

Simply drop that wart and the overflow flag from literals in split_tree
to avoid doing less than before.

Bootstrapped and tested on x86_64-unknown-linux-gnu, applied to trunk
sofar.

Richard.

2017-06-14  Richard Biener  <rguenther@suse.de>

	PR middle-end/81088
	* fold-const.c (split_tree): Drop TREE_OVERFLOW flag from
	literal constants.
	(fold_binary_loc): When associating do not treat pre-existing
	TREE_OVERFLOW on literal constants as a reason to allow
	TREE_OVERFLOW on associated literal constants.

	* c-c++-common/ubsan/pr81088.c: New testcase.

Index: gcc/fold-const.c
===================================================================
*** gcc/fold-const.c	(revision 249185)
--- gcc/fold-const.c	(working copy)
*************** split_tree (location_t loc, tree in, tre
*** 880,885 ****
--- 880,892 ----
  	}
      }
  
+   if (*litp
+       && TREE_OVERFLOW_P (*litp))
+     *litp = drop_tree_overflow (*litp);
+   if (*minus_litp
+       && TREE_OVERFLOW_P (*minus_litp))
+     *minus_litp = drop_tree_overflow (*minus_litp);
+ 
    return var;
  }
  
*************** fold_binary_loc (location_t loc,
*** 9703,9713 ****
  		       + (lit0 != 0) + (lit1 != 0)
  		       + (minus_lit0 != 0) + (minus_lit1 != 0))))
  	    {
- 	      bool any_overflows = false;
- 	      if (lit0) any_overflows |= TREE_OVERFLOW (lit0);
- 	      if (lit1) any_overflows |= TREE_OVERFLOW (lit1);
- 	      if (minus_lit0) any_overflows |= TREE_OVERFLOW (minus_lit0);
- 	      if (minus_lit1) any_overflows |= TREE_OVERFLOW (minus_lit1);
  	      var0 = associate_trees (loc, var0, var1, code, atype);
  	      con0 = associate_trees (loc, con0, con1, code, atype);
  	      lit0 = associate_trees (loc, lit0, lit1, code, atype);
--- 9710,9715 ----
*************** fold_binary_loc (location_t loc,
*** 9738,9746 ****
  		}
  
  	      /* Don't introduce overflows through reassociation.  */
! 	      if (!any_overflows
! 		  && ((lit0 && TREE_OVERFLOW_P (lit0))
! 		      || (minus_lit0 && TREE_OVERFLOW_P (minus_lit0))))
  		return NULL_TREE;
  
  	      if (minus_lit0)
--- 9740,9747 ----
  		}
  
  	      /* Don't introduce overflows through reassociation.  */
! 	      if ((lit0 && TREE_OVERFLOW_P (lit0))
! 		  || (minus_lit0 && TREE_OVERFLOW_P (minus_lit0)))
  		return NULL_TREE;
  
  	      if (minus_lit0)
Index: gcc/testsuite/c-c++-common/ubsan/pr81088.c
===================================================================
*** gcc/testsuite/c-c++-common/ubsan/pr81088.c	(nonexistent)
--- gcc/testsuite/c-c++-common/ubsan/pr81088.c	(working copy)
***************
*** 0 ****
--- 1,11 ----
+ /* { dg-do run } */
+ /* { dg-options "-fsanitize=undefined -fsanitize-undefined-trap-on-error" } */
+ 
+ short s = 2;
+ short y = 1;
+ int i;
+ int main()
+ {
+   i = -(s + (int)(~(unsigned)(0 / y))) + 0x7fffffff;
+   return 0;
+ }


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]