From 97a58d885b01ecf432e0d96248556245a232597e Mon Sep 17 00:00:00 2001 From: Stefan Liebler Date: Wed, 18 Oct 2023 15:08:40 +0200 Subject: 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. --- sysdeps/s390/fpu/fedisblxcpt.c | 3 ++- sysdeps/s390/fpu/feenablxcpt.c | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/sysdeps/s390/fpu/fedisblxcpt.c b/sysdeps/s390/fpu/fedisblxcpt.c index 728f103..55634c2 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 0807e61..d73659f 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; -- cgit v1.1