[llvm-bugs] [Bug 46373] New: Attempting to seed std::linear_congruential_engine<> that has a modulus of 0 results in divide by zero

via llvm-bugs llvm-bugs at lists.llvm.org
Wed Jun 17 23:06:08 PDT 2020


https://bugs.llvm.org/show_bug.cgi?id=46373

            Bug ID: 46373
           Summary: Attempting to seed std::linear_congruential_engine<>
                    that has a modulus of 0 results in divide by zero
           Product: libc++
           Version: unspecified
          Hardware: All
                OS: All
            Status: NEW
          Severity: normal
          Priority: P
         Component: All Bugs
          Assignee: unassignedclangbugs at nondot.org
          Reporter: dgreenaway at google.com
                CC: llvm-bugs at lists.llvm.org, mclow.lists at gmail.com

Instantiating a

  std::linear_congruential_engine<UIntType, a, c, m>

with a value 0 for "m" indicates that the linear congruential engine should use
the full size of the UIntType, instead of explicitly performing a mod operation
after each iteration.

While most of the code for std::linear_congruential_engine appears to correctly
handle m == 0, attempting to seed the engine from a generator triggers a divide
by zero:

    #include <random>
    #include <stdint.h>

    std::random_device device;
    std::seed_seq seq{device(), device()};
    std::linear_congruential_engine<uint64_t, 6364136223846793005,
1442695040888963407, 0> rng(seq);  // divide by zero

The problem appears to be in the "__seed" function inside the "random" header:

    template <class _UIntType, _UIntType __a, _UIntType __c, _UIntType __m>
    template<class _Sseq>
    void
    linear_congruential_engine<_UIntType, __a, __c, __m>::__seed(_Sseq& __q,
                                                    
integral_constant<unsigned, 2>)
    {
        const unsigned __k = 2;
        uint32_t __ar[__k+3];
        __q.generate(__ar, __ar + __k + 3);
        result_type __s = static_cast<result_type>((__ar[3] +
                                                  ((uint64_t)__ar[4] << 32)) %
__m);
        __x_ = __c == 0 && __s == 0 ? result_type(1) : __s;
    }

where we perform a "... % __m" operation without confirming that __m is
non-zero.

I believe this could be resolved by only performing the mod when "__m != 0".

-- 
You are receiving this mail because:
You are on the CC list for the bug.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-bugs/attachments/20200618/7a62cdfe/attachment-0001.html>


More information about the llvm-bugs mailing list