From: Nathan Sidwell Date: Wed, 20 Jan 2021 17:21:02 +0000 (-0800) Subject: c++: Avoid UB in signed shift [PR 98625] X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=911f797a9be2dc8ef59f5d5bd6d68baf650b8822;p=gcc.git c++: Avoid UB in signed shift [PR 98625] I'd forgotten that left shifting a negative value is UB until C++20. Insert some casts to do unsigned shifts. PT c++/98625 gcc/cp/ * module.cc (bytes_in::i, bytes_in::wi): Avoid left shift of signed type. --- diff --git a/gcc/cp/module.cc b/gcc/cp/module.cc index 3b40c7ead05..7f88e3fea89 100644 --- a/gcc/cp/module.cc +++ b/gcc/cp/module.cc @@ -878,9 +878,12 @@ bytes_in::i () v &= 0xf; if (v & 0x8) v |= -1 ^ 0x7; + /* unsigned necessary due to left shifts of -ve values. */ + unsigned uv = unsigned (v); if ((ptr = read (++bytes))) while (bytes--) - v = (v << 8) | (*ptr++ & 0xff); + uv = (uv << 8) | (*ptr++ & 0xff); + v = int (uv); } else if (v & 0x40) v |= -1 ^ 0x3f; @@ -969,9 +972,12 @@ bytes_in::wi () v &= 0xf; if (v & 0x8) v |= -1 ^ 0x7; + /* unsigned necessary due to left shifts of -ve values. */ + unsigned HOST_WIDE_INT uv = (unsigned HOST_WIDE_INT) v; if ((ptr = read (++bytes))) while (bytes--) - v = (v << 8) | (*ptr++ & 0xff); + uv = (uv << 8) | (*ptr++ & 0xff); + v = (HOST_WIDE_INT) uv; } else if (v & 0x40) v |= -1 ^ 0x3f;