On Tue, 25 Mar 2014, Jakub Jelinek wrote: > 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?
Can't one form a valid constant expression using this? Also isn't ABS_EXPR undefined for LONG_MIN as well? So why is ubsan not instrumenting that instead? Thanks, Richard. > 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 > > -- Richard Biener <rguent...@suse.de> SUSE / SUSE Labs SUSE LINUX Products GmbH - Nuernberg - AG Nuernberg - HRB 16746 GF: Jeff Hawn, Jennifer Guild, Felix Imend"orffer