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 // <system_error>
10 
11 // class error_category
12 
13 // const error_category& system_category();
14 
15 #include <system_error>
16 #include <cassert>
17 #include <string>
18 #include <cerrno>
19 
20 #include "test_macros.h"
21 
22 // See https://llvm.org/D65667
23 struct StaticInit {
24   const std::error_category* ec;
25   ~StaticInit() {
26     std::string str = ec->name();
27     assert(str == "system");
28   }
29 };
30 static StaticInit foo;
31 
32 int main(int, char**) {
33   {
34     const std::error_category& e_cat1 = std::system_category();
35     std::error_condition e_cond       = e_cat1.default_error_condition(5);
36 #ifdef _WIN32
37     // Windows' system error 5 is ERROR_ACCESS_DENIED, which maps to generic code permission_denied.
38     LIBCPP_ASSERT(e_cond.value() == static_cast<int>(std::errc::permission_denied));
39 #else
40     LIBCPP_ASSERT(e_cond.value() == 5);
41 #endif
42     LIBCPP_ASSERT(e_cond.category() == std::generic_category());
43     assert(e_cat1.equivalent(5, e_cond));
44 
45     e_cond = e_cat1.default_error_condition(5000);
46     LIBCPP_ASSERT(e_cond.value() == 5000);
47     LIBCPP_ASSERT(e_cond.category() == std::system_category());
48     assert(e_cat1.equivalent(5000, e_cond));
49   }
50 
51   // Test the result of message(int cond) when given a bad error condition
52   {
53     errno                             = E2BIG; // something that message will never generate
54     const std::error_category& e_cat1 = std::system_category();
55     const std::string msg             = e_cat1.message(-1);
56     // Exact message format varies by platform.  We can't detect
57     // some of these (Musl in particular) using the preprocessor,
58     // so accept a few sensible messages.  Newlib unfortunately
59     // responds with an empty message, which we probably want to
60     // treat as a failure code otherwise, but we can detect that
61     // with the preprocessor.
62 #if defined(_NEWLIB_VERSION)
63     const bool is_newlib = true;
64 #else
65     const bool is_newlib = false;
66 #endif
67     (void)is_newlib;
68     LIBCPP_ASSERT(msg.rfind("Error -1 occurred", 0) == 0       // AIX
69                   || msg.rfind("No error information", 0) == 0 // Musl
70                   || msg.rfind("Unknown error", 0) == 0        // Glibc
71                   || (is_newlib && msg.empty()));
72     assert(errno == E2BIG);
73   }
74 
75   {
76     foo.ec        = &std::system_category();
77     std::string m = foo.ec->name();
78     assert(m == "system");
79   }
80 
81   return 0;
82 }
83