diff --git a/libcxxabi/src/cxa_demangle.cpp b/libcxxabi/src/cxa_demangle.cpp --- a/libcxxabi/src/cxa_demangle.cpp +++ b/libcxxabi/src/cxa_demangle.cpp @@ -386,15 +386,12 @@ 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 --- a/libcxxabi/src/demangle/Utility.h +++ b/libcxxabi/src/demangle/Utility.h @@ -69,7 +69,9 @@ 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 @@ 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::max(); @@ -198,21 +194,6 @@ 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(std::malloc(InitSize)); - if (Buf == nullptr) - return false; - BufferSize = InitSize; - } else - BufferSize = *N; - - OB.reset(Buf, BufferSize); - return true; -} - DEMANGLE_NAMESPACE_END #endif diff --git a/llvm/include/llvm/Demangle/Utility.h b/llvm/include/llvm/Demangle/Utility.h --- a/llvm/include/llvm/Demangle/Utility.h +++ b/llvm/include/llvm/Demangle/Utility.h @@ -69,7 +69,9 @@ 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 @@ 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::max(); @@ -198,21 +194,6 @@ 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(std::malloc(InitSize)); - if (Buf == nullptr) - return false; - BufferSize = InitSize; - } else - BufferSize = *N; - - OB.reset(Buf, BufferSize); - return true; -} - DEMANGLE_NAMESPACE_END #endif diff --git a/llvm/lib/Demangle/DLangDemangle.cpp b/llvm/lib/Demangle/DLangDemangle.cpp --- a/llvm/lib/Demangle/DLangDemangle.cpp +++ b/llvm/lib/Demangle/DLangDemangle.cpp @@ -548,9 +548,6 @@ return nullptr; OutputBuffer Demangled; - if (!initializeOutputBuffer(nullptr, nullptr, Demangled, 1024)) - return nullptr; - if (strcmp(MangledName, "_Dmain") == 0) { Demangled << "D main"; } else { diff --git a/llvm/lib/Demangle/ItaniumDemangle.cpp b/llvm/lib/Demangle/ItaniumDemangle.cpp --- a/llvm/lib/Demangle/ItaniumDemangle.cpp +++ b/llvm/lib/Demangle/ItaniumDemangle.cpp @@ -375,15 +375,12 @@ int InternalStatus = demangle_success; Demangler Parser(MangledName, MangledName + std::strlen(MangledName)); - OutputBuffer OB; - Node *AST = Parser.parse(); if (AST == nullptr) InternalStatus = demangle_invalid_mangled_name; - else if (!initializeOutputBuffer(Buf, N, OB, 1024)) - InternalStatus = demangle_memory_alloc_failure; else { + OutputBuffer OB(Buf, N); assert(Parser.ForwardTemplateRefs.empty()); AST->print(OB); OB += '\0'; @@ -427,9 +424,7 @@ } static char *printNode(const Node *RootNode, char *Buf, size_t *N) { - OutputBuffer OB; - if (!initializeOutputBuffer(Buf, N, OB, 128)) - return nullptr; + OutputBuffer OB(Buf, N); RootNode->print(OB); OB += '\0'; if (N != nullptr) @@ -472,9 +467,7 @@ return nullptr; const Node *Name = static_cast(RootNode)->getName(); - OutputBuffer OB; - if (!initializeOutputBuffer(Buf, N, OB, 128)) - return nullptr; + OutputBuffer OB(Buf, N); KeepGoingLocalFunction: while (true) { @@ -525,9 +518,7 @@ return nullptr; NodeArray Params = static_cast(RootNode)->getParams(); - OutputBuffer OB; - if (!initializeOutputBuffer(Buf, N, OB, 128)) - return nullptr; + OutputBuffer OB(Buf, N); OB += '('; Params.printWithComma(OB); @@ -543,9 +534,7 @@ if (!isFunction()) return nullptr; - OutputBuffer OB; - if (!initializeOutputBuffer(Buf, N, OB, 128)) - return nullptr; + OutputBuffer OB(Buf, N); if (const Node *Ret = static_cast(RootNode)->getReturnType()) diff --git a/llvm/lib/Demangle/MicrosoftDemangle.cpp b/llvm/lib/Demangle/MicrosoftDemangle.cpp --- a/llvm/lib/Demangle/MicrosoftDemangle.cpp +++ b/llvm/lib/Demangle/MicrosoftDemangle.cpp @@ -246,7 +246,10 @@ StringView Demangler::copyString(StringView Borrowed) { char *Stable = Arena.allocUnalignedBuffer(Borrowed.size()); - std::memcpy(Stable, Borrowed.begin(), Borrowed.size()); + // This is not a micro-optimization, it avoids UB, should Borrowed be an null + // buffer. + if (Borrowed.size()) + std::memcpy(Stable, Borrowed.begin(), Borrowed.size()); return {Stable, Borrowed.size()}; } @@ -970,9 +973,6 @@ // Render this class template name into a string buffer so that we can // memorize it for the purpose of back-referencing. OutputBuffer OB; - if (!initializeOutputBuffer(nullptr, nullptr, OB, 1024)) - // FIXME: Propagate out-of-memory as an error? - std::terminate(); Identifier->output(OB, OF_Default); StringView Owned = copyString(OB); memorizeString(Owned); @@ -1283,11 +1283,6 @@ EncodedStringLiteralNode *Result = Arena.alloc(); - // Must happen before the first `goto StringLiteralError`. - if (!initializeOutputBuffer(nullptr, nullptr, OB, 1024)) - // FIXME: Propagate out-of-memory as an error? - std::terminate(); - // Prefix indicating the beginning of a string literal if (!MangledName.consumeFront("@_")) goto StringLiteralError; @@ -1446,9 +1441,6 @@ // Render the parent symbol's name into a buffer. OutputBuffer OB; - if (!initializeOutputBuffer(nullptr, nullptr, OB, 1024)) - // FIXME: Propagate out-of-memory as an error? - std::terminate(); OB << '`'; Scope->output(OB, OF_Default); OB << '\''; @@ -2311,8 +2303,6 @@ // Create an output stream so we can render each type. OutputBuffer OB; - if (!initializeOutputBuffer(nullptr, nullptr, OB, 1024)) - std::terminate(); for (size_t I = 0; I < Backrefs.FunctionParamCount; ++I) { OB.setCurrentPosition(0); @@ -2339,7 +2329,6 @@ char *Buf, size_t *N, int *Status, MSDemangleFlags Flags) { Demangler D; - OutputBuffer OB; StringView Name{MangledName}; SymbolNode *AST = D.parse(Name); @@ -2364,9 +2353,8 @@ int InternalStatus = demangle_success; if (D.Error) InternalStatus = demangle_invalid_mangled_name; - else if (!initializeOutputBuffer(Buf, N, OB, 1024)) - InternalStatus = demangle_memory_alloc_failure; else { + OutputBuffer OB(Buf, N); AST->output(OB, OF); OB += '\0'; if (N != nullptr) diff --git a/llvm/lib/Demangle/MicrosoftDemangleNodes.cpp b/llvm/lib/Demangle/MicrosoftDemangleNodes.cpp --- a/llvm/lib/Demangle/MicrosoftDemangleNodes.cpp +++ b/llvm/lib/Demangle/MicrosoftDemangleNodes.cpp @@ -119,7 +119,6 @@ std::string Node::toString(OutputFlags Flags) const { OutputBuffer OB; - initializeOutputBuffer(nullptr, nullptr, OB, 1024); this->output(OB, Flags); StringView SV = OB; std::string Owned(SV.begin(), SV.end()); diff --git a/llvm/lib/Demangle/RustDemangle.cpp b/llvm/lib/Demangle/RustDemangle.cpp --- a/llvm/lib/Demangle/RustDemangle.cpp +++ b/llvm/lib/Demangle/RustDemangle.cpp @@ -157,9 +157,6 @@ return nullptr; Demangler D; - if (!initializeOutputBuffer(nullptr, nullptr, D.Output, 1024)) - return nullptr; - if (!D.demangle(Mangled)) { std::free(D.Output.getBuffer()); return nullptr;