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

via libcxx-commits libcxx-commits at lists.llvm.org
Sat Dec 9 20:08:22 PST 2023


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-libcxx

Author: Stephan T. Lavavej (StephanTLavavej)

<details>
<summary>Changes</summary>

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.


---
Full diff: https://github.com/llvm/llvm-project/pull/74962.diff


12 Files Affected:

- (modified) libcxx/test/std/algorithms/alg.modifying.operations/alg.unique/ranges_unique_copy.pass.cpp (+2-2) 
- (modified) libcxx/test/std/containers/sequences/insert_range_sequence_containers.h (+2-1) 
- (modified) libcxx/test/std/containers/unord/unord.map/eq.different_hash.pass.cpp (+2-2) 
- (modified) libcxx/test/std/containers/unord/unord.multimap/eq.different_hash.pass.cpp (+2-2) 
- (modified) libcxx/test/std/containers/unord/unord.multiset/eq.different_hash.pass.cpp (+2-2) 
- (modified) libcxx/test/std/containers/unord/unord.set/eq.different_hash.pass.cpp (+4-4) 
- (modified) libcxx/test/std/containers/views/mdspan/layout_stride/index_operator.pass.cpp (+2-2) 
- (modified) libcxx/test/std/ranges/range.utility/range.utility.conv/container.h (+3-3) 
- (modified) libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.create/allocate_shared_for_overwrite.pass.cpp (+1-1) 
- (modified) libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.create/make_shared_for_overwrite.pass.cpp (+1-1) 
- (modified) libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.create/make_unique_for_overwrite.default_init.pass.cpp (+1-1) 
- (modified) libcxx/test/support/concat_macros.h (+10-10) 


``````````diff
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));
   }
 }
 

``````````

</details>


https://github.com/llvm/llvm-project/pull/74962


More information about the libcxx-commits mailing list