[PATCH] Perform ubsan instrumentation for x >= 0 ? x : -x
Richard Biener
rguenther@suse.de
Tue Mar 25 09:13:00 GMT 2014
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 <jakub@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 <rguenther@suse.de>
SUSE / SUSE Labs
SUSE LINUX Products GmbH - Nuernberg - AG Nuernberg - HRB 16746
GF: Jeff Hawn, Jennifer Guild, Felix Imend"orffer
More information about the Gcc-patches
mailing list