From 911f797a9be2dc8ef59f5d5bd6d68baf650b8822 Mon Sep 17 00:00:00 2001 From: Nathan Sidwell Date: Wed, 20 Jan 2021 09:21:02 -0800 Subject: [PATCH] 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. --- gcc/cp/module.cc | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) 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; -- 2.30.2