Hi!
While Marek has been debugging while some perl test fails when perl is built
with GCC 4.9, we've discovered that it is because of undefined behavior in
it:
...
&& (((UV)1 << NV_PRESERVES_UV_BITS) >
(UV)(SvIVX(sv) > 0 ? SvIVX(sv) : -SvIVX(sv)))
where SvIVX(sv) can be LONG_MIN, at which point there is undefined behavior
on the negation, but -fsanitize=undefined did detect only other issues in
the same source file and not this one, because fold-const.c folded it into
ABS_EXPR early.
This patch disables such folding, because all the A op 0 ? A : -A
operations this if is trying to optimize will need instrumentation with
-fsanitize=signed-integer-overflow.
Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?
2014-03-25 Jakub Jelinek <[email protected]>
PR sanitizer/60636
* fold-const.c (fold_cond_expr_with_comparison): Don't
fold A op 0 ? A : -A if -fsanitize=undefined.
* c-c++-common/ubsan/pr60636.c: New test.
--- gcc/fold-const.c.jj 2014-01-03 11:40:35.000000000 +0100
+++ gcc/fold-const.c 2014-03-24 17:59:45.395445617 +0100
@@ -4718,7 +4718,13 @@ fold_cond_expr_with_comparison (location
&& operand_equal_p (TREE_OPERAND (arg1, 0),
TREE_OPERAND (arg2, 1), 0)
&& operand_equal_p (TREE_OPERAND (arg1, 1),
- TREE_OPERAND (arg2, 0), 0))))
+ TREE_OPERAND (arg2, 0), 0)))
+ /* Don't fold this if sanitizing undefined behavior,
+ -A or Y-X might overflow and after folding this we wouldn't
+ be able to detect that. */
+ && ((flag_sanitize & SANITIZE_SI_OVERFLOW) == 0
+ || !INTEGRAL_TYPE_P (TREE_TYPE (arg01))
+ || TYPE_OVERFLOW_WRAPS (TREE_TYPE (arg01))))
switch (comp_code)
{
case EQ_EXPR:
--- gcc/testsuite/c-c++-common/ubsan/pr60636.c.jj 2014-03-24
18:04:33.875925324 +0100
+++ gcc/testsuite/c-c++-common/ubsan/pr60636.c 2014-03-24 18:09:18.696419079
+0100
@@ -0,0 +1,15 @@
+/* PR sanitizer/60636 */
+/* { dg-do run } */
+/* { dg-options "-fsanitize=undefined" } */
+
+volatile long long int a;
+
+int
+main ()
+{
+ long long int u = -__LONG_LONG_MAX__ - 1;
+ a = u > 0 ? u : -u;
+ return 0;
+}
+
+/* { dg-output "negation of -9223372036854775808 cannot be represented in type
'long long int'" } */
Jakub