From bfa356b2a9353d1f0b7ccc38f3787d5a4f3044ae Mon Sep 17 00:00:00 2001 From: redi Date: Tue, 18 Jun 2019 11:39:43 +0000 Subject: [PATCH] Avoid undefined behaviour in std::byte operators (LWG 2950) * include/c_global/cstddef (std::byte): Perform arithmetic operations in unsigned int to avoid promotion (LWG 2950). git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@272415 138bc75d-0d04-0410-961f-82ee72b054a4 --- libstdc++-v3/ChangeLog | 5 ++ libstdc++-v3/include/c_global/cstddef | 74 ++++++++++----------------- 2 files changed, 33 insertions(+), 46 deletions(-) diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index 40d1b0beb2ca..4570ab147d51 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,8 @@ +2019-06-18 Jonathan Wakely + + * include/c_global/cstddef (std::byte): Perform arithmetic operations + in unsigned int to avoid promotion (LWG 2950). + 2019-06-17 Jonathan Wakely * testsuite/20_util/allocator/1.cc: Add sized delete, which fixes a diff --git a/libstdc++-v3/include/c_global/cstddef b/libstdc++-v3/include/c_global/cstddef index 8c779ec354d8..c94c938f6f3c 100644 --- a/libstdc++-v3/include/c_global/cstddef +++ b/libstdc++-v3/include/c_global/cstddef @@ -120,71 +120,53 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION template using __byte_op_t = typename __byte_operand<_IntegerType>::__type; - template - constexpr __byte_op_t<_IntegerType>& - operator<<=(byte& __b, _IntegerType __shift) noexcept - { return __b = byte(static_cast(__b) << __shift); } - template constexpr __byte_op_t<_IntegerType> operator<<(byte __b, _IntegerType __shift) noexcept - { return byte(static_cast(__b) << __shift); } - - template - constexpr __byte_op_t<_IntegerType>& - operator>>=(byte& __b, _IntegerType __shift) noexcept - { return __b = byte(static_cast(__b) >> __shift); } + { return (byte)(unsigned char)((unsigned)__b << __shift); } template constexpr __byte_op_t<_IntegerType> operator>>(byte __b, _IntegerType __shift) noexcept - { return byte(static_cast(__b) >> __shift); } - - constexpr byte& - operator|=(byte& __l, byte __r) noexcept - { - return __l = - byte(static_cast(__l) | static_cast(__r)); - } + { return (byte)(unsigned char)((unsigned)__b >> __shift); } constexpr byte operator|(byte __l, byte __r) noexcept - { - return - byte(static_cast(__l) | static_cast(__r)); - } - - constexpr byte& - operator&=(byte& __l, byte __r) noexcept - { - return __l = - byte(static_cast(__l) & static_cast(__r)); - } + { return (byte)(unsigned char)((unsigned)__l | (unsigned)__r); } constexpr byte operator&(byte __l, byte __r) noexcept - { - return - byte(static_cast(__l) & static_cast(__r)); - } - - constexpr byte& - operator^=(byte& __l, byte __r) noexcept - { - return __l = - byte(static_cast(__l) ^ static_cast(__r)); - } + { return (byte)(unsigned char)((unsigned)__l & (unsigned)__r); } constexpr byte operator^(byte __l, byte __r) noexcept - { - return - byte(static_cast(__l) ^ static_cast(__r)); - } + { return (byte)(unsigned char)((unsigned)__l ^ (unsigned)__r); } constexpr byte operator~(byte __b) noexcept - { return byte(~static_cast(__b)); } + { return (byte)(unsigned char)~(unsigned)__b; } + + template + constexpr __byte_op_t<_IntegerType>& + operator<<=(byte& __b, _IntegerType __shift) noexcept + { return __b = __b << __shift; } + + template + constexpr __byte_op_t<_IntegerType>& + operator>>=(byte& __b, _IntegerType __shift) noexcept + { return __b = __b >> __shift; } + + constexpr byte& + operator|=(byte& __l, byte __r) noexcept + { return __l = __l | __r; } + + constexpr byte& + operator&=(byte& __l, byte __r) noexcept + { return __l = __l & __r; } + + constexpr byte& + operator^=(byte& __l, byte __r) noexcept + { return __l = __l ^ __r; } template constexpr _IntegerType -- 2.39.2