[libcxx-commits] [libcxx] [libc++][test] Fix more MSVC and Clang warnings (PR #74965)
via libcxx-commits
libcxx-commits at lists.llvm.org
Sat Dec 9 21:00:25 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.
As usual, I'm trying to strike a balance between avoiding "grab bag" PRs and creating a trillion PRs. After gathering the `static_cast` warning fixes in #<!-- -->74962, I believe that these changes are small enough to group together. Please let me know if you'd like me to decompose this further.
* `libcxx/test/std/algorithms/alg.sorting/alg.heap.operations/sort.heap/ranges_sort_heap.pass.cpp`
+ Fix Clang `-Wunused-variable`, because `LIBCPP_ASSERT` expands to nothing for MSVC's STL.
+ This is the same "always void-cast" change that #<!-- -->73437 applied to the neighboring `complexity.pass.cpp`. I missed that `ranges_sort_heap.pass.cpp` was also affected because we had disabled this test.
* `libcxx/test/std/input.output/file.streams/fstreams/ifstream.members/buffered_reads.pass.cpp`
* `libcxx/test/std/input.output/file.streams/fstreams/ofstream.members/buffered_writes.pass.cpp`
+ Fix MSVC "warning C4244: '`=`': conversion from '`__int64`' to '`_Ty`', possible loss of data".
+ This is a valid warning, possibly the best one that MSVC found in this entire saga. We're accumulating a `std::vector<std::streamsize>` and storing the result in `std::streamsize total_size` but we actually have to start with `std::streamsize{0}` or we'll truncate.
* `libcxx/test/std/input.output/filesystems/fs.enum/enum.path.format.pass.cpp`
+ Fix Clang `-Wunused-local-typedef` because the following usage is libc++-only.
+ I'm just expanding it at the point of use, and using the dedicated `LIBCPP_STATIC_ASSERT` to keep the line length down.
* `libcxx/test/std/input.output/syncstream/syncbuf/syncstream.syncbuf.assign/swap.pass.cpp`
+ Fix MSVC "warning C4242: 'argument': conversion from '`int`' to '`const _Elem`', possible loss of data".
+ This is a valid warning (possibly the second-best) as `sputc()` returns `int_type`. If `sputc()` returns something unexpected, we want to know, so we should separately say `expected.push_back(CharT('B'))`.
* `libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.single/new.size_align_nothrow.pass.cpp`
* `libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.single/new.size_nothrow.pass.cpp`
+ Fix MSVC "warning C6001: Using uninitialized memory '`x`'."
+ [N4964](https://wg21.link/N4964) \[new.delete.single\]/12:
> *Effects:* The deallocation functions (\[basic.stc.dynamic.deallocation\]) called by a *delete-expression* (\[expr.delete\]) to render the value of `ptr` invalid.
+ \[basic.stc.general\]/4:
> When the end of the duration of a region of storage is reached, the values of all pointers representing the address of any part of that region of storage become invalid pointer values (\[basic.compound\]). Indirection through an invalid pointer value and passing an invalid pointer value to a deallocation function have undefined behavior. Any other use of an invalid pointer value has implementation-defined behavior.
+ In certain configurations, after `delete x;` MSVC will consider `x` to be radioactive (and in other configurations, it'll physically null out `x` as a safety measure). We can copy it into `old_x` before deletion, which the implementation finds acceptable.
* `libcxx/test/std/ranges/range.adaptors/range.elements/general.pass.cpp`
* `libcxx/test/std/ranges/range.adaptors/range.elements/iterator/deref.pass.cpp`
+ Fix MSVC "warning C4242: 'initializing': conversion from '`_Ty`' to '`_Ty`', possible loss of data".
+ This was being emitted in `pair` and `tuple`'s perfect forwarding constructors. Passing `short{1}` allows MSVC to see that no truncation is happening.
* `libcxx/test/std/ranges/range.adaptors/range.elements/iterator/member_types.compile.pass.cpp`
+ Fix MSVC "warning C4242: 'initializing': conversion from '`_Ty`' to '`_Ty2`', possible loss of data".
+ Similarly, this was being emitted in `pair`'s perfect forwarding constructor. After passing `short{1}`, I reduced repetition by relying on CTAD. (I can undo that cleanup if it's stylistically undesirable.)
* `libcxx/test/std/utilities/function.objects/refwrap/refwrap.const/type_conv_ctor.pass.cpp`
+ Fix MSVC "warning C4930: '`std::reference_wrapper<int> purr(void)`': prototyped function not called (was a variable definition intended?)".
+ There's no reason for `purr()` to be locally declared (aside from isolating it to a narrow scope, which has minimal benefits); it can be declared like `meow()` above. :smile_cat:
* `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 static analysis warnings when replacing `operator new`:
```
warning C28196: The requirement that '(_Param_(1)>0)?(return!=0):(1)' is not satisfied. (The expression does not evaluate to true.)
warning C6387: 'return' could be '0': this does not adhere to the specification for the function 'new'.
warning C6011: Dereferencing NULL pointer 'reinterpret_cast<char *>ptr+i'.
```
+ All we need is a null check, which appears in other `operator new` replacements: https://github.com/llvm/llvm-project/blob/b85f1f9b182234ba366d78ae2174a149e44d08c1/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.single/new.size.replace.pass.cpp#L27-L28
---
Full diff: https://github.com/llvm/llvm-project/pull/74965.diff
13 Files Affected:
- (modified) libcxx/test/std/algorithms/alg.sorting/alg.heap.operations/sort.heap/ranges_sort_heap.pass.cpp (+1-1)
- (modified) libcxx/test/std/input.output/file.streams/fstreams/ifstream.members/buffered_reads.pass.cpp (+2-2)
- (modified) libcxx/test/std/input.output/file.streams/fstreams/ofstream.members/buffered_writes.pass.cpp (+2-2)
- (modified) libcxx/test/std/input.output/filesystems/fs.enum/enum.path.format.pass.cpp (+1-3)
- (modified) libcxx/test/std/input.output/syncstream/syncbuf/syncstream.syncbuf.assign/swap.pass.cpp (+2-1)
- (modified) libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.single/new.size_align_nothrow.pass.cpp (+2-1)
- (modified) libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.single/new.size_nothrow.pass.cpp (+2-1)
- (modified) libcxx/test/std/ranges/range.adaptors/range.elements/general.pass.cpp (+1-1)
- (modified) libcxx/test/std/ranges/range.adaptors/range.elements/iterator/deref.pass.cpp (+2-2)
- (modified) libcxx/test/std/ranges/range.adaptors/range.elements/iterator/member_types.compile.pass.cpp (+1-1)
- (modified) libcxx/test/std/utilities/function.objects/refwrap/refwrap.const/type_conv_ctor.pass.cpp (+2-1)
- (modified) libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.create/make_shared_for_overwrite.pass.cpp (+3)
- (modified) libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.create/make_unique_for_overwrite.default_init.pass.cpp (+3)
``````````diff
diff --git a/libcxx/test/std/algorithms/alg.sorting/alg.heap.operations/sort.heap/ranges_sort_heap.pass.cpp b/libcxx/test/std/algorithms/alg.sorting/alg.heap.operations/sort.heap/ranges_sort_heap.pass.cpp
index 1153ed573d635f..1e636ea9afac47 100644
--- a/libcxx/test/std/algorithms/alg.sorting/alg.heap.operations/sort.heap/ranges_sort_heap.pass.cpp
+++ b/libcxx/test/std/algorithms/alg.sorting/alg.heap.operations/sort.heap/ranges_sort_heap.pass.cpp
@@ -238,6 +238,7 @@ void test_complexity() {
const int debug_elements = std::min(100, n);
// Multiplier 2 because of comp(a,b) comp(b, a) checks.
const int debug_comparisons = 2 * (debug_elements + 1) * debug_elements;
+ (void)debug_comparisons;
std::shuffle(first, last, g);
std::make_heap(first, last, &MyInt::Comp);
// The exact stats of our current implementation are recorded here.
@@ -247,7 +248,6 @@ void test_complexity() {
LIBCPP_ASSERT(stats.moved <= 2 * n + n * logn);
#if _LIBCPP_HARDENING_MODE != _LIBCPP_HARDENING_MODE_DEBUG
LIBCPP_ASSERT(stats.compared <= n * logn);
- (void)debug_comparisons;
#else
LIBCPP_ASSERT(stats.compared <= 2 * n * logn + debug_comparisons);
#endif
diff --git a/libcxx/test/std/input.output/file.streams/fstreams/ifstream.members/buffered_reads.pass.cpp b/libcxx/test/std/input.output/file.streams/fstreams/ifstream.members/buffered_reads.pass.cpp
index d57b7c20a2da27..ecc11f4999ffa1 100644
--- a/libcxx/test/std/input.output/file.streams/fstreams/ifstream.members/buffered_reads.pass.cpp
+++ b/libcxx/test/std/input.output/file.streams/fstreams/ifstream.members/buffered_reads.pass.cpp
@@ -44,7 +44,7 @@
template <class BufferPolicy>
void test_read(BufferPolicy policy, const std::vector<std::streamsize>& payload_sizes) {
- std::streamsize total_size = std::accumulate(payload_sizes.begin(), payload_sizes.end(), 0);
+ std::streamsize total_size = std::accumulate(payload_sizes.begin(), payload_sizes.end(), std::streamsize{0});
std::vector<char> data(total_size);
for (std::size_t i = 0; i < data.size(); ++i) {
data[i] = static_cast<char>(i % (1 << 8 * sizeof(char)));
@@ -99,7 +99,7 @@ void test_read(BufferPolicy policy, const std::vector<std::streamsize>& payload_
#ifndef TEST_HAS_NO_WIDE_CHARACTERS
template <class BufferPolicy>
void test_read_codecvt(BufferPolicy policy, const std::vector<std::streamsize>& payload_sizes) {
- std::streamsize total_size = std::accumulate(payload_sizes.begin(), payload_sizes.end(), 0);
+ std::streamsize total_size = std::accumulate(payload_sizes.begin(), payload_sizes.end(), std::streamsize{0});
std::vector<wchar_t> data(total_size);
for (std::size_t i = 0; i < data.size(); ++i) {
data[i] = static_cast<wchar_t>(i);
diff --git a/libcxx/test/std/input.output/file.streams/fstreams/ofstream.members/buffered_writes.pass.cpp b/libcxx/test/std/input.output/file.streams/fstreams/ofstream.members/buffered_writes.pass.cpp
index e7820739505106..b5bbb0ca2ee4e7 100644
--- a/libcxx/test/std/input.output/file.streams/fstreams/ofstream.members/buffered_writes.pass.cpp
+++ b/libcxx/test/std/input.output/file.streams/fstreams/ofstream.members/buffered_writes.pass.cpp
@@ -45,7 +45,7 @@
template <class BufferPolicy>
void test_write(BufferPolicy policy, const std::vector<std::streamsize>& payload_sizes) {
std::size_t previously_written = 0;
- std::streamsize total_size = std::accumulate(payload_sizes.begin(), payload_sizes.end(), 0);
+ std::streamsize total_size = std::accumulate(payload_sizes.begin(), payload_sizes.end(), std::streamsize{0});
std::vector<char> data(total_size);
for (std::size_t i = 0; i < data.size(); ++i) {
data[i] = static_cast<char>(i % (1 << 8 * sizeof(char)));
@@ -97,7 +97,7 @@ void test_write(BufferPolicy policy, const std::vector<std::streamsize>& payload
template <class BufferPolicy>
void test_write_codecvt(BufferPolicy policy, const std::vector<std::streamsize>& payload_sizes) {
std::size_t previously_written = 0;
- std::streamsize total_size = std::accumulate(payload_sizes.begin(), payload_sizes.end(), 0);
+ std::streamsize total_size = std::accumulate(payload_sizes.begin(), payload_sizes.end(), std::streamsize{0});
std::vector<wchar_t> data(total_size);
for (std::size_t i = 0; i < data.size(); ++i) {
data[i] = static_cast<wchar_t>(i);
diff --git a/libcxx/test/std/input.output/filesystems/fs.enum/enum.path.format.pass.cpp b/libcxx/test/std/input.output/filesystems/fs.enum/enum.path.format.pass.cpp
index 7f3022a3ce9bdd..ad0cdb092def8f 100644
--- a/libcxx/test/std/input.output/filesystems/fs.enum/enum.path.format.pass.cpp
+++ b/libcxx/test/std/input.output/filesystems/fs.enum/enum.path.format.pass.cpp
@@ -25,9 +25,7 @@ int main(int, char**) {
typedef fs::path::format E;
static_assert(std::is_enum<E>::value, "");
- typedef std::underlying_type<E>::type UT;
-
- LIBCPP_ONLY(static_assert(std::is_same<UT, unsigned char>::value, "")); // Implementation detail
+ LIBCPP_STATIC_ASSERT(std::is_same<std::underlying_type<E>::type, unsigned char>::value, ""); // Implementation detail
static_assert(
E::auto_format != E::native_format &&
diff --git a/libcxx/test/std/input.output/syncstream/syncbuf/syncstream.syncbuf.assign/swap.pass.cpp b/libcxx/test/std/input.output/syncstream/syncbuf/syncstream.syncbuf.assign/swap.pass.cpp
index ba007da5a054a7..a236bf4752a076 100644
--- a/libcxx/test/std/input.output/syncstream/syncbuf/syncstream.syncbuf.assign/swap.pass.cpp
+++ b/libcxx/test/std/input.output/syncstream/syncbuf/syncstream.syncbuf.assign/swap.pass.cpp
@@ -75,7 +75,8 @@ static void test_short_write_after_swap() {
sync_buf2.sputn(expected.data(), expected.size());
sync_buf1.swap(sync_buf2);
- expected.push_back(sync_buf1.sputc(CharT('B')));
+ sync_buf1.sputc(CharT('B'));
+ expected.push_back(CharT('B'));
sync_buf2.sputc(CharT('Z'));
assert(sstr1.str().empty());
diff --git a/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.single/new.size_align_nothrow.pass.cpp b/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.single/new.size_align_nothrow.pass.cpp
index 4e5d36cd7c6dfc..1c575729678d5c 100644
--- a/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.single/new.size_align_nothrow.pass.cpp
+++ b/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.single/new.size_align_nothrow.pass.cpp
@@ -60,8 +60,9 @@ int main(int, char**) {
assert(reinterpret_cast<std::uintptr_t>(x) % alignof(TrackLifetimeOverAligned) == 0);
assert(info.address_constructed == x);
+ const auto old_x = x;
delete x;
- assert(info.address_destroyed == x);
+ assert(info.address_destroyed == old_x);
}
return 0;
diff --git a/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.single/new.size_nothrow.pass.cpp b/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.single/new.size_nothrow.pass.cpp
index 398de0068aba1b..56ae8df43f66fb 100644
--- a/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.single/new.size_nothrow.pass.cpp
+++ b/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.single/new.size_nothrow.pass.cpp
@@ -50,8 +50,9 @@ int main(int, char**) {
assert(x != nullptr);
assert(info.address_constructed == x);
+ const auto old_x = x;
delete x;
- assert(info.address_destroyed == x);
+ assert(info.address_destroyed == old_x);
}
return 0;
diff --git a/libcxx/test/std/ranges/range.adaptors/range.elements/general.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.elements/general.pass.cpp
index 78792ae54bdbfc..d5318ced73dcd9 100644
--- a/libcxx/test/std/ranges/range.adaptors/range.elements/general.pass.cpp
+++ b/libcxx/test/std/ranges/range.adaptors/range.elements/general.pass.cpp
@@ -70,7 +70,7 @@ int main(int, char**) {
// tuple
{
- std::tuple<short> tps[] = {{1}, {2}, {3}};
+ std::tuple<short> tps[] = {{short{1}}, {short{2}}, {short{3}}};
auto ev = tps | std::views::elements<0>;
auto expected = {1, 2, 3};
assert(std::ranges::equal(ev, expected));
diff --git a/libcxx/test/std/ranges/range.adaptors/range.elements/iterator/deref.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.elements/iterator/deref.pass.cpp
index d87a3e53392036..f88091f42699e1 100644
--- a/libcxx/test/std/ranges/range.adaptors/range.elements/iterator/deref.pass.cpp
+++ b/libcxx/test/std/ranges/range.adaptors/range.elements/iterator/deref.pass.cpp
@@ -50,7 +50,7 @@ constexpr void testValue(T t) {
constexpr bool test() {
// test tuple
{
- std::tuple<int, short, long> ts[] = {{1, 2, 3}, {4, 5, 6}};
+ std::tuple<int, short, long> ts[] = {{1, short{2}, 3}, {4, short{5}, 6}};
testReference<0>(ts);
testReference<1>(ts);
testReference<2>(ts);
@@ -61,7 +61,7 @@ constexpr bool test() {
// test pair
{
- std::pair<int, short> ps[] = {{1, 2}, {4, 5}};
+ std::pair<int, short> ps[] = {{1, short{2}}, {4, short{5}}};
testReference<0>(ps);
testReference<1>(ps);
testValue<0>(ps[0]);
diff --git a/libcxx/test/std/ranges/range.adaptors/range.elements/iterator/member_types.compile.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.elements/iterator/member_types.compile.pass.cpp
index 9a76c2fcb70c24..6fec655c67810a 100644
--- a/libcxx/test/std/ranges/range.adaptors/range.elements/iterator/member_types.compile.pass.cpp
+++ b/libcxx/test/std/ranges/range.adaptors/range.elements/iterator/member_types.compile.pass.cpp
@@ -65,7 +65,7 @@ static_assert(std::same_as<ElementsIter<Range<std::tuple<int>*>>::iterator_categ
std::random_access_iterator_tag>);
using Generator = decltype(std::views::iota(0, 1) | std::views::transform([](int) {
- return std::pair<int, short>{1, 1};
+ return std::pair{1, short{1}};
}));
static_assert(std::ranges::random_access_range<Generator>);
diff --git a/libcxx/test/std/utilities/function.objects/refwrap/refwrap.const/type_conv_ctor.pass.cpp b/libcxx/test/std/utilities/function.objects/refwrap/refwrap.const/type_conv_ctor.pass.cpp
index 2759b921fabe0c..3ff8a872095135 100644
--- a/libcxx/test/std/utilities/function.objects/refwrap/refwrap.const/type_conv_ctor.pass.cpp
+++ b/libcxx/test/std/utilities/function.objects/refwrap/refwrap.const/type_conv_ctor.pass.cpp
@@ -37,6 +37,8 @@ struct convertible_from_int {
void meow(std::reference_wrapper<int>) {}
void meow(convertible_from_int) {}
+std::reference_wrapper<int> purr();
+
int main(int, char**)
{
{
@@ -58,7 +60,6 @@ int main(int, char**)
meow(0);
}
{
- extern std::reference_wrapper<int> purr();
ASSERT_SAME_TYPE(decltype(true ? purr() : 0), int);
}
#if TEST_STD_VER > 14
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..ce8d91d4e26e6b 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
@@ -60,6 +60,9 @@ constexpr char pattern = 0xDE;
void* operator new(std::size_t count) {
void* ptr = std::malloc(count);
+ if (!ptr) {
+ std::abort(); // placate MSVC's unchecked malloc warning
+ }
for (std::size_t i = 0; i < count; ++i) {
*(reinterpret_cast<char*>(ptr) + i) = pattern;
}
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..5954703109257d 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
@@ -27,6 +27,9 @@ constexpr char pattern = 0xDE;
void* operator new(std::size_t count) {
void* ptr = std::malloc(count);
+ if (!ptr) {
+ std::abort(); // placate MSVC's unchecked malloc warning
+ }
for (std::size_t i = 0; i < count; ++i) {
*(reinterpret_cast<char*>(ptr) + i) = pattern;
}
``````````
</details>
https://github.com/llvm/llvm-project/pull/74965
More information about the libcxx-commits
mailing list