<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 - [bit.pow.two] functions use wrong constraints for -funsigned-char"
href="https://bugs.llvm.org/show_bug.cgi?id=49450">49450</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>[bit.pow.two] functions use wrong constraints for -funsigned-char
</td>
</tr>
<tr>
<th>Product</th>
<td>libc++
</td>
</tr>
<tr>
<th>Version</th>
<td>11.0
</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>zilla@kayari.org
</td>
</tr>
<tr>
<th>CC</th>
<td>llvm-bugs@lists.llvm.org, mclow.lists@gmail.com
</td>
</tr></table>
<p>
<div>
<pre>This C++20 program is ill-formed, because the "Integral powers of 2" functions
in <bit> are all constrained to only work for the unsigned integer types (as
defined in [basic.types] p2).
#include <bit>
static_assert( std::popcount('0') == 0 );
On targets where char is signed, it fails as expected:
bit.C:2:16: error: no matching function for call to 'popcount'
static_assert( std::popcount('0') == 0 );
^~~~~~~~~~~~~
/usr/bin/../include/c++/v1/bit:417:1: note: candidate template ignored:
requirement 'integral_constant<bool, false>::value' was not satisfied [with _Tp
= char]
popcount(_Tp __t) noexcept
^
1 error generated.
But on Aarch64 (or any target using -funsigned-char) the call to popcount
compiles:
bit.C:2:1: error: static_assert failed due to requirement 'std::popcount('0')
== 0'
static_assert( std::popcount('0') == 0 );
^ ~~~~~~~~~~~~~~~~~~~~~~~~
1 error generated.
The problem is in the __bitop_unsigned_integer constraint, fixed by this patch:
diff --git a/libcxx/include/bit b/libcxx/include/bit
index f8c37c3d6bbf..21b9dcafdb37 100644
--- a/libcxx/include/bit
+++ b/libcxx/include/bit
@@ -83,7 +83,7 @@ using __bitop_unsigned_integer _LIBCPP_NODEBUG_TYPE =
integral_constant<bool,
is_integral<_Tp>::value &&
is_unsigned<_Tp>::value &&
_IsNotSame<typename remove_cv<_Tp>::type, bool>::value &&
- _IsNotSame<typename remove_cv<_Tp>::type, signed char>::value &&
+ _IsNotSame<typename remove_cv<_Tp>::type, char>::value &&
_IsNotSame<typename remove_cv<_Tp>::type, wchar_t>::value &&
_IsNotSame<typename remove_cv<_Tp>::type, char16_t>::value &&
_IsNotSame<typename remove_cv<_Tp>::type, char32_t>::value
There's no need to exclude signed char, because is_unsigned<_Tp> already did
that. But you do need to exclude plain char, because is_integral<char> is true
and is_unsigned<char> is sometimes true, but char is not an unsigned integer
type.</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>