aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2020-10-28 10:24:20 +0100
committerJakub Jelinek <jakub@redhat.com>2020-10-28 10:24:20 +0100
commit279a9ce9d545f65a0bb1bc4564abafabfc25f82d (patch)
treedf958d1e0e695632ae03c0146e37513e99eebff3 /gcc
parent2241061463ad43de95eb7d3e07546bcb5efa8607 (diff)
downloadgcc-279a9ce9d545f65a0bb1bc4564abafabfc25f82d.zip
gcc-279a9ce9d545f65a0bb1bc4564abafabfc25f82d.tar.gz
gcc-279a9ce9d545f65a0bb1bc4564abafabfc25f82d.tar.bz2
wide-int: Fix up set_bit_large
> >> wide_int new_lb = wi::set_bit (r.lower_bound (0), 127) > >> > >> and creates the value: > >> > >> p new_lb > >> {<wide_int_storage> = {val = {-65535, -1, 0}, len = 2, precision = 128}, > >> static is_sign_extended = true} > > > > This is non-canonical and so invalid, if the low HWI has the MSB set > > and the high HWI is -1, it should have been just > > val = {-65535}, len = 1, precision = 128} > > > > I guess the bug is that wi::set_bit_large doesn't call canonize. > > Yeah, looks like a micro-optimisation gone wrong. 2020-10-28 Jakub Jelinek <jakub@redhat.com> * wide-int.cc (wi::set_bit_large): Call canonize unless setting msb bit and clearing bits above it.
Diffstat (limited to 'gcc')
-rw-r--r--gcc/wide-int.cc7
1 files changed, 5 insertions, 2 deletions
diff --git a/gcc/wide-int.cc b/gcc/wide-int.cc
index f4d949c..99d7ded 100644
--- a/gcc/wide-int.cc
+++ b/gcc/wide-int.cc
@@ -702,8 +702,11 @@ wi::set_bit_large (HOST_WIDE_INT *val, const HOST_WIDE_INT *xval,
/* If the bit we just set is at the msb of the block, make sure
that any higher bits are zeros. */
if (bit + 1 < precision && subbit == HOST_BITS_PER_WIDE_INT - 1)
- val[len++] = 0;
- return len;
+ {
+ val[len++] = 0;
+ return len;
+ }
+ return canonize (val, len, precision);
}
else
{