<html>
    <head>
      <base href="https://bugs.llvm.org/">
    </head>
    <body><table border="1" cellspacing="0" cellpadding="8">
        <tr>
          <th>Bug ID</th>
          <td><a class="bz_bug_link 
          bz_status_NEW "
   title="NEW - Attempting to seed std::linear_congruential_engine<> that has a modulus of 0 results in divide by zero"
   href="https://bugs.llvm.org/show_bug.cgi?id=46373">46373</a>
          </td>
        </tr>

        <tr>
          <th>Summary</th>
          <td>Attempting to seed std::linear_congruential_engine<> that has a modulus of 0 results in divide by zero
          </td>
        </tr>

        <tr>
          <th>Product</th>
          <td>libc++
          </td>
        </tr>

        <tr>
          <th>Version</th>
          <td>unspecified
          </td>
        </tr>

        <tr>
          <th>Hardware</th>
          <td>All
          </td>
        </tr>

        <tr>
          <th>OS</th>
          <td>All
          </td>
        </tr>

        <tr>
          <th>Status</th>
          <td>NEW
          </td>
        </tr>

        <tr>
          <th>Severity</th>
          <td>normal
          </td>
        </tr>

        <tr>
          <th>Priority</th>
          <td>P
          </td>
        </tr>

        <tr>
          <th>Component</th>
          <td>All Bugs
          </td>
        </tr>

        <tr>
          <th>Assignee</th>
          <td>unassignedclangbugs@nondot.org
          </td>
        </tr>

        <tr>
          <th>Reporter</th>
          <td>dgreenaway@google.com
          </td>
        </tr>

        <tr>
          <th>CC</th>
          <td>llvm-bugs@lists.llvm.org, mclow.lists@gmail.com
          </td>
        </tr></table>
      <p>
        <div>
        <pre>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".</pre>
        </div>
      </p>


      <hr>
      <span>You are receiving this mail because:</span>

      <ul>
          <li>You are on the CC list for the bug.</li>
      </ul>
    </body>
</html>