[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