[libcxx-commits] [libcxx] [libc++] [test] Fix portability issues for MSVC (PR #93259)
via libcxx-commits
libcxx-commits at lists.llvm.org
Sun May 26 21:58:52 PDT 2024
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-libcxx
Author: Stephan T. Lavavej (StephanTLavavej)
<details>
<summary>Changes</summary>
* Guard `std::__make_from_tuple_impl` tests with `#ifdef _LIBCPP_VERSION` and `LIBCPP_STATIC_ASSERT`.
* Change `_LIBCPP_CONSTEXPR_SINCE_CXX20` to `TEST_CONSTEXPR_CXX20`.
+ Other functions in `variant.swap/swap.pass.cpp` were already using the proper test macro.
* Mark `what` as `[[maybe_unused]]` when used by `TEST_LIBCPP_REQUIRE`.
+ This updates one occurrence in `libcxx/test/libcxx` for consistency.
* Windows `_putenv_s()` takes 2 arguments, not 3.
+ See [MSVC documentation][].
+ POSIX `setenv()` takes `int overwrite`, but Windows `_putenv_s()` always overwrites.
* Avoid non-Standard zero-length arrays.
+ Followup to #<!-- -->74183 and #<!-- -->79792.
* Add `operator++()` to `unsized_it`.
+ The Standard requires this due to [N4981][] \[move.iter.requirements\]/1 "The template parameter `Iterator` shall either meet the *Cpp17InputIterator* requirements (\[input.iterators\]) or model `input_iterator` (\[iterator.concept.input\])."
+ MSVC's STL requires this because it has a strengthened exception specification in `move_iterator` that inspects the underlying iterator's increment operator.
* `uniform_int_distribution` forbids `int8_t`/`uint8_t`.
+ See [N4981][] \[rand.req.genl\]/1.5. MSVC's STL enforces this.
+ Note that when changing the distribution's `IntType`, we need to be careful to preserve the original value range of `[0, max_input]`.
* fstreams are constructible from `const fs::path::value_type*` on wide systems.
+ See \[ifstream.cons\], \[ofstream.cons\], \[fstream.cons\].
* In `msvc_stdlib_force_include.h`, map `_HAS_CXX23` to `TEST_STD_VER` 23 instead of 99.
+ On 2023-05-23, https://github.com/llvm/llvm-project/commit/71400505ca048507e827013eb1ea0bc863525cab started recognizing 23 as a distinct value.
* Fix test name typo: `destory_elements.pass.cpp` => `destroy_elements.pass.cpp`
[N4981]: https://wg21.link/N4981
[MSVC documentation]: https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/putenv-s-wputenv-s?view=msvc-170
---
Full diff: https://github.com/llvm/llvm-project/pull/93259.diff
15 Files Affected:
- (modified) libcxx/test/libcxx/time/time.zone/time.zone.db/time.zone.db.tzdb/locate_zone.pass.cpp (+1-1)
- (modified) libcxx/test/std/algorithms/alg.nonmodifying/alg.contains/ranges.contains_subrange.pass.cpp (+13-12)
- (renamed) libcxx/test/std/containers/sequences/vector/vector.modifiers/destroy_elements.pass.cpp ()
- (modified) libcxx/test/std/input.output/file.streams/fstreams/fstream.cons/path.pass.cpp (+1-1)
- (modified) libcxx/test/std/input.output/file.streams/fstreams/ifstream.cons/path.pass.cpp (+1-1)
- (modified) libcxx/test/std/input.output/file.streams/fstreams/ofstream.cons/path.pass.cpp (+1-1)
- (modified) libcxx/test/std/iterators/predef.iterators/move.iterators/sized_sentinel.compile.pass.cpp (+1)
- (modified) libcxx/test/std/numerics/numeric.ops/numeric.ops.gcd/gcd.pass.cpp (+6-3)
- (modified) libcxx/test/std/time/time.zone/time.zone.db/time.zone.db.access/current_zone.pass.cpp (+1-1)
- (modified) libcxx/test/std/time/time.zone/time.zone.db/time.zone.db.access/locate_zone.pass.cpp (+1-1)
- (modified) libcxx/test/std/time/time.zone/time.zone.db/time.zone.db.tzdb/current_zone.pass.cpp (+1-1)
- (modified) libcxx/test/std/time/time.zone/time.zone.db/time.zone.db.tzdb/locate_zone.pass.cpp (+1-1)
- (modified) libcxx/test/std/utilities/tuple/tuple.tuple/tuple.apply/make_from_tuple.pass.cpp (+15-13)
- (modified) libcxx/test/std/utilities/variant/variant.variant/variant.swap/swap.pass.cpp (+1-1)
- (modified) libcxx/test/support/msvc_stdlib_force_include.h (+1-1)
``````````diff
diff --git a/libcxx/test/libcxx/time/time.zone/time.zone.db/time.zone.db.tzdb/locate_zone.pass.cpp b/libcxx/test/libcxx/time/time.zone/time.zone.db/time.zone.db.tzdb/locate_zone.pass.cpp
index 3ee213358f352..08c682964c374 100644
--- a/libcxx/test/libcxx/time/time.zone/time.zone.db/time.zone.db.tzdb/locate_zone.pass.cpp
+++ b/libcxx/test/libcxx/time/time.zone/time.zone.db/time.zone.db.tzdb/locate_zone.pass.cpp
@@ -73,7 +73,7 @@ L link link_to_link
TEST_VALIDATE_EXCEPTION(
std::runtime_error,
[&]([[maybe_unused]] const std::runtime_error& e) {
- std::string_view what{"tzdb: requested time zone not found"};
+ [[maybe_unused]] std::string_view what{"tzdb: requested time zone not found"};
TEST_LIBCPP_REQUIRE(
e.what() == what,
TEST_WRITE_CONCATENATED("\nExpected exception ", what, "\nActual exception ", e.what(), '\n'));
diff --git a/libcxx/test/std/algorithms/alg.nonmodifying/alg.contains/ranges.contains_subrange.pass.cpp b/libcxx/test/std/algorithms/alg.nonmodifying/alg.contains/ranges.contains_subrange.pass.cpp
index 761691c2afdcb..890ac23fff832 100644
--- a/libcxx/test/std/algorithms/alg.nonmodifying/alg.contains/ranges.contains_subrange.pass.cpp
+++ b/libcxx/test/std/algorithms/alg.nonmodifying/alg.contains/ranges.contains_subrange.pass.cpp
@@ -24,6 +24,7 @@
// Proj1 proj1 = {}, Proj2 proj2 = {}); // since C++23
#include <algorithm>
+#include <array>
#include <cassert>
#include <concepts>
#include <ranges>
@@ -130,10 +131,10 @@ constexpr void test_iterators() {
}
{ // range has zero length
- int a[] = {};
- int p[] = {3, 4, 2};
- auto whole = std::ranges::subrange(Iter1(a), Sent1(Iter1(a)));
- auto subrange = std::ranges::subrange(Iter2(p), Sent2(Iter2(std::end(p))));
+ std::array<int, 0> a = {};
+ int p[] = {3, 4, 2};
+ auto whole = std::ranges::subrange(Iter1(a.data()), Sent1(Iter1(a.data())));
+ auto subrange = std::ranges::subrange(Iter2(p), Sent2(Iter2(std::end(p))));
{
bool ret = std::ranges::contains_subrange(whole.begin(), whole.end(), subrange.begin(), subrange.end());
assert(!ret);
@@ -145,10 +146,10 @@ constexpr void test_iterators() {
}
{ // subrange has zero length
- int a[] = {3, 4, 2};
- int p[] = {};
- auto whole = std::ranges::subrange(Iter1(a), Sent1(Iter1(std::end(a))));
- auto subrange = std::ranges::subrange(Iter2(p), Sent2(Iter2(p)));
+ int a[] = {3, 4, 2};
+ std::array<int, 0> p = {};
+ auto whole = std::ranges::subrange(Iter1(a), Sent1(Iter1(std::end(a))));
+ auto subrange = std::ranges::subrange(Iter2(p.data()), Sent2(Iter2(p.data())));
{
bool ret = std::ranges::contains_subrange(whole.begin(), whole.end(), subrange.begin(), subrange.end());
assert(ret);
@@ -160,10 +161,10 @@ constexpr void test_iterators() {
}
{ // range and subrange both have zero length
- int a[] = {};
- int p[] = {};
- auto whole = std::ranges::subrange(Iter1(a), Sent1(Iter1(a)));
- auto subrange = std::ranges::subrange(Iter2(p), Sent2(Iter2(p)));
+ std::array<int, 0> a = {};
+ std::array<int, 0> p = {};
+ auto whole = std::ranges::subrange(Iter1(a.data()), Sent1(Iter1(a.data())));
+ auto subrange = std::ranges::subrange(Iter2(p.data()), Sent2(Iter2(p.data())));
{
bool ret = std::ranges::contains_subrange(whole.begin(), whole.end(), subrange.begin(), subrange.end());
assert(ret);
diff --git a/libcxx/test/std/containers/sequences/vector/vector.modifiers/destory_elements.pass.cpp b/libcxx/test/std/containers/sequences/vector/vector.modifiers/destroy_elements.pass.cpp
similarity index 100%
rename from libcxx/test/std/containers/sequences/vector/vector.modifiers/destory_elements.pass.cpp
rename to libcxx/test/std/containers/sequences/vector/vector.modifiers/destroy_elements.pass.cpp
diff --git a/libcxx/test/std/input.output/file.streams/fstreams/fstream.cons/path.pass.cpp b/libcxx/test/std/input.output/file.streams/fstreams/fstream.cons/path.pass.cpp
index 5edf22eaacf31..d6bb56d9b78b7 100644
--- a/libcxx/test/std/input.output/file.streams/fstreams/fstream.cons/path.pass.cpp
+++ b/libcxx/test/std/input.output/file.streams/fstreams/fstream.cons/path.pass.cpp
@@ -37,7 +37,7 @@ constexpr bool test_non_convert_to_path() {
static_assert(!std::is_constructible_v<std::fstream, const std::basic_string_view<CharT>>);
// Char* pointers
- if constexpr (!std::is_same_v<CharT, char>)
+ if constexpr (!std::is_same_v<CharT, char> && !std::is_same_v<CharT, fs::path::value_type>)
static_assert(!std::is_constructible_v<std::fstream, const CharT*>);
// Iterators
diff --git a/libcxx/test/std/input.output/file.streams/fstreams/ifstream.cons/path.pass.cpp b/libcxx/test/std/input.output/file.streams/fstreams/ifstream.cons/path.pass.cpp
index 2f27fd8e6e93d..792b65615679a 100644
--- a/libcxx/test/std/input.output/file.streams/fstreams/ifstream.cons/path.pass.cpp
+++ b/libcxx/test/std/input.output/file.streams/fstreams/ifstream.cons/path.pass.cpp
@@ -38,7 +38,7 @@ constexpr bool test_non_convert_to_path() {
static_assert(!std::is_constructible_v<std::ifstream, const std::basic_string_view<CharT>>);
// Char* pointers
- if constexpr (!std::is_same_v<CharT, char>)
+ if constexpr (!std::is_same_v<CharT, char> && !std::is_same_v<CharT, fs::path::value_type>)
static_assert(!std::is_constructible_v<std::ifstream, const CharT*>);
// Iterators
diff --git a/libcxx/test/std/input.output/file.streams/fstreams/ofstream.cons/path.pass.cpp b/libcxx/test/std/input.output/file.streams/fstreams/ofstream.cons/path.pass.cpp
index e55adfd83fc3c..602bdadd85813 100644
--- a/libcxx/test/std/input.output/file.streams/fstreams/ofstream.cons/path.pass.cpp
+++ b/libcxx/test/std/input.output/file.streams/fstreams/ofstream.cons/path.pass.cpp
@@ -37,7 +37,7 @@ constexpr bool test_non_convert_to_path() {
static_assert(!std::is_constructible_v<std::ofstream, const std::basic_string_view<CharT>>);
// Char* pointers
- if constexpr (!std::is_same_v<CharT, char>)
+ if constexpr (!std::is_same_v<CharT, char> && !std::is_same_v<CharT, fs::path::value_type>)
static_assert(!std::is_constructible_v<std::ofstream, const CharT*>);
// Iterators
diff --git a/libcxx/test/std/iterators/predef.iterators/move.iterators/sized_sentinel.compile.pass.cpp b/libcxx/test/std/iterators/predef.iterators/move.iterators/sized_sentinel.compile.pass.cpp
index cb49086dd6802..998b13ed49455 100644
--- a/libcxx/test/std/iterators/predef.iterators/move.iterators/sized_sentinel.compile.pass.cpp
+++ b/libcxx/test/std/iterators/predef.iterators/move.iterators/sized_sentinel.compile.pass.cpp
@@ -21,6 +21,7 @@ struct unsized_it {
using difference_type = std::ptrdiff_t;
value_type& operator*() const;
+ unsized_it& operator++();
bool operator==(const unsized_it&) const;
difference_type operator-(const unsized_it&) const { return 0; }
};
diff --git a/libcxx/test/std/numerics/numeric.ops/numeric.ops.gcd/gcd.pass.cpp b/libcxx/test/std/numerics/numeric.ops/numeric.ops.gcd/gcd.pass.cpp
index 212804356a056..5bc149b54d022 100644
--- a/libcxx/test/std/numerics/numeric.ops/numeric.ops.gcd/gcd.pass.cpp
+++ b/libcxx/test/std/numerics/numeric.ops/numeric.ops.gcd/gcd.pass.cpp
@@ -17,6 +17,7 @@
#include <cassert>
#include <climits>
#include <cstdint>
+#include <limits>
#include <random>
#include <type_traits>
@@ -67,12 +68,14 @@ T basic_gcd(T m, T n) {
template <typename Input>
void do_fuzzy_tests() {
std::mt19937 gen(1938);
- std::uniform_int_distribution<Input> distrib;
+ using DistIntType = std::conditional_t<sizeof(Input) == 1, int, Input>; // See N4981 [rand.req.genl]/1.5
+ constexpr Input max_input = std::numeric_limits<Input>::max();
+ std::uniform_int_distribution<DistIntType> distrib(0, max_input);
constexpr int nb_rounds = 10000;
for (int i = 0; i < nb_rounds; ++i) {
- Input n = distrib(gen);
- Input m = distrib(gen);
+ Input n = static_cast<Input>(distrib(gen));
+ Input m = static_cast<Input>(distrib(gen));
assert(std::gcd(n, m) == basic_gcd(n, m));
}
}
diff --git a/libcxx/test/std/time/time.zone/time.zone.db/time.zone.db.access/current_zone.pass.cpp b/libcxx/test/std/time/time.zone/time.zone.db/time.zone.db.access/current_zone.pass.cpp
index 2c43e121613c7..f31a679dd6214 100644
--- a/libcxx/test/std/time/time.zone/time.zone.db/time.zone.db.access/current_zone.pass.cpp
+++ b/libcxx/test/std/time/time.zone/time.zone.db/time.zone.db.access/current_zone.pass.cpp
@@ -32,7 +32,7 @@ static void set_tz(std::string zone) {
// Unlike POSIX it does not mention the string of putenv becomes part
// of the environment.
- int status = _putenv_s("TZ", zone.c_str(), 1);
+ int status = _putenv_s("TZ", zone.c_str());
assert(status == 0);
}
diff --git a/libcxx/test/std/time/time.zone/time.zone.db/time.zone.db.access/locate_zone.pass.cpp b/libcxx/test/std/time/time.zone/time.zone.db/time.zone.db.access/locate_zone.pass.cpp
index 4d600fcdf40e3..8dd895fd21814 100644
--- a/libcxx/test/std/time/time.zone/time.zone.db/time.zone.db.access/locate_zone.pass.cpp
+++ b/libcxx/test/std/time/time.zone/time.zone.db/time.zone.db.access/locate_zone.pass.cpp
@@ -40,7 +40,7 @@ static void test_exception([[maybe_unused]] std::string_view zone) {
TEST_VALIDATE_EXCEPTION(
std::runtime_error,
[&]([[maybe_unused]] const std::runtime_error& e) {
- std::string_view what{"tzdb: requested time zone not found"};
+ [[maybe_unused]] std::string_view what{"tzdb: requested time zone not found"};
TEST_LIBCPP_REQUIRE(
e.what() == what,
TEST_WRITE_CONCATENATED("\nExpected exception ", what, "\nActual exception ", e.what(), '\n'));
diff --git a/libcxx/test/std/time/time.zone/time.zone.db/time.zone.db.tzdb/current_zone.pass.cpp b/libcxx/test/std/time/time.zone/time.zone.db/time.zone.db.tzdb/current_zone.pass.cpp
index e6497e26323ce..98509c298ebcb 100644
--- a/libcxx/test/std/time/time.zone/time.zone.db/time.zone.db.tzdb/current_zone.pass.cpp
+++ b/libcxx/test/std/time/time.zone/time.zone.db/time.zone.db.tzdb/current_zone.pass.cpp
@@ -34,7 +34,7 @@ static void set_tz(std::string zone) {
// Unlike POSIX it does not mention the string of putenv becomes part
// of the environment.
- int status = _putenv_s("TZ", zone.c_str(), 1);
+ int status = _putenv_s("TZ", zone.c_str());
assert(status == 0);
}
diff --git a/libcxx/test/std/time/time.zone/time.zone.db/time.zone.db.tzdb/locate_zone.pass.cpp b/libcxx/test/std/time/time.zone/time.zone.db/time.zone.db.tzdb/locate_zone.pass.cpp
index f929dafcc9683..08ce48dfd0edb 100644
--- a/libcxx/test/std/time/time.zone/time.zone.db/time.zone.db.tzdb/locate_zone.pass.cpp
+++ b/libcxx/test/std/time/time.zone/time.zone.db/time.zone.db.tzdb/locate_zone.pass.cpp
@@ -42,7 +42,7 @@ static void test_exception([[maybe_unused]] std::string_view zone) {
TEST_VALIDATE_EXCEPTION(
std::runtime_error,
[&]([[maybe_unused]] const std::runtime_error& e) {
- std::string_view what{"tzdb: requested time zone not found"};
+ [[maybe_unused]] std::string_view what{"tzdb: requested time zone not found"};
TEST_LIBCPP_REQUIRE(
e.what() == what,
TEST_WRITE_CONCATENATED("\nExpected exception ", what, "\nActual exception ", e.what(), '\n'));
diff --git a/libcxx/test/std/utilities/tuple/tuple.tuple/tuple.apply/make_from_tuple.pass.cpp b/libcxx/test/std/utilities/tuple/tuple.tuple/tuple.apply/make_from_tuple.pass.cpp
index d7374351afa8b..accb601dd0036 100644
--- a/libcxx/test/std/utilities/tuple/tuple.tuple/tuple.apply/make_from_tuple.pass.cpp
+++ b/libcxx/test/std/utilities/tuple/tuple.tuple/tuple.apply/make_from_tuple.pass.cpp
@@ -209,6 +209,7 @@ template <class T, class Tuple>
static constexpr bool can_make_from_tuple =
std::is_same_v<decltype(test_make_from_tuple<T, Tuple>(T{}, Tuple{})), uint8_t>;
+#ifdef _LIBCPP_VERSION
template <class T, class Tuple>
auto test_make_from_tuple_impl(T&&, Tuple&& t)
-> decltype(std::__make_from_tuple_impl<T>(
@@ -224,6 +225,7 @@ uint32_t test_make_from_tuple_impl(...) {
template <class T, class Tuple>
static constexpr bool can_make_from_tuple_impl =
std::is_same_v<decltype(test_make_from_tuple_impl<T, Tuple>(T{}, Tuple{})), uint8_t>;
+#endif // _LIBCPP_VERSION
struct A {
int a;
@@ -263,23 +265,23 @@ static_assert(can_make_from_tuple<float, std::tuple<double>>);
// Test std::__make_from_tuple_impl constraints.
// reinterpret_cast
-static_assert(!can_make_from_tuple_impl<int*, std::tuple<A*>>);
-static_assert(can_make_from_tuple_impl<A*, std::tuple<A*>>);
+LIBCPP_STATIC_ASSERT(!can_make_from_tuple_impl<int*, std::tuple<A*>>);
+LIBCPP_STATIC_ASSERT(can_make_from_tuple_impl<A*, std::tuple<A*>>);
// const_cast
-static_assert(!can_make_from_tuple_impl<char*, std::tuple<const char*>>);
-static_assert(!can_make_from_tuple_impl<volatile char*, std::tuple<const volatile char*>>);
-static_assert(can_make_from_tuple_impl<volatile char*, std::tuple<volatile char*>>);
-static_assert(can_make_from_tuple_impl<char*, std::tuple<char*>>);
-static_assert(can_make_from_tuple_impl<const char*, std::tuple<char*>>);
-static_assert(can_make_from_tuple_impl<const volatile char*, std::tuple<volatile char*>>);
+LIBCPP_STATIC_ASSERT(!can_make_from_tuple_impl<char*, std::tuple<const char*>>);
+LIBCPP_STATIC_ASSERT(!can_make_from_tuple_impl<volatile char*, std::tuple<const volatile char*>>);
+LIBCPP_STATIC_ASSERT(can_make_from_tuple_impl<volatile char*, std::tuple<volatile char*>>);
+LIBCPP_STATIC_ASSERT(can_make_from_tuple_impl<char*, std::tuple<char*>>);
+LIBCPP_STATIC_ASSERT(can_make_from_tuple_impl<const char*, std::tuple<char*>>);
+LIBCPP_STATIC_ASSERT(can_make_from_tuple_impl<const volatile char*, std::tuple<volatile char*>>);
// static_cast
-static_assert(!can_make_from_tuple_impl<int, std::tuple<D>>);
-static_assert(!can_make_from_tuple_impl<D, std::tuple<int>>);
-static_assert(can_make_from_tuple_impl<long, std::tuple<int>>);
-static_assert(can_make_from_tuple_impl<double, std::tuple<float>>);
-static_assert(can_make_from_tuple_impl<float, std::tuple<double>>);
+LIBCPP_STATIC_ASSERT(!can_make_from_tuple_impl<int, std::tuple<D>>);
+LIBCPP_STATIC_ASSERT(!can_make_from_tuple_impl<D, std::tuple<int>>);
+LIBCPP_STATIC_ASSERT(can_make_from_tuple_impl<long, std::tuple<int>>);
+LIBCPP_STATIC_ASSERT(can_make_from_tuple_impl<double, std::tuple<float>>);
+LIBCPP_STATIC_ASSERT(can_make_from_tuple_impl<float, std::tuple<double>>);
} // namespace LWG3528
diff --git a/libcxx/test/std/utilities/variant/variant.variant/variant.swap/swap.pass.cpp b/libcxx/test/std/utilities/variant/variant.variant/variant.swap/swap.pass.cpp
index db05691c55818..039a2373348c4 100644
--- a/libcxx/test/std/utilities/variant/variant.variant/variant.swap/swap.pass.cpp
+++ b/libcxx/test/std/utilities/variant/variant.variant/variant.swap/swap.pass.cpp
@@ -516,7 +516,7 @@ constexpr void test_swap_sfinae() {
}
}
-_LIBCPP_CONSTEXPR_SINCE_CXX20 void test_swap_noexcept() {
+TEST_CONSTEXPR_CXX20 void test_swap_noexcept() {
{
using V = std::variant<int, NothrowMoveable>;
static_assert(std::is_swappable_v<V> && has_swap_member<V>(), "");
diff --git a/libcxx/test/support/msvc_stdlib_force_include.h b/libcxx/test/support/msvc_stdlib_force_include.h
index 6c26085e72c45..6e3424ec63749 100644
--- a/libcxx/test/support/msvc_stdlib_force_include.h
+++ b/libcxx/test/support/msvc_stdlib_force_include.h
@@ -91,7 +91,7 @@ const AssertionDialogAvoider assertion_dialog_avoider{};
#include <version>
#if _HAS_CXX23
-# define TEST_STD_VER 99
+# define TEST_STD_VER 23
#elif _HAS_CXX20
# define TEST_STD_VER 20
#elif _HAS_CXX17
``````````
</details>
https://github.com/llvm/llvm-project/pull/93259
More information about the libcxx-commits
mailing list