aboutsummaryrefslogtreecommitdiff
path: root/libcxx/test
diff options
context:
space:
mode:
Diffstat (limited to 'libcxx/test')
-rw-r--r--libcxx/test/benchmarks/numeric/gcd.bench.cpp2
-rw-r--r--libcxx/test/libcxx/clang_tidy.gen.py3
-rw-r--r--libcxx/test/libcxx/containers/sequences/forwardlist/assert.pass.cpp47
-rw-r--r--libcxx/test/libcxx/containers/sequences/vector.bool/assert.pass.cpp63
-rw-r--r--libcxx/test/libcxx/diagnostics/system_error_win_codes.pass.cpp25
-rw-r--r--libcxx/test/std/atomics/atomics.ref/exchange.pass.cpp39
-rw-r--r--libcxx/test/std/containers/sequences/vector.bool/at.pass.cpp125
-rw-r--r--libcxx/test/std/containers/sequences/vector.bool/at_const.pass.cpp121
-rw-r--r--libcxx/test/std/diagnostics/syserr/syserr.compare/eq_error_code_error_code.pass.cpp12
-rw-r--r--libcxx/test/std/diagnostics/syserr/syserr.errcat/syserr.errcat.derived/message.pass.cpp5
-rw-r--r--libcxx/test/std/diagnostics/syserr/syserr.errcat/syserr.errcat.objects/system_category.pass.cpp5
-rw-r--r--libcxx/test/std/input.output/filesystems/class.directory_entry/directory_entry.obs/file_type_obs.pass.cpp9
-rw-r--r--libcxx/test/std/input.output/filesystems/class.directory_entry/directory_entry.obs/status.pass.cpp2
-rw-r--r--libcxx/test/std/input.output/filesystems/class.directory_entry/directory_entry.obs/symlink_status.pass.cpp2
-rw-r--r--libcxx/test/std/input.output/filesystems/fs.op.funcs/fs.op.copy_file/copy_file_procfs.pass.cpp53
-rw-r--r--libcxx/test/support/filesystem_test_helper.h4
-rw-r--r--libcxx/test/tools/clang_tidy_checks/CMakeLists.txt1
-rw-r--r--libcxx/test/tools/clang_tidy_checks/libcpp_module.cpp2
-rw-r--r--libcxx/test/tools/clang_tidy_checks/nodebug_on_aliases.cpp35
-rw-r--r--libcxx/test/tools/clang_tidy_checks/nodebug_on_aliases.hpp18
-rw-r--r--libcxx/test/tools/clang_tidy_checks/uglify_attributes.cpp21
-rw-r--r--libcxx/test/tools/clang_tidy_checks/utilities.hpp22
22 files changed, 584 insertions, 32 deletions
diff --git a/libcxx/test/benchmarks/numeric/gcd.bench.cpp b/libcxx/test/benchmarks/numeric/gcd.bench.cpp
index abbc7e9..ca5fed5 100644
--- a/libcxx/test/benchmarks/numeric/gcd.bench.cpp
+++ b/libcxx/test/benchmarks/numeric/gcd.bench.cpp
@@ -25,7 +25,7 @@ static std::array<T, 1000> generate(std::uniform_int_distribution<T> distributio
static void bm_gcd_random(benchmark::State& state) {
std::array data = generate<int>();
- while (state.KeepRunningBatch(data.size()))
+ while (state.KeepRunningBatch(data.size() * data.size()))
for (auto v0 : data)
for (auto v1 : data)
benchmark::DoNotOptimize(std::gcd(v0, v1));
diff --git a/libcxx/test/libcxx/clang_tidy.gen.py b/libcxx/test/libcxx/clang_tidy.gen.py
index 0db9c0d..06f277e 100644
--- a/libcxx/test/libcxx/clang_tidy.gen.py
+++ b/libcxx/test/libcxx/clang_tidy.gen.py
@@ -33,8 +33,7 @@ for header in public_headers:
{lit_header_undeprecations.get(header, '')}
// TODO: run clang-tidy with modules enabled once they are supported
-// RUN: %{{clang-tidy}} %s --warnings-as-errors=* -header-filter=.* --checks='-*,libcpp-*' --load=%{{test-tools-dir}}/clang_tidy_checks/libcxx-tidy.plugin -- %{{compile_flags}} -fno-modules
-// RUN: %{{clang-tidy}} %s --warnings-as-errors=* -header-filter=.* --config-file=%{{libcxx-dir}}/.clang-tidy -- -Wweak-vtables %{{compile_flags}} -fno-modules
+// RUN: %{{clang-tidy}} %s --warnings-as-errors=* -header-filter=.* --config-file=%{{libcxx-dir}}/.clang-tidy --load=%{{test-tools-dir}}/clang_tidy_checks/libcxx-tidy.plugin -- -Wweak-vtables %{{compile_flags}} -fno-modules
#include <{header}>
""")
diff --git a/libcxx/test/libcxx/containers/sequences/forwardlist/assert.pass.cpp b/libcxx/test/libcxx/containers/sequences/forwardlist/assert.pass.cpp
new file mode 100644
index 0000000..6d1748e
--- /dev/null
+++ b/libcxx/test/libcxx/containers/sequences/forwardlist/assert.pass.cpp
@@ -0,0 +1,47 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// <forward_list>
+
+// Test hardening assertions for std::forward_list.
+
+// REQUIRES: has-unix-headers
+// REQUIRES: libcpp-hardening-mode={{extensive|debug}}
+// UNSUPPORTED: c++03
+// XFAIL: libcpp-hardening-mode=debug && availability-verbose_abort-missing
+
+#include <forward_list>
+
+#include "check_assertion.h"
+
+int main(int, char**) {
+ { // Default-constructed list.
+ std::forward_list<int> c;
+ const auto& const_c = c;
+ TEST_LIBCPP_ASSERT_FAILURE(c.front(), "forward_list::front called on an empty list");
+ TEST_LIBCPP_ASSERT_FAILURE(const_c.front(), "forward_list::front called on an empty list");
+ TEST_LIBCPP_ASSERT_FAILURE(c.pop_front(), "forward_list::pop_front called on an empty list");
+ }
+
+ { // Non-empty list becomes empty.
+ std::forward_list<int> c;
+ const auto& const_c = c;
+ c.push_front(1);
+
+ // Check that there's no assertion on valid access.
+ (void)c.front();
+ (void)const_c.front();
+
+ c.pop_front();
+ TEST_LIBCPP_ASSERT_FAILURE(c.pop_front(), "forward_list::pop_front called on an empty list");
+ TEST_LIBCPP_ASSERT_FAILURE(c.front(), "forward_list::front called on an empty list");
+ TEST_LIBCPP_ASSERT_FAILURE(const_c.front(), "forward_list::front called on an empty list");
+ }
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx/containers/sequences/vector.bool/assert.pass.cpp b/libcxx/test/libcxx/containers/sequences/vector.bool/assert.pass.cpp
new file mode 100644
index 0000000..41badad
--- /dev/null
+++ b/libcxx/test/libcxx/containers/sequences/vector.bool/assert.pass.cpp
@@ -0,0 +1,63 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// <vector>
+
+// Test hardening assertions for std::vector<bool>.
+
+// REQUIRES: has-unix-headers
+// UNSUPPORTED: libcpp-hardening-mode=none
+// UNSUPPORTED: c++03
+// XFAIL: libcpp-hardening-mode=debug && availability-verbose_abort-missing
+
+#include <vector>
+
+#include "check_assertion.h"
+#include "min_allocator.h"
+
+template <class Allocator>
+void test() {
+ std::vector<bool, Allocator> c;
+ TEST_LIBCPP_ASSERT_FAILURE(c.front(), "vector<bool>::front() called on an empty vector");
+ TEST_LIBCPP_ASSERT_FAILURE(c.back(), "vector<bool>::back() called on an empty vector");
+ TEST_LIBCPP_ASSERT_FAILURE(c[0], "vector<bool>::operator[] index out of bounds");
+ TEST_LIBCPP_ASSERT_FAILURE(c.pop_back(), "vector<bool>::pop_back called on an empty vector");
+
+ // Repeat the test with a const reference to test the const overloads.
+ {
+ const std::vector<bool, Allocator>& cc = c;
+ TEST_LIBCPP_ASSERT_FAILURE(cc.front(), "vector<bool>::front() called on an empty vector");
+ TEST_LIBCPP_ASSERT_FAILURE(cc.back(), "vector<bool>::back() called on an empty vector");
+ TEST_LIBCPP_ASSERT_FAILURE(cc[0], "vector<bool>::operator[] index out of bounds");
+ }
+
+ c.push_back(true);
+ c.push_back(false);
+ c.push_back(true);
+ TEST_LIBCPP_ASSERT_FAILURE(c[3], "vector<bool>::operator[] index out of bounds");
+ TEST_LIBCPP_ASSERT_FAILURE(c[100], "vector<bool>::operator[] index out of bounds");
+
+ // Repeat the test with a const reference to test the const overloads.
+ {
+ const std::vector<bool, Allocator>& cc = c;
+ TEST_LIBCPP_ASSERT_FAILURE(cc[3], "vector<bool>::operator[] index out of bounds");
+ TEST_LIBCPP_ASSERT_FAILURE(cc[100], "vector<bool>::operator[] index out of bounds");
+ }
+
+ TEST_LIBCPP_ASSERT_FAILURE(
+ c.erase(c.end()), "vector<bool>::erase(iterator) called with a non-dereferenceable iterator");
+ TEST_LIBCPP_ASSERT_FAILURE(
+ c.erase(c.begin() + 1, c.begin()), "vector<bool>::erase(iterator, iterator) called with an invalid range");
+}
+
+int main(int, char**) {
+ test<std::allocator<bool>>();
+ test<min_allocator<bool>>();
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx/diagnostics/system_error_win_codes.pass.cpp b/libcxx/test/libcxx/diagnostics/system_error_win_codes.pass.cpp
new file mode 100644
index 0000000..799a5b5
--- /dev/null
+++ b/libcxx/test/libcxx/diagnostics/system_error_win_codes.pass.cpp
@@ -0,0 +1,25 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: windows
+
+// Validate that system_error on windows accepts Windows' System Error Codes (as
+// used by win32 APIs and reported by GetLastError), and that they are properly
+// translated to generic conditions.
+
+#include <windows.h>
+#include <system_error>
+#include <cassert>
+
+#include "test_macros.h"
+
+int main(int, char**) {
+ LIBCPP_ASSERT(std::error_code(ERROR_ACCESS_DENIED, std::system_category()) == std::errc::permission_denied);
+ LIBCPP_ASSERT(std::error_code(ERROR_PATH_NOT_FOUND, std::system_category()) == std::errc::no_such_file_or_directory);
+ return 0;
+}
diff --git a/libcxx/test/std/atomics/atomics.ref/exchange.pass.cpp b/libcxx/test/std/atomics/atomics.ref/exchange.pass.cpp
index cd998d4..c2afa6b 100644
--- a/libcxx/test/std/atomics/atomics.ref/exchange.pass.cpp
+++ b/libcxx/test/std/atomics/atomics.ref/exchange.pass.cpp
@@ -17,24 +17,47 @@
#include <type_traits>
#include "atomic_helpers.h"
+#include "test_helper.h"
#include "test_macros.h"
template <typename T>
struct TestExchange {
void operator()() const {
- T x(T(1));
- std::atomic_ref<T> const a(x);
+ {
+ T x(T(1));
+ std::atomic_ref<T> const a(x);
+
+ {
+ std::same_as<T> decltype(auto) y = a.exchange(T(2));
+ assert(y == T(1));
+ ASSERT_NOEXCEPT(a.exchange(T(2)));
+ }
+
+ {
+ std::same_as<T> decltype(auto) y = a.exchange(T(3), std::memory_order_seq_cst);
+ assert(y == T(2));
+ ASSERT_NOEXCEPT(a.exchange(T(3), std::memory_order_seq_cst));
+ }
+ }
+ // memory_order::release
{
- std::same_as<T> decltype(auto) y = a.exchange(T(2));
- assert(y == T(1));
- ASSERT_NOEXCEPT(a.exchange(T(2)));
+ auto exchange = [](std::atomic_ref<T> const& x, T, T new_val) {
+ x.exchange(new_val, std::memory_order::release);
+ };
+ auto load = [](std::atomic_ref<T> const& x) { return x.load(std::memory_order::acquire); };
+ test_acquire_release<T>(exchange, load);
}
+ // memory_order::seq_cst
{
- std::same_as<T> decltype(auto) y = a.exchange(T(3), std::memory_order_seq_cst);
- assert(y == T(2));
- ASSERT_NOEXCEPT(a.exchange(T(3), std::memory_order_seq_cst));
+ auto exchange_no_arg = [](std::atomic_ref<T> const& x, T, T new_val) { x.exchange(new_val); };
+ auto exchange_with_order = [](std::atomic_ref<T> const& x, T, T new_val) {
+ x.exchange(new_val, std::memory_order::seq_cst);
+ };
+ auto load = [](std::atomic_ref<T> const& x) { return x.load(); };
+ test_seq_cst<T>(exchange_no_arg, load);
+ test_seq_cst<T>(exchange_with_order, load);
}
}
};
diff --git a/libcxx/test/std/containers/sequences/vector.bool/at.pass.cpp b/libcxx/test/std/containers/sequences/vector.bool/at.pass.cpp
new file mode 100644
index 0000000..16832dd
--- /dev/null
+++ b/libcxx/test/std/containers/sequences/vector.bool/at.pass.cpp
@@ -0,0 +1,125 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// <vector>
+
+// reference at(size_type n); // constexpr since C++20
+
+#include <cassert>
+#include <memory>
+#include <vector>
+
+#include "min_allocator.h"
+#include "test_allocator.h"
+#include "test_macros.h"
+
+#ifndef TEST_HAS_NO_EXCEPTIONS
+# include <stdexcept>
+#endif
+
+template <typename Allocator>
+TEST_CONSTEXPR_CXX20 void test() {
+ using C = std::vector<bool, Allocator>;
+ using reference = typename C::reference;
+ bool a[] = {1, 0, 1, 0, 1};
+ C v(a, a + sizeof(a) / sizeof(a[0]));
+ ASSERT_SAME_TYPE(reference, decltype(v.at(0)));
+ assert(v.at(0) == true);
+ assert(v.at(1) == false);
+ assert(v.at(2) == true);
+ assert(v.at(3) == false);
+ assert(v.at(4) == true);
+ v.at(1) = 1;
+ assert(v.at(1) == true);
+ v.at(3) = 1;
+ assert(v.at(3) == true);
+}
+
+template <typename Allocator>
+void test_exception() {
+#ifndef TEST_HAS_NO_EXCEPTIONS
+ {
+ bool a[] = {1, 0, 1, 1};
+ using C = std::vector<bool, Allocator>;
+ C v(a, a + sizeof(a) / sizeof(a[0]));
+
+ try {
+ TEST_IGNORE_NODISCARD v.at(4);
+ assert(false);
+ } catch (std::out_of_range const&) {
+ // pass
+ } catch (...) {
+ assert(false);
+ }
+
+ try {
+ TEST_IGNORE_NODISCARD v.at(5);
+ assert(false);
+ } catch (std::out_of_range const&) {
+ // pass
+ } catch (...) {
+ assert(false);
+ }
+
+ try {
+ TEST_IGNORE_NODISCARD v.at(6);
+ assert(false);
+ } catch (std::out_of_range const&) {
+ // pass
+ } catch (...) {
+ assert(false);
+ }
+
+ try {
+ using size_type = typename C::size_type;
+ TEST_IGNORE_NODISCARD v.at(static_cast<size_type>(-1));
+ assert(false);
+ } catch (std::out_of_range const&) {
+ // pass
+ } catch (...) {
+ assert(false);
+ }
+ }
+
+ {
+ std::vector<bool, Allocator> v;
+ try {
+ TEST_IGNORE_NODISCARD v.at(0);
+ assert(false);
+ } catch (std::out_of_range const&) {
+ // pass
+ } catch (...) {
+ assert(false);
+ }
+ }
+#endif
+}
+
+TEST_CONSTEXPR_CXX20 bool tests() {
+ test<std::allocator<bool> >();
+ test<min_allocator<bool> >();
+ test<test_allocator<bool> >();
+ return true;
+}
+
+void test_exceptions() {
+ test_exception<std::allocator<bool> >();
+ test_exception<min_allocator<bool> >();
+ test_exception<test_allocator<bool> >();
+}
+
+int main(int, char**) {
+ tests();
+ test_exceptions();
+
+#if TEST_STD_VER >= 20
+ static_assert(tests());
+#endif
+
+ return 0;
+}
diff --git a/libcxx/test/std/containers/sequences/vector.bool/at_const.pass.cpp b/libcxx/test/std/containers/sequences/vector.bool/at_const.pass.cpp
new file mode 100644
index 0000000..5ed794d
--- /dev/null
+++ b/libcxx/test/std/containers/sequences/vector.bool/at_const.pass.cpp
@@ -0,0 +1,121 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// <vector>
+
+// const_reference at(size_type n) const; // constexpr since C++20
+
+#include <cassert>
+#include <memory>
+#include <vector>
+
+#include "min_allocator.h"
+#include "test_allocator.h"
+#include "test_macros.h"
+
+#ifndef TEST_HAS_NO_EXCEPTIONS
+# include <stdexcept>
+#endif
+
+template <typename Allocator>
+TEST_CONSTEXPR_CXX20 void test() {
+ using C = const std::vector<bool, Allocator>;
+ using const_reference = typename C::const_reference;
+ bool a[] = {1, 0, 1, 0, 1};
+ C v(a, a + sizeof(a) / sizeof(a[0]));
+ ASSERT_SAME_TYPE(const_reference, decltype(v.at(0)));
+ assert(v.at(0) == true);
+ assert(v.at(1) == false);
+ assert(v.at(2) == true);
+ assert(v.at(3) == false);
+ assert(v.at(4) == true);
+}
+
+template <typename Allocator>
+void test_exception() {
+#ifndef TEST_HAS_NO_EXCEPTIONS
+ {
+ bool a[] = {1, 0, 1, 1};
+ using C = const std::vector<bool, Allocator>;
+ C v(a, a + sizeof(a) / sizeof(a[0]));
+
+ try {
+ TEST_IGNORE_NODISCARD v.at(4);
+ assert(false);
+ } catch (std::out_of_range const&) {
+ // pass
+ } catch (...) {
+ assert(false);
+ }
+
+ try {
+ TEST_IGNORE_NODISCARD v.at(5);
+ assert(false);
+ } catch (std::out_of_range const&) {
+ // pass
+ } catch (...) {
+ assert(false);
+ }
+
+ try {
+ TEST_IGNORE_NODISCARD v.at(6);
+ assert(false);
+ } catch (std::out_of_range const&) {
+ // pass
+ } catch (...) {
+ assert(false);
+ }
+
+ try {
+ using size_type = typename C::size_type;
+ TEST_IGNORE_NODISCARD v.at(static_cast<size_type>(-1));
+ assert(false);
+ } catch (std::out_of_range const&) {
+ // pass
+ } catch (...) {
+ assert(false);
+ }
+ }
+
+ {
+ std::vector<bool, Allocator> v;
+ try {
+ TEST_IGNORE_NODISCARD v.at(0);
+ assert(false);
+ } catch (std::out_of_range const&) {
+ // pass
+ } catch (...) {
+ assert(false);
+ }
+ }
+#endif
+}
+
+TEST_CONSTEXPR_CXX20 bool tests() {
+ test<std::allocator<bool> >();
+ test<min_allocator<bool> >();
+ test<test_allocator<bool> >();
+ return true;
+}
+
+void test_exceptions() {
+ test_exception<std::allocator<bool> >();
+ test_exception<min_allocator<bool> >();
+ test_exception<test_allocator<bool> >();
+}
+
+int main(int, char**) {
+ tests();
+ test_exceptions();
+
+#if TEST_STD_VER >= 20
+ static_assert(tests());
+#endif
+
+ return 0;
+}
diff --git a/libcxx/test/std/diagnostics/syserr/syserr.compare/eq_error_code_error_code.pass.cpp b/libcxx/test/std/diagnostics/syserr/syserr.compare/eq_error_code_error_code.pass.cpp
index f1f4973..a8b565b 100644
--- a/libcxx/test/std/diagnostics/syserr/syserr.compare/eq_error_code_error_code.pass.cpp
+++ b/libcxx/test/std/diagnostics/syserr/syserr.compare/eq_error_code_error_code.pass.cpp
@@ -22,6 +22,10 @@
#include "test_macros.h"
+#ifndef _WIN32
+# define TEST_SYSTEM_CATEGORY_IS_GENERIC_CATEGORY
+#endif
+
int main(int, char**) {
std::error_code e_code1(5, std::generic_category());
std::error_code e_code2(5, std::system_category());
@@ -45,7 +49,9 @@ int main(int, char**) {
assert(e_code2 == e_code2);
assert(e_code2 != e_code3);
assert(e_code2 != e_code4);
+#ifdef TEST_SYSTEM_CATEGORY_IS_GENERIC_CATEGORY
LIBCPP_ASSERT(e_code2 == e_condition1);
+#endif
assert(e_code2 == e_condition2);
LIBCPP_ASSERT(e_code2 != e_condition3);
assert(e_code2 != e_condition4);
@@ -65,11 +71,15 @@ int main(int, char**) {
assert(e_code4 == e_code4);
LIBCPP_ASSERT(e_code4 != e_condition1);
assert(e_code4 != e_condition2);
+#ifdef TEST_SYSTEM_CATEGORY_IS_GENERIC_CATEGORY
LIBCPP_ASSERT(e_code4 == e_condition3);
+#endif
assert(e_code4 == e_condition4);
assert(e_condition1 == e_code1);
+#ifdef TEST_SYSTEM_CATEGORY_IS_GENERIC_CATEGORY
LIBCPP_ASSERT(e_condition1 == e_code2);
+#endif
assert(e_condition1 != e_code3);
LIBCPP_ASSERT(e_condition1 != e_code4);
assert(e_condition1 == e_condition1);
@@ -89,7 +99,9 @@ int main(int, char**) {
assert(e_condition3 != e_code1);
LIBCPP_ASSERT(e_condition3 != e_code2);
assert(e_condition3 == e_code3);
+#ifdef TEST_SYSTEM_CATEGORY_IS_GENERIC_CATEGORY
LIBCPP_ASSERT(e_condition3 == e_code4);
+#endif
assert(e_condition3 != e_condition1);
assert(e_condition3 != e_condition2);
assert(e_condition3 == e_condition3);
diff --git a/libcxx/test/std/diagnostics/syserr/syserr.errcat/syserr.errcat.derived/message.pass.cpp b/libcxx/test/std/diagnostics/syserr/syserr.errcat/syserr.errcat.derived/message.pass.cpp
index 9f7eb42..f7f4313 100644
--- a/libcxx/test/std/diagnostics/syserr/syserr.errcat/syserr.errcat.derived/message.pass.cpp
+++ b/libcxx/test/std/diagnostics/syserr/syserr.errcat/syserr.errcat.derived/message.pass.cpp
@@ -29,8 +29,11 @@ int main(int, char**) {
assert(!m1.empty());
assert(!m2.empty());
assert(!m3.empty());
+#ifndef _WIN32
+ // On windows, system_category is distinct.
LIBCPP_ASSERT(m1 == m2);
- assert(m1 != m3);
+#endif
+ assert(m2 != m3);
return 0;
}
diff --git a/libcxx/test/std/diagnostics/syserr/syserr.errcat/syserr.errcat.objects/system_category.pass.cpp b/libcxx/test/std/diagnostics/syserr/syserr.errcat/syserr.errcat.objects/system_category.pass.cpp
index 6ba33ba..255cbe7 100644
--- a/libcxx/test/std/diagnostics/syserr/syserr.errcat/syserr.errcat.objects/system_category.pass.cpp
+++ b/libcxx/test/std/diagnostics/syserr/syserr.errcat/syserr.errcat.objects/system_category.pass.cpp
@@ -33,7 +33,12 @@ int main(int, char**) {
{
const std::error_category& e_cat1 = std::system_category();
std::error_condition e_cond = e_cat1.default_error_condition(5);
+#ifdef _WIN32
+ // Windows' system error 5 is ERROR_ACCESS_DENIED, which maps to generic code permission_denied.
+ LIBCPP_ASSERT(e_cond.value() == static_cast<int>(std::errc::permission_denied));
+#else
LIBCPP_ASSERT(e_cond.value() == 5);
+#endif
LIBCPP_ASSERT(e_cond.category() == std::generic_category());
assert(e_cat1.equivalent(5, e_cond));
diff --git a/libcxx/test/std/input.output/filesystems/class.directory_entry/directory_entry.obs/file_type_obs.pass.cpp b/libcxx/test/std/input.output/filesystems/class.directory_entry/directory_entry.obs/file_type_obs.pass.cpp
index 303a95a..071ee7f 100644
--- a/libcxx/test/std/input.output/filesystems/class.directory_entry/directory_entry.obs/file_type_obs.pass.cpp
+++ b/libcxx/test/std/input.output/filesystems/class.directory_entry/directory_entry.obs/file_type_obs.pass.cpp
@@ -172,8 +172,13 @@ static void test_with_ec_dne() {
file_status st = status(p, status_ec);
file_status sym_st = symlink_status(p, sym_status_ec);
std::error_code ec = GetTestEC(2);
- auto CheckEC = [&](std::error_code const& other_ec) {
- bool res = ec == other_ec;
+ auto CheckEC = [&](std::error_code const& other_ec) {
+ // Note: we're comparing equality of the _canonicalized_ error_condition
+ // here (unlike in other tests where we expect exactly the same
+ // error_code). This is because directory_entry can construct its own
+ // generic_category error when a file doesn't exist, instead of passing
+ // through an underlying system_category error.
+ bool res = ec.default_error_condition() == other_ec.default_error_condition();
ec = GetTestEC(2);
return res;
};
diff --git a/libcxx/test/std/input.output/filesystems/class.directory_entry/directory_entry.obs/status.pass.cpp b/libcxx/test/std/input.output/filesystems/class.directory_entry/directory_entry.obs/status.pass.cpp
index dd72232..dec04df 100644
--- a/libcxx/test/std/input.output/filesystems/class.directory_entry/directory_entry.obs/status.pass.cpp
+++ b/libcxx/test/std/input.output/filesystems/class.directory_entry/directory_entry.obs/status.pass.cpp
@@ -44,7 +44,7 @@ static void test_basic() {
file_status es = e.status(eec);
assert(ps.type() == es.type());
assert(ps.permissions() == es.permissions());
- assert(pec == eec);
+ assert(pec.default_error_condition() == eec.default_error_condition());
}
for (const auto& p : TestCases) {
const directory_entry e(p);
diff --git a/libcxx/test/std/input.output/filesystems/class.directory_entry/directory_entry.obs/symlink_status.pass.cpp b/libcxx/test/std/input.output/filesystems/class.directory_entry/directory_entry.obs/symlink_status.pass.cpp
index 24e8069..77da936 100644
--- a/libcxx/test/std/input.output/filesystems/class.directory_entry/directory_entry.obs/symlink_status.pass.cpp
+++ b/libcxx/test/std/input.output/filesystems/class.directory_entry/directory_entry.obs/symlink_status.pass.cpp
@@ -44,7 +44,7 @@ static void test_signature() {
file_status es = e.symlink_status(eec);
assert(ps.type() == es.type());
assert(ps.permissions() == es.permissions());
- assert(pec == eec);
+ assert(pec.default_error_condition() == eec.default_error_condition());
}
for (const auto& p : TestCases) {
const directory_entry e(p);
diff --git a/libcxx/test/std/input.output/filesystems/fs.op.funcs/fs.op.copy_file/copy_file_procfs.pass.cpp b/libcxx/test/std/input.output/filesystems/fs.op.funcs/fs.op.copy_file/copy_file_procfs.pass.cpp
new file mode 100644
index 0000000..29bc8e4
--- /dev/null
+++ b/libcxx/test/std/input.output/filesystems/fs.op.funcs/fs.op.copy_file/copy_file_procfs.pass.cpp
@@ -0,0 +1,53 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14
+// REQUIRES: linux
+// UNSUPPORTED: no-filesystem
+// XFAIL: no-localization
+// UNSUPPORTED: availability-filesystem-missing
+
+// <filesystem>
+
+// bool copy_file(const path& from, const path& to);
+// bool copy_file(const path& from, const path& to, error_code& ec) noexcept;
+// bool copy_file(const path& from, const path& to, copy_options options);
+// bool copy_file(const path& from, const path& to, copy_options options,
+// error_code& ec) noexcept;
+
+#include <cassert>
+#include <filesystem>
+#include <system_error>
+
+#include "test_macros.h"
+#include "filesystem_test_helper.h"
+
+namespace fs = std::filesystem;
+
+// Linux has various virtual filesystems such as /proc and /sys
+// where files may have no length (st_size == 0), but still contain data.
+// This is because the to-be-read data is usually generated ad-hoc by the reading syscall
+// These files can not be copied with kernel-side copies like copy_file_range or sendfile,
+// and must instead be copied via a traditional userspace read + write loop.
+int main(int, char** argv) {
+ const fs::path procfile{"/proc/self/comm"};
+ assert(file_size(procfile) == 0);
+
+ scoped_test_env env;
+ std::error_code ec = GetTestEC();
+
+ const fs::path dest = env.make_env_path("dest");
+
+ assert(copy_file(procfile, dest, ec));
+ assert(!ec);
+
+ // /proc/self/comm contains the filename of the executable, plus a null terminator
+ assert(file_size(dest) == fs::path(argv[0]).filename().string().size() + 1);
+
+ return 0;
+}
diff --git a/libcxx/test/support/filesystem_test_helper.h b/libcxx/test/support/filesystem_test_helper.h
index a63d645..2ad9efb 100644
--- a/libcxx/test/support/filesystem_test_helper.h
+++ b/libcxx/test/support/filesystem_test_helper.h
@@ -583,7 +583,11 @@ struct ExceptionChecker {
assert(ErrorIsImp(Err.code(), {expected_err}));
assert(Err.path1() == expected_path1);
assert(Err.path2() == expected_path2);
+#ifndef _WIN32
+ // On Windows, the error strings are windows error code strings, and don't
+ // match textually with the strings generated for generic std::errc::*.
LIBCPP_ONLY(check_libcxx_string(Err));
+#endif
}
void check_libcxx_string(fs::filesystem_error const& Err) {
diff --git a/libcxx/test/tools/clang_tidy_checks/CMakeLists.txt b/libcxx/test/tools/clang_tidy_checks/CMakeLists.txt
index 05c44e4..0f8f0e88 100644
--- a/libcxx/test/tools/clang_tidy_checks/CMakeLists.txt
+++ b/libcxx/test/tools/clang_tidy_checks/CMakeLists.txt
@@ -92,6 +92,7 @@ set(SOURCES
header_exportable_declarations.cpp
hide_from_abi.cpp
internal_ftm_use.cpp
+ nodebug_on_aliases.cpp
proper_version_checks.cpp
qualify_declval.cpp
robust_against_adl.cpp
diff --git a/libcxx/test/tools/clang_tidy_checks/libcpp_module.cpp b/libcxx/test/tools/clang_tidy_checks/libcpp_module.cpp
index 54beed5..bc7c8ce 100644
--- a/libcxx/test/tools/clang_tidy_checks/libcpp_module.cpp
+++ b/libcxx/test/tools/clang_tidy_checks/libcpp_module.cpp
@@ -13,6 +13,7 @@
#include "header_exportable_declarations.hpp"
#include "hide_from_abi.hpp"
#include "internal_ftm_use.hpp"
+#include "nodebug_on_aliases.hpp"
#include "proper_version_checks.hpp"
#include "qualify_declval.hpp"
#include "robust_against_adl.hpp"
@@ -26,6 +27,7 @@ public:
check_factories.registerCheck<libcpp::header_exportable_declarations>("libcpp-header-exportable-declarations");
check_factories.registerCheck<libcpp::hide_from_abi>("libcpp-hide-from-abi");
check_factories.registerCheck<libcpp::internal_ftm_use>("libcpp-internal-ftms");
+ check_factories.registerCheck<libcpp::nodebug_on_aliases>("libcpp-nodebug-on-aliases");
check_factories.registerCheck<libcpp::proper_version_checks>("libcpp-cpp-version-check");
check_factories.registerCheck<libcpp::robust_against_adl_check>("libcpp-robust-against-adl");
check_factories.registerCheck<libcpp::uglify_attributes>("libcpp-uglify-attributes");
diff --git a/libcxx/test/tools/clang_tidy_checks/nodebug_on_aliases.cpp b/libcxx/test/tools/clang_tidy_checks/nodebug_on_aliases.cpp
new file mode 100644
index 0000000..9b96269
--- /dev/null
+++ b/libcxx/test/tools/clang_tidy_checks/nodebug_on_aliases.cpp
@@ -0,0 +1,35 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang-tidy/ClangTidyCheck.h"
+
+#include "nodebug_on_aliases.hpp"
+#include "utilities.hpp"
+
+namespace libcpp {
+namespace {
+AST_MATCHER(clang::NamedDecl, isPretty) { return !is_ugly_name(Node.getName()); }
+} // namespace
+
+nodebug_on_aliases::nodebug_on_aliases(llvm::StringRef name, clang::tidy::ClangTidyContext* context)
+ : clang::tidy::ClangTidyCheck(name, context) {}
+
+void nodebug_on_aliases::registerMatchers(clang::ast_matchers::MatchFinder* finder) {
+ using namespace clang::ast_matchers;
+ finder->addMatcher(
+ typeAliasDecl(unless(anyOf(isPretty(), hasAttr(clang::attr::NoDebug), hasAncestor(functionDecl()))))
+ .bind("nodebug_on_internal_aliases"),
+ this);
+}
+
+void nodebug_on_aliases::check(const clang::ast_matchers::MatchFinder::MatchResult& result) {
+ if (const auto* alias = result.Nodes.getNodeAs<clang::TypeAliasDecl>("nodebug_on_internal_aliases")) {
+ diag(alias->getBeginLoc(), "Internal aliases should always be marked _LIBCPP_NODEBUG");
+ }
+}
+} // namespace libcpp
diff --git a/libcxx/test/tools/clang_tidy_checks/nodebug_on_aliases.hpp b/libcxx/test/tools/clang_tidy_checks/nodebug_on_aliases.hpp
new file mode 100644
index 0000000..1097e89
--- /dev/null
+++ b/libcxx/test/tools/clang_tidy_checks/nodebug_on_aliases.hpp
@@ -0,0 +1,18 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang-tidy/ClangTidyCheck.h"
+
+namespace libcpp {
+class nodebug_on_aliases : public clang::tidy::ClangTidyCheck {
+public:
+ nodebug_on_aliases(llvm::StringRef, clang::tidy::ClangTidyContext*);
+ void registerMatchers(clang::ast_matchers::MatchFinder*) override;
+ void check(const clang::ast_matchers::MatchFinder::MatchResult&) override;
+};
+} // namespace libcpp
diff --git a/libcxx/test/tools/clang_tidy_checks/uglify_attributes.cpp b/libcxx/test/tools/clang_tidy_checks/uglify_attributes.cpp
index 7812b23..24bacde 100644
--- a/libcxx/test/tools/clang_tidy_checks/uglify_attributes.cpp
+++ b/libcxx/test/tools/clang_tidy_checks/uglify_attributes.cpp
@@ -10,20 +10,11 @@
#include "clang-tidy/ClangTidyModuleRegistry.h"
#include "uglify_attributes.hpp"
+#include "utilities.hpp"
-#include <algorithm>
-#include <array>
-#include <span>
-#include <string_view>
+#include <optional>
namespace {
-bool isUgly(std::string_view str) {
- if (str.size() < 2)
- return false;
- if (str[0] == '_' && str[1] >= 'A' && str[1] <= 'Z')
- return true;
- return str.find("__") != std::string_view::npos;
-}
// Starting with Clang 17 ToT C++23 support is provided by CPlusPlus23 instead
// of C++23 support is provided by CPlusPlus2b. To allow a smooth transition for
@@ -77,17 +68,15 @@ AST_MATCHER(clang::Attr, isPretty) {
if (Node.isKeywordAttribute() || !Node.getAttrName())
return false;
if (Node.isCXX11Attribute() && !Node.hasScope()) {
- if (isUgly(Node.getAttrName()->getName()))
+ if (is_ugly_name(Node.getAttrName()->getName()))
return false;
return !llvm::is_contained(
get_standard_attributes(Finder->getASTContext().getLangOpts()), Node.getAttrName()->getName());
}
if (Node.hasScope())
- if (!isUgly(Node.getScopeName()->getName()))
+ if (!is_ugly_name(Node.getScopeName()->getName()))
return true;
- return !isUgly(Node.getAttrName()->getName());
-
- return false;
+ return !is_ugly_name(Node.getAttrName()->getName());
}
std::optional<std::string> getUglyfiedCXX11Attr(const clang::Attr& attr) {
diff --git a/libcxx/test/tools/clang_tidy_checks/utilities.hpp b/libcxx/test/tools/clang_tidy_checks/utilities.hpp
new file mode 100644
index 0000000..b780efe
--- /dev/null
+++ b/libcxx/test/tools/clang_tidy_checks/utilities.hpp
@@ -0,0 +1,22 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LIBCXX_TEST_TOOLS_CLANG_TIDY_CHECKS_UTILITIES_HPP
+#define LIBCXX_TEST_TOOLS_CLANG_TIDY_CHECKS_UTILITIES_HPP
+
+#include <string_view>
+
+inline bool is_ugly_name(std::string_view str) {
+ if (str.size() < 2)
+ return false;
+ if (str[0] == '_' && str[1] >= 'A' && str[1] <= 'Z')
+ return true;
+ return str.find("__") != std::string_view::npos;
+}
+
+#endif // LIBCXX_TEST_TOOLS_CLANG_TIDY_CHECKS_UTILITIES_HPP