-
Notifications
You must be signed in to change notification settings - Fork 13.6k
[libc++][test] Fix MSVC warnings with static_cast
s
#74962
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[libc++][test] Fix MSVC warnings with static_cast
s
#74962
Conversation
…st int', possible loss of data". libcxx/test/std/containers/insert_range_helpers.h defines: template <class T> struct TestCase { // ... std::size_t index = 0; libcxx/test/support/test_allocator.h defines: template <class T> class test_allocator { // ... typedef int difference_type; A targeted static_cast seemed better than suppressing this warning in every affected test.
container.h(41): warning C4267: 'initializing': conversion from 'size_t' to 'int', possible loss of data container.h(57): warning C4267: 'initializing': conversion from 'size_t' to 'int', possible loss of data container.h(73): warning C4244: 'initializing': conversion from 'ptrdiff_t' to 'int', possible loss of data
This was x86-specific for me. The LHS is int and the RHS is size_t. We know the array's size, so static_cast<int> is certainly safe, and this matches the following numberOfProj comparisons.
… 'size_t', possible loss of data". This was x86-specific for me. The args are indeed int64_t, and we're storing the result in size_t, so we should cast.
…o 'const _Ty', possible loss of data" concat_macros.h(55): warning C4244: 'argument': conversion from 'char16_t' to 'const _Ty', possible loss of data with [ _Ty=char ] concat_macros.h(72): warning C4244: 'argument': conversion from 'unsigned int' to 'const _Ty', possible loss of data with [ _Ty=char ] etc.
… expected value." `static_cast<std::size_t>` silences the warning. It's *almost* annoying enough to outright disable, but we use similar static_casts to deal with sign/truncation warnings elsewhere, because there's some value in ensuring that product code is clean with respect to these warnings. (If there were many more occurrences, then disabling the warning would be appropriate.)
These were inconsistent.
@llvm/pr-subscribers-libcxx Author: Stephan T. Lavavej (StephanTLavavej) ChangesFound while running libc++'s tests with MSVC's STL.
Full diff: https://github.com/llvm/llvm-project/pull/74962.diff 12 Files Affected:
diff --git a/libcxx/test/std/algorithms/alg.modifying.operations/alg.unique/ranges_unique_copy.pass.cpp b/libcxx/test/std/algorithms/alg.modifying.operations/alg.unique/ranges_unique_copy.pass.cpp
index b84600b92c2b29..a4cf97069c96a0 100644
--- a/libcxx/test/std/algorithms/alg.modifying.operations/alg.unique/ranges_unique_copy.pass.cpp
+++ b/libcxx/test/std/algorithms/alg.modifying.operations/alg.unique/ranges_unique_copy.pass.cpp
@@ -418,7 +418,7 @@ constexpr bool test() {
assert(std::ranges::equal(out, expected));
assert(base(result.in) == in.end());
assert(base(result.out) == out.end());
- assert(numberOfComp == in.size() - 1);
+ assert(numberOfComp == static_cast<int>(in.size() - 1));
assert(numberOfProj <= static_cast<int>(2 * (in.size() - 1)));
}
// range overload
@@ -434,7 +434,7 @@ constexpr bool test() {
assert(std::ranges::equal(out, expected));
assert(base(result.in) == in.end());
assert(base(result.out) == out.end());
- assert(numberOfComp == in.size() - 1);
+ assert(numberOfComp == static_cast<int>(in.size() - 1));
assert(numberOfProj <= static_cast<int>(2 * (in.size() - 1)));
}
}
diff --git a/libcxx/test/std/containers/sequences/insert_range_sequence_containers.h b/libcxx/test/std/containers/sequences/insert_range_sequence_containers.h
index b77b2510eae230..6e8fa1c2058714 100644
--- a/libcxx/test/std/containers/sequences/insert_range_sequence_containers.h
+++ b/libcxx/test/std/containers/sequences/insert_range_sequence_containers.h
@@ -427,7 +427,8 @@ template <> constexpr TestCase<int> FullContainer_End_LongRange<bool> {
template <class Container, class Iter, class Sent, class Validate>
constexpr void test_sequence_insert_range(Validate validate) {
using T = typename Container::value_type;
- auto get_pos = [](auto& c, auto& test_case) { return std::ranges::next(c.begin(), test_case.index); };
+ using D = typename Container::difference_type;
+ auto get_pos = [](auto& c, auto& test_case) { return std::ranges::next(c.begin(), static_cast<D>(test_case.index)); };
auto test = [&](auto& test_case) {
Container c(test_case.initial.begin(), test_case.initial.end());
diff --git a/libcxx/test/std/containers/unord/unord.map/eq.different_hash.pass.cpp b/libcxx/test/std/containers/unord/unord.map/eq.different_hash.pass.cpp
index 52a806f04d72d6..94de7589eb060e 100644
--- a/libcxx/test/std/containers/unord/unord.map/eq.different_hash.pass.cpp
+++ b/libcxx/test/std/containers/unord/unord.map/eq.different_hash.pass.cpp
@@ -36,7 +36,7 @@ std::size_t hash_neg(T val) {
}
template <class T>
std::size_t hash_scale(T val) {
- return val << 1;
+ return static_cast<std::size_t>(val << 1);
}
template <class T>
std::size_t hash_even(T val) {
@@ -57,7 +57,7 @@ std::size_t hash_neg(T* val) {
}
template <class T>
std::size_t hash_scale(T* val) {
- return *val << 1;
+ return static_cast<std::size_t>(*val << 1);
}
template <class T>
std::size_t hash_even(T* val) {
diff --git a/libcxx/test/std/containers/unord/unord.multimap/eq.different_hash.pass.cpp b/libcxx/test/std/containers/unord/unord.multimap/eq.different_hash.pass.cpp
index 2644c965764460..0aafb401d42ca9 100644
--- a/libcxx/test/std/containers/unord/unord.multimap/eq.different_hash.pass.cpp
+++ b/libcxx/test/std/containers/unord/unord.multimap/eq.different_hash.pass.cpp
@@ -37,7 +37,7 @@ std::size_t hash_neg(T val) {
}
template <class T>
std::size_t hash_scale(T val) {
- return val << 1;
+ return static_cast<std::size_t>(val << 1);
}
template <class T>
std::size_t hash_even(T val) {
@@ -58,7 +58,7 @@ std::size_t hash_neg(T* val) {
}
template <class T>
std::size_t hash_scale(T* val) {
- return *val << 1;
+ return static_cast<std::size_t>(*val << 1);
}
template <class T>
std::size_t hash_even(T* val) {
diff --git a/libcxx/test/std/containers/unord/unord.multiset/eq.different_hash.pass.cpp b/libcxx/test/std/containers/unord/unord.multiset/eq.different_hash.pass.cpp
index 9f53e8d79e8665..5b8f11e929279a 100644
--- a/libcxx/test/std/containers/unord/unord.multiset/eq.different_hash.pass.cpp
+++ b/libcxx/test/std/containers/unord/unord.multiset/eq.different_hash.pass.cpp
@@ -36,7 +36,7 @@ std::size_t hash_neg(T val) {
}
template <class T>
std::size_t hash_scale(T val) {
- return val << 1;
+ return static_cast<std::size_t>(val << 1);
}
template <class T>
std::size_t hash_even(T val) {
@@ -57,7 +57,7 @@ std::size_t hash_neg(T* val) {
}
template <class T>
std::size_t hash_scale(T* val) {
- return *val << 1;
+ return static_cast<std::size_t>(*val << 1);
}
template <class T>
std::size_t hash_even(T* val) {
diff --git a/libcxx/test/std/containers/unord/unord.set/eq.different_hash.pass.cpp b/libcxx/test/std/containers/unord/unord.set/eq.different_hash.pass.cpp
index a763c7fee623ab..3cb4815a5bcb12 100644
--- a/libcxx/test/std/containers/unord/unord.set/eq.different_hash.pass.cpp
+++ b/libcxx/test/std/containers/unord/unord.set/eq.different_hash.pass.cpp
@@ -36,7 +36,7 @@ std::size_t hash_neg(T val) {
}
template <class T>
std::size_t hash_scale(T val) {
- return val << 1;
+ return static_cast<std::size_t>(val << 1);
}
template <class T>
std::size_t hash_even(T val) {
@@ -56,11 +56,11 @@ std::size_t hash_neg(T* val) {
return std::numeric_limits<T>::max() - *val;
}
template <class T>
-size_t hash_scale(T* val) {
- return *val << 1;
+std::size_t hash_scale(T* val) {
+ return static_cast<std::size_t>(*val << 1);
}
template <class T>
-size_t hash_even(T* val) {
+std::size_t hash_even(T* val) {
return *val & 1 ? 1 : 0;
}
diff --git a/libcxx/test/std/containers/views/mdspan/layout_stride/index_operator.pass.cpp b/libcxx/test/std/containers/views/mdspan/layout_stride/index_operator.pass.cpp
index 01278e9076714a..7c755ec114f0b2 100644
--- a/libcxx/test/std/containers/views/mdspan/layout_stride/index_operator.pass.cpp
+++ b/libcxx/test/std/containers/views/mdspan/layout_stride/index_operator.pass.cpp
@@ -53,9 +53,9 @@ constexpr void iterate_stride(M m, const std::array<int, M::extents_type::rank()
constexpr int r = static_cast<int>(M::extents_type::rank()) - 1 - static_cast<int>(sizeof...(Args));
if constexpr (-1 == r) {
ASSERT_NOEXCEPT(m(args...));
- size_t expected_val = [&]<size_t... Pos>(std::index_sequence<Pos...>) {
+ size_t expected_val = static_cast<size_t>([&]<size_t... Pos>(std::index_sequence<Pos...>) {
return ((args * strides[Pos]) + ... + 0);
- }(std::make_index_sequence<M::extents_type::rank()>());
+ }(std::make_index_sequence<M::extents_type::rank()>()));
assert(expected_val == static_cast<size_t>(m(args...)));
} else {
for (typename M::index_type i = 0; i < m.extents().extent(r); i++) {
diff --git a/libcxx/test/std/ranges/range.utility/range.utility.conv/container.h b/libcxx/test/std/ranges/range.utility/range.utility.conv/container.h
index fafccacd456d5b..ca89e3757affc7 100644
--- a/libcxx/test/std/ranges/range.utility/range.utility.conv/container.h
+++ b/libcxx/test/std/ranges/range.utility/range.utility.conv/container.h
@@ -38,7 +38,7 @@ struct Container {
constexpr explicit Container(std::ranges::input_range auto&& in)
requires(Rank >= CtrChoice::DirectCtr)
- : ctr_choice(CtrChoice::DirectCtr), size_(std::ranges::size(in)) {
+ : ctr_choice(CtrChoice::DirectCtr), size_(static_cast<int>(std::ranges::size(in))) {
std::ranges::copy(in, begin());
}
@@ -54,7 +54,7 @@ struct Container {
constexpr Container(std::from_range_t, std::ranges::input_range auto&& in)
requires(Rank >= CtrChoice::FromRangeT)
- : ctr_choice(CtrChoice::FromRangeT), size_(std::ranges::size(in)) {
+ : ctr_choice(CtrChoice::FromRangeT), size_(static_cast<int>(std::ranges::size(in))) {
std::ranges::copy(in, begin());
}
@@ -70,7 +70,7 @@ struct Container {
template <class Iter>
constexpr Container(Iter b, Iter e)
requires(Rank >= CtrChoice::BeginEndPair)
- : ctr_choice(CtrChoice::BeginEndPair), size_(e - b) {
+ : ctr_choice(CtrChoice::BeginEndPair), size_(static_cast<int>(e - b)) {
std::ranges::copy(b, e, begin());
}
diff --git a/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.create/allocate_shared_for_overwrite.pass.cpp b/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.create/allocate_shared_for_overwrite.pass.cpp
index 27ff3cd563740c..e6e063304453a5 100644
--- a/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.create/allocate_shared_for_overwrite.pass.cpp
+++ b/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.create/allocate_shared_for_overwrite.pass.cpp
@@ -156,7 +156,7 @@ void testAllocatorOperationsCalled() {
template <class T>
struct AllocatorWithPattern {
- constexpr static char pattern = 0xDE;
+ constexpr static char pattern = static_cast<char>(0xDE);
using value_type = T;
diff --git a/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.create/make_shared_for_overwrite.pass.cpp b/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.create/make_shared_for_overwrite.pass.cpp
index 21e1786f015882..459b5a708cd4aa 100644
--- a/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.create/make_shared_for_overwrite.pass.cpp
+++ b/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.create/make_shared_for_overwrite.pass.cpp
@@ -56,7 +56,7 @@ static_assert(!HasMakeSharedForOverwrite<Foo[]>);
static_assert(!HasMakeSharedForOverwrite<int[], std::size_t, int>);
static_assert(!HasMakeSharedForOverwrite<Foo[], std::size_t, int>);
-constexpr char pattern = 0xDE;
+constexpr char pattern = static_cast<char>(0xDE);
void* operator new(std::size_t count) {
void* ptr = std::malloc(count);
diff --git a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.create/make_unique_for_overwrite.default_init.pass.cpp b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.create/make_unique_for_overwrite.default_init.pass.cpp
index 8011a37be08ecd..a1373ac3ac80c8 100644
--- a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.create/make_unique_for_overwrite.default_init.pass.cpp
+++ b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.create/make_unique_for_overwrite.default_init.pass.cpp
@@ -23,7 +23,7 @@
#include <cstdlib>
#include <memory>
-constexpr char pattern = 0xDE;
+constexpr char pattern = static_cast<char>(0xDE);
void* operator new(std::size_t count) {
void* ptr = std::malloc(count);
diff --git a/libcxx/test/support/concat_macros.h b/libcxx/test/support/concat_macros.h
index bc1306fbdb5331..7621914e53f02a 100644
--- a/libcxx/test/support/concat_macros.h
+++ b/libcxx/test/support/concat_macros.h
@@ -52,14 +52,14 @@ template <class OutIt>
requires std::output_iterator<OutIt, const char&>
void test_encode(OutIt& out_it, char16_t value) {
if (value < 0x80)
- *out_it++ = value;
+ *out_it++ = static_cast<char>(value);
else if (value < 0x800) {
- *out_it++ = 0b11000000 | (value >> 6);
- *out_it++ = 0b10000000 | (value & 0b00111111);
+ *out_it++ = static_cast<char>(0b11000000 | (value >> 6));
+ *out_it++ = static_cast<char>(0b10000000 | (value & 0b00111111));
} else {
- *out_it++ = 0b11100000 | (value >> 12);
- *out_it++ = 0b10000000 | ((value) >> 6 & 0b00111111);
- *out_it++ = 0b10000000 | (value & 0b00111111);
+ *out_it++ = static_cast<char>(0b11100000 | (value >> 12));
+ *out_it++ = static_cast<char>(0b10000000 | ((value) >> 6 & 0b00111111));
+ *out_it++ = static_cast<char>(0b10000000 | (value & 0b00111111));
}
}
@@ -69,10 +69,10 @@ void test_encode(OutIt& out_it, char32_t value) {
if ((value & 0xffff0000) == 0)
test_encode(out_it, static_cast<char16_t>(value));
else {
- *out_it++ = 0b11100000 | (value >> 18);
- *out_it++ = 0b10000000 | ((value) >> 12 & 0b00111111);
- *out_it++ = 0b10000000 | ((value) >> 6 & 0b00111111);
- *out_it++ = 0b10000000 | (value & 0b00111111);
+ *out_it++ = static_cast<char>(0b11100000 | (value >> 18));
+ *out_it++ = static_cast<char>(0b10000000 | ((value) >> 12 & 0b00111111));
+ *out_it++ = static_cast<char>(0b10000000 | ((value) >> 6 & 0b00111111));
+ *out_it++ = static_cast<char>(0b10000000 | (value & 0b00111111));
}
}
|
✅ With the latest revision this PR passed the C/C++ code formatter. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I feel that some of these places don't really warrant a compiler diagnostic, but I don't feel the static_casts make it too ugly. I expect this will regress on libc++'s side, not sure what to do about that. Just a remark not something we need to fix.
LGTM
libcxx/test/std/containers/views/mdspan/layout_stride/index_operator.pass.cpp
Outdated
Show resolved
Hide resolved
@@ -56,7 +56,7 @@ static_assert(!HasMakeSharedForOverwrite<Foo[]>); | |||
static_assert(!HasMakeSharedForOverwrite<int[], std::size_t, int>); | |||
static_assert(!HasMakeSharedForOverwrite<Foo[], std::size_t, int>); | |||
|
|||
constexpr char pattern = 0xDE; | |||
constexpr char pattern = static_cast<char>(0xDE); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Interesting that MSVC issues a diagnostic here too.
Thanks! Yeah, I expect that the MSVC team will regularly need to clean up warnings like these. We hadn't updated our llvm-project submodule in almost a year, so the rate of accumulation over time isn't as high as it might seem. Merging this now - the failing checks are all the usual unrelated sporadic timeouts/failures and the known failure that I recently fixed. |
Found while running libc++'s tests with MSVC's STL.
libcxx/test/std/algorithms/alg.modifying.operations/alg.unique/ranges_unique_copy.pass.cpp
==
': signed/unsigned mismatch".int
and the RHS issize_t
. We know thearray
's size, sostatic_cast<int>
is certainly safe, and this matches the followingnumberOfProj
comparisons.libcxx/test/std/containers/sequences/insert_range_sequence_containers.h
size_t
' to 'const int
', possible loss of data".test_case.index
issize_t
:llvm-project/libcxx/test/std/containers/insert_range_helpers.h
Lines 65 to 68 in b85f1f9
difference_type
isint
:llvm-project/libcxx/test/support/test_allocator.h
Lines 65 to 76 in b85f1f9
D
to make the long line more readable.libcxx/test/std/containers/unord/unord.map/eq.different_hash.pass.cpp
libcxx/test/std/containers/unord/unord.multimap/eq.different_hash.pass.cpp
libcxx/test/std/containers/unord/unord.multiset/eq.different_hash.pass.cpp
libcxx/test/std/containers/unord/unord.set/eq.different_hash.pass.cpp
static_cast
s to deal with sign/truncation warnings elsewhere, because there's some value in ensuring that product code is clean with respect to these warnings. If there were many more occurrences, then disabling the warning would be appropriate.size_t
tostd::size_t
.libcxx/test/std/containers/views/mdspan/layout_stride/index_operator.pass.cpp
__int64
' to 'size_t
', possible loss of data".args
are indeedint64_t
, and we're storing the result insize_t
, so we should cast.libcxx/test/std/ranges/range.utility/range.utility.conv/container.h
ptrdiff_t
' to 'int
', possible loss of data".size_t
' to 'int
', possible loss of data".int size_
, so we should explicitly cast from pointer subtraction andstd::ranges::size
.libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.create/allocate_shared_for_overwrite.pass.cpp
libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.create/make_shared_for_overwrite.pass.cpp
libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.create/make_unique_for_overwrite.default_init.pass.cpp
0xDE
is outside the range ofchar
(signed by default in our implementation).libcxx/test/support/concat_macros.h
char16_t
' to 'const char
', possible loss of data".unsigned int
' to 'const char
', possible loss of data".