Bug Summary

File:include/sys/select.h
Warning:line 95, column 10
Array access (via field 'fds_bits') results in a null pointer dereference

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple amd64-unknown-openbsd7.0 -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name SelectHelper.cpp -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=cplusplus -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model static -mframe-pointer=all -relaxed-aliasing -fno-rounding-math -mconstructor-aliases -munwind-tables -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/usr/src/gnu/usr.bin/clang/liblldbUtility/obj -resource-dir /usr/local/lib/clang/13.0.0 -I /usr/src/gnu/usr.bin/clang/liblldbUtility/../../../llvm/llvm/include -I /usr/src/gnu/usr.bin/clang/liblldbUtility/../include -I /usr/src/gnu/usr.bin/clang/liblldbUtility/obj -I /usr/src/gnu/usr.bin/clang/liblldbUtility/obj/../include -D NDEBUG -D __STDC_LIMIT_MACROS -D __STDC_CONSTANT_MACROS -D __STDC_FORMAT_MACROS -D LLVM_PREFIX="/usr" -I /usr/src/gnu/usr.bin/clang/liblldbUtility/../../../llvm/lldb/include -I /usr/src/gnu/usr.bin/clang/liblldbUtility/../../../llvm/lldb/source -I /usr/src/gnu/usr.bin/clang/liblldbUtility/../../../llvm/clang/include -internal-isystem /usr/include/c++/v1 -internal-isystem /usr/local/lib/clang/13.0.0/include -internal-externc-isystem /usr/include -O2 -Wno-unused-parameter -Wwrite-strings -Wno-missing-field-initializers -Wno-long-long -Wno-comment -std=c++14 -fdeprecated-macro -fdebug-compilation-dir=/usr/src/gnu/usr.bin/clang/liblldbUtility/obj -ferror-limit 19 -fvisibility-inlines-hidden -fwrapv -stack-protector 2 -fno-rtti -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -fno-builtin-malloc -fno-builtin-calloc -fno-builtin-realloc -fno-builtin-valloc -fno-builtin-free -fno-builtin-strdup -fno-builtin-strndup -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /home/ben/Projects/vmm/scan-build/2022-01-12-194120-40624-1 -x c++ /usr/src/gnu/usr.bin/clang/liblldbUtility/../../../llvm/lldb/source/Utility/SelectHelper.cpp

/usr/src/gnu/usr.bin/clang/liblldbUtility/../../../llvm/lldb/source/Utility/SelectHelper.cpp

1//===-- SelectHelper.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#if defined(__APPLE__)
10// Enable this special support for Apple builds where we can have unlimited
11// select bounds. We tried switching to poll() and kqueue and we were panicing
12// the kernel, so we have to stick with select for now.
13#define _DARWIN_UNLIMITED_SELECT
14#endif
15
16#include "lldb/Utility/SelectHelper.h"
17#include "lldb/Utility/LLDBAssert.h"
18#include "lldb/Utility/Status.h"
19#include "lldb/lldb-enumerations.h"
20#include "lldb/lldb-types.h"
21
22#include "llvm/ADT/DenseMap.h"
23#include "llvm/ADT/Optional.h"
24
25#include <algorithm>
26#include <chrono>
27
28#include <cerrno>
29#if defined(_WIN32)
30// Define NOMINMAX to avoid macros that conflict with std::min and std::max
31#define NOMINMAX
32#include <winsock2.h>
33#else
34#include <sys/time.h>
35#include <sys/select.h>
36#endif
37
38
39SelectHelper::SelectHelper()
40 : m_fd_map(), m_end_time() // Infinite timeout unless
41 // SelectHelper::SetTimeout() gets called
42{}
43
44void SelectHelper::SetTimeout(const std::chrono::microseconds &timeout) {
45 using namespace std::chrono;
46 m_end_time = steady_clock::time_point(steady_clock::now() + timeout);
47}
48
49void SelectHelper::FDSetRead(lldb::socket_t fd) {
50 m_fd_map[fd].read_set = true;
51}
52
53void SelectHelper::FDSetWrite(lldb::socket_t fd) {
54 m_fd_map[fd].write_set = true;
55}
56
57void SelectHelper::FDSetError(lldb::socket_t fd) {
58 m_fd_map[fd].error_set = true;
59}
60
61bool SelectHelper::FDIsSetRead(lldb::socket_t fd) const {
62 auto pos = m_fd_map.find(fd);
63 if (pos != m_fd_map.end())
64 return pos->second.read_is_set;
65 else
66 return false;
67}
68
69bool SelectHelper::FDIsSetWrite(lldb::socket_t fd) const {
70 auto pos = m_fd_map.find(fd);
71 if (pos != m_fd_map.end())
72 return pos->second.write_is_set;
73 else
74 return false;
75}
76
77bool SelectHelper::FDIsSetError(lldb::socket_t fd) const {
78 auto pos = m_fd_map.find(fd);
79 if (pos != m_fd_map.end())
80 return pos->second.error_is_set;
81 else
82 return false;
83}
84
85static void updateMaxFd(llvm::Optional<lldb::socket_t> &vold,
86 lldb::socket_t vnew) {
87 if (!vold.hasValue())
10
Taking true branch
88 vold = vnew;
89 else
90 vold = std::max(*vold, vnew);
91}
92
93lldb_private::Status SelectHelper::Select() {
94 lldb_private::Status error;
95#ifdef _WIN32
96 // On windows FD_SETSIZE limits the number of file descriptors, not their
97 // numeric value.
98 lldbassert(m_fd_map.size() <= FD_SETSIZE)lldb_private::lldb_assert(static_cast<bool>(m_fd_map.size
() <= 1024), "m_fd_map.size() <= FD_SETSIZE", __FUNCTION__
, "/usr/src/gnu/usr.bin/clang/liblldbUtility/../../../llvm/lldb/source/Utility/SelectHelper.cpp"
, 98)
;
99 if (m_fd_map.size() > FD_SETSIZE1024)
100 return lldb_private::Status("Too many file descriptors for select()");
101#endif
102
103 llvm::Optional<lldb::socket_t> max_read_fd;
104 llvm::Optional<lldb::socket_t> max_write_fd;
105 llvm::Optional<lldb::socket_t> max_error_fd;
106 llvm::Optional<lldb::socket_t> max_fd;
107 for (auto &pair : m_fd_map) {
108 pair.second.PrepareForSelect();
109 const lldb::socket_t fd = pair.first;
110#if !defined(__APPLE__) && !defined(_WIN32)
111 lldbassert(fd < static_cast<int>(FD_SETSIZE))lldb_private::lldb_assert(static_cast<bool>(fd < static_cast
<int>(1024)), "fd < static_cast<int>(FD_SETSIZE)"
, __FUNCTION__, "/usr/src/gnu/usr.bin/clang/liblldbUtility/../../../llvm/lldb/source/Utility/SelectHelper.cpp"
, 111)
;
1
Assuming 'fd' is < 1024
112 if (fd
1.1
'fd' is < 1024
1.1
'fd' is < 1024
1.1
'fd' is < 1024
>= static_cast<int>(FD_SETSIZE1024)) {
2
Taking false branch
113 error.SetErrorStringWithFormat("%i is too large for select()", fd);
114 return error;
115 }
116#endif
117 if (pair.second.read_set)
3
Assuming field 'read_set' is false
4
Taking false branch
118 updateMaxFd(max_read_fd, fd);
119 if (pair.second.write_set)
5
Assuming field 'write_set' is false
6
Taking false branch
120 updateMaxFd(max_write_fd, fd);
121 if (pair.second.error_set)
7
Assuming field 'error_set' is false
8
Taking false branch
122 updateMaxFd(max_error_fd, fd);
123 updateMaxFd(max_fd, fd);
9
Calling 'updateMaxFd'
11
Returning from 'updateMaxFd'
124 }
125
126 if (!max_fd.hasValue()) {
12
Calling 'Optional::hasValue'
17
Returning from 'Optional::hasValue'
18
Taking false branch
127 error.SetErrorString("no valid file descriptors");
128 return error;
129 }
130
131 const unsigned nfds = static_cast<unsigned>(*max_fd) + 1;
132 fd_set *read_fdset_ptr = nullptr;
19
'read_fdset_ptr' initialized to a null pointer value
133 fd_set *write_fdset_ptr = nullptr;
134 fd_set *error_fdset_ptr = nullptr;
135// Initialize and zero out the fdsets
136#if defined(__APPLE__)
137 llvm::SmallVector<fd_set, 1> read_fdset;
138 llvm::SmallVector<fd_set, 1> write_fdset;
139 llvm::SmallVector<fd_set, 1> error_fdset;
140
141 if (max_read_fd.hasValue()) {
142 read_fdset.resize((nfds / FD_SETSIZE1024) + 1);
143 read_fdset_ptr = read_fdset.data();
144 }
145 if (max_write_fd.hasValue()) {
146 write_fdset.resize((nfds / FD_SETSIZE1024) + 1);
147 write_fdset_ptr = write_fdset.data();
148 }
149 if (max_error_fd.hasValue()) {
150 error_fdset.resize((nfds / FD_SETSIZE1024) + 1);
151 error_fdset_ptr = error_fdset.data();
152 }
153 for (auto &fd_set : read_fdset)
154 FD_ZERO(&fd_set)do { fd_set *_p = (&fd_set); __size_t _n = (((1024) + (((
(unsigned)(sizeof(__fd_mask) * 8))) - 1)) / (((unsigned)(sizeof
(__fd_mask) * 8)))); while (_n > 0) _p->fds_bits[--_n] =
0; } while (0)
;
155 for (auto &fd_set : write_fdset)
156 FD_ZERO(&fd_set)do { fd_set *_p = (&fd_set); __size_t _n = (((1024) + (((
(unsigned)(sizeof(__fd_mask) * 8))) - 1)) / (((unsigned)(sizeof
(__fd_mask) * 8)))); while (_n > 0) _p->fds_bits[--_n] =
0; } while (0)
;
157 for (auto &fd_set : error_fdset)
158 FD_ZERO(&fd_set)do { fd_set *_p = (&fd_set); __size_t _n = (((1024) + (((
(unsigned)(sizeof(__fd_mask) * 8))) - 1)) / (((unsigned)(sizeof
(__fd_mask) * 8)))); while (_n > 0) _p->fds_bits[--_n] =
0; } while (0)
;
159#else
160 fd_set read_fdset;
161 fd_set write_fdset;
162 fd_set error_fdset;
163
164 if (max_read_fd.hasValue()) {
20
Taking false branch
165 FD_ZERO(&read_fdset)do { fd_set *_p = (&read_fdset); __size_t _n = (((1024) +
((((unsigned)(sizeof(__fd_mask) * 8))) - 1)) / (((unsigned)(
sizeof(__fd_mask) * 8)))); while (_n > 0) _p->fds_bits[
--_n] = 0; } while (0)
;
166 read_fdset_ptr = &read_fdset;
167 }
168 if (max_write_fd.hasValue()) {
21
Taking false branch
169 FD_ZERO(&write_fdset)do { fd_set *_p = (&write_fdset); __size_t _n = (((1024) +
((((unsigned)(sizeof(__fd_mask) * 8))) - 1)) / (((unsigned)(
sizeof(__fd_mask) * 8)))); while (_n > 0) _p->fds_bits[
--_n] = 0; } while (0)
;
170 write_fdset_ptr = &write_fdset;
171 }
172 if (max_error_fd.hasValue()) {
22
Taking false branch
173 FD_ZERO(&error_fdset)do { fd_set *_p = (&error_fdset); __size_t _n = (((1024) +
((((unsigned)(sizeof(__fd_mask) * 8))) - 1)) / (((unsigned)(
sizeof(__fd_mask) * 8)))); while (_n > 0) _p->fds_bits[
--_n] = 0; } while (0)
;
174 error_fdset_ptr = &error_fdset;
175 }
176#endif
177 // Set the FD bits in the fdsets for read/write/error
178 for (auto &pair : m_fd_map) {
179 const lldb::socket_t fd = pair.first;
180
181 if (pair.second.read_set)
182 FD_SET(fd, read_fdset_ptr)__fd_set((fd), (read_fdset_ptr));
183
184 if (pair.second.write_set)
185 FD_SET(fd, write_fdset_ptr)__fd_set((fd), (write_fdset_ptr));
186
187 if (pair.second.error_set)
188 FD_SET(fd, error_fdset_ptr)__fd_set((fd), (error_fdset_ptr));
189 }
190
191 // Setup our timeout time value if needed
192 struct timeval *tv_ptr = nullptr;
193 struct timeval tv = {0, 0};
194
195 while (true) {
23
Loop condition is true. Entering loop body
196 using namespace std::chrono;
197 // Setup out relative timeout based on the end time if we have one
198 if (m_end_time.hasValue()) {
24
Assuming the condition is false
25
Taking false branch
199 tv_ptr = &tv;
200 const auto remaining_dur = duration_cast<microseconds>(
201 m_end_time.getValue() - steady_clock::now());
202 if (remaining_dur.count() > 0) {
203 // Wait for a specific amount of time
204 const auto dur_secs = duration_cast<seconds>(remaining_dur);
205 const auto dur_usecs = remaining_dur % seconds(1);
206 tv.tv_sec = dur_secs.count();
207 tv.tv_usec = dur_usecs.count();
208 } else {
209 // Just poll once with no timeout
210 tv.tv_sec = 0;
211 tv.tv_usec = 0;
212 }
213 }
214 const int num_set_fds = ::select(nfds, read_fdset_ptr, write_fdset_ptr,
215 error_fdset_ptr, tv_ptr);
216 if (num_set_fds < 0) {
26
Assuming 'num_set_fds' is >= 0
27
Taking false branch
217 // We got an error
218 error.SetErrorToErrno();
219 if (error.GetError() == EINTR4) {
220 error.Clear();
221 continue; // Keep calling select if we get EINTR
222 } else
223 return error;
224 } else if (num_set_fds == 0) {
28
Assuming 'num_set_fds' is not equal to 0
29
Taking false branch
225 // Timeout
226 error.SetError(ETIMEDOUT60, lldb::eErrorTypePOSIX);
227 error.SetErrorString("timed out");
228 return error;
229 } else {
230 // One or more descriptors were set, update the FDInfo::select_is_set
231 // mask so users can ask the SelectHelper class so clients can call one
232 // of:
233
234 for (auto &pair : m_fd_map) {
235 const int fd = pair.first;
236
237 if (pair.second.read_set) {
30
Assuming field 'read_set' is true
31
Taking true branch
238 if (FD_ISSET(fd, read_fdset_ptr)__fd_isset((fd), (read_fdset_ptr)))
32
Passing null pointer value via 2nd parameter 'p'
33
Calling '__fd_isset'
239 pair.second.read_is_set = true;
240 }
241 if (pair.second.write_set) {
242 if (FD_ISSET(fd, write_fdset_ptr)__fd_isset((fd), (write_fdset_ptr)))
243 pair.second.write_is_set = true;
244 }
245 if (pair.second.error_set) {
246 if (FD_ISSET(fd, error_fdset_ptr)__fd_isset((fd), (error_fdset_ptr)))
247 pair.second.error_is_set = true;
248 }
249 }
250 break;
251 }
252 }
253 return error;
254}

/usr/src/gnu/usr.bin/clang/liblldbUtility/../../../llvm/llvm/include/llvm/ADT/Optional.h

1//===- Optional.h - Simple variant for passing optional values --*- C++ -*-===//
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// This file provides Optional, a template class modeled in the spirit of
10// OCaml's 'opt' variant. The idea is to strongly type whether or not
11// a value can be optional.
12//
13//===----------------------------------------------------------------------===//
14
15#ifndef LLVM_ADT_OPTIONAL_H
16#define LLVM_ADT_OPTIONAL_H
17
18#include "llvm/ADT/Hashing.h"
19#include "llvm/ADT/None.h"
20#include "llvm/ADT/STLForwardCompat.h"
21#include "llvm/Support/Compiler.h"
22#include "llvm/Support/type_traits.h"
23#include <cassert>
24#include <memory>
25#include <new>
26#include <utility>
27
28namespace llvm {
29
30class raw_ostream;
31
32namespace optional_detail {
33
34/// Storage for any type.
35//
36// The specialization condition intentionally uses
37// llvm::is_trivially_copy_constructible instead of
38// std::is_trivially_copy_constructible. GCC versions prior to 7.4 may
39// instantiate the copy constructor of `T` when
40// std::is_trivially_copy_constructible is instantiated. This causes
41// compilation to fail if we query the trivially copy constructible property of
42// a class which is not copy constructible.
43//
44// The current implementation of OptionalStorage insists that in order to use
45// the trivial specialization, the value_type must be trivially copy
46// constructible and trivially copy assignable due to =default implementations
47// of the copy/move constructor/assignment. It does not follow that this is
48// necessarily the case std::is_trivially_copyable is true (hence the expanded
49// specialization condition).
50//
51// The move constructible / assignable conditions emulate the remaining behavior
52// of std::is_trivially_copyable.
53template <typename T, bool = (llvm::is_trivially_copy_constructible<T>::value &&
54 std::is_trivially_copy_assignable<T>::value &&
55 (std::is_trivially_move_constructible<T>::value ||
56 !std::is_move_constructible<T>::value) &&
57 (std::is_trivially_move_assignable<T>::value ||
58 !std::is_move_assignable<T>::value))>
59class OptionalStorage {
60 union {
61 char empty;
62 T value;
63 };
64 bool hasVal;
65
66public:
67 ~OptionalStorage() { reset(); }
68
69 constexpr OptionalStorage() noexcept : empty(), hasVal(false) {}
70
71 constexpr OptionalStorage(OptionalStorage const &other) : OptionalStorage() {
72 if (other.hasValue()) {
73 emplace(other.value);
74 }
75 }
76 constexpr OptionalStorage(OptionalStorage &&other) : OptionalStorage() {
77 if (other.hasValue()) {
78 emplace(std::move(other.value));
79 }
80 }
81
82 template <class... Args>
83 constexpr explicit OptionalStorage(in_place_t, Args &&... args)
84 : value(std::forward<Args>(args)...), hasVal(true) {}
85
86 void reset() noexcept {
87 if (hasVal) {
88 value.~T();
89 hasVal = false;
90 }
91 }
92
93 constexpr bool hasValue() const noexcept { return hasVal; }
94
95 T &getValue() LLVM_LVALUE_FUNCTION& noexcept {
96 assert(hasVal)((void)0);
97 return value;
98 }
99 constexpr T const &getValue() const LLVM_LVALUE_FUNCTION& noexcept {
100 assert(hasVal)((void)0);
101 return value;
102 }
103#if LLVM_HAS_RVALUE_REFERENCE_THIS1
104 T &&getValue() && noexcept {
105 assert(hasVal)((void)0);
106 return std::move(value);
107 }
108#endif
109
110 template <class... Args> void emplace(Args &&... args) {
111 reset();
112 ::new ((void *)std::addressof(value)) T(std::forward<Args>(args)...);
113 hasVal = true;
114 }
115
116 OptionalStorage &operator=(T const &y) {
117 if (hasValue()) {
118 value = y;
119 } else {
120 ::new ((void *)std::addressof(value)) T(y);
121 hasVal = true;
122 }
123 return *this;
124 }
125 OptionalStorage &operator=(T &&y) {
126 if (hasValue()) {
127 value = std::move(y);
128 } else {
129 ::new ((void *)std::addressof(value)) T(std::move(y));
130 hasVal = true;
131 }
132 return *this;
133 }
134
135 OptionalStorage &operator=(OptionalStorage const &other) {
136 if (other.hasValue()) {
137 if (hasValue()) {
138 value = other.value;
139 } else {
140 ::new ((void *)std::addressof(value)) T(other.value);
141 hasVal = true;
142 }
143 } else {
144 reset();
145 }
146 return *this;
147 }
148
149 OptionalStorage &operator=(OptionalStorage &&other) {
150 if (other.hasValue()) {
151 if (hasValue()) {
152 value = std::move(other.value);
153 } else {
154 ::new ((void *)std::addressof(value)) T(std::move(other.value));
155 hasVal = true;
156 }
157 } else {
158 reset();
159 }
160 return *this;
161 }
162};
163
164template <typename T> class OptionalStorage<T, true> {
165 union {
166 char empty;
167 T value;
168 };
169 bool hasVal = false;
170
171public:
172 ~OptionalStorage() = default;
173
174 constexpr OptionalStorage() noexcept : empty{} {}
175
176 constexpr OptionalStorage(OptionalStorage const &other) = default;
177 constexpr OptionalStorage(OptionalStorage &&other) = default;
178
179 OptionalStorage &operator=(OptionalStorage const &other) = default;
180 OptionalStorage &operator=(OptionalStorage &&other) = default;
181
182 template <class... Args>
183 constexpr explicit OptionalStorage(in_place_t, Args &&... args)
184 : value(std::forward<Args>(args)...), hasVal(true) {}
185
186 void reset() noexcept {
187 if (hasVal) {
188 value.~T();
189 hasVal = false;
190 }
191 }
192
193 constexpr bool hasValue() const noexcept { return hasVal; }
14
Returning the value 1, which participates in a condition later
194
195 T &getValue() LLVM_LVALUE_FUNCTION& noexcept {
196 assert(hasVal)((void)0);
197 return value;
198 }
199 constexpr T const &getValue() const LLVM_LVALUE_FUNCTION& noexcept {
200 assert(hasVal)((void)0);
201 return value;
202 }
203#if LLVM_HAS_RVALUE_REFERENCE_THIS1
204 T &&getValue() && noexcept {
205 assert(hasVal)((void)0);
206 return std::move(value);
207 }
208#endif
209
210 template <class... Args> void emplace(Args &&... args) {
211 reset();
212 ::new ((void *)std::addressof(value)) T(std::forward<Args>(args)...);
213 hasVal = true;
214 }
215
216 OptionalStorage &operator=(T const &y) {
217 if (hasValue()) {
218 value = y;
219 } else {
220 ::new ((void *)std::addressof(value)) T(y);
221 hasVal = true;
222 }
223 return *this;
224 }
225 OptionalStorage &operator=(T &&y) {
226 if (hasValue()) {
227 value = std::move(y);
228 } else {
229 ::new ((void *)std::addressof(value)) T(std::move(y));
230 hasVal = true;
231 }
232 return *this;
233 }
234};
235
236} // namespace optional_detail
237
238template <typename T> class Optional {
239 optional_detail::OptionalStorage<T> Storage;
240
241public:
242 using value_type = T;
243
244 constexpr Optional() {}
245 constexpr Optional(NoneType) {}
246
247 constexpr Optional(const T &y) : Storage(in_place, y) {}
248 constexpr Optional(const Optional &O) = default;
249
250 constexpr Optional(T &&y) : Storage(in_place, std::move(y)) {}
251 constexpr Optional(Optional &&O) = default;
252
253 template <typename... ArgTypes>
254 constexpr Optional(in_place_t, ArgTypes &&...Args)
255 : Storage(in_place, std::forward<ArgTypes>(Args)...) {}
256
257 Optional &operator=(T &&y) {
258 Storage = std::move(y);
259 return *this;
260 }
261 Optional &operator=(Optional &&O) = default;
262
263 /// Create a new object by constructing it in place with the given arguments.
264 template <typename... ArgTypes> void emplace(ArgTypes &&... Args) {
265 Storage.emplace(std::forward<ArgTypes>(Args)...);
266 }
267
268 static constexpr Optional create(const T *y) {
269 return y ? Optional(*y) : Optional();
270 }
271
272 Optional &operator=(const T &y) {
273 Storage = y;
274 return *this;
275 }
276 Optional &operator=(const Optional &O) = default;
277
278 void reset() { Storage.reset(); }
279
280 constexpr const T *getPointer() const { return &Storage.getValue(); }
281 T *getPointer() { return &Storage.getValue(); }
282 constexpr const T &getValue() const LLVM_LVALUE_FUNCTION& {
283 return Storage.getValue();
284 }
285 T &getValue() LLVM_LVALUE_FUNCTION& { return Storage.getValue(); }
286
287 constexpr explicit operator bool() const { return hasValue(); }
288 constexpr bool hasValue() const { return Storage.hasValue(); }
13
Calling 'OptionalStorage::hasValue'
15
Returning from 'OptionalStorage::hasValue'
16
Returning the value 1, which participates in a condition later
289 constexpr const T *operator->() const { return getPointer(); }
290 T *operator->() { return getPointer(); }
291 constexpr const T &operator*() const LLVM_LVALUE_FUNCTION& {
292 return getValue();
293 }
294 T &operator*() LLVM_LVALUE_FUNCTION& { return getValue(); }
295
296 template <typename U>
297 constexpr T getValueOr(U &&value) const LLVM_LVALUE_FUNCTION& {
298 return hasValue() ? getValue() : std::forward<U>(value);
299 }
300
301 /// Apply a function to the value if present; otherwise return None.
302 template <class Function>
303 auto map(const Function &F) const LLVM_LVALUE_FUNCTION&
304 -> Optional<decltype(F(getValue()))> {
305 if (*this) return F(getValue());
306 return None;
307 }
308
309#if LLVM_HAS_RVALUE_REFERENCE_THIS1
310 T &&getValue() && { return std::move(Storage.getValue()); }
311 T &&operator*() && { return std::move(Storage.getValue()); }
312
313 template <typename U>
314 T getValueOr(U &&value) && {
315 return hasValue() ? std::move(getValue()) : std::forward<U>(value);
316 }
317
318 /// Apply a function to the value if present; otherwise return None.
319 template <class Function>
320 auto map(const Function &F) &&
321 -> Optional<decltype(F(std::move(*this).getValue()))> {
322 if (*this) return F(std::move(*this).getValue());
323 return None;
324 }
325#endif
326};
327
328template <class T> llvm::hash_code hash_value(const Optional<T> &O) {
329 return O ? hash_combine(true, *O) : hash_value(false);
330}
331
332template <typename T, typename U>
333constexpr bool operator==(const Optional<T> &X, const Optional<U> &Y) {
334 if (X && Y)
335 return *X == *Y;
336 return X.hasValue() == Y.hasValue();
337}
338
339template <typename T, typename U>
340constexpr bool operator!=(const Optional<T> &X, const Optional<U> &Y) {
341 return !(X == Y);
342}
343
344template <typename T, typename U>
345constexpr bool operator<(const Optional<T> &X, const Optional<U> &Y) {
346 if (X && Y)
347 return *X < *Y;
348 return X.hasValue() < Y.hasValue();
349}
350
351template <typename T, typename U>
352constexpr bool operator<=(const Optional<T> &X, const Optional<U> &Y) {
353 return !(Y < X);
354}
355
356template <typename T, typename U>
357constexpr bool operator>(const Optional<T> &X, const Optional<U> &Y) {
358 return Y < X;
359}
360
361template <typename T, typename U>
362constexpr bool operator>=(const Optional<T> &X, const Optional<U> &Y) {
363 return !(X < Y);
364}
365
366template <typename T>
367constexpr bool operator==(const Optional<T> &X, NoneType) {
368 return !X;
369}
370
371template <typename T>
372constexpr bool operator==(NoneType, const Optional<T> &X) {
373 return X == None;
374}
375
376template <typename T>
377constexpr bool operator!=(const Optional<T> &X, NoneType) {
378 return !(X == None);
379}
380
381template <typename T>
382constexpr bool operator!=(NoneType, const Optional<T> &X) {
383 return X != None;
384}
385
386template <typename T> constexpr bool operator<(const Optional<T> &, NoneType) {
387 return false;
388}
389
390template <typename T> constexpr bool operator<(NoneType, const Optional<T> &X) {
391 return X.hasValue();
392}
393
394template <typename T>
395constexpr bool operator<=(const Optional<T> &X, NoneType) {
396 return !(None < X);
397}
398
399template <typename T>
400constexpr bool operator<=(NoneType, const Optional<T> &X) {
401 return !(X < None);
402}
403
404template <typename T> constexpr bool operator>(const Optional<T> &X, NoneType) {
405 return None < X;
406}
407
408template <typename T> constexpr bool operator>(NoneType, const Optional<T> &X) {
409 return X < None;
410}
411
412template <typename T>
413constexpr bool operator>=(const Optional<T> &X, NoneType) {
414 return None <= X;
415}
416
417template <typename T>
418constexpr bool operator>=(NoneType, const Optional<T> &X) {
419 return X <= None;
420}
421
422template <typename T>
423constexpr bool operator==(const Optional<T> &X, const T &Y) {
424 return X && *X == Y;
425}
426
427template <typename T>
428constexpr bool operator==(const T &X, const Optional<T> &Y) {
429 return Y && X == *Y;
430}
431
432template <typename T>
433constexpr bool operator!=(const Optional<T> &X, const T &Y) {
434 return !(X == Y);
435}
436
437template <typename T>
438constexpr bool operator!=(const T &X, const Optional<T> &Y) {
439 return !(X == Y);
440}
441
442template <typename T>
443constexpr bool operator<(const Optional<T> &X, const T &Y) {
444 return !X || *X < Y;
445}
446
447template <typename T>
448constexpr bool operator<(const T &X, const Optional<T> &Y) {
449 return Y && X < *Y;
450}
451
452template <typename T>
453constexpr bool operator<=(const Optional<T> &X, const T &Y) {
454 return !(Y < X);
455}
456
457template <typename T>
458constexpr bool operator<=(const T &X, const Optional<T> &Y) {
459 return !(Y < X);
460}
461
462template <typename T>
463constexpr bool operator>(const Optional<T> &X, const T &Y) {
464 return Y < X;
465}
466
467template <typename T>
468constexpr bool operator>(const T &X, const Optional<T> &Y) {
469 return Y < X;
470}
471
472template <typename T>
473constexpr bool operator>=(const Optional<T> &X, const T &Y) {
474 return !(X < Y);
475}
476
477template <typename T>
478constexpr bool operator>=(const T &X, const Optional<T> &Y) {
479 return !(X < Y);
480}
481
482raw_ostream &operator<<(raw_ostream &OS, NoneType);
483
484template <typename T, typename = decltype(std::declval<raw_ostream &>()
485 << std::declval<const T &>())>
486raw_ostream &operator<<(raw_ostream &OS, const Optional<T> &O) {
487 if (O)
488 OS << *O;
489 else
490 OS << None;
491 return OS;
492}
493
494} // end namespace llvm
495
496#endif // LLVM_ADT_OPTIONAL_H

/usr/include/sys/select.h

1/* $OpenBSD: select.h,v 1.17 2016/09/12 19:41:20 guenther Exp $ */
2
3/*-
4 * Copyright (c) 1992, 1993
5 * The Regents of the University of California. All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the University nor the names of its contributors
16 * may be used to endorse or promote products derived from this software
17 * without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 *
31 * @(#)select.h 8.2 (Berkeley) 1/4/94
32 */
33
34#ifndef _SYS_SELECT_H_
35#define _SYS_SELECT_H_
36
37#include <sys/types.h>
38
39#ifndef _TIMEVAL_DECLARED
40#define _TIMEVAL_DECLARED
41struct timeval {
42 time_t tv_sec; /* seconds */
43 suseconds_t tv_usec; /* and microseconds */
44};
45#endif
46
47#ifndef _TIMESPEC_DECLARED
48#define _TIMESPEC_DECLARED
49struct timespec {
50 time_t tv_sec; /* seconds */
51 long tv_nsec; /* and nanoseconds */
52};
53#endif
54
55/*
56 * Select uses bit masks of file descriptors in longs. These macros
57 * manipulate such bit fields (the filesystem macros use chars).
58 * FD_SETSIZE may be defined by the user, but the default here should
59 * be enough for most uses.
60 */
61#ifndef FD_SETSIZE1024
62#define FD_SETSIZE1024 1024
63#endif
64
65/*
66 * We don't want to pollute the namespace with select(2) internals.
67 * Non-underscore versions are exposed later #if __BSD_VISIBLE
68 */
69#define __NBBY8 8 /* number of bits in a byte */
70typedef uint32_t __fd_mask;
71#define __NFDBITS((unsigned)(sizeof(__fd_mask) * 8)) ((unsigned)(sizeof(__fd_mask) * __NBBY8)) /* bits per mask */
72#define __howmany(x, y)(((x) + ((y) - 1)) / (y)) (((x) + ((y) - 1)) / (y))
73
74typedef struct fd_set {
75 __fd_mask fds_bits[__howmany(FD_SETSIZE, __NFDBITS)(((1024) + ((((unsigned)(sizeof(__fd_mask) * 8))) - 1)) / (((
unsigned)(sizeof(__fd_mask) * 8))))
];
76} fd_set;
77
78static __inlineinline void
79__fd_set(int fd, fd_set *p)
80{
81 p->fds_bits[fd / __NFDBITS((unsigned)(sizeof(__fd_mask) * 8))] |= (1U << (fd % __NFDBITS((unsigned)(sizeof(__fd_mask) * 8))));
82}
83#define FD_SET(n, p)__fd_set((n), (p)) __fd_set((n), (p))
84
85static __inlineinline void
86__fd_clr(int fd, fd_set *p)
87{
88 p->fds_bits[fd / __NFDBITS((unsigned)(sizeof(__fd_mask) * 8))] &= ~(1U << (fd % __NFDBITS((unsigned)(sizeof(__fd_mask) * 8))));
89}
90#define FD_CLR(n, p)__fd_clr((n), (p)) __fd_clr((n), (p))
91
92static __inlineinline int
93__fd_isset(int fd, const fd_set *p)
94{
95 return (p->fds_bits[fd / __NFDBITS((unsigned)(sizeof(__fd_mask) * 8))] & (1U << (fd % __NFDBITS((unsigned)(sizeof(__fd_mask) * 8)))));
34
Array access (via field 'fds_bits') results in a null pointer dereference
96}
97#define FD_ISSET(n, p)__fd_isset((n), (p)) __fd_isset((n), (p))
98
99#if __BSD_VISIBLE1
100#define FD_COPY(f, t)(void)(*(t) = *(f)) (void)(*(t) = *(f))
101#endif
102#define FD_ZERO(p)do { fd_set *_p = (p); __size_t _n = (((1024) + ((((unsigned)
(sizeof(__fd_mask) * 8))) - 1)) / (((unsigned)(sizeof(__fd_mask
) * 8)))); while (_n > 0) _p->fds_bits[--_n] = 0; } while
(0)
do { \
103 fd_set *_p = (p); \
104 __size_t _n = __howmany(FD_SETSIZE, __NFDBITS)(((1024) + ((((unsigned)(sizeof(__fd_mask) * 8))) - 1)) / (((
unsigned)(sizeof(__fd_mask) * 8))))
; \
105 \
106 while (_n > 0) \
107 _p->fds_bits[--_n] = 0; \
108} while (0)
109
110#if __BSD_VISIBLE1
111#define NBBY8 __NBBY8
112#define fd_mask__fd_mask __fd_mask
113#define NFDBITS((unsigned)(sizeof(__fd_mask) * 8)) __NFDBITS((unsigned)(sizeof(__fd_mask) * 8))
114#ifndef howmany
115#define howmany(x, y)(((x) + ((y) - 1)) / (y)) __howmany(x, y)(((x) + ((y) - 1)) / (y))
116#endif
117#endif /* __BSD_VISIBLE */
118
119#ifndef _KERNEL
120#ifndef _SIGSET_T_DEFINED_
121#define _SIGSET_T_DEFINED_
122typedef unsigned int sigset_t;
123#endif
124
125#ifndef _SELECT_DEFINED_
126#define _SELECT_DEFINED_
127__BEGIN_DECLSextern "C" {
128int select(int, fd_set * __restrict, fd_set * __restrict,
129 fd_set * __restrict, struct timeval * __restrict);
130int pselect(int, fd_set * __restrict, fd_set * __restrict,
131 fd_set * __restrict, const struct timespec * __restrict,
132 const sigset_t * __restrict);
133__END_DECLS}
134#endif
135#endif /* !_KERNEL */
136
137#endif /* !_SYS_SELECT_H_ */