1 //===----------------------------------------------------------------------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 // See https://llvm.org/PR20183 10 // XFAIL: use_system_cxx_lib && target={{.+}}-apple-macosx10.{{9|10|11}} 11 12 // The behavior of std::random_device changed on Apple platforms with 13 // https://llvm.org/D116045. 14 // XFAIL: use_system_cxx_lib && target={{.+}}-apple-macosx10.{{9|10|11|12|13|14|15}} 15 // XFAIL: use_system_cxx_lib && target={{.+}}-apple-macosx{{11.0|12.0}} 16 17 // UNSUPPORTED: no-random-device 18 19 // <random> 20 21 // class random_device; 22 23 // explicit random_device(const string& token = implementation-defined); // before C++20 24 // random_device() : random_device(implementation-defined) {} // C++20 25 // explicit random_device(const string& token); // C++20 26 27 // For the following ctors, the standard states: "The semantics and default 28 // value of the token parameter are implementation-defined". Implementations 29 // therefore aren't required to accept any string, but the default shouldn't 30 // throw. 31 32 #include <random> 33 #include <system_error> 34 #include <cassert> 35 36 #if !defined(_WIN32) 37 #include <unistd.h> 38 #endif 39 40 #include "test_macros.h" 41 #if TEST_STD_VER >= 11 42 #include "test_convertible.h" 43 #endif 44 check_random_device_valid(const std::string & token)45void check_random_device_valid(const std::string &token) { 46 std::random_device r(token); 47 } 48 check_random_device_invalid(const std::string & token)49void check_random_device_invalid(const std::string &token) { 50 #ifndef TEST_HAS_NO_EXCEPTIONS 51 try { 52 std::random_device r(token); 53 LIBCPP_ASSERT(false); 54 } catch (const std::system_error&) { 55 } 56 #else 57 ((void)token); 58 #endif 59 } 60 main(int,char **)61int main(int, char**) { 62 { 63 std::random_device r; 64 } 65 // Check the validity of various tokens 66 { 67 #if defined(_LIBCPP_USING_ARC4_RANDOM) 68 check_random_device_valid("/dev/urandom"); 69 check_random_device_valid("/dev/random"); 70 check_random_device_valid("/dev/null"); 71 check_random_device_valid("/dev/nonexistent"); 72 check_random_device_valid("wrong file"); 73 #elif defined(_LIBCPP_USING_DEV_RANDOM) 74 check_random_device_valid("/dev/urandom"); 75 check_random_device_valid("/dev/random"); 76 check_random_device_valid("/dev/null"); 77 check_random_device_invalid("/dev/nonexistent"); 78 check_random_device_invalid("wrong file"); 79 #else 80 check_random_device_valid("/dev/urandom"); 81 check_random_device_invalid("/dev/random"); 82 check_random_device_invalid("/dev/null"); 83 check_random_device_invalid("/dev/nonexistent"); 84 check_random_device_invalid("wrong file"); 85 #endif 86 } 87 88 #if !defined(_WIN32) 89 // Test that random_device(const string&) properly handles getting 90 // a file descriptor with the value '0'. Do this by closing the standard 91 // streams so that the descriptor '0' is available. 92 { 93 int ec; 94 ec = close(STDIN_FILENO); 95 assert(!ec); 96 ec = close(STDOUT_FILENO); 97 assert(!ec); 98 ec = close(STDERR_FILENO); 99 assert(!ec); 100 std::random_device r; 101 } 102 #endif // !defined(_WIN32) 103 104 #if TEST_STD_VER >= 11 105 static_assert(test_convertible<std::random_device>(), ""); 106 #endif 107 108 return 0; 109 } 110