From: Stefan Liebler Date: Wed, 18 Oct 2023 13:08:40 +0000 (+0200) Subject: s390: Fix undefined behaviour in feenableexcept, fedisableexcept [BZ #30960] X-Git-Tag: glibc-2.39~360 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=97a58d885b01ecf432e0d96248556245a232597e;p=thirdparty%2Fglibc.git s390: Fix undefined behaviour in feenableexcept, fedisableexcept [BZ #30960] If feenableexcept or fedisableexcept gets excepts=FE_INVALID=0x80 as input, we have a signed left shift: 0x80 << 24 which is not representable as int and thus is undefined behaviour according to C standard. This patch casts excepts as unsigned int before shifting, which is defined. For me, the observed undefined behaviour is that the shift is done with "unsigned"-instructions, which is exactly what we want. Furthermore, I don't get any exception-flags. After the fix, the code is using the same instruction sequence as before. --- diff --git a/sysdeps/s390/fpu/fedisblxcpt.c b/sysdeps/s390/fpu/fedisblxcpt.c index 728f103f43a..55634c299fa 100644 --- a/sysdeps/s390/fpu/fedisblxcpt.c +++ b/sysdeps/s390/fpu/fedisblxcpt.c @@ -26,7 +26,8 @@ fedisableexcept (int excepts) _FPU_GETCW (temp); old_exc = (temp & FPC_EXCEPTION_MASK) >> FPC_EXCEPTION_MASK_SHIFT; - new_flags = (temp & (~((excepts & FE_ALL_EXCEPT) << FPC_EXCEPTION_MASK_SHIFT))); + new_flags = (temp & ~(((unsigned int) excepts & FE_ALL_EXCEPT) + << FPC_EXCEPTION_MASK_SHIFT)); _FPU_SETCW (new_flags); return old_exc; diff --git a/sysdeps/s390/fpu/feenablxcpt.c b/sysdeps/s390/fpu/feenablxcpt.c index 0807e610a21..d73659f0781 100644 --- a/sysdeps/s390/fpu/feenablxcpt.c +++ b/sysdeps/s390/fpu/feenablxcpt.c @@ -26,7 +26,8 @@ feenableexcept (int excepts) _FPU_GETCW (temp); old_exc = (temp & FPC_EXCEPTION_MASK) >> FPC_EXCEPTION_MASK_SHIFT; - new_flags = (temp | ((excepts & FE_ALL_EXCEPT) << FPC_EXCEPTION_MASK_SHIFT)); + new_flags = (temp | (((unsigned int) excepts & FE_ALL_EXCEPT) + << FPC_EXCEPTION_MASK_SHIFT)); _FPU_SETCW (new_flags); return old_exc;