diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2017-01-06 20:13:54 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2017-01-06 20:13:54 +0000 |
commit | 4a2db4d30e1653093d4d8b06e8221e2f8b723507 (patch) | |
tree | 941a9d805eb2afbba58f445381819ba0e1dc355f /test | |
parent | cb08bb04c85c6dcd3d951725505317c31eeff323 (diff) | |
download | src-4a2db4d30e1653093d4d8b06e8221e2f8b723507.tar.gz src-4a2db4d30e1653093d4d8b06e8221e2f8b723507.zip |
Notes
Diffstat (limited to 'test')
26 files changed, 731 insertions, 112 deletions
diff --git a/test/libcxx/test/config.py b/test/libcxx/test/config.py index dd90e7a37430..7043b8a01c4a 100644 --- a/test/libcxx/test/config.py +++ b/test/libcxx/test/config.py @@ -57,7 +57,9 @@ class Configuration(object): def __init__(self, lit_config, config): self.lit_config = lit_config self.config = config + self.is_windows = platform.system() == 'Windows' self.cxx = None + self.cxx_is_clang_cl = None self.cxx_stdlib_under_test = None self.project_obj_root = None self.libcxx_src_root = None @@ -95,6 +97,13 @@ class Configuration(object): self.lit_config.fatal( "parameter '{}' should be true or false".format(name)) + def make_static_lib_name(self, name): + """Return the full filename for the specified library name""" + if self.is_windows: + return name + '.lib' + else: + return 'lib' + name + '.a' + def configure(self): self.configure_executor() self.configure_target_info() @@ -171,20 +180,25 @@ class Configuration(object): def configure_cxx(self): # Gather various compiler parameters. cxx = self.get_lit_conf('cxx_under_test') - + self.cxx_is_clang_cl = cxx is not None and \ + os.path.basename(cxx) == 'clang-cl.exe' # If no specific cxx_under_test was given, attempt to infer it as # clang++. - if cxx is None: + if cxx is None or self.cxx_is_clang_cl: clangxx = lit.util.which('clang++', self.config.environment['PATH']) if clangxx: cxx = clangxx self.lit_config.note( "inferred cxx_under_test as: %r" % cxx) + elif self.cxx_is_clang_cl: + self.lit_config.fatal('Failed to find clang++ substitution for' + ' clang-cl') if not cxx: self.lit_config.fatal('must specify user parameter cxx_under_test ' '(e.g., --param=cxx_under_test=clang++)') - self.cxx = CXXCompiler(cxx) + self.cxx = CXXCompiler(cxx) if not self.cxx_is_clang_cl else \ + self._configure_clang_cl(cxx) cxx_type = self.cxx.type if cxx_type is not None: assert self.cxx.version is not None @@ -194,6 +208,25 @@ class Configuration(object): self.config.available_features.add('%s-%s.%s' % ( cxx_type, maj_v, min_v)) + def _configure_clang_cl(self, clang_path): + assert self.cxx_is_clang_cl + # FIXME: don't hardcode the target + flags = ['-fms-compatibility-version=19.00', + '--target=i686-unknown-windows'] + compile_flags = [] + link_flags = ['-fuse-ld=lld'] + if 'INCLUDE' in os.environ: + compile_flags += ['-isystem %s' % p.strip() + for p in os.environ['INCLUDE'].split(';') + if p.strip()] + if 'LIB' in os.environ: + link_flags += ['-L%s' % p.strip() + for p in os.environ['LIB'].split(';') if p.strip()] + return CXXCompiler(clang_path, flags=flags, + compile_flags=compile_flags, + link_flags=link_flags) + + def configure_src_root(self): self.libcxx_src_root = self.get_lit_conf( 'libcxx_src_root', os.path.dirname(self.config.test_source_root)) @@ -335,9 +368,13 @@ class Configuration(object): if self.get_lit_bool('has_libatomic', False): self.config.available_features.add('libatomic') - if '__cpp_if_constexpr' not in self.cxx.dumpMacros(): + macros = self.cxx.dumpMacros() + if '__cpp_if_constexpr' not in macros: self.config.available_features.add('libcpp-no-if-constexpr') + if '__cpp_structured_bindings' not in macros: + self.config.available_features.add('libcpp-no-structured-bindings') + def configure_compile_flags(self): no_default_flags = self.get_lit_bool('no_default_flags', False) if not no_default_flags: @@ -349,6 +386,9 @@ class Configuration(object): # Configure extra flags compile_flags_str = self.get_lit_conf('compile_flags', '') self.cxx.compile_flags += shlex.split(compile_flags_str) + # FIXME: Can we remove this? + if self.is_windows: + self.cxx.compile_flags += ['-D_CRT_SECURE_NO_WARNINGS'] def configure_default_compile_flags(self): # Try and get the std version from the command line. Fall back to @@ -396,7 +436,8 @@ class Configuration(object): def configure_compile_flags_header_includes(self): support_path = os.path.join(self.libcxx_src_root, 'test/support') - if self.cxx_stdlib_under_test != 'libstdc++': + if self.cxx_stdlib_under_test != 'libstdc++' and \ + not self.is_windows: self.cxx.compile_flags += [ '-include', os.path.join(support_path, 'nasty_macros.hpp')] self.configure_config_site_header() @@ -412,9 +453,11 @@ class Configuration(object): self.lit_config.fatal("cxx_headers='%s' is not a directory." % cxx_headers) self.cxx.compile_flags += ['-I' + cxx_headers] - cxxabi_headers = os.path.join(self.libcxx_obj_root, 'include', 'c++-build') - if os.path.isdir(cxxabi_headers): - self.cxx.compile_flags += ['-I' + cxxabi_headers] + if self.libcxx_obj_root is not None: + cxxabi_headers = os.path.join(self.libcxx_obj_root, 'include', + 'c++-build') + if os.path.isdir(cxxabi_headers): + self.cxx.compile_flags += ['-I' + cxxabi_headers] def configure_config_site_header(self): # Check for a possible __config_site in the build directory. We @@ -455,6 +498,8 @@ class Configuration(object): # Transform each macro name into the feature name used in the tests. # Ex. _LIBCPP_HAS_NO_THREADS -> libcpp-has-no-threads for m in feature_macros: + if m == '_LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS': + continue if m == '_LIBCPP_ABI_VERSION': self.config.available_features.add('libcpp-abi-version-v%s' % feature_macros[m]) @@ -530,6 +575,9 @@ class Configuration(object): # Configure libraries if self.cxx_stdlib_under_test == 'libc++': self.cxx.link_flags += ['-nodefaultlibs'] + # FIXME: Handle MSVCRT as part of the ABI library handling. + if self.is_windows: + self.cxx.link_flags += ['-nostdlib', '-lmsvcrtd'] self.configure_link_flags_cxx_library() self.configure_link_flags_abi_library() self.configure_extra_library_flags() @@ -554,15 +602,16 @@ class Configuration(object): if not self.use_system_cxx_lib: if self.cxx_library_root: self.cxx.link_flags += ['-L' + self.cxx_library_root] - if self.cxx_runtime_root: + if self.cxx_runtime_root and not self.is_windows: self.cxx.link_flags += ['-Wl,-rpath,' + self.cxx_runtime_root] def configure_link_flags_abi_library_path(self): # Configure ABI library paths. self.abi_library_root = self.get_lit_conf('abi_library_path') if self.abi_library_root: - self.cxx.link_flags += ['-L' + self.abi_library_root, - '-Wl,-rpath,' + self.abi_library_root] + self.cxx.link_flags += ['-L' + self.abi_library_root] + if not self.is_windows: + self.cxx.link_flags += ['-Wl,-rpath,' + self.abi_library_root] def configure_link_flags_cxx_library(self): libcxx_experimental = self.get_lit_bool('enable_experimental', default=False) @@ -575,7 +624,10 @@ class Configuration(object): else: cxx_library_root = self.get_lit_conf('cxx_library_root') if cxx_library_root: - abs_path = os.path.join(cxx_library_root, 'libc++.a') + libname = self.make_static_lib_name('c++') + abs_path = os.path.join(cxx_library_root, libname) + assert os.path.exists(abs_path) and \ + "static libc++ library does not exist" self.cxx.link_flags += [abs_path] else: self.cxx.link_flags += ['-lc++'] @@ -594,7 +646,8 @@ class Configuration(object): else: cxxabi_library_root = self.get_lit_conf('abi_library_path') if cxxabi_library_root: - abs_path = os.path.join(cxxabi_library_root, 'libc++abi.a') + libname = self.make_static_lib_name('c++abi') + abs_path = os.path.join(cxxabi_library_root, libname) self.cxx.link_flags += [abs_path] else: self.cxx.link_flags += ['-lc++abi'] diff --git a/test/libcxx/utilities/memory/util.dynamic.safety/get_pointer_safety_cxx03.pass.cpp b/test/libcxx/utilities/memory/util.dynamic.safety/get_pointer_safety_cxx03.pass.cpp new file mode 100644 index 000000000000..6d49cea8ba1f --- /dev/null +++ b/test/libcxx/utilities/memory/util.dynamic.safety/get_pointer_safety_cxx03.pass.cpp @@ -0,0 +1,46 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// <memory> + +// pointer_safety get_pointer_safety(); + +#include <memory> +#include <cassert> + +#include "test_macros.h" + +// libc++ doesn't offer std::pointer_safety in C++03 under the new ABI +#if TEST_STD_VER < 11 && defined(_LIBCPP_ABI_POINTER_SAFETY_ENUM_TYPE) +#define TEST_IS_UNSUPPORTED +#endif + +#ifndef TEST_IS_UNSUPPORTED +void test_pr26961() { + std::pointer_safety d; + d = std::get_pointer_safety(); + assert(d == std::get_pointer_safety()); +} +#endif + +int main() +{ +#ifndef TEST_IS_UNSUPPORTED + { + // Test that std::pointer_safety is still offered in C++03 under the old ABI. + std::pointer_safety r = std::get_pointer_safety(); + assert(r == std::pointer_safety::relaxed || + r == std::pointer_safety::preferred || + r == std::pointer_safety::strict); + } + { + test_pr26961(); + } +#endif +} diff --git a/test/libcxx/utilities/memory/util.dynamic.safety/get_pointer_safety_new_abi.pass.cpp b/test/libcxx/utilities/memory/util.dynamic.safety/get_pointer_safety_new_abi.pass.cpp new file mode 100644 index 000000000000..752edb6dadd9 --- /dev/null +++ b/test/libcxx/utilities/memory/util.dynamic.safety/get_pointer_safety_new_abi.pass.cpp @@ -0,0 +1,38 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// <memory> + +// pointer_safety get_pointer_safety(); + +// The pointer_safety interface is no longer provided in C++03 in the new ABI. +// XFAIL: c++98, c++03 + +// MODULES_DEFINES: _LIBCPP_ABI_POINTER_SAFETY_ENUM_TYPE +#define _LIBCPP_ABI_POINTER_SAFETY_ENUM_TYPE +#include <memory> +#include <cassert> + +int main() +{ + { + static_assert(std::is_enum<std::pointer_safety>::value, ""); + static_assert(!std::is_convertible<std::pointer_safety, int>::value, ""); + static_assert(std::is_same< + std::underlying_type<std::pointer_safety>::type, + unsigned char + >::value, ""); + } + { + std::pointer_safety r = std::get_pointer_safety(); + assert(r == std::pointer_safety::relaxed || + r == std::pointer_safety::preferred || + r == std::pointer_safety::strict); + } +} diff --git a/test/libcxx/utilities/variant/variant.variant/variant.assign/copy.pass.cpp b/test/libcxx/utilities/variant/variant.variant/variant.assign/copy.pass.cpp index a94aa2f78299..cb17dfeb071a 100644 --- a/test/libcxx/utilities/variant/variant.variant/variant.assign/copy.pass.cpp +++ b/test/libcxx/utilities/variant/variant.variant/variant.assign/copy.pass.cpp @@ -10,8 +10,9 @@ // UNSUPPORTED: c++98, c++03, c++11, c++14 -// Clang 3.8 doesn't generate constexpr special members correctly. -// XFAIL: clang-3.8, apple-clang-7, apple-clang-8 +// The following compilers don't generate constexpr special members correctly. +// XFAIL: clang-3.5, clang-3.6, clang-3.7, clang-3.8 +// XFAIL: apple-clang-6, apple-clang-7, apple-clang-8 // <variant> @@ -63,7 +64,7 @@ struct TCopyAssignNTMoveAssign { int value; }; -static_assert(std::is_trivially_copy_assignable_v<TCopyAssignNTMoveAssign>); +static_assert(std::is_trivially_copy_assignable_v<TCopyAssignNTMoveAssign>, ""); void test_copy_assignment_sfinae() { { @@ -99,8 +100,8 @@ void test_copy_assignment_same_index() { } } test; constexpr auto result = test(); - static_assert(result.index == 0); - static_assert(result.value == 42); + static_assert(result.index == 0, ""); + static_assert(result.value == 42, ""); } { struct { @@ -113,8 +114,8 @@ void test_copy_assignment_same_index() { } } test; constexpr auto result = test(); - static_assert(result.index == 1); - static_assert(result.value == 42l); + static_assert(result.index == 1, ""); + static_assert(result.value == 42l, ""); } { struct { @@ -127,8 +128,8 @@ void test_copy_assignment_same_index() { } } test; constexpr auto result = test(); - static_assert(result.index == 1); - static_assert(result.value == 42); + static_assert(result.index == 1, ""); + static_assert(result.value == 42, ""); } { struct { @@ -141,8 +142,8 @@ void test_copy_assignment_same_index() { } } test; constexpr auto result = test(); - static_assert(result.index == 1); - static_assert(result.value == 42); + static_assert(result.index == 1, ""); + static_assert(result.value == 42, ""); } } @@ -158,8 +159,8 @@ void test_copy_assignment_different_index() { } } test; constexpr auto result = test(); - static_assert(result.index == 1); - static_assert(result.value == 42l); + static_assert(result.index == 1, ""); + static_assert(result.value == 42l, ""); } { struct { @@ -172,8 +173,8 @@ void test_copy_assignment_different_index() { } } test; constexpr auto result = test(); - static_assert(result.index == 1); - static_assert(result.value == 42); + static_assert(result.index == 1, ""); + static_assert(result.value == 42, ""); } } diff --git a/test/libcxx/utilities/variant/variant.variant/variant.assign/move.pass.cpp b/test/libcxx/utilities/variant/variant.variant/variant.assign/move.pass.cpp index a3d92472dd5e..286a623882fe 100644 --- a/test/libcxx/utilities/variant/variant.variant/variant.assign/move.pass.cpp +++ b/test/libcxx/utilities/variant/variant.variant/variant.assign/move.pass.cpp @@ -10,9 +10,9 @@ // UNSUPPORTED: c++98, c++03, c++11, c++14 -// Clang 3.8 doesn't generate constexpr special members correctly. -// XFAIL: clang-3.8, apple-clang-7, apple-clang-8 - +// The following compilers don't generate constexpr special members correctly. +// XFAIL: clang-3.5, clang-3.6, clang-3.7, clang-3.8 +// XFAIL: apple-clang-6, apple-clang-7, apple-clang-8 // <variant> @@ -64,7 +64,7 @@ struct TMoveAssignNTCopyAssign { int value; }; -static_assert(std::is_trivially_move_assignable_v<TMoveAssignNTCopyAssign>); +static_assert(std::is_trivially_move_assignable_v<TMoveAssignNTCopyAssign>, ""); void test_move_assignment_sfinae() { { @@ -100,8 +100,8 @@ void test_move_assignment_same_index() { } } test; constexpr auto result = test(); - static_assert(result.index == 0); - static_assert(result.value == 42); + static_assert(result.index == 0, ""); + static_assert(result.value == 42, ""); } { struct { @@ -114,8 +114,8 @@ void test_move_assignment_same_index() { } } test; constexpr auto result = test(); - static_assert(result.index == 1); - static_assert(result.value == 42l); + static_assert(result.index == 1, ""); + static_assert(result.value == 42l, ""); } { struct { @@ -128,8 +128,8 @@ void test_move_assignment_same_index() { } } test; constexpr auto result = test(); - static_assert(result.index == 1); - static_assert(result.value == 42); + static_assert(result.index == 1, ""); + static_assert(result.value == 42, ""); } } @@ -145,8 +145,8 @@ void test_move_assignment_different_index() { } } test; constexpr auto result = test(); - static_assert(result.index == 1); - static_assert(result.value == 42l); + static_assert(result.index == 1, ""); + static_assert(result.value == 42l, ""); } { struct { @@ -159,8 +159,8 @@ void test_move_assignment_different_index() { } } test; constexpr auto result = test(); - static_assert(result.index == 1); - static_assert(result.value == 42); + static_assert(result.index == 1, ""); + static_assert(result.value == 42, ""); } } diff --git a/test/libcxx/utilities/variant/variant.variant/variant.ctor/copy.pass.cpp b/test/libcxx/utilities/variant/variant.variant/variant.ctor/copy.pass.cpp index 59c433050590..0d30a78a48ac 100644 --- a/test/libcxx/utilities/variant/variant.variant/variant.ctor/copy.pass.cpp +++ b/test/libcxx/utilities/variant/variant.variant/variant.ctor/copy.pass.cpp @@ -72,45 +72,45 @@ void test_copy_ctor_sfinae() { void test_copy_ctor_basic() { { constexpr std::variant<int> v(std::in_place_index<0>, 42); - static_assert(v.index() == 0); + static_assert(v.index() == 0, ""); constexpr std::variant<int> v2 = v; - static_assert(v2.index() == 0); - static_assert(std::get<0>(v2) == 42); + static_assert(v2.index() == 0, ""); + static_assert(std::get<0>(v2) == 42, ""); } { constexpr std::variant<int, long> v(std::in_place_index<1>, 42); - static_assert(v.index() == 1); + static_assert(v.index() == 1, ""); constexpr std::variant<int, long> v2 = v; - static_assert(v2.index() == 1); - static_assert(std::get<1>(v2) == 42); + static_assert(v2.index() == 1, ""); + static_assert(std::get<1>(v2) == 42, ""); } { constexpr std::variant<TCopy> v(std::in_place_index<0>, 42); - static_assert(v.index() == 0); + static_assert(v.index() == 0, ""); constexpr std::variant<TCopy> v2(v); - static_assert(v2.index() == 0); - static_assert(std::get<0>(v2).value == 42); + static_assert(v2.index() == 0, ""); + static_assert(std::get<0>(v2).value == 42, ""); } { constexpr std::variant<int, TCopy> v(std::in_place_index<1>, 42); - static_assert(v.index() == 1); + static_assert(v.index() == 1, ""); constexpr std::variant<int, TCopy> v2(v); - static_assert(v2.index() == 1); - static_assert(std::get<1>(v2).value == 42); + static_assert(v2.index() == 1, ""); + static_assert(std::get<1>(v2).value == 42, ""); } { constexpr std::variant<TCopyNTMove> v(std::in_place_index<0>, 42); - static_assert(v.index() == 0); + static_assert(v.index() == 0, ""); constexpr std::variant<TCopyNTMove> v2(v); - static_assert(v2.index() == 0); - static_assert(std::get<0>(v2).value == 42); + static_assert(v2.index() == 0, ""); + static_assert(std::get<0>(v2).value == 42, ""); } { constexpr std::variant<int, TCopyNTMove> v(std::in_place_index<1>, 42); - static_assert(v.index() == 1); + static_assert(v.index() == 1, ""); constexpr std::variant<int, TCopyNTMove> v2(v); - static_assert(v2.index() == 1); - static_assert(std::get<1>(v2).value == 42); + static_assert(v2.index() == 1, ""); + static_assert(std::get<1>(v2).value == 42, ""); } } diff --git a/test/libcxx/utilities/variant/variant.variant/variant.ctor/move.pass.cpp b/test/libcxx/utilities/variant/variant.variant/variant.ctor/move.pass.cpp index e67a495d9799..91e8c194d144 100644 --- a/test/libcxx/utilities/variant/variant.variant/variant.ctor/move.pass.cpp +++ b/test/libcxx/utilities/variant/variant.variant/variant.ctor/move.pass.cpp @@ -82,8 +82,8 @@ void test_move_ctor_basic() { } } test; constexpr auto result = test(); - static_assert(result.index == 0); - static_assert(result.value == 42); + static_assert(result.index == 0, ""); + static_assert(result.value == 42, ""); } { struct { @@ -94,8 +94,8 @@ void test_move_ctor_basic() { } } test; constexpr auto result = test(); - static_assert(result.index == 1); - static_assert(result.value == 42); + static_assert(result.index == 1, ""); + static_assert(result.value == 42, ""); } { struct { @@ -106,8 +106,8 @@ void test_move_ctor_basic() { } } test; constexpr auto result = test(); - static_assert(result.index == 0); - static_assert(result.value.value == 42); + static_assert(result.index == 0, ""); + static_assert(result.value.value == 42, ""); } { struct { @@ -118,8 +118,8 @@ void test_move_ctor_basic() { } } test; constexpr auto result = test(); - static_assert(result.index == 1); - static_assert(result.value.value == 42); + static_assert(result.index == 1, ""); + static_assert(result.value.value == 42, ""); } { struct { @@ -130,8 +130,8 @@ void test_move_ctor_basic() { } } test; constexpr auto result = test(); - static_assert(result.index == 0); - static_assert(result.value.value == 42); + static_assert(result.index == 0, ""); + static_assert(result.value.value == 42, ""); } { struct { @@ -142,8 +142,8 @@ void test_move_ctor_basic() { } } test; constexpr auto result = test(); - static_assert(result.index == 1); - static_assert(result.value.value == 42); + static_assert(result.index == 1, ""); + static_assert(result.value.value == 42, ""); } } diff --git a/test/std/utilities/memory/util.dynamic.safety/get_pointer_safety.pass.cpp b/test/std/utilities/memory/util.dynamic.safety/get_pointer_safety.pass.cpp index 1f27b45e8ab8..df77be9643db 100644 --- a/test/std/utilities/memory/util.dynamic.safety/get_pointer_safety.pass.cpp +++ b/test/std/utilities/memory/util.dynamic.safety/get_pointer_safety.pass.cpp @@ -11,13 +11,27 @@ // pointer_safety get_pointer_safety(); +// UNSUPPORTED: c++98, c++03 + #include <memory> #include <cassert> + +void test_pr26961() { + std::pointer_safety d; + d = std::get_pointer_safety(); + assert(d == std::get_pointer_safety()); +} + int main() { + { std::pointer_safety r = std::get_pointer_safety(); assert(r == std::pointer_safety::relaxed || r == std::pointer_safety::preferred || r == std::pointer_safety::strict); + } + { + test_pr26961(); + } } diff --git a/test/std/utilities/time/time.duration/time.duration.arithmetic/op_++.pass.cpp b/test/std/utilities/time/time.duration/time.duration.arithmetic/op_++.pass.cpp index 8a8f4b1c0d9b..702c38d2d4a9 100644 --- a/test/std/utilities/time/time.duration/time.duration.arithmetic/op_++.pass.cpp +++ b/test/std/utilities/time/time.duration/time.duration.arithmetic/op_++.pass.cpp @@ -11,15 +11,31 @@ // duration -// duration& operator++(); +// constexpr duration& operator++(); // constexpr in c++17 #include <chrono> #include <cassert> +#include "test_macros.h" + +#if TEST_STD_VER > 14 +constexpr bool test_constexpr() +{ + std::chrono::hours h(3); + return (++h).count() == 4; +} +#endif + int main() { + { std::chrono::hours h(3); std::chrono::hours& href = ++h; assert(&href == &h); assert(h.count() == 4); + } + +#if TEST_STD_VER > 14 + static_assert(test_constexpr(), ""); +#endif } diff --git a/test/std/utilities/time/time.duration/time.duration.arithmetic/op_++int.pass.cpp b/test/std/utilities/time/time.duration/time.duration.arithmetic/op_++int.pass.cpp index cf5028281007..49b8c76ee8ee 100644 --- a/test/std/utilities/time/time.duration/time.duration.arithmetic/op_++int.pass.cpp +++ b/test/std/utilities/time/time.duration/time.duration.arithmetic/op_++int.pass.cpp @@ -11,15 +11,32 @@ // duration -// duration operator++(int); +// constexpr duration operator++(int); // constexpr in c++17 #include <chrono> #include <cassert> +#include "test_macros.h" + +#if TEST_STD_VER > 14 +constexpr bool test_constexpr() +{ + std::chrono::hours h1(3); + std::chrono::hours h2 = h1++; + return h1.count() == 4 && h2.count() == 3; +} +#endif + int main() { - std::chrono::hours h(3); - std::chrono::hours h2 = h++; - assert(h.count() == 4); + { + std::chrono::hours h1(3); + std::chrono::hours h2 = h1++; + assert(h1.count() == 4); assert(h2.count() == 3); + } + +#if TEST_STD_VER > 14 + static_assert(test_constexpr(), ""); +#endif } diff --git a/test/std/utilities/time/time.duration/time.duration.arithmetic/op_+=.pass.cpp b/test/std/utilities/time/time.duration/time.duration.arithmetic/op_+=.pass.cpp index 8d8cf4539c16..bec8effbe220 100644 --- a/test/std/utilities/time/time.duration/time.duration.arithmetic/op_+=.pass.cpp +++ b/test/std/utilities/time/time.duration/time.duration.arithmetic/op_+=.pass.cpp @@ -11,16 +11,35 @@ // duration -// duration& operator+=(const duration& d); +// constexpr duration& operator+=(const duration& d); // constexpr in c++17 #include <chrono> #include <cassert> +#include "test_macros.h" + +#if TEST_STD_VER > 14 +constexpr bool test_constexpr() +{ + std::chrono::seconds s(3); + s += std::chrono::seconds(2); + if (s.count() != 5) return false; + s += std::chrono::minutes(2); + return s.count() == 125; +} +#endif + int main() { + { std::chrono::seconds s(3); s += std::chrono::seconds(2); assert(s.count() == 5); s += std::chrono::minutes(2); assert(s.count() == 125); + } + +#if TEST_STD_VER > 14 + static_assert(test_constexpr(), ""); +#endif } diff --git a/test/std/utilities/time/time.duration/time.duration.arithmetic/op_--.pass.cpp b/test/std/utilities/time/time.duration/time.duration.arithmetic/op_--.pass.cpp index 0aadfbcd5991..98b22a7b18bd 100644 --- a/test/std/utilities/time/time.duration/time.duration.arithmetic/op_--.pass.cpp +++ b/test/std/utilities/time/time.duration/time.duration.arithmetic/op_--.pass.cpp @@ -11,15 +11,31 @@ // duration -// duration& operator--(); +// constexpr duration& operator--(); // constexpr in C++17 #include <chrono> #include <cassert> +#include "test_macros.h" + +#if TEST_STD_VER > 14 +constexpr bool test_constexpr() +{ + std::chrono::hours h(3); + return (--h).count() == 2; +} +#endif + int main() { + { std::chrono::hours h(3); std::chrono::hours& href = --h; assert(&href == &h); assert(h.count() == 2); + } + +#if TEST_STD_VER > 14 + static_assert(test_constexpr(), ""); +#endif } diff --git a/test/std/utilities/time/time.duration/time.duration.arithmetic/op_--int.pass.cpp b/test/std/utilities/time/time.duration/time.duration.arithmetic/op_--int.pass.cpp index 7fc6a1df603f..a908c44dda85 100644 --- a/test/std/utilities/time/time.duration/time.duration.arithmetic/op_--int.pass.cpp +++ b/test/std/utilities/time/time.duration/time.duration.arithmetic/op_--int.pass.cpp @@ -11,15 +11,33 @@ // duration -// duration operator--(int); +// constexpr duration operator--(int); // constexpr in C++17 #include <chrono> #include <cassert> +#include "test_macros.h" + +#if TEST_STD_VER > 14 +constexpr bool test_constexpr() +{ + std::chrono::hours h1(3); + std::chrono::hours h2 = h1--; + return h1.count() == 2 && h2.count() == 3; +} +#endif + + int main() { - std::chrono::hours h(3); - std::chrono::hours h2 = h--; - assert(h.count() == 2); + { + std::chrono::hours h1(3); + std::chrono::hours h2 = h1--; + assert(h1.count() == 2); assert(h2.count() == 3); + } + +#if TEST_STD_VER > 14 + static_assert(test_constexpr(), ""); +#endif } diff --git a/test/std/utilities/time/time.duration/time.duration.arithmetic/op_-=.pass.cpp b/test/std/utilities/time/time.duration/time.duration.arithmetic/op_-=.pass.cpp index a0a7aed202b1..185db177882e 100644 --- a/test/std/utilities/time/time.duration/time.duration.arithmetic/op_-=.pass.cpp +++ b/test/std/utilities/time/time.duration/time.duration.arithmetic/op_-=.pass.cpp @@ -16,11 +16,30 @@ #include <chrono> #include <cassert> +#include "test_macros.h" + +#if TEST_STD_VER > 14 +constexpr bool test_constexpr() +{ + std::chrono::seconds s(3); + s -= std::chrono::seconds(2); + if (s.count() != 1) return false; + s -= std::chrono::minutes(2); + return s.count() == -119; +} +#endif + int main() { + { std::chrono::seconds s(3); s -= std::chrono::seconds(2); assert(s.count() == 1); s -= std::chrono::minutes(2); assert(s.count() == -119); + } + +#if TEST_STD_VER > 14 + static_assert(test_constexpr(), ""); +#endif } diff --git a/test/std/utilities/time/time.duration/time.duration.arithmetic/op_divide=.pass.cpp b/test/std/utilities/time/time.duration/time.duration.arithmetic/op_divide=.pass.cpp index 09786bcd8cf8..4ae774b6c1f1 100644 --- a/test/std/utilities/time/time.duration/time.duration.arithmetic/op_divide=.pass.cpp +++ b/test/std/utilities/time/time.duration/time.duration.arithmetic/op_divide=.pass.cpp @@ -16,9 +16,26 @@ #include <chrono> #include <cassert> +#include "test_macros.h" + +#if TEST_STD_VER > 14 +constexpr bool test_constexpr() +{ + std::chrono::seconds s(15); + s /= 5; + return s.count() == 3; +} +#endif + int main() { + { std::chrono::nanoseconds ns(15); ns /= 5; assert(ns.count() == 3); + } + +#if TEST_STD_VER > 14 + static_assert(test_constexpr(), ""); +#endif } diff --git a/test/std/utilities/time/time.duration/time.duration.arithmetic/op_mod=duration.pass.cpp b/test/std/utilities/time/time.duration/time.duration.arithmetic/op_mod=duration.pass.cpp index 8a4a2b472324..624468671244 100644 --- a/test/std/utilities/time/time.duration/time.duration.arithmetic/op_mod=duration.pass.cpp +++ b/test/std/utilities/time/time.duration/time.duration.arithmetic/op_mod=duration.pass.cpp @@ -16,12 +16,30 @@ #include <chrono> #include <cassert> +#include "test_macros.h" + +#if TEST_STD_VER > 14 +constexpr bool test_constexpr() +{ + std::chrono::microseconds us1(11); + std::chrono::microseconds us2(3); + us1 %= us2; + return us1.count() == 2; +} +#endif + int main() { - std::chrono::microseconds us(11); + { + std::chrono::microseconds us1(11); std::chrono::microseconds us2(3); - us %= us2; - assert(us.count() == 2); - us %= std::chrono::milliseconds(3); - assert(us.count() == 2); + us1 %= us2; + assert(us1.count() == 2); + us1 %= std::chrono::milliseconds(3); + assert(us1.count() == 2); + } + +#if TEST_STD_VER > 14 + static_assert(test_constexpr(), ""); +#endif } diff --git a/test/std/utilities/time/time.duration/time.duration.arithmetic/op_mod=rep.pass.cpp b/test/std/utilities/time/time.duration/time.duration.arithmetic/op_mod=rep.pass.cpp index 8758e17ba6af..a4852d261f7e 100644 --- a/test/std/utilities/time/time.duration/time.duration.arithmetic/op_mod=rep.pass.cpp +++ b/test/std/utilities/time/time.duration/time.duration.arithmetic/op_mod=rep.pass.cpp @@ -16,9 +16,26 @@ #include <chrono> #include <cassert> +#include "test_macros.h" + +#if TEST_STD_VER > 14 +constexpr bool test_constexpr() +{ + std::chrono::seconds s(11); + s %= 3; + return s.count() == 2; +} +#endif + int main() { + { std::chrono::microseconds us(11); us %= 3; assert(us.count() == 2); + } + +#if TEST_STD_VER > 14 + static_assert(test_constexpr(), ""); +#endif } diff --git a/test/std/utilities/time/time.duration/time.duration.arithmetic/op_times=.pass.cpp b/test/std/utilities/time/time.duration/time.duration.arithmetic/op_times=.pass.cpp index b97534a3615a..0f76788c00ef 100644 --- a/test/std/utilities/time/time.duration/time.duration.arithmetic/op_times=.pass.cpp +++ b/test/std/utilities/time/time.duration/time.duration.arithmetic/op_times=.pass.cpp @@ -16,9 +16,26 @@ #include <chrono> #include <cassert> +#include "test_macros.h" + +#if TEST_STD_VER > 14 +constexpr bool test_constexpr() +{ + std::chrono::seconds s(3); + s *= 5; + return s.count() == 15; +} +#endif + int main() { + { std::chrono::nanoseconds ns(3); ns *= 5; assert(ns.count() == 15); + } + +#if TEST_STD_VER > 14 + static_assert(test_constexpr(), ""); +#endif } diff --git a/test/std/utilities/tuple/tuple.tuple/tuple.helper/tuple_size.pass.cpp b/test/std/utilities/tuple/tuple.tuple/tuple.helper/tuple_size.pass.cpp index 3e4145c79cb5..49b4215a1956 100644 --- a/test/std/utilities/tuple/tuple.tuple/tuple.helper/tuple_size.pass.cpp +++ b/test/std/utilities/tuple/tuple.tuple/tuple.helper/tuple_size.pass.cpp @@ -20,13 +20,6 @@ #include <tuple> #include <type_traits> -template <class T, class = decltype(std::tuple_size<T>::value)> -constexpr bool has_value(int) { return true; } -template <class> constexpr bool has_value(long) { return false; } -template <class T> constexpr bool has_value() { return has_value<T>(0); } - -struct Dummy {}; - template <class T, std::size_t N> void test() { @@ -40,21 +33,10 @@ void test() std::tuple_size<const volatile T> >::value), ""); } -void test_tuple_size_value_sfinae() { - // Test that the ::value member does not exist - static_assert(has_value<std::tuple<int> const>(), ""); - static_assert(has_value<std::pair<int, long> volatile>(), ""); - static_assert(!has_value<int>(), ""); - static_assert(!has_value<const int>(), ""); - static_assert(!has_value<volatile void>(), ""); - static_assert(!has_value<const volatile std::tuple<int>&>(), ""); -} - int main() { test<std::tuple<>, 0>(); test<std::tuple<int>, 1>(); test<std::tuple<char, int>, 2>(); test<std::tuple<char, char*, int>, 3>(); - test_tuple_size_value_sfinae(); } diff --git a/test/std/utilities/tuple/tuple.tuple/tuple.helper/tuple_size_incomplete.fail.cpp b/test/std/utilities/tuple/tuple.tuple/tuple.helper/tuple_size_incomplete.fail.cpp new file mode 100644 index 000000000000..818001833995 --- /dev/null +++ b/test/std/utilities/tuple/tuple.tuple/tuple.helper/tuple_size_incomplete.fail.cpp @@ -0,0 +1,63 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// <tuple> + +// template <class... Types> class tuple; + +// template <class... Types> +// class tuple_size<tuple<Types...>> +// : public integral_constant<size_t, sizeof...(Types)> { }; + +// UNSUPPORTED: c++98, c++03 + +#include <tuple> +#include <array> +#include <type_traits> + +struct Dummy1 {}; +struct Dummy2 {}; +struct Dummy3 {}; + +template <> +class std::tuple_size<Dummy1> { +public: + static size_t value; +}; + +template <> +class std::tuple_size<Dummy2> { +public: + static void value() {} +}; + +template <> +class std::tuple_size<Dummy3> {}; + +int main() +{ + // Test that tuple_size<const T> is not incomplete when tuple_size<T>::value + // is well-formed but not a constant expression. + { + // expected-error@__tuple:* 1 {{is not a constant expression}} + (void)std::tuple_size<const Dummy1>::value; // expected-note {{here}} + } + // Test that tuple_size<const T> is not incomplete when tuple_size<T>::value + // is well-formed but not convertible to size_t. + { + // expected-error@__tuple:* 1 {{value of type 'void ()' is not implicitly convertible to}} + (void)std::tuple_size<const Dummy2>::value; // expected-note {{here}} + } + // Test that tuple_size<const T> generates an error when tuple_size<T> is + // complete but ::value isn't a constant expression convertible to size_t. + { + // expected-error@__tuple:* 1 {{no member named 'value'}} + (void)std::tuple_size<const Dummy3>::value; // expected-note {{here}} + } +} diff --git a/test/std/utilities/tuple/tuple.tuple/tuple.helper/tuple_size_incomplete.pass.cpp b/test/std/utilities/tuple/tuple.tuple/tuple.helper/tuple_size_incomplete.pass.cpp new file mode 100644 index 000000000000..ccdd48e4c11d --- /dev/null +++ b/test/std/utilities/tuple/tuple.tuple/tuple.helper/tuple_size_incomplete.pass.cpp @@ -0,0 +1,67 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// <tuple> + +// template <class... Types> class tuple; + +// template <class... Types> +// class tuple_size<tuple<Types...>> +// : public integral_constant<size_t, sizeof...(Types)> { }; + +// XFAIL: gcc-4.9 +// UNSUPPORTED: c++98, c++03 + +#include <tuple> +#include <array> +#include <type_traits> + +template <class T, size_t Size = sizeof(std::tuple_size<T>)> +constexpr bool is_complete(int) { static_assert(Size > 0, ""); return true; } +template <class> constexpr bool is_complete(long) { return false; } +template <class T> constexpr bool is_complete() { return is_complete<T>(0); } + +struct Dummy1 {}; +struct Dummy2 {}; + +namespace std { +template <> class tuple_size<Dummy1> : public integral_constant<size_t, 0> {}; +} + +template <class T> +void test_complete() { + static_assert(is_complete<T>(), ""); + static_assert(is_complete<const T>(), ""); + static_assert(is_complete<volatile T>(), ""); + static_assert(is_complete<const volatile T>(), ""); +} + +template <class T> +void test_incomplete() { + static_assert(!is_complete<T>(), ""); + static_assert(!is_complete<const T>(), ""); + static_assert(!is_complete<volatile T>(), ""); + static_assert(!is_complete<const volatile T>(), ""); +} + + +int main() +{ + test_complete<std::tuple<> >(); + test_complete<std::tuple<int&> >(); + test_complete<std::tuple<int&&, int&, void*>>(); + test_complete<std::pair<int, long> >(); + test_complete<std::array<int, 5> >(); + test_complete<Dummy1>(); + + test_incomplete<void>(); + test_incomplete<int>(); + test_incomplete<std::tuple<int>&>(); + test_incomplete<Dummy2>(); +} diff --git a/test/std/utilities/tuple/tuple.tuple/tuple.helper/tuple_size_structured_bindings.pass.cpp b/test/std/utilities/tuple/tuple.tuple/tuple.helper/tuple_size_structured_bindings.pass.cpp new file mode 100644 index 000000000000..aadbf3d5a369 --- /dev/null +++ b/test/std/utilities/tuple/tuple.tuple/tuple.helper/tuple_size_structured_bindings.pass.cpp @@ -0,0 +1,138 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// <tuple> + +// template <class... Types> class tuple; + +// template <class... Types> +// class tuple_size<tuple<Types...>> +// : public integral_constant<size_t, sizeof...(Types)> { }; + +// UNSUPPORTED: c++98, c++03, c++11, c++14 +// UNSUPPORTED: libcpp-no-structured-bindings + +#include <tuple> +#include <array> +#include <type_traits> +#include <cassert> + +struct S { int x; }; + +void test_decomp_user_type() { + { + S s{99}; + auto [m1] = s; + auto& [r1] = s; + assert(m1 == 99); + assert(&r1 == &s.x); + } + { + S const s{99}; + auto [m1] = s; + auto& [r1] = s; + assert(m1 == 99); + assert(&r1 == &s.x); + } +} + +void test_decomp_tuple() { + typedef std::tuple<int> T; + { + T s{99}; + auto [m1] = s; + auto& [r1] = s; + assert(m1 == 99); + assert(&r1 == &std::get<0>(s)); + } + { + T const s{99}; + auto [m1] = s; + auto& [r1] = s; + assert(m1 == 99); + assert(&r1 == &std::get<0>(s)); + } +} + + +void test_decomp_pair() { + typedef std::pair<int, double> T; + { + T s{99, 42.1}; + auto [m1, m2] = s; + auto& [r1, r2] = s; + assert(m1 == 99); + assert(&r1 == &std::get<0>(s)); + } + { + T const s{99, 42.1}; + auto [m1, m2] = s; + auto& [r1, r2] = s; + assert(m1 == 99); + assert(&r1 == &std::get<0>(s)); + } +} + +void test_decomp_array() { + typedef std::array<int, 3> T; + { + T s{{99, 42, -1}}; + auto [m1, m2, m3] = s; + auto& [r1, r2, r3] = s; + assert(m1 == 99); + assert(&r1 == &std::get<0>(s)); + } + { + T const s{{99, 42, -1}}; + auto [m1, m2, m3] = s; + auto& [r1, r2, r3] = s; + assert(m1 == 99); + assert(&r1 == &std::get<0>(s)); + } +} + +struct Test { + int x; +}; + +template <size_t N> +int get(Test const&) { static_assert(N == 0, ""); return -1; } + +template <> +class std::tuple_element<0, Test> { +public: + typedef int type; +}; + +void test_before_tuple_size_specialization() { + Test const t{99}; + auto& [p] = t; + assert(p == 99); +} + +template <> +class std::tuple_size<Test> { +public: + static const size_t value = 1; +}; + +void test_after_tuple_size_specialization() { + Test const t{99}; + auto& [p] = t; + assert(p == -1); +} + +int main() { + test_decomp_user_type(); + test_decomp_tuple(); + test_decomp_pair(); + test_decomp_array(); + test_before_tuple_size_specialization(); + test_after_tuple_size_specialization(); +} diff --git a/test/std/utilities/tuple/tuple.tuple/tuple.helper/tuple_size_value_sfinae.pass.cpp b/test/std/utilities/tuple/tuple.tuple/tuple.helper/tuple_size_value_sfinae.pass.cpp new file mode 100644 index 000000000000..31ebe5878379 --- /dev/null +++ b/test/std/utilities/tuple/tuple.tuple/tuple.helper/tuple_size_value_sfinae.pass.cpp @@ -0,0 +1,39 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// <tuple> + +// template <class... Types> class tuple; + +// template <class... Types> +// class tuple_size<tuple<Types...>> +// : public integral_constant<size_t, sizeof...(Types)> { }; + +// XFAIL: gcc-4.9 +// UNSUPPORTED: c++98, c++03 + +#include <tuple> +#include <type_traits> + +template <class T, class = decltype(std::tuple_size<T>::value)> +constexpr bool has_value(int) { return true; } +template <class> constexpr bool has_value(long) { return false; } +template <class T> constexpr bool has_value() { return has_value<T>(0); } + +struct Dummy {}; + +int main() { + // Test that the ::value member does not exist + static_assert(has_value<std::tuple<int> const>(), ""); + static_assert(has_value<std::pair<int, long> volatile>(), ""); + static_assert(!has_value<int>(), ""); + static_assert(!has_value<const int>(), ""); + static_assert(!has_value<volatile void>(), ""); + static_assert(!has_value<const volatile std::tuple<int>&>(), ""); +} diff --git a/test/std/utilities/variant/variant.variant/variant.status/index.pass.cpp b/test/std/utilities/variant/variant.variant/variant.status/index.pass.cpp index 4b30188ce6ff..6675b5f2b2ba 100644 --- a/test/std/utilities/variant/variant.variant/variant.status/index.pass.cpp +++ b/test/std/utilities/variant/variant.variant/variant.status/index.pass.cpp @@ -10,8 +10,10 @@ // UNSUPPORTED: c++98, c++03, c++11, c++14 -// Clang 3.8 doesn't allow constexpr variables of non-literal type -// XFAIL: clang-3.8, apple-clang-7, apple-clang-8 +// The following compilers don't allow constexpr variables of non-literal type. +// XFAIL: gcc-5, gcc-6 +// XFAIL: clang-3.5, clang-3.6, clang-3.7, clang-3.8 +// XFAIL: apple-clang-6, apple-clang-7, apple-clang-8 // <variant> diff --git a/test/std/utilities/variant/variant.variant/variant.status/valueless_by_exception.pass.cpp b/test/std/utilities/variant/variant.variant/variant.status/valueless_by_exception.pass.cpp index 8546beb1319c..a0c57e132403 100644 --- a/test/std/utilities/variant/variant.variant/variant.status/valueless_by_exception.pass.cpp +++ b/test/std/utilities/variant/variant.variant/variant.status/valueless_by_exception.pass.cpp @@ -10,8 +10,10 @@ // UNSUPPORTED: c++98, c++03, c++11, c++14 -// Clang 3.8 doesn't allow constexpr variables of non-literal type -// XFAIL: clang-3.8, apple-clang-7, apple-clang-8 +// The following compilers don't allow constexpr variables of non-literal type. +// XFAIL: gcc-5, gcc-6 +// XFAIL: clang-3.5, clang-3.6, clang-3.7, clang-3.8 +// XFAIL: apple-clang-6, apple-clang-7, apple-clang-8 // <variant> diff --git a/test/std/utilities/variant/variant.variant/variant.swap/swap.pass.cpp b/test/std/utilities/variant/variant.variant/variant.swap/swap.pass.cpp index 416c6b4e334d..48cda222083f 100644 --- a/test/std/utilities/variant/variant.variant/variant.swap/swap.pass.cpp +++ b/test/std/utilities/variant/variant.variant/variant.swap/swap.pass.cpp @@ -489,7 +489,7 @@ void test_swap_sfinae() { // but is still swappable via the generic swap algorithm, since the // variant is move constructible and move assignable. using V = std::variant<int, NotSwappable>; - LIBCPP_STATIC_ASSERT(!has_swap_member<V>()); + LIBCPP_STATIC_ASSERT(!has_swap_member<V>(), ""); static_assert(std::is_swappable_v<V>, ""); } { @@ -569,7 +569,7 @@ void test_swap_noexcept() { // but is still swappable via the generic swap algorithm, since the // variant is move constructible and move assignable. using V = std::variant<int, NotSwappable>; - LIBCPP_STATIC_ASSERT(!has_swap_member<V>()); + LIBCPP_STATIC_ASSERT(!has_swap_member<V>(), ""); static_assert(std::is_swappable_v<V>, ""); static_assert(std::is_nothrow_swappable_v<V>, ""); V v1, v2; |