This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] Fix PR81088
- From: Richard Biener <rguenther at suse dot de>
- To: gcc-patches at gcc dot gnu dot org
- Date: Wed, 14 Jun 2017 13:39:39 +0200 (CEST)
- Subject: [PATCH] Fix PR81088
- Authentication-results: sourceware.org; auth=none
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;
+ }