This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [PATCH] Implement -fsanitize=float-cast-overflow
- From: "Joseph S. Myers" <joseph at codesourcery dot com>
- To: Jakub Jelinek <jakub at redhat dot com>
- Cc: Marek Polacek <polacek at redhat dot com>, GCC Patches <gcc-patches at gcc dot gnu dot org>
- Date: Wed, 14 May 2014 17:37:25 +0000
- Subject: Re: [PATCH] Implement -fsanitize=float-cast-overflow
- Authentication-results: sourceware.org; auth=none
- References: <20140513170801 dot GG2663 at redhat dot com> <Pine dot LNX dot 4 dot 64 dot 1405131745570 dot 23277 at digraph dot polyomino dot org dot uk> <20140514113839 dot GE10386 at tucnak dot redhat dot com>
On Wed, 14 May 2014, Jakub Jelinek wrote:
> So what do you see as the way to handle this properly?
> I mean, for REAL_MODE_FORMAT (TYPE_MODE (expr_type))->b == 2 supposedly to avoid issues with
> rounding of the max we could just
> REAL_VALUE_TYPE maxval = dconst1;
> SET_REAL_EXP (&maxval, REAL_EXP (&maxval) + TYPE_PRECISION (type) - !TYPE_UNSIGNED (type));
> real_convert (&maxval, TYPE_MODE (expr_type), &maxval);
> max = build_real (expr_type, maxval);
> or so, then supposedly max is always the smallest representable binary
> floating point value above or equal to TYPE_MAX_VALUE + 1.0.
Yes. Either the power of 2 is exactly representable, or it rounds up to
+Inf, and in either case >= (or unordered) is the right test.
> For the min value, if it is unsigned, then -1.0 is ok for all binary or
> decimal floats, if it is signed, then supposedly we could do the above
Yes.
> with s/max/min/;s/dconst1/dconstm1/; and, after the real_convert
> do inexact = real_arithmetic (&newminval, MINUS_EXPR, &minval, &dconst1);
> if !inexact just min = build_real (expr_type, newminval); and be done with
> it (the question is if for IBM double double this will DTRT for
> LONG_LONG_MIN, which I think should be that the high double will contain
> (double) LONG_LONG_MIN and the low double -1.0). For inexact
> (which should be the same thing as if result of real_arithmetic + real_convert
> is the same as original minval) we need to subtract more than one, dunno if
> we should just compute it from the REAL_EXP and precision, or just keep
> subtracing powers of two until after real_convert it is no longer bitwise
> identical to original minval. We don't have anything close to
> real_nextafter nor real_convert variant that can round for arbitrary
> rounding modes.
> Any preferences how to implement this?
In the inexact case but where the power of 2 is representable, you could
always handle it as < min rather than <= min-1 - although computing the
actual nextafter value based on the precision of the floating-point type
shouldn't be hard and would allow <= to be used everywhere.
(If min overflows to -Inf, then <= -Inf is correct, use of < would be an
incorrect test.)
> For _Decimal*, no idea unfortunately, perhaps for the first iteration
> ubsan should ignore decimal to int conversions.
Yes, that seems reasonable. (Computing the exact max+1 or min-1 as an
MPFR value and then using mpfr_snprintf (then decimal_real_from_string)
would be one way of converting to decimal with a controlled rounding
direction.)
--
Joseph S. Myers
joseph@codesourcery.com