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: [email protected]
Reporter: [email protected]
CC: [email protected], [email protected]
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._______________________________________________
llvm-bugs mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-bugs