From: Jonathan Wakely Date: Tue, 18 Jun 2019 11:39:43 +0000 (+0100) Subject: Avoid undefined behaviour in std::byte operators (LWG 2950) X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=0c65926ffa960ddbe7df9ea86328f8905df861cf;p=gcc.git 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). From-SVN: r272415 --- diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index 40d1b0beb2c..4570ab147d5 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 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 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