Bug Summary

File:clang/lib/Serialization/ModuleManager.cpp
Warning:line 179, column 5
Called C++ object pointer is null

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name ModuleManager.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 -analyzer-config-compatibility-mode=true -mrelocation-model pic -pic-level 2 -mframe-pointer=none -relaxed-aliasing -fmath-errno -fno-rounding-math -mconstructor-aliases -munwind-tables -target-cpu x86-64 -tune-cpu generic -fno-split-dwarf-inlining -debugger-tuning=gdb -ffunction-sections -fdata-sections -resource-dir /usr/lib/llvm-12/lib/clang/12.0.0 -D CLANG_VENDOR="Debian " -D _DEBUG -D _GNU_SOURCE -D __STDC_CONSTANT_MACROS -D __STDC_FORMAT_MACROS -D __STDC_LIMIT_MACROS -I /build/llvm-toolchain-snapshot-12~++20200902111123+4820af2bfc7/build-llvm/tools/clang/lib/Serialization -I /build/llvm-toolchain-snapshot-12~++20200902111123+4820af2bfc7/clang/lib/Serialization -I /build/llvm-toolchain-snapshot-12~++20200902111123+4820af2bfc7/clang/include -I /build/llvm-toolchain-snapshot-12~++20200902111123+4820af2bfc7/build-llvm/tools/clang/include -I /build/llvm-toolchain-snapshot-12~++20200902111123+4820af2bfc7/build-llvm/include -I /build/llvm-toolchain-snapshot-12~++20200902111123+4820af2bfc7/llvm/include -U NDEBUG -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/6.3.0/../../../../include/c++/6.3.0 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/6.3.0/../../../../include/x86_64-linux-gnu/c++/6.3.0 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/6.3.0/../../../../include/x86_64-linux-gnu/c++/6.3.0 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/6.3.0/../../../../include/c++/6.3.0/backward -internal-isystem /usr/local/include -internal-isystem /usr/lib/llvm-12/lib/clang/12.0.0/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-comment -std=c++14 -fdeprecated-macro -fdebug-compilation-dir /build/llvm-toolchain-snapshot-12~++20200902111123+4820af2bfc7/build-llvm/tools/clang/lib/Serialization -fdebug-prefix-map=/build/llvm-toolchain-snapshot-12~++20200902111123+4820af2bfc7=. -ferror-limit 19 -fvisibility-inlines-hidden -stack-protector 2 -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -analyzer-output=html -analyzer-config stable-report-filename=true -faddrsig -o /tmp/scan-build-2020-09-03-003231-17038-1 -x c++ /build/llvm-toolchain-snapshot-12~++20200902111123+4820af2bfc7/clang/lib/Serialization/ModuleManager.cpp

/build/llvm-toolchain-snapshot-12~++20200902111123+4820af2bfc7/clang/lib/Serialization/ModuleManager.cpp

1//===- ModuleManager.cpp - Module Manager ---------------------------------===//
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 defines the ModuleManager class, which manages a set of loaded
10// modules for the ASTReader.
11//
12//===----------------------------------------------------------------------===//
13
14#include "clang/Serialization/ModuleManager.h"
15#include "clang/Basic/FileManager.h"
16#include "clang/Basic/LLVM.h"
17#include "clang/Lex/HeaderSearch.h"
18#include "clang/Lex/ModuleMap.h"
19#include "clang/Serialization/GlobalModuleIndex.h"
20#include "clang/Serialization/InMemoryModuleCache.h"
21#include "clang/Serialization/ModuleFile.h"
22#include "clang/Serialization/PCHContainerOperations.h"
23#include "llvm/ADT/STLExtras.h"
24#include "llvm/ADT/SetVector.h"
25#include "llvm/ADT/SmallPtrSet.h"
26#include "llvm/ADT/SmallVector.h"
27#include "llvm/ADT/StringRef.h"
28#include "llvm/ADT/iterator.h"
29#include "llvm/Support/Chrono.h"
30#include "llvm/Support/DOTGraphTraits.h"
31#include "llvm/Support/ErrorOr.h"
32#include "llvm/Support/GraphWriter.h"
33#include "llvm/Support/MemoryBuffer.h"
34#include "llvm/Support/VirtualFileSystem.h"
35#include <algorithm>
36#include <cassert>
37#include <memory>
38#include <string>
39#include <system_error>
40
41using namespace clang;
42using namespace serialization;
43
44ModuleFile *ModuleManager::lookupByFileName(StringRef Name) const {
45 auto Entry = FileMgr.getFile(Name, /*OpenFile=*/false,
46 /*CacheFailure=*/false);
47 if (Entry)
48 return lookup(*Entry);
49
50 return nullptr;
51}
52
53ModuleFile *ModuleManager::lookupByModuleName(StringRef Name) const {
54 if (const Module *Mod = HeaderSearchInfo.getModuleMap().findModule(Name))
55 if (const FileEntry *File = Mod->getASTFile())
56 return lookup(File);
57
58 return nullptr;
59}
60
61ModuleFile *ModuleManager::lookup(const FileEntry *File) const {
62 auto Known = Modules.find(File);
63 if (Known == Modules.end())
64 return nullptr;
65
66 return Known->second;
67}
68
69std::unique_ptr<llvm::MemoryBuffer>
70ModuleManager::lookupBuffer(StringRef Name) {
71 auto Entry = FileMgr.getFile(Name, /*OpenFile=*/false,
72 /*CacheFailure=*/false);
73 if (!Entry)
74 return nullptr;
75 return std::move(InMemoryBuffers[*Entry]);
76}
77
78static bool checkSignature(ASTFileSignature Signature,
79 ASTFileSignature ExpectedSignature,
80 std::string &ErrorStr) {
81 if (!ExpectedSignature || Signature == ExpectedSignature)
82 return false;
83
84 ErrorStr =
85 Signature ? "signature mismatch" : "could not read module signature";
86 return true;
87}
88
89static void updateModuleImports(ModuleFile &MF, ModuleFile *ImportedBy,
90 SourceLocation ImportLoc) {
91 if (ImportedBy) {
92 MF.ImportedBy.insert(ImportedBy);
93 ImportedBy->Imports.insert(&MF);
94 } else {
95 if (!MF.DirectlyImported)
96 MF.ImportLoc = ImportLoc;
97
98 MF.DirectlyImported = true;
99 }
100}
101
102ModuleManager::AddModuleResult
103ModuleManager::addModule(StringRef FileName, ModuleKind Type,
104 SourceLocation ImportLoc, ModuleFile *ImportedBy,
105 unsigned Generation,
106 off_t ExpectedSize, time_t ExpectedModTime,
107 ASTFileSignature ExpectedSignature,
108 ASTFileSignatureReader ReadSignature,
109 ModuleFile *&Module,
110 std::string &ErrorStr) {
111 Module = nullptr;
112
113 // Look for the file entry. This only fails if the expected size or
114 // modification time differ.
115 const FileEntry *Entry;
116 if (Type == MK_ExplicitModule || Type == MK_PrebuiltModule) {
1
Assuming 'Type' is not equal to MK_ExplicitModule
2
Assuming 'Type' is not equal to MK_PrebuiltModule
3
Taking false branch
117 // If we're not expecting to pull this file out of the module cache, it
118 // might have a different mtime due to being moved across filesystems in
119 // a distributed build. The size must still match, though. (As must the
120 // contents, but we can't check that.)
121 ExpectedModTime = 0;
122 }
123 // Note: ExpectedSize and ExpectedModTime will be 0 for MK_ImplicitModule
124 // when using an ASTFileSignature.
125 if (lookupModuleFile(FileName, ExpectedSize, ExpectedModTime, Entry)) {
4
Calling 'ModuleManager::lookupModuleFile'
9
Returning from 'ModuleManager::lookupModuleFile'
10
Taking false branch
126 ErrorStr = "module file out of date";
127 return OutOfDate;
128 }
129
130 if (!Entry
10.1
'Entry' is null
10.1
'Entry' is null
&& FileName != "-") {
11
Taking false branch
131 ErrorStr = "module file not found";
132 return Missing;
133 }
134
135 // Check whether we already loaded this module, before
136 if (ModuleFile *ModuleEntry = Modules.lookup(Entry)) {
12
Assuming 'ModuleEntry' is null
13
Taking false branch
137 // Check the stored signature.
138 if (checkSignature(ModuleEntry->Signature, ExpectedSignature, ErrorStr))
139 return OutOfDate;
140
141 Module = ModuleEntry;
142 updateModuleImports(*ModuleEntry, ImportedBy, ImportLoc);
143 return AlreadyLoaded;
144 }
145
146 // Allocate a new module.
147 auto NewModule = std::make_unique<ModuleFile>(Type, Generation);
148 NewModule->Index = Chain.size();
149 NewModule->FileName = FileName.str();
150 NewModule->File = Entry;
151 NewModule->ImportLoc = ImportLoc;
152 NewModule->InputFilesValidationTimestamp = 0;
153
154 if (NewModule->Kind == MK_ImplicitModule) {
14
Assuming field 'Kind' is not equal to MK_ImplicitModule
15
Taking false branch
155 std::string TimestampFilename = NewModule->getTimestampFilename();
156 llvm::vfs::Status Status;
157 // A cached stat value would be fine as well.
158 if (!FileMgr.getNoncachedStatValue(TimestampFilename, Status))
159 NewModule->InputFilesValidationTimestamp =
160 llvm::sys::toTimeT(Status.getLastModificationTime());
161 }
162
163 // Load the contents of the module
164 if (std::unique_ptr<llvm::MemoryBuffer> Buffer = lookupBuffer(FileName)) {
16
Calling 'unique_ptr::operator bool'
19
Returning from 'unique_ptr::operator bool'
20
Taking false branch
165 // The buffer was already provided for us.
166 NewModule->Buffer = &ModuleCache->addBuiltPCM(FileName, std::move(Buffer));
167 // Since the cached buffer is reused, it is safe to close the file
168 // descriptor that was opened while stat()ing the PCM in
169 // lookupModuleFile() above, it won't be needed any longer.
170 Entry->closeFile();
171 } else if (llvm::MemoryBuffer *Buffer =
21
Assuming 'Buffer' is null
22
Taking false branch
172 getModuleCache().lookupPCM(FileName)) {
173 NewModule->Buffer = Buffer;
174 // As above, the file descriptor is no longer needed.
175 Entry->closeFile();
176 } else if (getModuleCache().shouldBuildPCM(FileName)) {
23
Assuming the condition is true
24
Taking true branch
177 // Report that the module is out of date, since we tried (and failed) to
178 // import it earlier.
179 Entry->closeFile();
25
Called C++ object pointer is null
180 return OutOfDate;
181 } else {
182 // Open the AST file.
183 llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> Buf((std::error_code()));
184 if (FileName == "-") {
185 Buf = llvm::MemoryBuffer::getSTDIN();
186 } else {
187 // Get a buffer of the file and close the file descriptor when done.
188 // The file is volatile because in a parallel build we expect multiple
189 // compiler processes to use the same module file rebuilding it if needed.
190 //
191 // RequiresNullTerminator is false because module files don't need it, and
192 // this allows the file to still be mmapped.
193 Buf = FileMgr.getBufferForFile(NewModule->File,
194 /*IsVolatile=*/true,
195 /*RequiresNullTerminator=*/false);
196 }
197
198 if (!Buf) {
199 ErrorStr = Buf.getError().message();
200 return Missing;
201 }
202
203 NewModule->Buffer = &getModuleCache().addPCM(FileName, std::move(*Buf));
204 }
205
206 // Initialize the stream.
207 NewModule->Data = PCHContainerRdr.ExtractPCH(*NewModule->Buffer);
208
209 // Read the signature eagerly now so that we can check it. Avoid calling
210 // ReadSignature unless there's something to check though.
211 if (ExpectedSignature && checkSignature(ReadSignature(NewModule->Data),
212 ExpectedSignature, ErrorStr))
213 return OutOfDate;
214
215 // We're keeping this module. Store it everywhere.
216 Module = Modules[Entry] = NewModule.get();
217
218 updateModuleImports(*NewModule, ImportedBy, ImportLoc);
219
220 if (!NewModule->isModule())
221 PCHChain.push_back(NewModule.get());
222 if (!ImportedBy)
223 Roots.push_back(NewModule.get());
224
225 Chain.push_back(std::move(NewModule));
226 return NewlyLoaded;
227}
228
229void ModuleManager::removeModules(ModuleIterator First, ModuleMap *modMap) {
230 auto Last = end();
231 if (First == Last)
232 return;
233
234 // Explicitly clear VisitOrder since we might not notice it is stale.
235 VisitOrder.clear();
236
237 // Collect the set of module file pointers that we'll be removing.
238 llvm::SmallPtrSet<ModuleFile *, 4> victimSet(
239 (llvm::pointer_iterator<ModuleIterator>(First)),
240 (llvm::pointer_iterator<ModuleIterator>(Last)));
241
242 auto IsVictim = [&](ModuleFile *MF) {
243 return victimSet.count(MF);
244 };
245 // Remove any references to the now-destroyed modules.
246 for (auto I = begin(); I != First; ++I) {
247 I->Imports.remove_if(IsVictim);
248 I->ImportedBy.remove_if(IsVictim);
249 }
250 Roots.erase(std::remove_if(Roots.begin(), Roots.end(), IsVictim),
251 Roots.end());
252
253 // Remove the modules from the PCH chain.
254 for (auto I = First; I != Last; ++I) {
255 if (!I->isModule()) {
256 PCHChain.erase(llvm::find(PCHChain, &*I), PCHChain.end());
257 break;
258 }
259 }
260
261 // Delete the modules and erase them from the various structures.
262 for (ModuleIterator victim = First; victim != Last; ++victim) {
263 Modules.erase(victim->File);
264
265 if (modMap) {
266 StringRef ModuleName = victim->ModuleName;
267 if (Module *mod = modMap->findModule(ModuleName)) {
268 mod->setASTFile(nullptr);
269 }
270 }
271 }
272
273 // Delete the modules.
274 Chain.erase(Chain.begin() + (First - begin()), Chain.end());
275}
276
277void
278ModuleManager::addInMemoryBuffer(StringRef FileName,
279 std::unique_ptr<llvm::MemoryBuffer> Buffer) {
280 const FileEntry *Entry =
281 FileMgr.getVirtualFile(FileName, Buffer->getBufferSize(), 0);
282 InMemoryBuffers[Entry] = std::move(Buffer);
283}
284
285ModuleManager::VisitState *ModuleManager::allocateVisitState() {
286 // Fast path: if we have a cached state, use it.
287 if (FirstVisitState) {
288 VisitState *Result = FirstVisitState;
289 FirstVisitState = FirstVisitState->NextState;
290 Result->NextState = nullptr;
291 return Result;
292 }
293
294 // Allocate and return a new state.
295 return new VisitState(size());
296}
297
298void ModuleManager::returnVisitState(VisitState *State) {
299 assert(State->NextState == nullptr && "Visited state is in list?")((State->NextState == nullptr && "Visited state is in list?"
) ? static_cast<void> (0) : __assert_fail ("State->NextState == nullptr && \"Visited state is in list?\""
, "/build/llvm-toolchain-snapshot-12~++20200902111123+4820af2bfc7/clang/lib/Serialization/ModuleManager.cpp"
, 299, __PRETTY_FUNCTION__))
;
300 State->NextState = FirstVisitState;
301 FirstVisitState = State;
302}
303
304void ModuleManager::setGlobalIndex(GlobalModuleIndex *Index) {
305 GlobalIndex = Index;
306 if (!GlobalIndex) {
307 ModulesInCommonWithGlobalIndex.clear();
308 return;
309 }
310
311 // Notify the global module index about all of the modules we've already
312 // loaded.
313 for (ModuleFile &M : *this)
314 if (!GlobalIndex->loadedModuleFile(&M))
315 ModulesInCommonWithGlobalIndex.push_back(&M);
316}
317
318void ModuleManager::moduleFileAccepted(ModuleFile *MF) {
319 if (!GlobalIndex || GlobalIndex->loadedModuleFile(MF))
320 return;
321
322 ModulesInCommonWithGlobalIndex.push_back(MF);
323}
324
325ModuleManager::ModuleManager(FileManager &FileMgr,
326 InMemoryModuleCache &ModuleCache,
327 const PCHContainerReader &PCHContainerRdr,
328 const HeaderSearch &HeaderSearchInfo)
329 : FileMgr(FileMgr), ModuleCache(&ModuleCache),
330 PCHContainerRdr(PCHContainerRdr), HeaderSearchInfo(HeaderSearchInfo) {}
331
332ModuleManager::~ModuleManager() { delete FirstVisitState; }
333
334void ModuleManager::visit(llvm::function_ref<bool(ModuleFile &M)> Visitor,
335 llvm::SmallPtrSetImpl<ModuleFile *> *ModuleFilesHit) {
336 // If the visitation order vector is the wrong size, recompute the order.
337 if (VisitOrder.size() != Chain.size()) {
338 unsigned N = size();
339 VisitOrder.clear();
340 VisitOrder.reserve(N);
341
342 // Record the number of incoming edges for each module. When we
343 // encounter a module with no incoming edges, push it into the queue
344 // to seed the queue.
345 SmallVector<ModuleFile *, 4> Queue;
346 Queue.reserve(N);
347 llvm::SmallVector<unsigned, 4> UnusedIncomingEdges;
348 UnusedIncomingEdges.resize(size());
349 for (ModuleFile &M : llvm::reverse(*this)) {
350 unsigned Size = M.ImportedBy.size();
351 UnusedIncomingEdges[M.Index] = Size;
352 if (!Size)
353 Queue.push_back(&M);
354 }
355
356 // Traverse the graph, making sure to visit a module before visiting any
357 // of its dependencies.
358 while (!Queue.empty()) {
359 ModuleFile *CurrentModule = Queue.pop_back_val();
360 VisitOrder.push_back(CurrentModule);
361
362 // For any module that this module depends on, push it on the
363 // stack (if it hasn't already been marked as visited).
364 for (auto M = CurrentModule->Imports.rbegin(),
365 MEnd = CurrentModule->Imports.rend();
366 M != MEnd; ++M) {
367 // Remove our current module as an impediment to visiting the
368 // module we depend on. If we were the last unvisited module
369 // that depends on this particular module, push it into the
370 // queue to be visited.
371 unsigned &NumUnusedEdges = UnusedIncomingEdges[(*M)->Index];
372 if (NumUnusedEdges && (--NumUnusedEdges == 0))
373 Queue.push_back(*M);
374 }
375 }
376
377 assert(VisitOrder.size() == N && "Visitation order is wrong?")((VisitOrder.size() == N && "Visitation order is wrong?"
) ? static_cast<void> (0) : __assert_fail ("VisitOrder.size() == N && \"Visitation order is wrong?\""
, "/build/llvm-toolchain-snapshot-12~++20200902111123+4820af2bfc7/clang/lib/Serialization/ModuleManager.cpp"
, 377, __PRETTY_FUNCTION__))
;
378
379 delete FirstVisitState;
380 FirstVisitState = nullptr;
381 }
382
383 VisitState *State = allocateVisitState();
384 unsigned VisitNumber = State->NextVisitNumber++;
385
386 // If the caller has provided us with a hit-set that came from the global
387 // module index, mark every module file in common with the global module
388 // index that is *not* in that set as 'visited'.
389 if (ModuleFilesHit && !ModulesInCommonWithGlobalIndex.empty()) {
390 for (unsigned I = 0, N = ModulesInCommonWithGlobalIndex.size(); I != N; ++I)
391 {
392 ModuleFile *M = ModulesInCommonWithGlobalIndex[I];
393 if (!ModuleFilesHit->count(M))
394 State->VisitNumber[M->Index] = VisitNumber;
395 }
396 }
397
398 for (unsigned I = 0, N = VisitOrder.size(); I != N; ++I) {
399 ModuleFile *CurrentModule = VisitOrder[I];
400 // Should we skip this module file?
401 if (State->VisitNumber[CurrentModule->Index] == VisitNumber)
402 continue;
403
404 // Visit the module.
405 assert(State->VisitNumber[CurrentModule->Index] == VisitNumber - 1)((State->VisitNumber[CurrentModule->Index] == VisitNumber
- 1) ? static_cast<void> (0) : __assert_fail ("State->VisitNumber[CurrentModule->Index] == VisitNumber - 1"
, "/build/llvm-toolchain-snapshot-12~++20200902111123+4820af2bfc7/clang/lib/Serialization/ModuleManager.cpp"
, 405, __PRETTY_FUNCTION__))
;
406 State->VisitNumber[CurrentModule->Index] = VisitNumber;
407 if (!Visitor(*CurrentModule))
408 continue;
409
410 // The visitor has requested that cut off visitation of any
411 // module that the current module depends on. To indicate this
412 // behavior, we mark all of the reachable modules as having been visited.
413 ModuleFile *NextModule = CurrentModule;
414 do {
415 // For any module that this module depends on, push it on the
416 // stack (if it hasn't already been marked as visited).
417 for (llvm::SetVector<ModuleFile *>::iterator
418 M = NextModule->Imports.begin(),
419 MEnd = NextModule->Imports.end();
420 M != MEnd; ++M) {
421 if (State->VisitNumber[(*M)->Index] != VisitNumber) {
422 State->Stack.push_back(*M);
423 State->VisitNumber[(*M)->Index] = VisitNumber;
424 }
425 }
426
427 if (State->Stack.empty())
428 break;
429
430 // Pop the next module off the stack.
431 NextModule = State->Stack.pop_back_val();
432 } while (true);
433 }
434
435 returnVisitState(State);
436}
437
438bool ModuleManager::lookupModuleFile(StringRef FileName,
439 off_t ExpectedSize,
440 time_t ExpectedModTime,
441 const FileEntry *&File) {
442 if (FileName == "-") {
5
Assuming the condition is true
6
Taking true branch
443 File = nullptr;
7
Null pointer value stored to 'Entry'
444 return false;
8
Returning zero, which participates in a condition later
445 }
446
447 // Open the file immediately to ensure there is no race between stat'ing and
448 // opening the file.
449 auto FileOrErr = FileMgr.getFile(FileName, /*OpenFile=*/true,
450 /*CacheFailure=*/false);
451 if (!FileOrErr) {
452 File = nullptr;
453 return false;
454 }
455 File = *FileOrErr;
456
457 if ((ExpectedSize && ExpectedSize != File->getSize()) ||
458 (ExpectedModTime && ExpectedModTime != File->getModificationTime()))
459 // Do not destroy File, as it may be referenced. If we need to rebuild it,
460 // it will be destroyed by removeModules.
461 return true;
462
463 return false;
464}
465
466#ifndef NDEBUG
467namespace llvm {
468
469 template<>
470 struct GraphTraits<ModuleManager> {
471 using NodeRef = ModuleFile *;
472 using ChildIteratorType = llvm::SetVector<ModuleFile *>::const_iterator;
473 using nodes_iterator = pointer_iterator<ModuleManager::ModuleConstIterator>;
474
475 static ChildIteratorType child_begin(NodeRef Node) {
476 return Node->Imports.begin();
477 }
478
479 static ChildIteratorType child_end(NodeRef Node) {
480 return Node->Imports.end();
481 }
482
483 static nodes_iterator nodes_begin(const ModuleManager &Manager) {
484 return nodes_iterator(Manager.begin());
485 }
486
487 static nodes_iterator nodes_end(const ModuleManager &Manager) {
488 return nodes_iterator(Manager.end());
489 }
490 };
491
492 template<>
493 struct DOTGraphTraits<ModuleManager> : public DefaultDOTGraphTraits {
494 explicit DOTGraphTraits(bool IsSimple = false)
495 : DefaultDOTGraphTraits(IsSimple) {}
496
497 static bool renderGraphFromBottomUp() { return true; }
498
499 std::string getNodeLabel(ModuleFile *M, const ModuleManager&) {
500 return M->ModuleName;
501 }
502 };
503
504} // namespace llvm
505
506void ModuleManager::viewGraph() {
507 llvm::ViewGraph(*this, "Modules");
508}
509#endif

/usr/lib/gcc/x86_64-linux-gnu/6.3.0/../../../../include/c++/6.3.0/bits/unique_ptr.h

1// unique_ptr implementation -*- C++ -*-
2
3// Copyright (C) 2008-2016 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/unique_ptr.h
26 * This is an internal header file, included by other library headers.
27 * Do not attempt to use it directly. @headername{memory}
28 */
29
30#ifndef _UNIQUE_PTR_H1
31#define _UNIQUE_PTR_H1 1
32
33#include <bits/c++config.h>
34#include <debug/assertions.h>
35#include <type_traits>
36#include <utility>
37#include <tuple>
38
39namespace std _GLIBCXX_VISIBILITY(default)__attribute__ ((__visibility__ ("default")))
40{
41_GLIBCXX_BEGIN_NAMESPACE_VERSION
42
43 /**
44 * @addtogroup pointer_abstractions
45 * @{
46 */
47
48#if _GLIBCXX_USE_DEPRECATED1
49 template<typename> class auto_ptr;
50#endif
51
52 /// Primary template of default_delete, used by unique_ptr
53 template<typename _Tp>
54 struct default_delete
55 {
56 /// Default constructor
57 constexpr default_delete() noexcept = default;
58
59 /** @brief Converting constructor.
60 *
61 * Allows conversion from a deleter for arrays of another type, @p _Up,
62 * only if @p _Up* is convertible to @p _Tp*.
63 */
64 template<typename _Up, typename = typename
65 enable_if<is_convertible<_Up*, _Tp*>::value>::type>
66 default_delete(const default_delete<_Up>&) noexcept { }
67
68 /// Calls @c delete @p __ptr
69 void
70 operator()(_Tp* __ptr) const
71 {
72 static_assert(!is_void<_Tp>::value,
73 "can't delete pointer to incomplete type");
74 static_assert(sizeof(_Tp)>0,
75 "can't delete pointer to incomplete type");
76 delete __ptr;
77 }
78 };
79
80 // _GLIBCXX_RESOLVE_LIB_DEFECTS
81 // DR 740 - omit specialization for array objects with a compile time length
82 /// Specialization for arrays, default_delete.
83 template<typename _Tp>
84 struct default_delete<_Tp[]>
85 {
86 public:
87 /// Default constructor
88 constexpr default_delete() noexcept = default;
89
90 /** @brief Converting constructor.
91 *
92 * Allows conversion from a deleter for arrays of another type, such as
93 * a const-qualified version of @p _Tp.
94 *
95 * Conversions from types derived from @c _Tp are not allowed because
96 * it is unsafe to @c delete[] an array of derived types through a
97 * pointer to the base type.
98 */
99 template<typename _Up, typename = typename
100 enable_if<is_convertible<_Up(*)[], _Tp(*)[]>::value>::type>
101 default_delete(const default_delete<_Up[]>&) noexcept { }
102
103 /// Calls @c delete[] @p __ptr
104 template<typename _Up>
105 typename enable_if<is_convertible<_Up(*)[], _Tp(*)[]>::value>::type
106 operator()(_Up* __ptr) const
107 {
108 static_assert(sizeof(_Tp)>0,
109 "can't delete pointer to incomplete type");
110 delete [] __ptr;
111 }
112 };
113
114 /// 20.7.1.2 unique_ptr for single objects.
115 template <typename _Tp, typename _Dp = default_delete<_Tp> >
116 class unique_ptr
117 {
118 // use SFINAE to determine whether _Del::pointer exists
119 class _Pointer
120 {
121 template<typename _Up>
122 static typename _Up::pointer __test(typename _Up::pointer*);
123
124 template<typename _Up>
125 static _Tp* __test(...);
126
127 typedef typename remove_reference<_Dp>::type _Del;
128
129 public:
130 typedef decltype(__test<_Del>(0)) type;
131 };
132
133 typedef std::tuple<typename _Pointer::type, _Dp> __tuple_type;
134 __tuple_type _M_t;
135
136 public:
137 typedef typename _Pointer::type pointer;
138 typedef _Tp element_type;
139 typedef _Dp deleter_type;
140
141
142 // helper template for detecting a safe conversion from another
143 // unique_ptr
144 template<typename _Up, typename _Ep>
145 using __safe_conversion_up = __and_<
146 is_convertible<typename unique_ptr<_Up, _Ep>::pointer, pointer>,
147 __not_<is_array<_Up>>,
148 __or_<__and_<is_reference<deleter_type>,
149 is_same<deleter_type, _Ep>>,
150 __and_<__not_<is_reference<deleter_type>>,
151 is_convertible<_Ep, deleter_type>>
152 >
153 >;
154
155 // Constructors.
156
157 /// Default constructor, creates a unique_ptr that owns nothing.
158 constexpr unique_ptr() noexcept
159 : _M_t()
160 { static_assert(!is_pointer<deleter_type>::value,
161 "constructed with null function pointer deleter"); }
162
163 /** Takes ownership of a pointer.
164 *
165 * @param __p A pointer to an object of @c element_type
166 *
167 * The deleter will be value-initialized.
168 */
169 explicit
170 unique_ptr(pointer __p) noexcept
171 : _M_t()
172 {
173 std::get<0>(_M_t) = __p;
174 static_assert(!is_pointer<deleter_type>::value,
175 "constructed with null function pointer deleter");
176 }
177
178 /** Takes ownership of a pointer.
179 *
180 * @param __p A pointer to an object of @c element_type
181 * @param __d A reference to a deleter.
182 *
183 * The deleter will be initialized with @p __d
184 */
185 unique_ptr(pointer __p,
186 typename conditional<is_reference<deleter_type>::value,
187 deleter_type, const deleter_type&>::type __d) noexcept
188 : _M_t(__p, __d) { }
189
190 /** Takes ownership of a pointer.
191 *
192 * @param __p A pointer to an object of @c element_type
193 * @param __d An rvalue reference to a deleter.
194 *
195 * The deleter will be initialized with @p std::move(__d)
196 */
197 unique_ptr(pointer __p,
198 typename remove_reference<deleter_type>::type&& __d) noexcept
199 : _M_t(std::move(__p), std::move(__d))
200 { static_assert(!std::is_reference<deleter_type>::value,
201 "rvalue deleter bound to reference"); }
202
203 /// Creates a unique_ptr that owns nothing.
204 constexpr unique_ptr(nullptr_t) noexcept : unique_ptr() { }
205
206 // Move constructors.
207
208 /// Move constructor.
209 unique_ptr(unique_ptr&& __u) noexcept
210 : _M_t(__u.release(), std::forward<deleter_type>(__u.get_deleter())) { }
211
212 /** @brief Converting constructor from another type
213 *
214 * Requires that the pointer owned by @p __u is convertible to the
215 * type of pointer owned by this object, @p __u does not own an array,
216 * and @p __u has a compatible deleter type.
217 */
218 template<typename _Up, typename _Ep, typename = _Require<
219 __safe_conversion_up<_Up, _Ep>,
220 typename conditional<is_reference<_Dp>::value,
221 is_same<_Ep, _Dp>,
222 is_convertible<_Ep, _Dp>>::type>>
223 unique_ptr(unique_ptr<_Up, _Ep>&& __u) noexcept
224 : _M_t(__u.release(), std::forward<_Ep>(__u.get_deleter()))
225 { }
226
227#if _GLIBCXX_USE_DEPRECATED1
228 /// Converting constructor from @c auto_ptr
229 template<typename _Up, typename = _Require<
230 is_convertible<_Up*, _Tp*>, is_same<_Dp, default_delete<_Tp>>>>
231 unique_ptr(auto_ptr<_Up>&& __u) noexcept;
232#endif
233
234 /// Destructor, invokes the deleter if the stored pointer is not null.
235 ~unique_ptr() noexcept
236 {
237 auto& __ptr = std::get<0>(_M_t);
238 if (__ptr != nullptr)
239 get_deleter()(__ptr);
240 __ptr = pointer();
241 }
242
243 // Assignment.
244
245 /** @brief Move assignment operator.
246 *
247 * @param __u The object to transfer ownership from.
248 *
249 * Invokes the deleter first if this object owns a pointer.
250 */
251 unique_ptr&
252 operator=(unique_ptr&& __u) noexcept
253 {
254 reset(__u.release());
255 get_deleter() = std::forward<deleter_type>(__u.get_deleter());
256 return *this;
257 }
258
259 /** @brief Assignment from another type.
260 *
261 * @param __u The object to transfer ownership from, which owns a
262 * convertible pointer to a non-array object.
263 *
264 * Invokes the deleter first if this object owns a pointer.
265 */
266 template<typename _Up, typename _Ep>
267 typename enable_if< __and_<
268 __safe_conversion_up<_Up, _Ep>,
269 is_assignable<deleter_type&, _Ep&&>
270 >::value,
271 unique_ptr&>::type
272 operator=(unique_ptr<_Up, _Ep>&& __u) noexcept
273 {
274 reset(__u.release());
275 get_deleter() = std::forward<_Ep>(__u.get_deleter());
276 return *this;
277 }
278
279 /// Reset the %unique_ptr to empty, invoking the deleter if necessary.
280 unique_ptr&
281 operator=(nullptr_t) noexcept
282 {
283 reset();
284 return *this;
285 }
286
287 // Observers.
288
289 /// Dereference the stored pointer.
290 typename add_lvalue_reference<element_type>::type
291 operator*() const
292 {
293 __glibcxx_assert(get() != pointer());
294 return *get();
295 }
296
297 /// Return the stored pointer.
298 pointer
299 operator->() const noexcept
300 {
301 _GLIBCXX_DEBUG_PEDASSERT(get() != pointer());
302 return get();
303 }
304
305 /// Return the stored pointer.
306 pointer
307 get() const noexcept
308 { return std::get<0>(_M_t); }
309
310 /// Return a reference to the stored deleter.
311 deleter_type&
312 get_deleter() noexcept
313 { return std::get<1>(_M_t); }
314
315 /// Return a reference to the stored deleter.
316 const deleter_type&
317 get_deleter() const noexcept
318 { return std::get<1>(_M_t); }
319
320 /// Return @c true if the stored pointer is not null.
321 explicit operator bool() const noexcept
322 { return get() == pointer() ? false : true; }
17
'?' condition is true
18
Returning zero, which participates in a condition later
323
324 // Modifiers.
325
326 /// Release ownership of any stored pointer.
327 pointer
328 release() noexcept
329 {
330 pointer __p = get();
331 std::get<0>(_M_t) = pointer();
332 return __p;
333 }
334
335 /** @brief Replace the stored pointer.
336 *
337 * @param __p The new pointer to store.
338 *
339 * The deleter will be invoked if a pointer is already owned.
340 */
341 void
342 reset(pointer __p = pointer()) noexcept
343 {
344 using std::swap;
345 swap(std::get<0>(_M_t), __p);
346 if (__p != pointer())
347 get_deleter()(__p);
348 }
349
350 /// Exchange the pointer and deleter with another object.
351 void
352 swap(unique_ptr& __u) noexcept
353 {
354 using std::swap;
355 swap(_M_t, __u._M_t);
356 }
357
358 // Disable copy from lvalue.
359 unique_ptr(const unique_ptr&) = delete;
360 unique_ptr& operator=(const unique_ptr&) = delete;
361 };
362
363 /// 20.7.1.3 unique_ptr for array objects with a runtime length
364 // [unique.ptr.runtime]
365 // _GLIBCXX_RESOLVE_LIB_DEFECTS
366 // DR 740 - omit specialization for array objects with a compile time length
367 template<typename _Tp, typename _Dp>
368 class unique_ptr<_Tp[], _Dp>
369 {
370 // use SFINAE to determine whether _Del::pointer exists
371 class _Pointer
372 {
373 template<typename _Up>
374 static typename _Up::pointer __test(typename _Up::pointer*);
375
376 template<typename _Up>
377 static _Tp* __test(...);
378
379 typedef typename remove_reference<_Dp>::type _Del;
380
381 public:
382 typedef decltype(__test<_Del>(0)) type;
383 };
384
385 typedef std::tuple<typename _Pointer::type, _Dp> __tuple_type;
386 __tuple_type _M_t;
387
388 template<typename _Up>
389 using __remove_cv = typename remove_cv<_Up>::type;
390
391 // like is_base_of<_Tp, _Up> but false if unqualified types are the same
392 template<typename _Up>
393 using __is_derived_Tp
394 = __and_< is_base_of<_Tp, _Up>,
395 __not_<is_same<__remove_cv<_Tp>, __remove_cv<_Up>>> >;
396
397
398 public:
399 typedef typename _Pointer::type pointer;
400 typedef _Tp element_type;
401 typedef _Dp deleter_type;
402
403 // helper template for detecting a safe conversion from another
404 // unique_ptr
405 template<typename _Up, typename _Ep,
406 typename _Up_up = unique_ptr<_Up, _Ep>,
407 typename _Up_element_type = typename _Up_up::element_type>
408 using __safe_conversion_up = __and_<
409 is_array<_Up>,
410 is_same<pointer, element_type*>,
411 is_same<typename _Up_up::pointer, _Up_element_type*>,
412 is_convertible<_Up_element_type(*)[], element_type(*)[]>,
413 __or_<__and_<is_reference<deleter_type>, is_same<deleter_type, _Ep>>,
414 __and_<__not_<is_reference<deleter_type>>,
415 is_convertible<_Ep, deleter_type>>>
416 >;
417
418 // helper template for detecting a safe conversion from a raw pointer
419 template<typename _Up>
420 using __safe_conversion_raw = __and_<
421 __or_<__or_<is_same<_Up, pointer>,
422 is_same<_Up, nullptr_t>>,
423 __and_<is_pointer<_Up>,
424 is_same<pointer, element_type*>,
425 is_convertible<
426 typename remove_pointer<_Up>::type(*)[],
427 element_type(*)[]>
428 >
429 >
430 >;
431
432 // Constructors.
433
434 /// Default constructor, creates a unique_ptr that owns nothing.
435 constexpr unique_ptr() noexcept
436 : _M_t()
437 { static_assert(!std::is_pointer<deleter_type>::value,
438 "constructed with null function pointer deleter"); }
439
440 /** Takes ownership of a pointer.
441 *
442 * @param __p A pointer to an array of a type safely convertible
443 * to an array of @c element_type
444 *
445 * The deleter will be value-initialized.
446 */
447 template<typename _Up,
448 typename = typename enable_if<
449 __safe_conversion_raw<_Up>::value, bool>::type>
450 explicit
451 unique_ptr(_Up __p) noexcept
452 : _M_t(__p, deleter_type())
453 { static_assert(!is_pointer<deleter_type>::value,
454 "constructed with null function pointer deleter"); }
455
456 /** Takes ownership of a pointer.
457 *
458 * @param __p A pointer to an array of a type safely convertible
459 * to an array of @c element_type
460 * @param __d A reference to a deleter.
461 *
462 * The deleter will be initialized with @p __d
463 */
464 template<typename _Up,
465 typename = typename enable_if<
466 __safe_conversion_raw<_Up>::value, bool>::type>
467 unique_ptr(_Up __p,
468 typename conditional<is_reference<deleter_type>::value,
469 deleter_type, const deleter_type&>::type __d) noexcept
470 : _M_t(__p, __d) { }
471
472 /** Takes ownership of a pointer.
473 *
474 * @param __p A pointer to an array of a type safely convertible
475 * to an array of @c element_type
476 * @param __d A reference to a deleter.
477 *
478 * The deleter will be initialized with @p std::move(__d)
479 */
480 template<typename _Up,
481 typename = typename enable_if<
482 __safe_conversion_raw<_Up>::value, bool>::type>
483 unique_ptr(_Up __p, typename
484 remove_reference<deleter_type>::type&& __d) noexcept
485 : _M_t(std::move(__p), std::move(__d))
486 { static_assert(!is_reference<deleter_type>::value,
487 "rvalue deleter bound to reference"); }
488
489 /// Move constructor.
490 unique_ptr(unique_ptr&& __u) noexcept
491 : _M_t(__u.release(), std::forward<deleter_type>(__u.get_deleter())) { }
492
493 /// Creates a unique_ptr that owns nothing.
494 constexpr unique_ptr(nullptr_t) noexcept : unique_ptr() { }
495
496 template<typename _Up, typename _Ep,
497 typename = _Require<__safe_conversion_up<_Up, _Ep>>>
498 unique_ptr(unique_ptr<_Up, _Ep>&& __u) noexcept
499 : _M_t(__u.release(), std::forward<_Ep>(__u.get_deleter()))
500 { }
501
502 /// Destructor, invokes the deleter if the stored pointer is not null.
503 ~unique_ptr()
504 {
505 auto& __ptr = std::get<0>(_M_t);
506 if (__ptr != nullptr)
507 get_deleter()(__ptr);
508 __ptr = pointer();
509 }
510
511 // Assignment.
512
513 /** @brief Move assignment operator.
514 *
515 * @param __u The object to transfer ownership from.
516 *
517 * Invokes the deleter first if this object owns a pointer.
518 */
519 unique_ptr&
520 operator=(unique_ptr&& __u) noexcept
521 {
522 reset(__u.release());
523 get_deleter() = std::forward<deleter_type>(__u.get_deleter());
524 return *this;
525 }
526
527 /** @brief Assignment from another type.
528 *
529 * @param __u The object to transfer ownership from, which owns a
530 * convertible pointer to an array object.
531 *
532 * Invokes the deleter first if this object owns a pointer.
533 */
534 template<typename _Up, typename _Ep>
535 typename
536 enable_if<__and_<__safe_conversion_up<_Up, _Ep>,
537 is_assignable<deleter_type&, _Ep&&>
538 >::value,
539 unique_ptr&>::type
540 operator=(unique_ptr<_Up, _Ep>&& __u) noexcept
541 {
542 reset(__u.release());
543 get_deleter() = std::forward<_Ep>(__u.get_deleter());
544 return *this;
545 }
546
547 /// Reset the %unique_ptr to empty, invoking the deleter if necessary.
548 unique_ptr&
549 operator=(nullptr_t) noexcept
550 {
551 reset();
552 return *this;
553 }
554
555 // Observers.
556
557 /// Access an element of owned array.
558 typename std::add_lvalue_reference<element_type>::type
559 operator[](size_t __i) const
560 {
561 __glibcxx_assert(get() != pointer());
562 return get()[__i];
563 }
564
565 /// Return the stored pointer.
566 pointer
567 get() const noexcept
568 { return std::get<0>(_M_t); }
569
570 /// Return a reference to the stored deleter.
571 deleter_type&
572 get_deleter() noexcept
573 { return std::get<1>(_M_t); }
574
575 /// Return a reference to the stored deleter.
576 const deleter_type&
577 get_deleter() const noexcept
578 { return std::get<1>(_M_t); }
579
580 /// Return @c true if the stored pointer is not null.
581 explicit operator bool() const noexcept
582 { return get() == pointer() ? false : true; }
583
584 // Modifiers.
585
586 /// Release ownership of any stored pointer.
587 pointer
588 release() noexcept
589 {
590 pointer __p = get();
591 std::get<0>(_M_t) = pointer();
592 return __p;
593 }
594
595 /** @brief Replace the stored pointer.
596 *
597 * @param __p The new pointer to store.
598 *
599 * The deleter will be invoked if a pointer is already owned.
600 */
601 template <typename _Up,
602 typename = _Require<
603 __or_<is_same<_Up, pointer>,
604 __and_<is_same<pointer, element_type*>,
605 is_pointer<_Up>,
606 is_convertible<
607 typename remove_pointer<_Up>::type(*)[],
608 element_type(*)[]
609 >
610 >
611 >
612 >>
613 void
614 reset(_Up __p) noexcept
615 {
616 pointer __ptr = __p;
617 using std::swap;
618 swap(std::get<0>(_M_t), __ptr);
619 if (__ptr != nullptr)
620 get_deleter()(__ptr);
621 }
622
623 void reset(nullptr_t = nullptr) noexcept
624 {
625 reset(pointer());
626 }
627
628 /// Exchange the pointer and deleter with another object.
629 void
630 swap(unique_ptr& __u) noexcept
631 {
632 using std::swap;
633 swap(_M_t, __u._M_t);
634 }
635
636 // Disable copy from lvalue.
637 unique_ptr(const unique_ptr&) = delete;
638 unique_ptr& operator=(const unique_ptr&) = delete;
639 };
640
641 template<typename _Tp, typename _Dp>
642 inline void
643 swap(unique_ptr<_Tp, _Dp>& __x,
644 unique_ptr<_Tp, _Dp>& __y) noexcept
645 { __x.swap(__y); }
646
647 template<typename _Tp, typename _Dp,
648 typename _Up, typename _Ep>
649 inline bool
650 operator==(const unique_ptr<_Tp, _Dp>& __x,
651 const unique_ptr<_Up, _Ep>& __y)
652 { return __x.get() == __y.get(); }
653
654 template<typename _Tp, typename _Dp>
655 inline bool
656 operator==(const unique_ptr<_Tp, _Dp>& __x, nullptr_t) noexcept
657 { return !__x; }
658
659 template<typename _Tp, typename _Dp>
660 inline bool
661 operator==(nullptr_t, const unique_ptr<_Tp, _Dp>& __x) noexcept
662 { return !__x; }
663
664 template<typename _Tp, typename _Dp,
665 typename _Up, typename _Ep>
666 inline bool
667 operator!=(const unique_ptr<_Tp, _Dp>& __x,
668 const unique_ptr<_Up, _Ep>& __y)
669 { return __x.get() != __y.get(); }
670
671 template<typename _Tp, typename _Dp>
672 inline bool
673 operator!=(const unique_ptr<_Tp, _Dp>& __x, nullptr_t) noexcept
674 { return (bool)__x; }
675
676 template<typename _Tp, typename _Dp>
677 inline bool
678 operator!=(nullptr_t, const unique_ptr<_Tp, _Dp>& __x) noexcept
679 { return (bool)__x; }
680
681 template<typename _Tp, typename _Dp,
682 typename _Up, typename _Ep>
683 inline bool
684 operator<(const unique_ptr<_Tp, _Dp>& __x,
685 const unique_ptr<_Up, _Ep>& __y)
686 {
687 typedef typename
688 std::common_type<typename unique_ptr<_Tp, _Dp>::pointer,
689 typename unique_ptr<_Up, _Ep>::pointer>::type _CT;
690 return std::less<_CT>()(__x.get(), __y.get());
691 }
692
693 template<typename _Tp, typename _Dp>
694 inline bool
695 operator<(const unique_ptr<_Tp, _Dp>& __x, nullptr_t)
696 { return std::less<typename unique_ptr<_Tp, _Dp>::pointer>()(__x.get(),
697 nullptr); }
698
699 template<typename _Tp, typename _Dp>
700 inline bool
701 operator<(nullptr_t, const unique_ptr<_Tp, _Dp>& __x)
702 { return std::less<typename unique_ptr<_Tp, _Dp>::pointer>()(nullptr,
703 __x.get()); }
704
705 template<typename _Tp, typename _Dp,
706 typename _Up, typename _Ep>
707 inline bool
708 operator<=(const unique_ptr<_Tp, _Dp>& __x,
709 const unique_ptr<_Up, _Ep>& __y)
710 { return !(__y < __x); }
711
712 template<typename _Tp, typename _Dp>
713 inline bool
714 operator<=(const unique_ptr<_Tp, _Dp>& __x, nullptr_t)
715 { return !(nullptr < __x); }
716
717 template<typename _Tp, typename _Dp>
718 inline bool
719 operator<=(nullptr_t, const unique_ptr<_Tp, _Dp>& __x)
720 { return !(__x < nullptr); }
721
722 template<typename _Tp, typename _Dp,
723 typename _Up, typename _Ep>
724 inline bool
725 operator>(const unique_ptr<_Tp, _Dp>& __x,
726 const unique_ptr<_Up, _Ep>& __y)
727 { return (__y < __x); }
728
729 template<typename _Tp, typename _Dp>
730 inline bool
731 operator>(const unique_ptr<_Tp, _Dp>& __x, nullptr_t)
732 { return std::less<typename unique_ptr<_Tp, _Dp>::pointer>()(nullptr,
733 __x.get()); }
734
735 template<typename _Tp, typename _Dp>
736 inline bool
737 operator>(nullptr_t, const unique_ptr<_Tp, _Dp>& __x)
738 { return std::less<typename unique_ptr<_Tp, _Dp>::pointer>()(__x.get(),
739 nullptr); }
740
741 template<typename _Tp, typename _Dp,
742 typename _Up, typename _Ep>
743 inline bool
744 operator>=(const unique_ptr<_Tp, _Dp>& __x,
745 const unique_ptr<_Up, _Ep>& __y)
746 { return !(__x < __y); }
747
748 template<typename _Tp, typename _Dp>
749 inline bool
750 operator>=(const unique_ptr<_Tp, _Dp>& __x, nullptr_t)
751 { return !(__x < nullptr); }
752
753 template<typename _Tp, typename _Dp>
754 inline bool
755 operator>=(nullptr_t, const unique_ptr<_Tp, _Dp>& __x)
756 { return !(nullptr < __x); }
757
758 /// std::hash specialization for unique_ptr.
759 template<typename _Tp, typename _Dp>
760 struct hash<unique_ptr<_Tp, _Dp>>
761 : public __hash_base<size_t, unique_ptr<_Tp, _Dp>>
762 {
763 size_t
764 operator()(const unique_ptr<_Tp, _Dp>& __u) const noexcept
765 {
766 typedef unique_ptr<_Tp, _Dp> _UP;
767 return std::hash<typename _UP::pointer>()(__u.get());
768 }
769 };
770
771#if __cplusplus201402L > 201103L
772
773#define __cpp_lib_make_unique201304 201304
774
775 template<typename _Tp>
776 struct _MakeUniq
777 { typedef unique_ptr<_Tp> __single_object; };
778
779 template<typename _Tp>
780 struct _MakeUniq<_Tp[]>
781 { typedef unique_ptr<_Tp[]> __array; };
782
783 template<typename _Tp, size_t _Bound>
784 struct _MakeUniq<_Tp[_Bound]>
785 { struct __invalid_type { }; };
786
787 /// std::make_unique for single objects
788 template<typename _Tp, typename... _Args>
789 inline typename _MakeUniq<_Tp>::__single_object
790 make_unique(_Args&&... __args)
791 { return unique_ptr<_Tp>(new _Tp(std::forward<_Args>(__args)...)); }
792
793 /// std::make_unique for arrays of unknown bound
794 template<typename _Tp>
795 inline typename _MakeUniq<_Tp>::__array
796 make_unique(size_t __num)
797 { return unique_ptr<_Tp>(new remove_extent_t<_Tp>[__num]()); }
798
799 /// Disable std::make_unique for arrays of known bound
800 template<typename _Tp, typename... _Args>
801 inline typename _MakeUniq<_Tp>::__invalid_type
802 make_unique(_Args&&...) = delete;
803#endif
804
805 // @} group pointer_abstractions
806
807_GLIBCXX_END_NAMESPACE_VERSION
808} // namespace
809
810#endif /* _UNIQUE_PTR_H */