Coverage Report

Created: 2020-02-25 14:32

/Users/buildslave/jenkins/workspace/coverage/llvm-project/libcxx/src/system_error.cpp
Line
Count
Source (jump to first uncovered line)
1
//===---------------------- system_error.cpp ------------------------------===//
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
#include "__config"
10
11
#include "system_error"
12
13
#include "include/config_elast.h"
14
#include "cerrno"
15
#include "cstring"
16
#include "cstdio"
17
#include "cstdlib"
18
#include "string"
19
#include "string.h"
20
#include "__debug"
21
22
#if defined(__ANDROID__)
23
#include <android/api-level.h>
24
#endif
25
26
_LIBCPP_BEGIN_NAMESPACE_STD
27
28
// class error_category
29
30
#if defined(_LIBCPP_DEPRECATED_ABI_LEGACY_LIBRARY_DEFINITIONS_FOR_INLINE_FUNCTIONS)
31
error_category::error_category() _NOEXCEPT
32
36.9k
{
33
36.9k
}
34
#endif
35
36
error_category::~error_category() _NOEXCEPT
37
9.83k
{
38
9.83k
}
39
40
error_condition
41
error_category::default_error_condition(int ev) const _NOEXCEPT
42
4
{
43
4
    return error_condition(ev, *this);
44
4
}
45
46
bool
47
error_category::equivalent(int code, const error_condition& condition) const _NOEXCEPT
48
4
{
49
4
    return default_error_condition(code) == condition;
50
4
}
51
52
bool
53
error_category::equivalent(const error_code& code, int condition) const _NOEXCEPT
54
0
{
55
0
    return *this == code.category() && code.value() == condition;
56
0
}
57
58
#if !defined(_LIBCPP_HAS_NO_THREADS)
59
namespace {
60
61
//  GLIBC also uses 1024 as the maximum buffer size internally.
62
constexpr size_t strerror_buff_size = 1024;
63
64
string do_strerror_r(int ev);
65
66
#if defined(_LIBCPP_MSVCRT_LIKE)
67
string do_strerror_r(int ev) {
68
  char buffer[strerror_buff_size];
69
  if (::strerror_s(buffer, strerror_buff_size, ev) == 0)
70
    return string(buffer);
71
  std::snprintf(buffer, strerror_buff_size, "unknown error %d", ev);
72
  return string(buffer);
73
}
74
#else
75
76
// Only one of the two following functions will be used, depending on
77
// the return type of strerror_r:
78
79
// For the GNU variant, a char* return value:
80
__attribute__((unused)) const char *
81
0
handle_strerror_r_return(char *strerror_return, char *buffer) {
82
0
  // GNU always returns a string pointer in its return value. The
83
0
  // string might point to either the input buffer, or a static
84
0
  // buffer, but we don't care which.
85
0
  return strerror_return;
86
0
}
87
88
// For the POSIX variant: an int return value.
89
__attribute__((unused)) const char *
90
40
handle_strerror_r_return(int strerror_return, char *buffer) {
91
40
  // The POSIX variant either:
92
40
  // - fills in the provided buffer and returns 0
93
40
  // - returns a positive error value, or
94
40
  // - returns -1 and fills in errno with an error value.
95
40
  if (strerror_return == 0)
96
40
    return buffer;
97
0
98
0
  // Only handle EINVAL. Other errors abort.
99
0
  int new_errno = strerror_return == -1 ? errno : strerror_return;
100
0
  if (new_errno == EINVAL)
101
0
    return "";
102
0
103
0
  _LIBCPP_ASSERT(new_errno == ERANGE, "unexpected error from ::strerror_r");
104
0
  // FIXME maybe? 'strerror_buff_size' is likely to exceed the
105
0
  // maximum error size so ERANGE shouldn't be returned.
106
0
  std::abort();
107
0
}
108
109
// This function handles both GNU and POSIX variants, dispatching to
110
// one of the two above functions.
111
40
string do_strerror_r(int ev) {
112
40
    char buffer[strerror_buff_size];
113
40
    // Preserve errno around the call. (The C++ standard requires that
114
40
    // system_error functions not modify errno).
115
40
    const int old_errno = errno;
116
40
    const char *error_message = handle_strerror_r_return(
117
40
        ::strerror_r(ev, buffer, strerror_buff_size), buffer);
118
40
    // If we didn't get any message, print one now.
119
40
    if (!error_message[0]) {
120
0
      std::snprintf(buffer, strerror_buff_size, "Unknown error %d", ev);
121
0
      error_message = buffer;
122
0
    }
123
40
    errno = old_errno;
124
40
    return string(error_message);
125
40
}
126
#endif
127
} // end namespace
128
#endif
129
130
string
131
__do_message::message(int ev) const
132
40
{
133
#if defined(_LIBCPP_HAS_NO_THREADS)
134
    return string(::strerror(ev));
135
#else
136
    return do_strerror_r(ev);
137
40
#endif
138
40
}
139
140
class _LIBCPP_HIDDEN __generic_error_category
141
    : public __do_message
142
{
143
public:
144
    virtual const char* name() const _NOEXCEPT;
145
    virtual string message(int ev) const;
146
};
147
148
const char*
149
__generic_error_category::name() const _NOEXCEPT
150
0
{
151
0
    return "generic";
152
0
}
153
154
string
155
__generic_error_category::message(int ev) const
156
40
{
157
40
#ifdef _LIBCPP_ELAST
158
40
    if (ev > _LIBCPP_ELAST)
159
40
      
return string("unspecified generic_category error")0
;
160
40
#endif  // _LIBCPP_ELAST
161
40
    return __do_message::message(ev);
162
40
}
163
164
const error_category&
165
generic_category() _NOEXCEPT
166
1.14M
{
167
1.14M
    static __generic_error_category s;
168
1.14M
    return s;
169
1.14M
}
170
171
class _LIBCPP_HIDDEN __system_error_category
172
    : public __do_message
173
{
174
public:
175
    virtual const char* name() const _NOEXCEPT;
176
    virtual string message(int ev) const;
177
    virtual error_condition default_error_condition(int ev) const _NOEXCEPT;
178
};
179
180
const char*
181
__system_error_category::name() const _NOEXCEPT
182
0
{
183
0
    return "system";
184
0
}
185
186
string
187
__system_error_category::message(int ev) const
188
0
{
189
0
#ifdef _LIBCPP_ELAST
190
0
    if (ev > _LIBCPP_ELAST)
191
0
      return string("unspecified system_category error");
192
0
#endif  // _LIBCPP_ELAST
193
0
    return __do_message::message(ev);
194
0
}
195
196
error_condition
197
__system_error_category::default_error_condition(int ev) const _NOEXCEPT
198
0
{
199
0
#ifdef _LIBCPP_ELAST
200
0
    if (ev > _LIBCPP_ELAST)
201
0
      return error_condition(ev, system_category());
202
0
#endif  // _LIBCPP_ELAST
203
0
    return error_condition(ev, generic_category());
204
0
}
205
206
const error_category&
207
system_category() _NOEXCEPT
208
929k
{
209
929k
    static __system_error_category s;
210
929k
    return s;
211
929k
}
212
213
// error_condition
214
215
string
216
error_condition::message() const
217
0
{
218
0
    return __cat_->message(__val_);
219
0
}
220
221
// error_code
222
223
string
224
error_code::message() const
225
40
{
226
40
    return __cat_->message(__val_);
227
40
}
228
229
// system_error
230
231
string
232
system_error::__init(const error_code& ec, string what_arg)
233
0
{
234
0
    if (ec)
235
0
    {
236
0
        if (!what_arg.empty())
237
0
            what_arg += ": ";
238
0
        what_arg += ec.message();
239
0
    }
240
0
    return what_arg;
241
0
}
242
243
system_error::system_error(error_code ec, const string& what_arg)
244
    : runtime_error(__init(ec, what_arg)),
245
      __ec_(ec)
246
0
{
247
0
}
248
249
system_error::system_error(error_code ec, const char* what_arg)
250
    : runtime_error(__init(ec, what_arg)),
251
      __ec_(ec)
252
0
{
253
0
}
254
255
system_error::system_error(error_code ec)
256
    : runtime_error(__init(ec, "")),
257
      __ec_(ec)
258
0
{
259
0
}
260
261
system_error::system_error(int ev, const error_category& ecat, const string& what_arg)
262
    : runtime_error(__init(error_code(ev, ecat), what_arg)),
263
      __ec_(error_code(ev, ecat))
264
0
{
265
0
}
266
267
system_error::system_error(int ev, const error_category& ecat, const char* what_arg)
268
    : runtime_error(__init(error_code(ev, ecat), what_arg)),
269
      __ec_(error_code(ev, ecat))
270
0
{
271
0
}
272
273
system_error::system_error(int ev, const error_category& ecat)
274
    : runtime_error(__init(error_code(ev, ecat), "")),
275
      __ec_(error_code(ev, ecat))
276
0
{
277
0
}
278
279
system_error::~system_error() _NOEXCEPT
280
0
{
281
0
}
282
283
void
284
__throw_system_error(int ev, const char* what_arg)
285
0
{
286
0
#ifndef _LIBCPP_NO_EXCEPTIONS
287
0
    throw system_error(error_code(ev, system_category()), what_arg);
288
#else
289
    (void)ev;
290
    (void)what_arg;
291
    _VSTD::abort();
292
#endif
293
}
294
295
_LIBCPP_END_NAMESPACE_STD