Bug Summary

File:tools/lld/lib/ReaderWriter/MachO/CompactUnwindPass.cpp
Warning:line 374, column 7
Called C++ object pointer is null

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name CompactUnwindPass.cpp -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-eagerly-assume -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 -mrelocation-model pic -pic-level 2 -mthread-model posix -fmath-errno -masm-verbose -mconstructor-aliases -munwind-tables -fuse-init-array -target-cpu x86-64 -dwarf-column-info -debugger-tuning=gdb -momit-leaf-frame-pointer -ffunction-sections -fdata-sections -resource-dir /usr/lib/llvm-7/lib/clang/7.0.0 -D _DEBUG -D _GNU_SOURCE -D __STDC_CONSTANT_MACROS -D __STDC_FORMAT_MACROS -D __STDC_LIMIT_MACROS -I /build/llvm-toolchain-snapshot-7~svn338205/build-llvm/tools/lld/lib/ReaderWriter/MachO -I /build/llvm-toolchain-snapshot-7~svn338205/tools/lld/lib/ReaderWriter/MachO -I /build/llvm-toolchain-snapshot-7~svn338205/tools/lld/include -I /build/llvm-toolchain-snapshot-7~svn338205/build-llvm/tools/lld/include -I /build/llvm-toolchain-snapshot-7~svn338205/build-llvm/include -I /build/llvm-toolchain-snapshot-7~svn338205/include -I /build/llvm-toolchain-snapshot-7~svn338205/tools/lld/lib/ReaderWriter/MachO/. -U NDEBUG -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/8/../../../../include/c++/8 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/8/../../../../include/x86_64-linux-gnu/c++/8 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/8/../../../../include/x86_64-linux-gnu/c++/8 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/8/../../../../include/c++/8/backward -internal-isystem /usr/include/clang/7.0.0/include/ -internal-isystem /usr/local/include -internal-isystem /usr/lib/llvm-7/lib/clang/7.0.0/include -internal-externc-isystem /usr/lib/gcc/x86_64-linux-gnu/8/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-unused-parameter -Wwrite-strings -Wno-missing-field-initializers -Wno-long-long -Wno-maybe-uninitialized -Wno-class-memaccess -Wno-comment -std=c++11 -fdeprecated-macro -fdebug-compilation-dir /build/llvm-toolchain-snapshot-7~svn338205/build-llvm/tools/lld/lib/ReaderWriter/MachO -ferror-limit 19 -fmessage-length 0 -fvisibility-inlines-hidden -fobjc-runtime=gcc -fdiagnostics-show-option -vectorize-loops -vectorize-slp -analyzer-output=html -analyzer-config stable-report-filename=true -o /tmp/scan-build-2018-07-29-043837-17923-1 -x c++ /build/llvm-toolchain-snapshot-7~svn338205/tools/lld/lib/ReaderWriter/MachO/CompactUnwindPass.cpp -faddrsig

/build/llvm-toolchain-snapshot-7~svn338205/tools/lld/lib/ReaderWriter/MachO/CompactUnwindPass.cpp

1//===- lib/ReaderWriter/MachO/CompactUnwindPass.cpp -------------*- C++ -*-===//
2//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9///
10/// \file A pass to convert MachO's __compact_unwind sections into the final
11/// __unwind_info format used during runtime. See
12/// mach-o/compact_unwind_encoding.h for more details on the formats involved.
13///
14//===----------------------------------------------------------------------===//
15
16#include "ArchHandler.h"
17#include "File.h"
18#include "MachONormalizedFileBinaryUtils.h"
19#include "MachOPasses.h"
20#include "lld/Common/LLVM.h"
21#include "lld/Core/DefinedAtom.h"
22#include "lld/Core/File.h"
23#include "lld/Core/Reference.h"
24#include "lld/Core/Simple.h"
25#include "llvm/ADT/DenseMap.h"
26#include "llvm/Support/Debug.h"
27#include "llvm/Support/Format.h"
28
29#define DEBUG_TYPE"macho-compact-unwind" "macho-compact-unwind"
30
31namespace lld {
32namespace mach_o {
33
34namespace {
35struct CompactUnwindEntry {
36 const Atom *rangeStart;
37 const Atom *personalityFunction;
38 const Atom *lsdaLocation;
39 const Atom *ehFrame;
40
41 uint32_t rangeLength;
42
43 // There are 3 types of compact unwind entry, distinguished by the encoding
44 // value: 0 indicates a function with no unwind info;
45 // _archHandler.dwarfCompactUnwindType() indicates that the entry defers to
46 // __eh_frame, and that the ehFrame entry will be valid; any other value is a
47 // real compact unwind entry -- personalityFunction will be set and
48 // lsdaLocation may be.
49 uint32_t encoding;
50
51 CompactUnwindEntry(const DefinedAtom *function)
52 : rangeStart(function), personalityFunction(nullptr),
53 lsdaLocation(nullptr), ehFrame(nullptr), rangeLength(function->size()),
54 encoding(0) {}
55
56 CompactUnwindEntry()
57 : rangeStart(nullptr), personalityFunction(nullptr),
58 lsdaLocation(nullptr), ehFrame(nullptr), rangeLength(0), encoding(0) {}
59};
60
61struct UnwindInfoPage {
62 ArrayRef<CompactUnwindEntry> entries;
63};
64}
65
66class UnwindInfoAtom : public SimpleDefinedAtom {
67public:
68 UnwindInfoAtom(ArchHandler &archHandler, const File &file, bool isBig,
69 std::vector<const Atom *> &personalities,
70 std::vector<uint32_t> &commonEncodings,
71 std::vector<UnwindInfoPage> &pages, uint32_t numLSDAs)
72 : SimpleDefinedAtom(file), _archHandler(archHandler),
73 _commonEncodingsOffset(7 * sizeof(uint32_t)),
74 _personalityArrayOffset(_commonEncodingsOffset +
75 commonEncodings.size() * sizeof(uint32_t)),
76 _topLevelIndexOffset(_personalityArrayOffset +
77 personalities.size() * sizeof(uint32_t)),
78 _lsdaIndexOffset(_topLevelIndexOffset +
79 3 * (pages.size() + 1) * sizeof(uint32_t)),
80 _firstPageOffset(_lsdaIndexOffset + 2 * numLSDAs * sizeof(uint32_t)),
81 _isBig(isBig) {
82
83 addHeader(commonEncodings.size(), personalities.size(), pages.size());
84 addCommonEncodings(commonEncodings);
85 addPersonalityFunctions(personalities);
86 addTopLevelIndexes(pages);
87 addLSDAIndexes(pages, numLSDAs);
88 addSecondLevelPages(pages);
89 }
90
91 ~UnwindInfoAtom() override = default;
92
93 ContentType contentType() const override {
94 return DefinedAtom::typeProcessedUnwindInfo;
95 }
96
97 Alignment alignment() const override { return 4; }
98
99 uint64_t size() const override { return _contents.size(); }
100
101 ContentPermissions permissions() const override {
102 return DefinedAtom::permR__;
103 }
104
105 ArrayRef<uint8_t> rawContent() const override { return _contents; }
106
107 void addHeader(uint32_t numCommon, uint32_t numPersonalities,
108 uint32_t numPages) {
109 using normalized::write32;
110
111 uint32_t headerSize = 7 * sizeof(uint32_t);
112 _contents.resize(headerSize);
113
114 uint8_t *headerEntries = _contents.data();
115 // version
116 write32(headerEntries, 1, _isBig);
117 // commonEncodingsArraySectionOffset
118 write32(headerEntries + sizeof(uint32_t), _commonEncodingsOffset, _isBig);
119 // commonEncodingsArrayCount
120 write32(headerEntries + 2 * sizeof(uint32_t), numCommon, _isBig);
121 // personalityArraySectionOffset
122 write32(headerEntries + 3 * sizeof(uint32_t), _personalityArrayOffset,
123 _isBig);
124 // personalityArrayCount
125 write32(headerEntries + 4 * sizeof(uint32_t), numPersonalities, _isBig);
126 // indexSectionOffset
127 write32(headerEntries + 5 * sizeof(uint32_t), _topLevelIndexOffset, _isBig);
128 // indexCount
129 write32(headerEntries + 6 * sizeof(uint32_t), numPages + 1, _isBig);
130 }
131
132 /// Add the list of common encodings to the section; this is simply an array
133 /// of uint32_t compact values. Size has already been specified in the header.
134 void addCommonEncodings(std::vector<uint32_t> &commonEncodings) {
135 using normalized::write32;
136
137 _contents.resize(_commonEncodingsOffset +
138 commonEncodings.size() * sizeof(uint32_t));
139 uint8_t *commonEncodingsArea =
140 reinterpret_cast<uint8_t *>(_contents.data() + _commonEncodingsOffset);
141
142 for (uint32_t encoding : commonEncodings) {
143 write32(commonEncodingsArea, encoding, _isBig);
144 commonEncodingsArea += sizeof(uint32_t);
145 }
146 }
147
148 void addPersonalityFunctions(std::vector<const Atom *> personalities) {
149 _contents.resize(_personalityArrayOffset +
150 personalities.size() * sizeof(uint32_t));
151
152 for (unsigned i = 0; i < personalities.size(); ++i)
153 addImageReferenceIndirect(_personalityArrayOffset + i * sizeof(uint32_t),
154 personalities[i]);
155 }
156
157 void addTopLevelIndexes(std::vector<UnwindInfoPage> &pages) {
158 using normalized::write32;
159
160 uint32_t numIndexes = pages.size() + 1;
161 _contents.resize(_topLevelIndexOffset + numIndexes * 3 * sizeof(uint32_t));
162
163 uint32_t pageLoc = _firstPageOffset;
164
165 // The most difficult job here is calculating the LSDAs; everything else
166 // follows fairly naturally, but we can't state where the first
167 uint8_t *indexData = &_contents[_topLevelIndexOffset];
168 uint32_t numLSDAs = 0;
169 for (unsigned i = 0; i < pages.size(); ++i) {
170 // functionOffset
171 addImageReference(_topLevelIndexOffset + 3 * i * sizeof(uint32_t),
172 pages[i].entries[0].rangeStart);
173 // secondLevelPagesSectionOffset
174 write32(indexData + (3 * i + 1) * sizeof(uint32_t), pageLoc, _isBig);
175 write32(indexData + (3 * i + 2) * sizeof(uint32_t),
176 _lsdaIndexOffset + numLSDAs * 2 * sizeof(uint32_t), _isBig);
177
178 for (auto &entry : pages[i].entries)
179 if (entry.lsdaLocation)
180 ++numLSDAs;
181 }
182
183 // Finally, write out the final sentinel index
184 auto &finalEntry = pages[pages.size() - 1].entries.back();
185 addImageReference(_topLevelIndexOffset +
186 3 * pages.size() * sizeof(uint32_t),
187 finalEntry.rangeStart, finalEntry.rangeLength);
188 // secondLevelPagesSectionOffset => 0
189 write32(indexData + (3 * pages.size() + 2) * sizeof(uint32_t),
190 _lsdaIndexOffset + numLSDAs * 2 * sizeof(uint32_t), _isBig);
191 }
192
193 void addLSDAIndexes(std::vector<UnwindInfoPage> &pages, uint32_t numLSDAs) {
194 _contents.resize(_lsdaIndexOffset + numLSDAs * 2 * sizeof(uint32_t));
195
196 uint32_t curOffset = _lsdaIndexOffset;
197 for (auto &page : pages) {
198 for (auto &entry : page.entries) {
199 if (!entry.lsdaLocation)
200 continue;
201
202 addImageReference(curOffset, entry.rangeStart);
203 addImageReference(curOffset + sizeof(uint32_t), entry.lsdaLocation);
204 curOffset += 2 * sizeof(uint32_t);
205 }
206 }
207 }
208
209 void addSecondLevelPages(std::vector<UnwindInfoPage> &pages) {
210 for (auto &page : pages) {
211 addRegularSecondLevelPage(page);
212 }
213 }
214
215 void addRegularSecondLevelPage(const UnwindInfoPage &page) {
216 uint32_t curPageOffset = _contents.size();
217 const int16_t headerSize = sizeof(uint32_t) + 2 * sizeof(uint16_t);
218 uint32_t curPageSize =
219 headerSize + 2 * page.entries.size() * sizeof(uint32_t);
220 _contents.resize(curPageOffset + curPageSize);
221
222 using normalized::write32;
223 using normalized::write16;
224 // 2 => regular page
225 write32(&_contents[curPageOffset], 2, _isBig);
226 // offset of 1st entry
227 write16(&_contents[curPageOffset + 4], headerSize, _isBig);
228 write16(&_contents[curPageOffset + 6], page.entries.size(), _isBig);
229
230 uint32_t pagePos = curPageOffset + headerSize;
231 for (auto &entry : page.entries) {
232 addImageReference(pagePos, entry.rangeStart);
233
234 write32(_contents.data() + pagePos + sizeof(uint32_t), entry.encoding,
235 _isBig);
236 if ((entry.encoding & 0x0f000000U) ==
237 _archHandler.dwarfCompactUnwindType())
238 addEhFrameReference(pagePos + sizeof(uint32_t), entry.ehFrame);
239
240 pagePos += 2 * sizeof(uint32_t);
241 }
242 }
243
244 void addEhFrameReference(uint32_t offset, const Atom *dest,
245 Reference::Addend addend = 0) {
246 addReference(Reference::KindNamespace::mach_o, _archHandler.kindArch(),
247 _archHandler.unwindRefToEhFrameKind(), offset, dest, addend);
248 }
249
250 void addImageReference(uint32_t offset, const Atom *dest,
251 Reference::Addend addend = 0) {
252 addReference(Reference::KindNamespace::mach_o, _archHandler.kindArch(),
253 _archHandler.imageOffsetKind(), offset, dest, addend);
254 }
255
256 void addImageReferenceIndirect(uint32_t offset, const Atom *dest) {
257 addReference(Reference::KindNamespace::mach_o, _archHandler.kindArch(),
258 _archHandler.imageOffsetKindIndirect(), offset, dest, 0);
259 }
260
261private:
262 mach_o::ArchHandler &_archHandler;
263 std::vector<uint8_t> _contents;
264 uint32_t _commonEncodingsOffset;
265 uint32_t _personalityArrayOffset;
266 uint32_t _topLevelIndexOffset;
267 uint32_t _lsdaIndexOffset;
268 uint32_t _firstPageOffset;
269 bool _isBig;
270};
271
272/// Pass for instantiating and optimizing GOT slots.
273///
274class CompactUnwindPass : public Pass {
275public:
276 CompactUnwindPass(const MachOLinkingContext &context)
277 : _ctx(context), _archHandler(_ctx.archHandler()),
278 _file(*_ctx.make_file<MachOFile>("<mach-o Compact Unwind Pass>")),
279 _isBig(MachOLinkingContext::isBigEndian(_ctx.arch())) {
280 _file.setOrdinal(_ctx.getNextOrdinalAndIncrement());
281 }
282
283private:
284 llvm::Error perform(SimpleFile &mergedFile) override {
285 LLVM_DEBUG(llvm::dbgs() << "MachO Compact Unwind pass\n")do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("macho-compact-unwind")) { llvm::dbgs() << "MachO Compact Unwind pass\n"
; } } while (false)
;
286
287 std::map<const Atom *, CompactUnwindEntry> unwindLocs;
288 std::map<const Atom *, const Atom *> dwarfFrames;
289 std::vector<const Atom *> personalities;
290 uint32_t numLSDAs = 0;
291
292 // First collect all __compact_unwind and __eh_frame entries, addressable by
293 // the function referred to.
294 collectCompactUnwindEntries(mergedFile, unwindLocs, personalities,
1
Calling 'CompactUnwindPass::collectCompactUnwindEntries'
295 numLSDAs);
296
297 collectDwarfFrameEntries(mergedFile, dwarfFrames);
298
299 // Skip rest of pass if no unwind info.
300 if (unwindLocs.empty() && dwarfFrames.empty())
301 return llvm::Error::success();
302
303 // FIXME: if there are more than 4 personality functions then we need to
304 // defer to DWARF info for the ones we don't put in the list. They should
305 // also probably be sorted by frequency.
306 assert(personalities.size() <= 4)(static_cast <bool> (personalities.size() <= 4) ? void
(0) : __assert_fail ("personalities.size() <= 4", "/build/llvm-toolchain-snapshot-7~svn338205/tools/lld/lib/ReaderWriter/MachO/CompactUnwindPass.cpp"
, 306, __extension__ __PRETTY_FUNCTION__))
;
307
308 // TODO: Find commmon encodings for use by compressed pages.
309 std::vector<uint32_t> commonEncodings;
310
311 // Now sort the entries by final address and fixup the compact encoding to
312 // its final form (i.e. set personality function bits & create DWARF
313 // references where needed).
314 std::vector<CompactUnwindEntry> unwindInfos = createUnwindInfoEntries(
315 mergedFile, unwindLocs, personalities, dwarfFrames);
316
317 // Remove any unused eh-frame atoms.
318 pruneUnusedEHFrames(mergedFile, unwindInfos, unwindLocs, dwarfFrames);
319
320 // Finally, we can start creating pages based on these entries.
321
322 LLVM_DEBUG(llvm::dbgs() << " Splitting entries into pages\n")do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("macho-compact-unwind")) { llvm::dbgs() << " Splitting entries into pages\n"
; } } while (false)
;
323 // FIXME: we split the entries into pages naively: lots of 4k pages followed
324 // by a small one. ld64 tried to minimize space and align them to real 4k
325 // boundaries. That might be worth doing, or perhaps we could perform some
326 // minor balancing for expected number of lookups.
327 std::vector<UnwindInfoPage> pages;
328 auto remainingInfos = llvm::makeArrayRef(unwindInfos);
329 do {
330 pages.push_back(UnwindInfoPage());
331
332 // FIXME: we only create regular pages at the moment. These can hold up to
333 // 1021 entries according to the documentation.
334 unsigned entriesInPage = std::min(1021U, (unsigned)remainingInfos.size());
335
336 pages.back().entries = remainingInfos.slice(0, entriesInPage);
337 remainingInfos = remainingInfos.slice(entriesInPage);
338
339 LLVM_DEBUG(llvm::dbgs()do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("macho-compact-unwind")) { llvm::dbgs() << " Page from "
<< pages.back().entries[0].rangeStart->name() <<
" to " << pages.back().entries.back().rangeStart->name
() << " + " << llvm::format("0x%x", pages.back().
entries.back().rangeLength) << " has " << entriesInPage
<< " entries\n"; } } while (false)
340 << " Page from "do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("macho-compact-unwind")) { llvm::dbgs() << " Page from "
<< pages.back().entries[0].rangeStart->name() <<
" to " << pages.back().entries.back().rangeStart->name
() << " + " << llvm::format("0x%x", pages.back().
entries.back().rangeLength) << " has " << entriesInPage
<< " entries\n"; } } while (false)
341 << pages.back().entries[0].rangeStart->name() << " to "do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("macho-compact-unwind")) { llvm::dbgs() << " Page from "
<< pages.back().entries[0].rangeStart->name() <<
" to " << pages.back().entries.back().rangeStart->name
() << " + " << llvm::format("0x%x", pages.back().
entries.back().rangeLength) << " has " << entriesInPage
<< " entries\n"; } } while (false)
342 << pages.back().entries.back().rangeStart->name() << " + "do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("macho-compact-unwind")) { llvm::dbgs() << " Page from "
<< pages.back().entries[0].rangeStart->name() <<
" to " << pages.back().entries.back().rangeStart->name
() << " + " << llvm::format("0x%x", pages.back().
entries.back().rangeLength) << " has " << entriesInPage
<< " entries\n"; } } while (false)
343 << llvm::format("0x%x",do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("macho-compact-unwind")) { llvm::dbgs() << " Page from "
<< pages.back().entries[0].rangeStart->name() <<
" to " << pages.back().entries.back().rangeStart->name
() << " + " << llvm::format("0x%x", pages.back().
entries.back().rangeLength) << " has " << entriesInPage
<< " entries\n"; } } while (false)
344 pages.back().entries.back().rangeLength)do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("macho-compact-unwind")) { llvm::dbgs() << " Page from "
<< pages.back().entries[0].rangeStart->name() <<
" to " << pages.back().entries.back().rangeStart->name
() << " + " << llvm::format("0x%x", pages.back().
entries.back().rangeLength) << " has " << entriesInPage
<< " entries\n"; } } while (false)
345 << " has " << entriesInPage << " entries\n")do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("macho-compact-unwind")) { llvm::dbgs() << " Page from "
<< pages.back().entries[0].rangeStart->name() <<
" to " << pages.back().entries.back().rangeStart->name
() << " + " << llvm::format("0x%x", pages.back().
entries.back().rangeLength) << " has " << entriesInPage
<< " entries\n"; } } while (false)
;
346 } while (!remainingInfos.empty());
347
348 auto *unwind = new (_file.allocator())
349 UnwindInfoAtom(_archHandler, _file, _isBig, personalities,
350 commonEncodings, pages, numLSDAs);
351 mergedFile.addAtom(*unwind);
352
353 // Finally, remove all __compact_unwind atoms now that we've processed them.
354 mergedFile.removeDefinedAtomsIf([](const DefinedAtom *atom) {
355 return atom->contentType() == DefinedAtom::typeCompactUnwindInfo;
356 });
357
358 return llvm::Error::success();
359 }
360
361 void collectCompactUnwindEntries(
362 const SimpleFile &mergedFile,
363 std::map<const Atom *, CompactUnwindEntry> &unwindLocs,
364 std::vector<const Atom *> &personalities, uint32_t &numLSDAs) {
365 LLVM_DEBUG(llvm::dbgs() << " Collecting __compact_unwind entries\n")do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("macho-compact-unwind")) { llvm::dbgs() << " Collecting __compact_unwind entries\n"
; } } while (false)
;
366
367 for (const DefinedAtom *atom : mergedFile.defined()) {
368 if (atom->contentType() != DefinedAtom::typeCompactUnwindInfo)
2
Assuming the condition is false
3
Taking false branch
369 continue;
370
371 auto unwindEntry = extractCompactUnwindEntry(atom);
4
Calling 'CompactUnwindPass::extractCompactUnwindEntry'
8
Returning from 'CompactUnwindPass::extractCompactUnwindEntry'
372 unwindLocs.insert(std::make_pair(unwindEntry.rangeStart, unwindEntry));
9
Calling 'make_pair<const lld::Atom *&, lld::mach_o::(anonymous namespace)::CompactUnwindEntry &>'
26
Returning from 'make_pair<const lld::Atom *&, lld::mach_o::(anonymous namespace)::CompactUnwindEntry &>'
373
374 LLVM_DEBUG(llvm::dbgs() << " Entry for "do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("macho-compact-unwind")) { llvm::dbgs() << " Entry for "
<< unwindEntry.rangeStart->name() << ", encoding="
<< llvm::format("0x%08x", unwindEntry.encoding); } } while
(false)
27
Within the expansion of the macro 'LLVM_DEBUG':
a
Assuming 'DebugFlag' is not equal to 0
b
Assuming the condition is true
c
Called C++ object pointer is null
375 << unwindEntry.rangeStart->name() << ", encoding="do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("macho-compact-unwind")) { llvm::dbgs() << " Entry for "
<< unwindEntry.rangeStart->name() << ", encoding="
<< llvm::format("0x%08x", unwindEntry.encoding); } } while
(false)
376 << llvm::format("0x%08x", unwindEntry.encoding))do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("macho-compact-unwind")) { llvm::dbgs() << " Entry for "
<< unwindEntry.rangeStart->name() << ", encoding="
<< llvm::format("0x%08x", unwindEntry.encoding); } } while
(false)
;
377 if (unwindEntry.personalityFunction)
378 LLVM_DEBUG(llvm::dbgs()do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("macho-compact-unwind")) { llvm::dbgs() << ", personality="
<< unwindEntry.personalityFunction->name() <<
", lsdaLoc=" << unwindEntry.lsdaLocation->name(); }
} while (false)
379 << ", personality="do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("macho-compact-unwind")) { llvm::dbgs() << ", personality="
<< unwindEntry.personalityFunction->name() <<
", lsdaLoc=" << unwindEntry.lsdaLocation->name(); }
} while (false)
380 << unwindEntry.personalityFunction->name()do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("macho-compact-unwind")) { llvm::dbgs() << ", personality="
<< unwindEntry.personalityFunction->name() <<
", lsdaLoc=" << unwindEntry.lsdaLocation->name(); }
} while (false)
381 << ", lsdaLoc=" << unwindEntry.lsdaLocation->name())do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("macho-compact-unwind")) { llvm::dbgs() << ", personality="
<< unwindEntry.personalityFunction->name() <<
", lsdaLoc=" << unwindEntry.lsdaLocation->name(); }
} while (false)
;
382 LLVM_DEBUG(llvm::dbgs() << '\n')do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("macho-compact-unwind")) { llvm::dbgs() << '\n'; } } while
(false)
;
383
384 // Count number of LSDAs we see, since we need to know how big the index
385 // will be while laying out the section.
386 if (unwindEntry.lsdaLocation)
387 ++numLSDAs;
388
389 // Gather the personality functions now, so that they're in deterministic
390 // order (derived from the DefinedAtom order).
391 if (unwindEntry.personalityFunction) {
392 auto pFunc = std::find(personalities.begin(), personalities.end(),
393 unwindEntry.personalityFunction);
394 if (pFunc == personalities.end())
395 personalities.push_back(unwindEntry.personalityFunction);
396 }
397 }
398 }
399
400 CompactUnwindEntry extractCompactUnwindEntry(const DefinedAtom *atom) {
401 CompactUnwindEntry entry;
402
403 for (const Reference *ref : *atom) {
404 switch (ref->offsetInAtom()) {
405 case 0:
406 // FIXME: there could legitimately be functions with multiple encoding
407 // entries. However, nothing produces them at the moment.
408 assert(ref->addend() == 0 && "unexpected offset into function")(static_cast <bool> (ref->addend() == 0 && "unexpected offset into function"
) ? void (0) : __assert_fail ("ref->addend() == 0 && \"unexpected offset into function\""
, "/build/llvm-toolchain-snapshot-7~svn338205/tools/lld/lib/ReaderWriter/MachO/CompactUnwindPass.cpp"
, 408, __extension__ __PRETTY_FUNCTION__))
;
409 entry.rangeStart = ref->target();
410 break;
411 case 0x10:
412 assert(ref->addend() == 0 && "unexpected offset into personality fn")(static_cast <bool> (ref->addend() == 0 && "unexpected offset into personality fn"
) ? void (0) : __assert_fail ("ref->addend() == 0 && \"unexpected offset into personality fn\""
, "/build/llvm-toolchain-snapshot-7~svn338205/tools/lld/lib/ReaderWriter/MachO/CompactUnwindPass.cpp"
, 412, __extension__ __PRETTY_FUNCTION__))
;
413 entry.personalityFunction = ref->target();
414 break;
415 case 0x18:
416 assert(ref->addend() == 0 && "unexpected offset into LSDA atom")(static_cast <bool> (ref->addend() == 0 && "unexpected offset into LSDA atom"
) ? void (0) : __assert_fail ("ref->addend() == 0 && \"unexpected offset into LSDA atom\""
, "/build/llvm-toolchain-snapshot-7~svn338205/tools/lld/lib/ReaderWriter/MachO/CompactUnwindPass.cpp"
, 416, __extension__ __PRETTY_FUNCTION__))
;
417 entry.lsdaLocation = ref->target();
418 break;
419 }
420 }
421
422 if (atom->rawContent().size() < 4 * sizeof(uint32_t))
5
Assuming the condition is true
6
Taking true branch
423 return entry;
7
Null pointer value stored to 'unwindEntry.rangeStart'
424
425 using normalized::read32;
426 entry.rangeLength =
427 read32(atom->rawContent().data() + 2 * sizeof(uint32_t), _isBig);
428 entry.encoding =
429 read32(atom->rawContent().data() + 3 * sizeof(uint32_t), _isBig);
430 return entry;
431 }
432
433 void
434 collectDwarfFrameEntries(const SimpleFile &mergedFile,
435 std::map<const Atom *, const Atom *> &dwarfFrames) {
436 for (const DefinedAtom *ehFrameAtom : mergedFile.defined()) {
437 if (ehFrameAtom->contentType() != DefinedAtom::typeCFI)
438 continue;
439 if (ArchHandler::isDwarfCIE(_isBig, ehFrameAtom))
440 continue;
441
442 if (const Atom *function = _archHandler.fdeTargetFunction(ehFrameAtom))
443 dwarfFrames[function] = ehFrameAtom;
444 }
445 }
446
447 /// Every atom defined in __TEXT,__text needs an entry in the final
448 /// __unwind_info section (in order). These comes from two sources:
449 /// + Input __compact_unwind sections where possible (after adding the
450 /// personality function offset which is only known now).
451 /// + A synthesised reference to __eh_frame if there's no __compact_unwind
452 /// or too many personality functions to be accommodated.
453 std::vector<CompactUnwindEntry> createUnwindInfoEntries(
454 const SimpleFile &mergedFile,
455 const std::map<const Atom *, CompactUnwindEntry> &unwindLocs,
456 const std::vector<const Atom *> &personalities,
457 const std::map<const Atom *, const Atom *> &dwarfFrames) {
458 std::vector<CompactUnwindEntry> unwindInfos;
459
460 LLVM_DEBUG(llvm::dbgs() << " Creating __unwind_info entries\n")do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("macho-compact-unwind")) { llvm::dbgs() << " Creating __unwind_info entries\n"
; } } while (false)
;
461 // The final order in the __unwind_info section must be derived from the
462 // order of typeCode atoms, since that's how they'll be put into the object
463 // file eventually (yuck!).
464 for (const DefinedAtom *atom : mergedFile.defined()) {
465 if (atom->contentType() != DefinedAtom::typeCode)
466 continue;
467
468 unwindInfos.push_back(finalizeUnwindInfoEntryForAtom(
469 atom, unwindLocs, personalities, dwarfFrames));
470
471 LLVM_DEBUG(llvm::dbgs()do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("macho-compact-unwind")) { llvm::dbgs() << " Entry for "
<< atom->name() << ", final encoding=" <<
llvm::format("0x%08x", unwindInfos.back().encoding) <<
'\n'; } } while (false)
472 << " Entry for " << atom->name() << ", final encoding="do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("macho-compact-unwind")) { llvm::dbgs() << " Entry for "
<< atom->name() << ", final encoding=" <<
llvm::format("0x%08x", unwindInfos.back().encoding) <<
'\n'; } } while (false)
473 << llvm::format("0x%08x", unwindInfos.back().encoding)do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("macho-compact-unwind")) { llvm::dbgs() << " Entry for "
<< atom->name() << ", final encoding=" <<
llvm::format("0x%08x", unwindInfos.back().encoding) <<
'\n'; } } while (false)
474 << '\n')do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("macho-compact-unwind")) { llvm::dbgs() << " Entry for "
<< atom->name() << ", final encoding=" <<
llvm::format("0x%08x", unwindInfos.back().encoding) <<
'\n'; } } while (false)
;
475 }
476
477 return unwindInfos;
478 }
479
480 /// Remove unused EH frames.
481 ///
482 /// An EH frame is considered unused if there is a corresponding compact
483 /// unwind atom that doesn't require the EH frame.
484 void pruneUnusedEHFrames(
485 SimpleFile &mergedFile,
486 const std::vector<CompactUnwindEntry> &unwindInfos,
487 const std::map<const Atom *, CompactUnwindEntry> &unwindLocs,
488 const std::map<const Atom *, const Atom *> &dwarfFrames) {
489
490 // Worklist of all 'used' FDEs.
491 std::vector<const DefinedAtom *> usedDwarfWorklist;
492
493 // We have to check two conditions when building the worklist:
494 // (1) EH frames used by compact unwind entries.
495 for (auto &entry : unwindInfos)
496 if (entry.ehFrame)
497 usedDwarfWorklist.push_back(cast<DefinedAtom>(entry.ehFrame));
498
499 // (2) EH frames that reference functions with no corresponding compact
500 // unwind info.
501 for (auto &entry : dwarfFrames)
502 if (!unwindLocs.count(entry.first))
503 usedDwarfWorklist.push_back(cast<DefinedAtom>(entry.second));
504
505 // Add all transitively referenced CFI atoms by processing the worklist.
506 std::set<const Atom *> usedDwarfFrames;
507 while (!usedDwarfWorklist.empty()) {
508 const DefinedAtom *cfiAtom = usedDwarfWorklist.back();
509 usedDwarfWorklist.pop_back();
510 usedDwarfFrames.insert(cfiAtom);
511 for (const auto *ref : *cfiAtom) {
512 const DefinedAtom *cfiTarget = dyn_cast<DefinedAtom>(ref->target());
513 if (cfiTarget->contentType() == DefinedAtom::typeCFI)
514 usedDwarfWorklist.push_back(cfiTarget);
515 }
516 }
517
518 // Finally, delete all unreferenced CFI atoms.
519 mergedFile.removeDefinedAtomsIf([&](const DefinedAtom *atom) {
520 if ((atom->contentType() == DefinedAtom::typeCFI) &&
521 !usedDwarfFrames.count(atom))
522 return true;
523 return false;
524 });
525 }
526
527 CompactUnwindEntry finalizeUnwindInfoEntryForAtom(
528 const DefinedAtom *function,
529 const std::map<const Atom *, CompactUnwindEntry> &unwindLocs,
530 const std::vector<const Atom *> &personalities,
531 const std::map<const Atom *, const Atom *> &dwarfFrames) {
532 auto unwindLoc = unwindLocs.find(function);
533
534 CompactUnwindEntry entry;
535 if (unwindLoc == unwindLocs.end()) {
536 // Default entry has correct encoding (0 => no unwind), but we need to
537 // synthesise the function.
538 entry.rangeStart = function;
539 entry.rangeLength = function->size();
540 } else
541 entry = unwindLoc->second;
542
543
544 // If there's no __compact_unwind entry, or it explicitly says to use
545 // __eh_frame, we need to try and fill in the correct DWARF atom.
546 if (entry.encoding == _archHandler.dwarfCompactUnwindType() ||
547 entry.encoding == 0) {
548 auto dwarfFrame = dwarfFrames.find(function);
549 if (dwarfFrame != dwarfFrames.end()) {
550 entry.encoding = _archHandler.dwarfCompactUnwindType();
551 entry.ehFrame = dwarfFrame->second;
552 }
553 }
554
555 auto personality = std::find(personalities.begin(), personalities.end(),
556 entry.personalityFunction);
557 uint32_t personalityIdx = personality == personalities.end()
558 ? 0
559 : personality - personalities.begin() + 1;
560
561 // FIXME: We should also use DWARF when there isn't enough room for the
562 // personality function in the compact encoding.
563 assert(personalityIdx < 4 && "too many personality functions")(static_cast <bool> (personalityIdx < 4 && "too many personality functions"
) ? void (0) : __assert_fail ("personalityIdx < 4 && \"too many personality functions\""
, "/build/llvm-toolchain-snapshot-7~svn338205/tools/lld/lib/ReaderWriter/MachO/CompactUnwindPass.cpp"
, 563, __extension__ __PRETTY_FUNCTION__))
;
564
565 entry.encoding |= personalityIdx << 28;
566
567 if (entry.lsdaLocation)
568 entry.encoding |= 1U << 30;
569
570 return entry;
571 }
572
573 const MachOLinkingContext &_ctx;
574 mach_o::ArchHandler &_archHandler;
575 MachOFile &_file;
576 bool _isBig;
577};
578
579void addCompactUnwindPass(PassManager &pm, const MachOLinkingContext &ctx) {
580 assert(ctx.needsCompactUnwindPass())(static_cast <bool> (ctx.needsCompactUnwindPass()) ? void
(0) : __assert_fail ("ctx.needsCompactUnwindPass()", "/build/llvm-toolchain-snapshot-7~svn338205/tools/lld/lib/ReaderWriter/MachO/CompactUnwindPass.cpp"
, 580, __extension__ __PRETTY_FUNCTION__))
;
581 pm.add(llvm::make_unique<CompactUnwindPass>(ctx));
582}
583
584} // end namesapce mach_o
585} // end namesapce lld

/usr/lib/gcc/x86_64-linux-gnu/8/../../../../include/c++/8/bits/stl_pair.h

1// Pair implementation -*- C++ -*-
2
3// Copyright (C) 2001-2018 Free Software Foundation, Inc.
4//
5// This file is part of the GNU ISO C++ Library. This library is free
6// software; you can redistribute it and/or modify it under the
7// terms of the GNU General Public License as published by the
8// Free Software Foundation; either version 3, or (at your option)
9// any later version.
10
11// This library is distributed in the hope that it will be useful,
12// but WITHOUT ANY WARRANTY; without even the implied warranty of
13// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14// GNU General Public License for more details.
15
16// Under Section 7 of GPL version 3, you are granted additional
17// permissions described in the GCC Runtime Library Exception, version
18// 3.1, as published by the Free Software Foundation.
19
20// You should have received a copy of the GNU General Public License and
21// a copy of the GCC Runtime Library Exception along with this program;
22// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
23// <http://www.gnu.org/licenses/>.
24
25/*
26 *
27 * Copyright (c) 1994
28 * Hewlett-Packard Company
29 *
30 * Permission to use, copy, modify, distribute and sell this software
31 * and its documentation for any purpose is hereby granted without fee,
32 * provided that the above copyright notice appear in all copies and
33 * that both that copyright notice and this permission notice appear
34 * in supporting documentation. Hewlett-Packard Company makes no
35 * representations about the suitability of this software for any
36 * purpose. It is provided "as is" without express or implied warranty.
37 *
38 *
39 * Copyright (c) 1996,1997
40 * Silicon Graphics Computer Systems, Inc.
41 *
42 * Permission to use, copy, modify, distribute and sell this software
43 * and its documentation for any purpose is hereby granted without fee,
44 * provided that the above copyright notice appear in all copies and
45 * that both that copyright notice and this permission notice appear
46 * in supporting documentation. Silicon Graphics makes no
47 * representations about the suitability of this software for any
48 * purpose. It is provided "as is" without express or implied warranty.
49 */
50
51/** @file bits/stl_pair.h
52 * This is an internal header file, included by other library headers.
53 * Do not attempt to use it directly. @headername{utility}
54 */
55
56#ifndef _STL_PAIR_H1
57#define _STL_PAIR_H1 1
58
59#include <bits/move.h> // for std::move / std::forward, and std::swap
60
61#if __cplusplus201103L >= 201103L
62#include <type_traits> // for std::__decay_and_strip too
63#endif
64
65namespace std _GLIBCXX_VISIBILITY(default)__attribute__ ((__visibility__ ("default")))
66{
67_GLIBCXX_BEGIN_NAMESPACE_VERSION
68
69 /**
70 * @addtogroup utilities
71 * @{
72 */
73
74#if __cplusplus201103L >= 201103L
75 /// piecewise_construct_t
76 struct piecewise_construct_t { explicit piecewise_construct_t() = default; };
77
78 /// piecewise_construct
79 _GLIBCXX17_INLINE constexpr piecewise_construct_t piecewise_construct =
80 piecewise_construct_t();
81
82 // Forward declarations.
83 template<typename...>
84 class tuple;
85
86 template<std::size_t...>
87 struct _Index_tuple;
88
89 // Concept utility functions, reused in conditionally-explicit
90 // constructors.
91 // See PR 70437, don't look at is_constructible or
92 // is_convertible if the types are the same to
93 // avoid querying those properties for incomplete types.
94 template <bool, typename _T1, typename _T2>
95 struct _PCC
96 {
97 template <typename _U1, typename _U2>
98 static constexpr bool _ConstructiblePair()
99 {
100 return __and_<is_constructible<_T1, const _U1&>,
101 is_constructible<_T2, const _U2&>>::value;
102 }
103
104 template <typename _U1, typename _U2>
105 static constexpr bool _ImplicitlyConvertiblePair()
106 {
107 return __and_<is_convertible<const _U1&, _T1>,
108 is_convertible<const _U2&, _T2>>::value;
109 }
110
111 template <typename _U1, typename _U2>
112 static constexpr bool _MoveConstructiblePair()
113 {
114 return __and_<is_constructible<_T1, _U1&&>,
115 is_constructible<_T2, _U2&&>>::value;
116 }
117
118 template <typename _U1, typename _U2>
119 static constexpr bool _ImplicitlyMoveConvertiblePair()
120 {
121 return __and_<is_convertible<_U1&&, _T1>,
122 is_convertible<_U2&&, _T2>>::value;
123 }
124
125 template <bool __implicit, typename _U1, typename _U2>
126 static constexpr bool _CopyMovePair()
127 {
128 using __do_converts = __and_<is_convertible<const _U1&, _T1>,
129 is_convertible<_U2&&, _T2>>;
130 using __converts = typename conditional<__implicit,
131 __do_converts,
132 __not_<__do_converts>>::type;
133 return __and_<is_constructible<_T1, const _U1&>,
134 is_constructible<_T2, _U2&&>,
135 __converts
136 >::value;
137 }
138
139 template <bool __implicit, typename _U1, typename _U2>
140 static constexpr bool _MoveCopyPair()
141 {
142 using __do_converts = __and_<is_convertible<_U1&&, _T1>,
143 is_convertible<const _U2&, _T2>>;
144 using __converts = typename conditional<__implicit,
145 __do_converts,
146 __not_<__do_converts>>::type;
147 return __and_<is_constructible<_T1, _U1&&>,
148 is_constructible<_T2, const _U2&&>,
149 __converts
150 >::value;
151 }
152 };
153
154 template <typename _T1, typename _T2>
155 struct _PCC<false, _T1, _T2>
156 {
157 template <typename _U1, typename _U2>
158 static constexpr bool _ConstructiblePair()
159 {
160 return false;
161 }
162
163 template <typename _U1, typename _U2>
164 static constexpr bool _ImplicitlyConvertiblePair()
165 {
166 return false;
167 }
168
169 template <typename _U1, typename _U2>
170 static constexpr bool _MoveConstructiblePair()
171 {
172 return false;
173 }
174
175 template <typename _U1, typename _U2>
176 static constexpr bool _ImplicitlyMoveConvertiblePair()
177 {
178 return false;
179 }
180 };
181
182 // PR libstdc++/79141, a utility type for preventing
183 // initialization of an argument of a disabled assignment
184 // operator from a pair of empty braces.
185 struct __nonesuch_no_braces : std::__nonesuch {
186 explicit __nonesuch_no_braces(const __nonesuch&) = delete;
187 };
188
189#endif
190
191 /**
192 * @brief Struct holding two objects of arbitrary type.
193 *
194 * @tparam _T1 Type of first object.
195 * @tparam _T2 Type of second object.
196 */
197 template<typename _T1, typename _T2>
198 struct pair
199 {
200 typedef _T1 first_type; /// @c first_type is the first bound type
201 typedef _T2 second_type; /// @c second_type is the second bound type
202
203 _T1 first; /// @c first is a copy of the first object
204 _T2 second; /// @c second is a copy of the second object
205
206 // _GLIBCXX_RESOLVE_LIB_DEFECTS
207 // 265. std::pair::pair() effects overly restrictive
208 /** The default constructor creates @c first and @c second using their
209 * respective default constructors. */
210#if __cplusplus201103L >= 201103L
211 template <typename _U1 = _T1,
212 typename _U2 = _T2,
213 typename enable_if<__and_<
214 __is_implicitly_default_constructible<_U1>,
215 __is_implicitly_default_constructible<_U2>>
216 ::value, bool>::type = true>
217#endif
218 _GLIBCXX_CONSTEXPRconstexpr pair()
219 : first(), second() { }
220
221#if __cplusplus201103L >= 201103L
222 template <typename _U1 = _T1,
223 typename _U2 = _T2,
224 typename enable_if<__and_<
225 is_default_constructible<_U1>,
226 is_default_constructible<_U2>,
227 __not_<
228 __and_<__is_implicitly_default_constructible<_U1>,
229 __is_implicitly_default_constructible<_U2>>>>
230 ::value, bool>::type = false>
231 explicit constexpr pair()
232 : first(), second() { }
233#endif
234
235 /** Two objects may be passed to a @c pair constructor to be copied. */
236#if __cplusplus201103L < 201103L
237 pair(const _T1& __a, const _T2& __b)
238 : first(__a), second(__b) { }
239#else
240 // Shortcut for constraining the templates that don't take pairs.
241 using _PCCP = _PCC<true, _T1, _T2>;
242
243 template<typename _U1 = _T1, typename _U2=_T2, typename
244 enable_if<_PCCP::template
245 _ConstructiblePair<_U1, _U2>()
246 && _PCCP::template
247 _ImplicitlyConvertiblePair<_U1, _U2>(),
248 bool>::type=true>
249 constexpr pair(const _T1& __a, const _T2& __b)
250 : first(__a), second(__b) { }
251
252 template<typename _U1 = _T1, typename _U2=_T2, typename
253 enable_if<_PCCP::template
254 _ConstructiblePair<_U1, _U2>()
255 && !_PCCP::template
256 _ImplicitlyConvertiblePair<_U1, _U2>(),
257 bool>::type=false>
258 explicit constexpr pair(const _T1& __a, const _T2& __b)
259 : first(__a), second(__b) { }
260#endif
261
262 /** There is also a templated copy ctor for the @c pair class itself. */
263#if __cplusplus201103L < 201103L
264 template<typename _U1, typename _U2>
265 pair(const pair<_U1, _U2>& __p)
266 : first(__p.first), second(__p.second) { }
267#else
268 // Shortcut for constraining the templates that take pairs.
269 template <typename _U1, typename _U2>
270 using _PCCFP = _PCC<!is_same<_T1, _U1>::value
271 || !is_same<_T2, _U2>::value,
272 _T1, _T2>;
273
274 template<typename _U1, typename _U2, typename
275 enable_if<_PCCFP<_U1, _U2>::template
276 _ConstructiblePair<_U1, _U2>()
277 && _PCCFP<_U1, _U2>::template
278 _ImplicitlyConvertiblePair<_U1, _U2>(),
279 bool>::type=true>
280 constexpr pair(const pair<_U1, _U2>& __p)
281 : first(__p.first), second(__p.second) { }
282
283 template<typename _U1, typename _U2, typename
284 enable_if<_PCCFP<_U1, _U2>::template
285 _ConstructiblePair<_U1, _U2>()
286 && !_PCCFP<_U1, _U2>::template
287 _ImplicitlyConvertiblePair<_U1, _U2>(),
288 bool>::type=false>
289 explicit constexpr pair(const pair<_U1, _U2>& __p)
290 : first(__p.first), second(__p.second) { }
291
292 constexpr pair(const pair&) = default;
293 constexpr pair(pair&&) = default;
294
295 // DR 811.
296 template<typename _U1, typename
297 enable_if<_PCCP::template
298 _MoveCopyPair<true, _U1, _T2>(),
299 bool>::type=true>
300 constexpr pair(_U1&& __x, const _T2& __y)
301 : first(std::forward<_U1>(__x)), second(__y) { }
302
303 template<typename _U1, typename
304 enable_if<_PCCP::template
305 _MoveCopyPair<false, _U1, _T2>(),
306 bool>::type=false>
307 explicit constexpr pair(_U1&& __x, const _T2& __y)
308 : first(std::forward<_U1>(__x)), second(__y) { }
309
310 template<typename _U2, typename
311 enable_if<_PCCP::template
312 _CopyMovePair<true, _T1, _U2>(),
313 bool>::type=true>
314 constexpr pair(const _T1& __x, _U2&& __y)
315 : first(__x), second(std::forward<_U2>(__y)) { }
316
317 template<typename _U2, typename
318 enable_if<_PCCP::template
319 _CopyMovePair<false, _T1, _U2>(),
320 bool>::type=false>
321 explicit pair(const _T1& __x, _U2&& __y)
322 : first(__x), second(std::forward<_U2>(__y)) { }
323
324 template<typename _U1, typename _U2, typename
325 enable_if<_PCCP::template
326 _MoveConstructiblePair<_U1, _U2>()
327 && _PCCP::template
328 _ImplicitlyMoveConvertiblePair<_U1, _U2>(),
329 bool>::type=true>
330 constexpr pair(_U1&& __x, _U2&& __y)
331 : first(std::forward<_U1>(__x)), second(std::forward<_U2>(__y)) { }
17
Calling 'forward<const lld::Atom *&>'
19
Returning from 'forward<const lld::Atom *&>'
20
Calling 'forward<lld::mach_o::(anonymous namespace)::CompactUnwindEntry &>'
22
Returning from 'forward<lld::mach_o::(anonymous namespace)::CompactUnwindEntry &>'
23
Returning without writing to '__x'
332
333 template<typename _U1, typename _U2, typename
334 enable_if<_PCCP::template
335 _MoveConstructiblePair<_U1, _U2>()
336 && !_PCCP::template
337 _ImplicitlyMoveConvertiblePair<_U1, _U2>(),
338 bool>::type=false>
339 explicit constexpr pair(_U1&& __x, _U2&& __y)
340 : first(std::forward<_U1>(__x)), second(std::forward<_U2>(__y)) { }
341
342
343 template<typename _U1, typename _U2, typename
344 enable_if<_PCCFP<_U1, _U2>::template
345 _MoveConstructiblePair<_U1, _U2>()
346 && _PCCFP<_U1, _U2>::template
347 _ImplicitlyMoveConvertiblePair<_U1, _U2>(),
348 bool>::type=true>
349 constexpr pair(pair<_U1, _U2>&& __p)
350 : first(std::forward<_U1>(__p.first)),
351 second(std::forward<_U2>(__p.second)) { }
352
353 template<typename _U1, typename _U2, typename
354 enable_if<_PCCFP<_U1, _U2>::template
355 _MoveConstructiblePair<_U1, _U2>()
356 && !_PCCFP<_U1, _U2>::template
357 _ImplicitlyMoveConvertiblePair<_U1, _U2>(),
358 bool>::type=false>
359 explicit constexpr pair(pair<_U1, _U2>&& __p)
360 : first(std::forward<_U1>(__p.first)),
361 second(std::forward<_U2>(__p.second)) { }
362
363 template<typename... _Args1, typename... _Args2>
364 pair(piecewise_construct_t, tuple<_Args1...>, tuple<_Args2...>);
365
366 pair&
367 operator=(typename conditional<
368 __and_<is_copy_assignable<_T1>,
369 is_copy_assignable<_T2>>::value,
370 const pair&, const __nonesuch_no_braces&>::type __p)
371 {
372 first = __p.first;
373 second = __p.second;
374 return *this;
375 }
376
377 pair&
378 operator=(typename conditional<
379 __not_<__and_<is_copy_assignable<_T1>,
380 is_copy_assignable<_T2>>>::value,
381 const pair&, const __nonesuch_no_braces&>::type __p) = delete;
382
383 pair&
384 operator=(typename conditional<
385 __and_<is_move_assignable<_T1>,
386 is_move_assignable<_T2>>::value,
387 pair&&, __nonesuch_no_braces&&>::type __p)
388 noexcept(__and_<is_nothrow_move_assignable<_T1>,
389 is_nothrow_move_assignable<_T2>>::value)
390 {
391 first = std::forward<first_type>(__p.first);
392 second = std::forward<second_type>(__p.second);
393 return *this;
394 }
395
396 template<typename _U1, typename _U2>
397 typename enable_if<__and_<is_assignable<_T1&, const _U1&>,
398 is_assignable<_T2&, const _U2&>>::value,
399 pair&>::type
400 operator=(const pair<_U1, _U2>& __p)
401 {
402 first = __p.first;
403 second = __p.second;
404 return *this;
405 }
406
407 template<typename _U1, typename _U2>
408 typename enable_if<__and_<is_assignable<_T1&, _U1&&>,
409 is_assignable<_T2&, _U2&&>>::value,
410 pair&>::type
411 operator=(pair<_U1, _U2>&& __p)
412 {
413 first = std::forward<_U1>(__p.first);
414 second = std::forward<_U2>(__p.second);
415 return *this;
416 }
417
418 void
419 swap(pair& __p)
420 noexcept(__and_<__is_nothrow_swappable<_T1>,
421 __is_nothrow_swappable<_T2>>::value)
422 {
423 using std::swap;
424 swap(first, __p.first);
425 swap(second, __p.second);
426 }
427
428 private:
429 template<typename... _Args1, std::size_t... _Indexes1,
430 typename... _Args2, std::size_t... _Indexes2>
431 pair(tuple<_Args1...>&, tuple<_Args2...>&,
432 _Index_tuple<_Indexes1...>, _Index_tuple<_Indexes2...>);
433#endif
434 };
435
436#if __cpp_deduction_guides >= 201606
437 template<typename _T1, typename _T2> pair(_T1, _T2) -> pair<_T1, _T2>;
438#endif
439
440 /// Two pairs of the same type are equal iff their members are equal.
441 template<typename _T1, typename _T2>
442 inline _GLIBCXX_CONSTEXPRconstexpr bool
443 operator==(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y)
444 { return __x.first == __y.first && __x.second == __y.second; }
445
446 /// <http://gcc.gnu.org/onlinedocs/libstdc++/manual/utilities.html>
447 template<typename _T1, typename _T2>
448 inline _GLIBCXX_CONSTEXPRconstexpr bool
449 operator<(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y)
450 { return __x.first < __y.first
451 || (!(__y.first < __x.first) && __x.second < __y.second); }
452
453 /// Uses @c operator== to find the result.
454 template<typename _T1, typename _T2>
455 inline _GLIBCXX_CONSTEXPRconstexpr bool
456 operator!=(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y)
457 { return !(__x == __y); }
458
459 /// Uses @c operator< to find the result.
460 template<typename _T1, typename _T2>
461 inline _GLIBCXX_CONSTEXPRconstexpr bool
462 operator>(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y)
463 { return __y < __x; }
464
465 /// Uses @c operator< to find the result.
466 template<typename _T1, typename _T2>
467 inline _GLIBCXX_CONSTEXPRconstexpr bool
468 operator<=(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y)
469 { return !(__y < __x); }
470
471 /// Uses @c operator< to find the result.
472 template<typename _T1, typename _T2>
473 inline _GLIBCXX_CONSTEXPRconstexpr bool
474 operator>=(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y)
475 { return !(__x < __y); }
476
477#if __cplusplus201103L >= 201103L
478 /// See std::pair::swap().
479 // Note: no std::swap overloads in C++03 mode, this has performance
480 // implications, see, eg, libstdc++/38466.
481 template<typename _T1, typename _T2>
482 inline
483#if __cplusplus201103L > 201402L || !defined(__STRICT_ANSI__1) // c++1z or gnu++11
484 // Constrained free swap overload, see p0185r1
485 typename enable_if<__and_<__is_swappable<_T1>,
486 __is_swappable<_T2>>::value>::type
487#else
488 void
489#endif
490 swap(pair<_T1, _T2>& __x, pair<_T1, _T2>& __y)
491 noexcept(noexcept(__x.swap(__y)))
492 { __x.swap(__y); }
493
494#if __cplusplus201103L > 201402L || !defined(__STRICT_ANSI__1) // c++1z or gnu++11
495 template<typename _T1, typename _T2>
496 typename enable_if<!__and_<__is_swappable<_T1>,
497 __is_swappable<_T2>>::value>::type
498 swap(pair<_T1, _T2>&, pair<_T1, _T2>&) = delete;
499#endif
500#endif // __cplusplus >= 201103L
501
502 /**
503 * @brief A convenience wrapper for creating a pair from two objects.
504 * @param __x The first object.
505 * @param __y The second object.
506 * @return A newly-constructed pair<> object of the appropriate type.
507 *
508 * The standard requires that the objects be passed by reference-to-const,
509 * but LWG issue #181 says they should be passed by const value. We follow
510 * the LWG by default.
511 */
512 // _GLIBCXX_RESOLVE_LIB_DEFECTS
513 // 181. make_pair() unintended behavior
514#if __cplusplus201103L >= 201103L
515 // NB: DR 706.
516 template<typename _T1, typename _T2>
517 constexpr pair<typename __decay_and_strip<_T1>::__type,
518 typename __decay_and_strip<_T2>::__type>
519 make_pair(_T1&& __x, _T2&& __y)
520 {
521 typedef typename __decay_and_strip<_T1>::__type __ds_type1;
522 typedef typename __decay_and_strip<_T2>::__type __ds_type2;
523 typedef pair<__ds_type1, __ds_type2> __pair_type;
524 return __pair_type(std::forward<_T1>(__x), std::forward<_T2>(__y));
10
Calling 'forward<const lld::Atom *&>'
12
Returning from 'forward<const lld::Atom *&>'
13
Calling 'forward<lld::mach_o::(anonymous namespace)::CompactUnwindEntry &>'
15
Returning from 'forward<lld::mach_o::(anonymous namespace)::CompactUnwindEntry &>'
16
Calling constructor for 'pair<const lld::Atom *, lld::mach_o::(anonymous namespace)::CompactUnwindEntry>'
24
Returning from constructor for 'pair<const lld::Atom *, lld::mach_o::(anonymous namespace)::CompactUnwindEntry>'
25
Returning without writing to '__x'
525 }
526#else
527 template<typename _T1, typename _T2>
528 inline pair<_T1, _T2>
529 make_pair(_T1 __x, _T2 __y)
530 { return pair<_T1, _T2>(__x, __y); }
531#endif
532
533 /// @}
534
535_GLIBCXX_END_NAMESPACE_VERSION
536} // namespace std
537
538#endif /* _STL_PAIR_H */

/usr/lib/gcc/x86_64-linux-gnu/8/../../../../include/c++/8/bits/move.h

1// Move, forward and identity for C++11 + swap -*- C++ -*-
2
3// Copyright (C) 2007-2018 Free Software Foundation, Inc.
4//
5// This file is part of the GNU ISO C++ Library. This library is free
6// software; you can redistribute it and/or modify it under the
7// terms of the GNU General Public License as published by the
8// Free Software Foundation; either version 3, or (at your option)
9// any later version.
10
11// This library is distributed in the hope that it will be useful,
12// but WITHOUT ANY WARRANTY; without even the implied warranty of
13// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14// GNU General Public License for more details.
15
16// Under Section 7 of GPL version 3, you are granted additional
17// permissions described in the GCC Runtime Library Exception, version
18// 3.1, as published by the Free Software Foundation.
19
20// You should have received a copy of the GNU General Public License and
21// a copy of the GCC Runtime Library Exception along with this program;
22// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
23// <http://www.gnu.org/licenses/>.
24
25/** @file bits/move.h
26 * This is an internal header file, included by other library headers.
27 * Do not attempt to use it directly. @headername{utility}
28 */
29
30#ifndef _MOVE_H1
31#define _MOVE_H1 1
32
33#include <bits/c++config.h>
34#include <bits/concept_check.h>
35
36namespace std _GLIBCXX_VISIBILITY(default)__attribute__ ((__visibility__ ("default")))
37{
38_GLIBCXX_BEGIN_NAMESPACE_VERSION
39
40 // Used, in C++03 mode too, by allocators, etc.
41 /**
42 * @brief Same as C++11 std::addressof
43 * @ingroup utilities
44 */
45 template<typename _Tp>
46 inline _GLIBCXX_CONSTEXPRconstexpr _Tp*
47 __addressof(_Tp& __r) _GLIBCXX_NOEXCEPTnoexcept
48 { return __builtin_addressof(__r); }
49
50#if __cplusplus201103L >= 201103L
51
52_GLIBCXX_END_NAMESPACE_VERSION
53} // namespace
54
55#include <type_traits> // Brings in std::declval too.
56
57namespace std _GLIBCXX_VISIBILITY(default)__attribute__ ((__visibility__ ("default")))
58{
59_GLIBCXX_BEGIN_NAMESPACE_VERSION
60
61 /**
62 * @addtogroup utilities
63 * @{
64 */
65
66 /**
67 * @brief Forward an lvalue.
68 * @return The parameter cast to the specified type.
69 *
70 * This function is used to implement "perfect forwarding".
71 */
72 template<typename _Tp>
73 constexpr _Tp&&
74 forward(typename std::remove_reference<_Tp>::type& __t) noexcept
75 { return static_cast<_Tp&&>(__t); }
11
Returning without writing to '__t'
14
Returning without writing to '__t.rangeStart'
18
Returning without writing to '__t'
21
Returning without writing to '__t.rangeStart'
76
77 /**
78 * @brief Forward an rvalue.
79 * @return The parameter cast to the specified type.
80 *
81 * This function is used to implement "perfect forwarding".
82 */
83 template<typename _Tp>
84 constexpr _Tp&&
85 forward(typename std::remove_reference<_Tp>::type&& __t) noexcept
86 {
87 static_assert(!std::is_lvalue_reference<_Tp>::value, "template argument"
88 " substituting _Tp is an lvalue reference type");
89 return static_cast<_Tp&&>(__t);
90 }
91
92 /**
93 * @brief Convert a value to an rvalue.
94 * @param __t A thing of arbitrary type.
95 * @return The parameter cast to an rvalue-reference to allow moving it.
96 */
97 template<typename _Tp>
98 constexpr typename std::remove_reference<_Tp>::type&&
99 move(_Tp&& __t) noexcept
100 { return static_cast<typename std::remove_reference<_Tp>::type&&>(__t); }
101
102
103 template<typename _Tp>
104 struct __move_if_noexcept_cond
105 : public __and_<__not_<is_nothrow_move_constructible<_Tp>>,
106 is_copy_constructible<_Tp>>::type { };
107
108 /**
109 * @brief Conditionally convert a value to an rvalue.
110 * @param __x A thing of arbitrary type.
111 * @return The parameter, possibly cast to an rvalue-reference.
112 *
113 * Same as std::move unless the type's move constructor could throw and the
114 * type is copyable, in which case an lvalue-reference is returned instead.
115 */
116 template<typename _Tp>
117 constexpr typename
118 conditional<__move_if_noexcept_cond<_Tp>::value, const _Tp&, _Tp&&>::type
119 move_if_noexcept(_Tp& __x) noexcept
120 { return std::move(__x); }
121
122 // declval, from type_traits.
123
124#if __cplusplus201103L > 201402L
125 // _GLIBCXX_RESOLVE_LIB_DEFECTS
126 // 2296. std::addressof should be constexpr
127# define __cpp_lib_addressof_constexpr 201603
128#endif
129 /**
130 * @brief Returns the actual address of the object or function
131 * referenced by r, even in the presence of an overloaded
132 * operator&.
133 * @param __r Reference to an object or function.
134 * @return The actual address.
135 */
136 template<typename _Tp>
137 inline _GLIBCXX17_CONSTEXPR _Tp*
138 addressof(_Tp& __r) noexcept
139 { return std::__addressof(__r); }
140
141 // _GLIBCXX_RESOLVE_LIB_DEFECTS
142 // 2598. addressof works on temporaries
143 template<typename _Tp>
144 const _Tp* addressof(const _Tp&&) = delete;
145
146 // C++11 version of std::exchange for internal use.
147 template <typename _Tp, typename _Up = _Tp>
148 inline _Tp
149 __exchange(_Tp& __obj, _Up&& __new_val)
150 {
151 _Tp __old_val = std::move(__obj);
152 __obj = std::forward<_Up>(__new_val);
153 return __old_val;
154 }
155
156 /// @} group utilities
157
158#define _GLIBCXX_MOVE(__val)std::move(__val) std::move(__val)
159#define _GLIBCXX_FORWARD(_Tp, __val)std::forward<_Tp>(__val) std::forward<_Tp>(__val)
160#else
161#define _GLIBCXX_MOVE(__val)std::move(__val) (__val)
162#define _GLIBCXX_FORWARD(_Tp, __val)std::forward<_Tp>(__val) (__val)
163#endif
164
165 /**
166 * @addtogroup utilities
167 * @{
168 */
169
170 /**
171 * @brief Swaps two values.
172 * @param __a A thing of arbitrary type.
173 * @param __b Another thing of arbitrary type.
174 * @return Nothing.
175 */
176 template<typename _Tp>
177 inline
178#if __cplusplus201103L >= 201103L
179 typename enable_if<__and_<__not_<__is_tuple_like<_Tp>>,
180 is_move_constructible<_Tp>,
181 is_move_assignable<_Tp>>::value>::type
182 swap(_Tp& __a, _Tp& __b)
183 noexcept(__and_<is_nothrow_move_constructible<_Tp>,
184 is_nothrow_move_assignable<_Tp>>::value)
185#else
186 void
187 swap(_Tp& __a, _Tp& __b)
188#endif
189 {
190 // concept requirements
191 __glibcxx_function_requires(_SGIAssignableConcept<_Tp>)
192
193 _Tp __tmp = _GLIBCXX_MOVE(__a)std::move(__a);
194 __a = _GLIBCXX_MOVE(__b)std::move(__b);
195 __b = _GLIBCXX_MOVE(__tmp)std::move(__tmp);
196 }
197
198 // _GLIBCXX_RESOLVE_LIB_DEFECTS
199 // DR 809. std::swap should be overloaded for array types.
200 /// Swap the contents of two arrays.
201 template<typename _Tp, size_t _Nm>
202 inline
203#if __cplusplus201103L >= 201103L
204 typename enable_if<__is_swappable<_Tp>::value>::type
205 swap(_Tp (&__a)[_Nm], _Tp (&__b)[_Nm])
206 noexcept(__is_nothrow_swappable<_Tp>::value)
207#else
208 void
209 swap(_Tp (&__a)[_Nm], _Tp (&__b)[_Nm])
210#endif
211 {
212 for (size_t __n = 0; __n < _Nm; ++__n)
213 swap(__a[__n], __b[__n]);
214 }
215
216 /// @} group utilities
217_GLIBCXX_END_NAMESPACE_VERSION
218} // namespace
219
220#endif /* _MOVE_H */