aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJonathan Wakely <jwakely@redhat.com>2019-06-18 12:39:43 +0100
committerJonathan Wakely <redi@gcc.gnu.org>2019-06-18 12:39:43 +0100
commit0c65926ffa960ddbe7df9ea86328f8905df861cf (patch)
tree597b8d18820d74dc4f718ec184bdf2ab2798d236
parent5ed12b58ef022b5186edc6c31eb05addc828fd8b (diff)
downloadgcc-0c65926ffa960ddbe7df9ea86328f8905df861cf.zip
gcc-0c65926ffa960ddbe7df9ea86328f8905df861cf.tar.gz
gcc-0c65926ffa960ddbe7df9ea86328f8905df861cf.tar.bz2
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
-rw-r--r--libstdc++-v3/ChangeLog5
-rw-r--r--libstdc++-v3/include/c_global/cstddef74
2 files changed, 33 insertions, 46 deletions
diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog
index 40d1b0b..4570ab1 100644
--- a/libstdc++-v3/ChangeLog
+++ b/libstdc++-v3/ChangeLog
@@ -1,3 +1,8 @@
+2019-06-18 Jonathan Wakely <jwakely@redhat.com>
+
+ * include/c_global/cstddef (std::byte): Perform arithmetic operations
+ in unsigned int to avoid promotion (LWG 2950).
+
2019-06-17 Jonathan Wakely <jwakely@redhat.com>
* 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 8c779ec..c94c938 100644
--- a/libstdc++-v3/include/c_global/cstddef
+++ b/libstdc++-v3/include/c_global/cstddef
@@ -121,70 +121,52 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
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