summaryrefslogtreecommitdiff
path: root/libcxxabi/src
diff options
context:
space:
mode:
authorNathan Sidwell <nathan@acm.org>2022-02-28 10:13:44 -0800
committerNathan Sidwell <nathan@acm.org>2022-10-17 04:23:16 -0700
commitd3b10150b683142a7481893ddffe9206e1d29f95 (patch)
treee35600e8395894be0a9070b631b9691219d10390 /libcxxabi/src
parent335f94bfef0e9a53a44de2f0a2a62b29e2c593e9 (diff)
downloadllvm-d3b10150b683142a7481893ddffe9206e1d29f95.tar.gz
[demangler] Simplify OutputBuffer initialization
Every non-testcase use of OutputBuffer contains code to allocate an initial buffer (using either 128 or 1024 as initial guesses). There's now no need to do that, given recent changes to the buffer extension heuristics -- it allocates a 1k(ish) buffer on first need. Just pass in a buffer (if any) to the constructor. Thus the OutputBuffer's ownership of the buffer starts at its own lifetime start. We can reduce the lifetime of this object in several cases. That new constructor takes a 'size_t *' for the size argument, as all uses with a non-null buffer are passing through a malloc'd buffer from their own caller in this manner. The buffer reset member function is never used, and is deleted. Some adjustment to a couple of uses is needed, due to the lazy buffer creation of this patch. a) the Microsoft demangler can demangle empty strings to nothing, which it then memoizes. We need to avoid the UB of passing nullptr to memcpy. b) a unit test checks insertion of no characters into an empty buffer. We need to avoid UB when converting that to std::string. The original buffer initialization code would return a failure code if that first malloc failed. Existing code either ignored that, called std::terminate with a FIXME, or returned an error code. But that's not foolproof anyway, as a subsequent buffer extension failure ends up calling std::terminate. I am working on addressing that unfortunate failure mode in a manner more consistent with the C++ ABI design. Reviewed By: dblaikie Differential Revision: https://reviews.llvm.org/D122604
Diffstat (limited to 'libcxxabi/src')
-rw-r--r--libcxxabi/src/cxa_demangle.cpp5
-rw-r--r--libcxxabi/src/demangle/Utility.h25
2 files changed, 4 insertions, 26 deletions
diff --git a/libcxxabi/src/cxa_demangle.cpp b/libcxxabi/src/cxa_demangle.cpp
index ddab6d33358a..7baac680074c 100644
--- a/libcxxabi/src/cxa_demangle.cpp
+++ b/libcxxabi/src/cxa_demangle.cpp
@@ -386,15 +386,12 @@ __cxa_demangle(const char *MangledName, char *Buf, size_t *N, int *Status) {
int InternalStatus = demangle_success;
Demangler Parser(MangledName, MangledName + std::strlen(MangledName));
- OutputBuffer O;
-
Node *AST = Parser.parse();
if (AST == nullptr)
InternalStatus = demangle_invalid_mangled_name;
- else if (!initializeOutputBuffer(Buf, N, O, 1024))
- InternalStatus = demangle_memory_alloc_failure;
else {
+ OutputBuffer O(Buf, N);
assert(Parser.ForwardTemplateRefs.empty());
AST->print(O);
O += '\0';
diff --git a/libcxxabi/src/demangle/Utility.h b/libcxxabi/src/demangle/Utility.h
index db19dcac0147..c9b211b5441a 100644
--- a/libcxxabi/src/demangle/Utility.h
+++ b/libcxxabi/src/demangle/Utility.h
@@ -69,7 +69,9 @@ class OutputBuffer {
public:
OutputBuffer(char *StartBuf, size_t Size)
- : Buffer(StartBuf), CurrentPosition(0), BufferCapacity(Size) {}
+ : Buffer(StartBuf), BufferCapacity(Size) {}
+ OutputBuffer(char *StartBuf, size_t *SizePtr)
+ : OutputBuffer(StartBuf, StartBuf ? *SizePtr : 0) {}
OutputBuffer() = default;
// Non-copyable
OutputBuffer(const OutputBuffer &) = delete;
@@ -77,12 +79,6 @@ public:
operator StringView() const { return StringView(Buffer, CurrentPosition); }
- void reset(char *Buffer_, size_t BufferCapacity_) {
- CurrentPosition = 0;
- Buffer = Buffer_;
- BufferCapacity = BufferCapacity_;
- }
-
/// If a ParameterPackExpansion (or similar type) is encountered, the offset
/// into the pack that we're currently printing.
unsigned CurrentPackIndex = std::numeric_limits<unsigned>::max();
@@ -198,21 +194,6 @@ public:
ScopedOverride &operator=(const ScopedOverride &) = delete;
};
-inline bool initializeOutputBuffer(char *Buf, size_t *N, OutputBuffer &OB,
- size_t InitSize) {
- size_t BufferSize;
- if (Buf == nullptr) {
- Buf = static_cast<char *>(std::malloc(InitSize));
- if (Buf == nullptr)
- return false;
- BufferSize = InitSize;
- } else
- BufferSize = *N;
-
- OB.reset(Buf, BufferSize);
- return true;
-}
-
DEMANGLE_NAMESPACE_END
#endif