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 <ja...@redhat.com> 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