* include/c_global/cstddef (std::byte): Perform arithmetic operations in unsigned int to avoid promotion (LWG 2950).
Tested x86_64-linux, committed to trunk.
commit bfa356b2a9353d1f0b7ccc38f3787d5a4f3044ae Author: redi <redi@138bc75d-0d04-0410-961f-82ee72b054a4> Date: Tue Jun 18 11:39:43 2019 +0000 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 diff --git a/libstdc++-v3/include/c_global/cstddef b/libstdc++-v3/include/c_global/cstddef index 8c779ec354d..c94c938f6f3 100644 --- a/libstdc++-v3/include/c_global/cstddef +++ b/libstdc++-v3/include/c_global/cstddef @@ -120,71 +120,53 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION template<typename _IntegerType> using __byte_op_t = typename __byte_operand<_IntegerType>::__type; - template<typename _IntegerType> - constexpr __byte_op_t<_IntegerType>& - operator<<=(byte& __b, _IntegerType __shift) noexcept - { return __b = byte(static_cast<unsigned char>(__b) << __shift); } - template<typename _IntegerType> constexpr __byte_op_t<_IntegerType> operator<<(byte __b, _IntegerType __shift) noexcept - { return byte(static_cast<unsigned char>(__b) << __shift); } - - template<typename _IntegerType> - constexpr __byte_op_t<_IntegerType>& - operator>>=(byte& __b, _IntegerType __shift) noexcept - { return __b = byte(static_cast<unsigned char>(__b) >> __shift); } + { return (byte)(unsigned char)((unsigned)__b << __shift); } template<typename _IntegerType> constexpr __byte_op_t<_IntegerType> operator>>(byte __b, _IntegerType __shift) noexcept - { return byte(static_cast<unsigned char>(__b) >> __shift); } - - constexpr byte& - operator|=(byte& __l, byte __r) noexcept - { - return __l = - byte(static_cast<unsigned char>(__l) | static_cast<unsigned char>(__r)); - } + { return (byte)(unsigned char)((unsigned)__b >> __shift); } constexpr byte operator|(byte __l, byte __r) noexcept - { - return - byte(static_cast<unsigned char>(__l) | static_cast<unsigned char>(__r)); - } - - constexpr byte& - operator&=(byte& __l, byte __r) noexcept - { - return __l = - byte(static_cast<unsigned char>(__l) & static_cast<unsigned char>(__r)); - } + { return (byte)(unsigned char)((unsigned)__l | (unsigned)__r); } constexpr byte operator&(byte __l, byte __r) noexcept - { - return - byte(static_cast<unsigned char>(__l) & static_cast<unsigned char>(__r)); - } - - constexpr byte& - operator^=(byte& __l, byte __r) noexcept - { - return __l = - byte(static_cast<unsigned char>(__l) ^ static_cast<unsigned char>(__r)); - } + { return (byte)(unsigned char)((unsigned)__l & (unsigned)__r); } constexpr byte operator^(byte __l, byte __r) noexcept - { - return - byte(static_cast<unsigned char>(__l) ^ static_cast<unsigned char>(__r)); - } + { return (byte)(unsigned char)((unsigned)__l ^ (unsigned)__r); } constexpr byte operator~(byte __b) noexcept - { return byte(~static_cast<unsigned char>(__b)); } + { return (byte)(unsigned char)~(unsigned)__b; } + + template<typename _IntegerType> + constexpr __byte_op_t<_IntegerType>& + operator<<=(byte& __b, _IntegerType __shift) noexcept + { return __b = __b << __shift; } + + template<typename _IntegerType> + 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<typename _IntegerType> constexpr _IntegerType