From 5aca3c4b037937a6ff5b9352e926e7b8a0a53ede Mon Sep 17 00:00:00 2001 From: "Paul A. Patience" Date: Mon, 14 Feb 2022 10:41:07 +0000 Subject: Fix various instances of implicit conversions. The implicit conversions were discovered with Clang's UBSan (with the -fsanitizer=implicit-conversion option). * gc.c (sweep_one): Convert only the inverted REACHABLE, since block->t.type is already of the right type. * hash.c (eql_hash, eq_hash, hash_iter_init, us_hash_iter_init): Explicitly convert to ucnum. * linenoise/linenoise.c (enable_raw_mode): Explicitly convert the inverted flag sets to tcflag_t. * mpi/mpi.c (mp_set_uintptr): Explicitly convert to uint_ptr_t. * regex.c (char_set_add): Explicitly convert to bitcell_t. * struct.c (struct_inst_hash): Correct type of hash from cnum to ucnum. --- gc.c | 2 +- hash.c | 14 +++++++------- linenoise/linenoise.c | 4 ++-- mpi/mpi.c | 2 +- regex.c | 3 ++- struct.c | 2 +- 6 files changed, 14 insertions(+), 13 deletions(-) diff --git a/gc.c b/gc.c index 0c727ed4..311f66d2 100644 --- a/gc.c +++ b/gc.c @@ -606,7 +606,7 @@ static int sweep_one(obj_t *block) #if CONFIG_GEN_GC block->t.gen = 1; #endif - block->t.type = convert(type_t, block->t.type & ~REACHABLE); + block->t.type &= convert(type_t, ~REACHABLE); return 0; } diff --git a/hash.c b/hash.c index dcbd31b2..1b3030c2 100644 --- a/hash.c +++ b/hash.c @@ -395,7 +395,7 @@ static ucnum eql_hash(val obj, int *count) case NIL: return convert(ucnum, -1); case BGNUM: - return mp_hash(mp(obj)); + return convert(ucnum, mp_hash(mp(obj))); case FLNUM: return hash_double(obj->fl.n); case RNG: @@ -409,9 +409,9 @@ static ucnum eql_hash(val obj, int *count) } } case TAG_CHR: - return c_chr(obj); + return convert(ucnum, c_chr(obj)); case TAG_NUM: - return c_num(obj, self); + return convert(ucnum, c_num(obj, self)); case TAG_LIT: switch (CHAR_BIT * sizeof (mem_t *)) { case 32: @@ -437,9 +437,9 @@ static ucnum eq_hash(val obj) return coerce(ucnum, obj) >> 5; } case TAG_CHR: - return c_chr(obj); + return convert(ucnum, c_chr(obj)); case TAG_NUM: - return c_num(obj, self); + return convert(ucnum, c_num(obj, self)); case TAG_LIT: switch (CHAR_BIT * sizeof (mem_t *)) { case 32: @@ -1204,7 +1204,7 @@ void hash_iter_init(struct hash_iter *hi, val hash, val self) { struct hash *h = coerce(struct hash *, cobj_handle(self, hash, hash_cls)); hi->next = 0; - hi->chain = -1; + hi->chain = convert(ucnum, -1); hi->cons = nil; hi->hash = hash; h->usecount++; @@ -1214,7 +1214,7 @@ void us_hash_iter_init(struct hash_iter *hi, val hash) { struct hash *h = coerce(struct hash *, hash->co.handle); hi->next = 0; - hi->chain = -1; + hi->chain = convert(ucnum, -1); hi->cons = nil; hi->hash = hash; h->usecount++; diff --git a/linenoise/linenoise.c b/linenoise/linenoise.c index 920c45d9..b3645a18 100644 --- a/linenoise/linenoise.c +++ b/linenoise/linenoise.c @@ -283,13 +283,13 @@ static int enable_raw_mode(lino_t *ls) { raw = ls->orig_termios; /* modify the original mode */ /* input modes: no break, no CR to NL, no parity check, no strip char, * no start/stop output control. */ - raw.c_iflag &= ~(BRKINT | ICRNL | INPCK | ISTRIP | IXON); + raw.c_iflag &= convert(tcflag_t, ~(BRKINT | ICRNL | INPCK | ISTRIP | IXON)); /* we don't change any output modes (c_oflag) */ /* control modes - set 8 bit chars */ raw.c_cflag |= (CS8); /* local modes - choing off, canonical off, no extended functions, * no signal chars (^Z,^C) */ - raw.c_lflag &= ~(ECHO | ICANON | IEXTEN | ISIG); + raw.c_lflag &= convert(tcflag_t, ~(ECHO | ICANON | IEXTEN | ISIG)); /* control chars - set return condition: min number of bytes and timer. * We want read to return every single byte, without timeout. */ raw.c_cc[VMIN] = 1; raw.c_cc[VTIME] = 0; /* 1 byte, no timer */ diff --git a/mpi/mpi.c b/mpi/mpi.c index a1541d8b..34003253 100644 --- a/mpi/mpi.c +++ b/mpi/mpi.c @@ -421,7 +421,7 @@ mp_err mp_set_uintptr(mp_int *mp, uint_ptr_t z) mp_err mp_set_intptr(mp_int *mp, int_ptr_t z) { - uint_ptr_t w = z; + uint_ptr_t w = convert(uint_ptr_t, z); uint_ptr_t v = z >= 0 ? w : -w; mp_err err = mp_set_uintptr(mp, v); diff --git a/regex.c b/regex.c index a9ac0a5c..1d971625 100644 --- a/regex.c +++ b/regex.c @@ -597,7 +597,8 @@ static void char_set_add(char_set_t *set, wchar_t ch) /* fallthrough */ case CHSET_SMALL: assert (ch < 256); - set->s.bitcell[CHAR_SET_INDEX(ch)] |= (1 << CHAR_SET_BIT(ch)); + set->s.bitcell[CHAR_SET_INDEX(ch)] |= + convert(bitcell_t, 1) << CHAR_SET_BIT(ch); break; case CHSET_LARGE: assert (ch < 0x10000); diff --git a/struct.c b/struct.c index 592c439b..c4b58785 100644 --- a/struct.c +++ b/struct.c @@ -1852,7 +1852,7 @@ static ucnum struct_inst_hash(val obj, int *count, ucnum seed) check_init_lazy_struct(obj, si); for (sl = 0; sl < nslots; sl++) { - cnum hash = equal_hash(si->slot[sl], count, seed); + ucnum hash = equal_hash(si->slot[sl], count, seed); out += hash; out &= NUM_MAX; } -- cgit v1.2.3