[libcxx-commits] [libcxx] 774295c - [libc++][test] Fix MSVC warnings with `static_cast`s (#74962)

via libcxx-commits libcxx-commits at lists.llvm.org
Sun Dec 10 13:41:35 PST 2023


Author: Stephan T. Lavavej
Date: 2023-12-10T13:41:30-08:00
New Revision: 774295ca1d5ff752cb478b61f22a5b1dbe33074f

URL: https://github.com/llvm/llvm-project/commit/774295ca1d5ff752cb478b61f22a5b1dbe33074f
DIFF: https://github.com/llvm/llvm-project/commit/774295ca1d5ff752cb478b61f22a5b1dbe33074f.diff

LOG: [libc++][test] Fix MSVC warnings with `static_cast`s (#74962)

Found while running libc++'s tests with MSVC's STL.

*
`libcxx/test/std/algorithms/alg.modifying.operations/alg.unique/ranges_unique_copy.pass.cpp`
  + Fix MSVC "warning C4389: '`==`': signed/unsigned mismatch".
+ 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.
*
`libcxx/test/std/containers/sequences/insert_range_sequence_containers.h`
+ Fix MSVC "warning C4267: 'argument': conversion from '`size_t`' to
'`const int`', possible loss of data".
+ `test_case.index` is `size_t`:
https://github.com/llvm/llvm-project/blob/b85f1f9b182234ba366d78ae2174a149e44d08c1/libcxx/test/std/containers/insert_range_helpers.h#L65-L68
+ But the container's `difference_type` is `int`:
https://github.com/llvm/llvm-project/blob/b85f1f9b182234ba366d78ae2174a149e44d08c1/libcxx/test/support/test_allocator.h#L65-L76
  + I introduced an alias `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`
+ Fix MSVC "warning C6297: Arithmetic overflow. Results might not be an
expected value."
+ This warning is almost annoying enough to outright disable, but we use
similar `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.
+ Cleanup: Change 2 inconsistently unqualified occurrences of `size_t`
to `std::size_t`.
*
`libcxx/test/std/containers/views/mdspan/layout_stride/index_operator.pass.cpp`
+ Fix MSVC "warning C4244: 'initializing': conversion from '`__int64`'
to '`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.
* `libcxx/test/std/ranges/range.utility/range.utility.conv/container.h`
+ Fix MSVC "warning C4244: 'initializing': conversion from '`ptrdiff_t`'
to '`int`', possible loss of data".
+ Fix MSVC "warning C4267: 'initializing': conversion from '`size_t`' to
'`int`', possible loss of data".
+ We're initializing `int size_`, so we should explicitly cast from
pointer subtraction and `std::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`
+ Fix MSVC "warning C4309: 'initializing': truncation of constant
value".
+ MSVC emits this warning because `0xDE` is outside the range of `char`
(signed by default in our implementation).
* `libcxx/test/support/concat_macros.h`
+ Fix MSVC "warning C4244: 'argument': conversion from '`char16_t`' to
'`const char`', possible loss of data".
+ Fix MSVC "warning C4244: 'argument': conversion from '`unsigned int`'
to '`const char`', possible loss of data".
  + This code was very recently introduced by @mordante in #73395.

Added: 
    

Modified: 
    libcxx/test/std/algorithms/alg.modifying.operations/alg.unique/ranges_unique_copy.pass.cpp
    libcxx/test/std/containers/sequences/insert_range_sequence_containers.h
    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
    libcxx/test/std/containers/views/mdspan/layout_stride/index_operator.pass.cpp
    libcxx/test/std/ranges/range.utility/range.utility.conv/container.h
    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
    libcxx/test/support/concat_macros.h

Removed: 
    


################################################################################
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..352ee474cae767 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::
diff erence_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.
diff erent_hash.pass.cpp b/libcxx/test/std/containers/unord/unord.map/eq.
diff erent_hash.pass.cpp
index 52a806f04d72d6..94de7589eb060e 100644
--- a/libcxx/test/std/containers/unord/unord.map/eq.
diff erent_hash.pass.cpp
+++ b/libcxx/test/std/containers/unord/unord.map/eq.
diff erent_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.
diff erent_hash.pass.cpp b/libcxx/test/std/containers/unord/unord.multimap/eq.
diff erent_hash.pass.cpp
index 2644c965764460..0aafb401d42ca9 100644
--- a/libcxx/test/std/containers/unord/unord.multimap/eq.
diff erent_hash.pass.cpp
+++ b/libcxx/test/std/containers/unord/unord.multimap/eq.
diff erent_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.
diff erent_hash.pass.cpp b/libcxx/test/std/containers/unord/unord.multiset/eq.
diff erent_hash.pass.cpp
index 9f53e8d79e8665..5b8f11e929279a 100644
--- a/libcxx/test/std/containers/unord/unord.multiset/eq.
diff erent_hash.pass.cpp
+++ b/libcxx/test/std/containers/unord/unord.multiset/eq.
diff erent_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.
diff erent_hash.pass.cpp b/libcxx/test/std/containers/unord/unord.set/eq.
diff erent_hash.pass.cpp
index a763c7fee623ab..3cb4815a5bcb12 100644
--- a/libcxx/test/std/containers/unord/unord.set/eq.
diff erent_hash.pass.cpp
+++ b/libcxx/test/std/containers/unord/unord.set/eq.
diff erent_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..30281a8d922d10 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,10 +53,10 @@ 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...>) {
+    std::size_t expected_val = static_cast<std::size_t>([&]<std::size_t... Pos>(std::index_sequence<Pos...>) {
       return ((args * strides[Pos]) + ... + 0);
-    }(std::make_index_sequence<M::extents_type::rank()>());
-    assert(expected_val == static_cast<size_t>(m(args...)));
+    }(std::make_index_sequence<M::extents_type::rank()>()));
+    assert(expected_val == static_cast<std::size_t>(m(args...)));
   } else {
     for (typename M::index_type i = 0; i < m.extents().extent(r); i++) {
       iterate_stride(m, strides, i, args...);
@@ -73,7 +73,7 @@ constexpr void test_iteration(std::array<int, E::rank()> strides, Args... args)
 }
 
 constexpr bool test() {
-  constexpr size_t D = std::dynamic_extent;
+  constexpr std::size_t D = std::dynamic_extent;
   test_iteration<std::extents<int>>(std::array<int, 0>{});
   test_iteration<std::extents<unsigned, D>>(std::array<int, 1>{2}, 1);
   test_iteration<std::extents<unsigned, D>>(std::array<int, 1>{3}, 7);
@@ -102,7 +102,7 @@ constexpr bool test() {
 }
 
 constexpr bool test_large() {
-  constexpr size_t D = std::dynamic_extent;
+  constexpr std::size_t D = std::dynamic_extent;
   test_iteration<std::extents<int64_t, D, 8, D, D>>(std::array<int, 4>{2000, 2, 20, 200}, 7, 9, 10);
   test_iteration<std::extents<int64_t, D, 8, 1, D>>(std::array<int, 4>{2000, 20, 20, 200}, 7, 10);
   return true;

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 57c5f5e0632e71..d7340b8faf6e56 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));
   }
 }
 


        


More information about the libcxx-commits mailing list