From aabeb5eb7f0aaa2c80147d904959c882cdeba1e5 Mon Sep 17 00:00:00 2001 From: Kirill Stoimenov Date: Tue, 26 Apr 2022 20:24:06 +0000 Subject: [PATCH] Revert "[demangler] Simplify OutputBuffer initialization" Reverting due to a bot failure: https://lab.llvm.org/buildbot/#/builders/5/builds/22738 This reverts commit 5b3ca24a35e91bf9c19af856e7f92c69b17f989e. --- libcxxabi/src/cxa_demangle.cpp | 5 +++- libcxxabi/src/demangle/Utility.h | 25 +++++++++++++++++--- llvm/include/llvm/Demangle/Utility.h | 25 +++++++++++++++++--- llvm/lib/Demangle/DLangDemangle.cpp | 3 +++ llvm/lib/Demangle/ItaniumDemangle.cpp | 21 ++++++++++++---- llvm/lib/Demangle/MicrosoftDemangle.cpp | 17 ++++++++++++- llvm/lib/Demangle/MicrosoftDemangleNodes.cpp | 1 + llvm/lib/Demangle/RustDemangle.cpp | 3 +++ 8 files changed, 87 insertions(+), 13 deletions(-) diff --git a/libcxxabi/src/cxa_demangle.cpp b/libcxxabi/src/cxa_demangle.cpp index 7baac680074c..ddab6d33358a 100644 --- a/libcxxabi/src/cxa_demangle.cpp +++ b/libcxxabi/src/cxa_demangle.cpp @@ -386,12 +386,15 @@ __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 00572880237a..6e0fa38632c8 100644 --- a/libcxxabi/src/demangle/Utility.h +++ b/libcxxabi/src/demangle/Utility.h @@ -69,9 +69,7 @@ class OutputBuffer { public: OutputBuffer(char *StartBuf, size_t Size) - : Buffer(StartBuf), BufferCapacity(Size) {} - OutputBuffer(char *StartBuf, size_t *SizePtr) - : OutputBuffer(StartBuf, StartBuf ? *SizePtr : 0) {} + : Buffer(StartBuf), CurrentPosition(0), BufferCapacity(Size) {} OutputBuffer() = default; // Non-copyable OutputBuffer(const OutputBuffer &) = delete; @@ -79,6 +77,12 @@ 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::max(); @@ -193,6 +197,21 @@ 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(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 index 7025469d0353..b17eadcfa3be 100644 --- a/llvm/include/llvm/Demangle/Utility.h +++ b/llvm/include/llvm/Demangle/Utility.h @@ -69,9 +69,7 @@ class OutputBuffer { public: OutputBuffer(char *StartBuf, size_t Size) - : Buffer(StartBuf), BufferCapacity(Size) {} - OutputBuffer(char *StartBuf, size_t *SizePtr) - : OutputBuffer(StartBuf, StartBuf ? *SizePtr : 0) {} + : Buffer(StartBuf), CurrentPosition(0), BufferCapacity(Size) {} OutputBuffer() = default; // Non-copyable OutputBuffer(const OutputBuffer &) = delete; @@ -79,6 +77,12 @@ 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::max(); @@ -193,6 +197,21 @@ 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(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 index b747b0f9cc67..7cecd8007087 100644 --- a/llvm/lib/Demangle/DLangDemangle.cpp +++ b/llvm/lib/Demangle/DLangDemangle.cpp @@ -548,6 +548,9 @@ char *llvm::dlangDemangle(const char *MangledName) { 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 index 9b646ea800aa..1c9209d8f369 100644 --- a/llvm/lib/Demangle/ItaniumDemangle.cpp +++ b/llvm/lib/Demangle/ItaniumDemangle.cpp @@ -375,12 +375,15 @@ char *llvm::itaniumDemangle(const char *MangledName, char *Buf, 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'; @@ -424,7 +427,9 @@ bool ItaniumPartialDemangler::partialDemangle(const char *MangledName) { } static char *printNode(const Node *RootNode, char *Buf, size_t *N) { - OutputBuffer OB(Buf, N); + OutputBuffer OB; + if (!initializeOutputBuffer(Buf, N, OB, 128)) + return nullptr; RootNode->print(OB); OB += '\0'; if (N != nullptr) @@ -467,7 +472,9 @@ char *ItaniumPartialDemangler::getFunctionDeclContextName(char *Buf, return nullptr; const Node *Name = static_cast(RootNode)->getName(); - OutputBuffer OB(Buf, N); + OutputBuffer OB; + if (!initializeOutputBuffer(Buf, N, OB, 128)) + return nullptr; KeepGoingLocalFunction: while (true) { @@ -518,7 +525,9 @@ char *ItaniumPartialDemangler::getFunctionParameters(char *Buf, return nullptr; NodeArray Params = static_cast(RootNode)->getParams(); - OutputBuffer OB(Buf, N); + OutputBuffer OB; + if (!initializeOutputBuffer(Buf, N, OB, 128)) + return nullptr; OB += '('; Params.printWithComma(OB); @@ -534,7 +543,9 @@ char *ItaniumPartialDemangler::getFunctionReturnType( if (!isFunction()) return nullptr; - OutputBuffer OB(Buf, N); + OutputBuffer OB; + if (!initializeOutputBuffer(Buf, N, OB, 128)) + return nullptr; if (const Node *Ret = static_cast(RootNode)->getReturnType()) diff --git a/llvm/lib/Demangle/MicrosoftDemangle.cpp b/llvm/lib/Demangle/MicrosoftDemangle.cpp index 26087a5b444c..aca8cf7a0a58 100644 --- a/llvm/lib/Demangle/MicrosoftDemangle.cpp +++ b/llvm/lib/Demangle/MicrosoftDemangle.cpp @@ -966,6 +966,9 @@ void Demangler::memorizeIdentifier(IdentifierNode *Identifier) { // 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); @@ -1276,6 +1279,11 @@ Demangler::demangleStringLiteral(StringView &MangledName) { 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; @@ -1434,6 +1442,9 @@ Demangler::demangleLocallyScopedNamePiece(StringView &MangledName) { // 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 << '\''; @@ -2296,6 +2307,8 @@ void Demangler::dumpBackReferences() { // 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); @@ -2322,6 +2335,7 @@ char *llvm::microsoftDemangle(const char *MangledName, size_t *NMangled, char *Buf, size_t *N, int *Status, MSDemangleFlags Flags) { Demangler D; + OutputBuffer OB; StringView Name{MangledName}; SymbolNode *AST = D.parse(Name); @@ -2346,8 +2360,9 @@ char *llvm::microsoftDemangle(const char *MangledName, size_t *NMangled, 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 index 975649f28ad2..494cdabad41f 100644 --- a/llvm/lib/Demangle/MicrosoftDemangleNodes.cpp +++ b/llvm/lib/Demangle/MicrosoftDemangleNodes.cpp @@ -119,6 +119,7 @@ static void outputCallingConvention(OutputBuffer &OB, CallingConv CC) { 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 index 8c01155127d8..32b10db2a968 100644 --- a/llvm/lib/Demangle/RustDemangle.cpp +++ b/llvm/lib/Demangle/RustDemangle.cpp @@ -157,6 +157,9 @@ char *llvm::rustDemangle(const char *MangledName) { return nullptr; Demangler D; + if (!initializeOutputBuffer(nullptr, nullptr, D.Output, 1024)) + return nullptr; + if (!D.demangle(Mangled)) { std::free(D.Output.getBuffer()); return nullptr;