[llvm-bugs] [Bug 49450] New: [bit.pow.two] functions use wrong constraints for -funsigned-char
via llvm-bugs
llvm-bugs at lists.llvm.org
Fri Mar 5 03:45:32 PST 2021
https://bugs.llvm.org/show_bug.cgi?id=49450
Bug ID: 49450
Summary: [bit.pow.two] functions use wrong constraints for
-funsigned-char
Product: libc++
Version: 11.0
Hardware: All
OS: All
Status: NEW
Severity: normal
Priority: P
Component: All Bugs
Assignee: unassignedclangbugs at nondot.org
Reporter: zilla at kayari.org
CC: llvm-bugs at lists.llvm.org, mclow.lists at gmail.com
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.
--
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/20210305/51cca1f3/attachment.html>
More information about the llvm-bugs
mailing list