[PATCH] Avoid undefined behaviour in std::byte operators (LWG 2950)
Jonathan Wakely
jwakely@redhat.com
Tue Jun 18 11:40:00 GMT 2019
* include/c_global/cstddef (std::byte): Perform arithmetic operations
in unsigned int to avoid promotion (LWG 2950).
Tested x86_64-linux, committed to trunk.
-------------- next part --------------
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
More information about the Libstdc++
mailing list