<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>