瀏覽代碼

Do the math in uniform_int_distribution::operator() as unsigned to prevent UB when overflowing. Also add a UBSAN notification that we're ffine with unsigned overflow. This fixes PR#32617. Thanks to Vincent & Christoph for their help with this issue.

git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@343996 91177308-0d34-0410-b5e6-96231b3b80d8
Marshall Clow 6 年之前
父節點
當前提交
c7cc66995c
共有 1 個文件被更改,包括 3 次插入2 次删除
  1. 3 2
      include/algorithm

+ 3 - 2
include/algorithm

@@ -2899,10 +2899,11 @@ template<class _IntType>
 template<class _URNG>
 template<class _URNG>
 typename uniform_int_distribution<_IntType>::result_type
 typename uniform_int_distribution<_IntType>::result_type
 uniform_int_distribution<_IntType>::operator()(_URNG& __g, const param_type& __p)
 uniform_int_distribution<_IntType>::operator()(_URNG& __g, const param_type& __p)
+_LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK
 {
 {
     typedef typename conditional<sizeof(result_type) <= sizeof(uint32_t),
     typedef typename conditional<sizeof(result_type) <= sizeof(uint32_t),
                                             uint32_t, uint64_t>::type _UIntType;
                                             uint32_t, uint64_t>::type _UIntType;
-    const _UIntType _Rp = __p.b() - __p.a() + _UIntType(1);
+    const _UIntType _Rp = _UIntType(__p.b()) - _UIntType(__p.a()) + _UIntType(1);
     if (_Rp == 1)
     if (_Rp == 1)
         return __p.a();
         return __p.a();
     const size_t _Dt = numeric_limits<_UIntType>::digits;
     const size_t _Dt = numeric_limits<_UIntType>::digits;
@@ -2989,7 +2990,7 @@ random_shuffle(_RandomAccessIterator __first, _RandomAccessIterator __last,
         {
         {
             difference_type __i = __rand(__d);
             difference_type __i = __rand(__d);
             if (__i != difference_type(0))
             if (__i != difference_type(0))
-	            swap(*__first, *(__first + __i));
+              swap(*__first, *(__first + __i));
         }
         }
     }
     }
 }
 }