Hi, On Tue, 4 Sep 2018, Aldy Hernandez wrote:
> > to make the result ~[0, 5], is it? At least the original code dropped > > that to VARYING. For the same reason truncating [3, 765] from > > short to unsigned char isn't [3, 253]. But maybe I'm missing something. Sorry for chiming in, but this catched my eye: > Correct, but in that case we will realize that in wide_int_range_convert and > refuse to do the conversion: > > /* If the conversion is not truncating we can convert the min and > max values and canonicalize the resulting range. Otherwise we > can do the conversion if the size of the range is less than what > the precision of the target type can represent. */ > if (outer_prec >= inner_prec > || wi::rshift (wi::sub (vr0_max, vr0_min), > wi::uhwi (outer_prec, inner_prec), > inner_sign) == 0) (followed by this code:) + { + min = widest_int::from (vr0_min, inner_sign); + max = widest_int::from (vr0_max, inner_sign); + widest_int min_value + = widest_int::from (wi::min_value (outer_prec, outer_sign),outer_sign); + widest_int max_value + = widest_int::from (wi::max_value (outer_prec, outer_sign),outer_sign); + return !wi::eq_p (min, min_value) || !wi::eq_p (max, max_value); + } + return false; How can this test and following code catch all problematic cases? Assume a range of [253..257], truncating to 8 bits unsigned. The size of the range is 5 (not 4 as the code above calculates), well representable in 8 bits. Nevertheless, the min of the new range isn't 253, nor is the max of the new range 257. In fact the new range must be [0..255] (if you have no multi ranges or anti-ranges). So whatever this function is supposed to do (what btw?), it certainly does not convert a range. Ciao, Michael.