Author: rsmith Date: Fri Aug 24 16:30:26 2018 New Revision: 340671 URL: http://llvm.org/viewvc/llvm-project?rev=340671&view=rev Log: Port my recent changes from LLVM copy of the demangler:
r340663 - Allow Allocator::make to make a node of a different type than that requested. r340664 - Add documentation comment to ForwardTemplateReference. r340665 - Fix ExpandedSpecialSubstitution demangling for Sa and Sb. r340670 - Allow demangler's node allocator to fail, and bail out of the entire demangling process when it does. Modified: libcxxabi/trunk/src/demangle/ItaniumDemangle.h Modified: libcxxabi/trunk/src/demangle/ItaniumDemangle.h URL: http://llvm.org/viewvc/llvm-project/libcxxabi/trunk/src/demangle/ItaniumDemangle.h?rev=340671&r1=340670&r2=340671&view=diff ============================================================================== --- libcxxabi/trunk/src/demangle/ItaniumDemangle.h (original) +++ libcxxabi/trunk/src/demangle/ItaniumDemangle.h Fri Aug 24 16:30:26 2018 @@ -1123,6 +1123,24 @@ public: } }; +/// A forward-reference to a template argument that was not known at the point +/// where the template parameter name was parsed in a mangling. +/// +/// This is created when demangling the name of a specialization of a +/// conversion function template: +/// +/// \code +/// struct A { +/// template<typename T> operator T*(); +/// }; +/// \endcode +/// +/// When demangling a specialization of the conversion function template, we +/// encounter the name of the template (including the \c T) before we reach +/// the template argument list, so we cannot substitute the parameter name +/// for the corresponding argument while parsing. Instead, we create a +/// \c ForwardTemplateReference node that is resolved after we parse the +/// template arguments. struct ForwardTemplateReference : Node { size_t Index; Node *Ref = nullptr; @@ -1271,10 +1289,11 @@ public: void printLeft(OutputStream &S) const override { switch (SSK) { case SpecialSubKind::allocator: - S += "std::basic_string<char, std::char_traits<char>, " - "std::allocator<char> >"; + S += "std::allocator"; break; case SpecialSubKind::basic_string: + S += "std::basic_string"; + break; case SpecialSubKind::string: S += "std::basic_string<char, std::char_traits<char>, " "std::allocator<char> >"; @@ -2165,7 +2184,7 @@ struct Db { ASTAllocator.reset(); } - template <class T, class... Args> T *make(Args &&... args) { + template <class T, class... Args> Node *make(Args &&... args) { return ASTAllocator.template makeNode<T>(std::forward<Args>(args)...); } @@ -2358,7 +2377,10 @@ template<typename Alloc> Node *Db<Alloc> if (consumeIf('s')) { First = parse_discriminator(First, Last); - return make<LocalName>(Encoding, make<NameType>("string literal")); + auto *StringLitName = make<NameType>("string literal"); + if (!StringLitName) + return nullptr; + return make<LocalName>(Encoding, StringLitName); } if (consumeIf('d')) { @@ -2772,6 +2794,8 @@ Node *Db<Alloc>::parseCtorDtorName(Node case SpecialSubKind::ostream: case SpecialSubKind::iostream: SoFar = make<ExpandedSpecialSubstitution>(SSK); + if (!SoFar) + return nullptr; default: break; } @@ -2833,13 +2857,18 @@ template<typename Alloc> Node *Db<Alloc> Node *SoFar = nullptr; auto PushComponent = [&](Node *Comp) { + if (!Comp) return false; if (SoFar) SoFar = make<NestedName>(SoFar, Comp); else SoFar = Comp; if (State) State->EndsWithTemplateArgs = false; + return SoFar != nullptr; }; - if (consumeIf("St")) + if (consumeIf("St")) { SoFar = make<NameType>("std"); + if (!SoFar) + return nullptr; + } while (!consumeIf('E')) { consumeIf('L'); // extension @@ -2853,10 +2882,8 @@ template<typename Alloc> Node *Db<Alloc> // ::= <template-param> if (look() == 'T') { - Node *TP = parseTemplateParam(); - if (TP == nullptr) + if (!PushComponent(parseTemplateParam())) return nullptr; - PushComponent(TP); Subs.push_back(SoFar); continue; } @@ -2867,6 +2894,8 @@ template<typename Alloc> Node *Db<Alloc> if (TA == nullptr || SoFar == nullptr) return nullptr; SoFar = make<NameWithTemplateArgs>(SoFar, TA); + if (!SoFar) + return nullptr; if (State) State->EndsWithTemplateArgs = true; Subs.push_back(SoFar); continue; @@ -2874,10 +2903,8 @@ template<typename Alloc> Node *Db<Alloc> // ::= <decltype> if (look() == 'D' && (look(1) == 't' || look(1) == 'T')) { - Node *DT = parseDecltype(); - if (DT == nullptr) + if (!PushComponent(parseDecltype())) return nullptr; - PushComponent(DT); Subs.push_back(SoFar); continue; } @@ -2885,9 +2912,8 @@ template<typename Alloc> Node *Db<Alloc> // ::= <substitution> if (look() == 'S' && look(1) != 't') { Node *S = parseSubstitution(); - if (S == nullptr) + if (!PushComponent(S)) return nullptr; - PushComponent(S); if (SoFar != S) Subs.push_back(S); continue; @@ -2897,10 +2923,8 @@ template<typename Alloc> Node *Db<Alloc> if (look() == 'C' || (look() == 'D' && look(1) != 'C')) { if (SoFar == nullptr) return nullptr; - Node *CtorDtor = parseCtorDtorName(SoFar, State); - if (CtorDtor == nullptr) + if (!PushComponent(parseCtorDtorName(SoFar, State))) return nullptr; - PushComponent(CtorDtor); SoFar = parseAbiTags(SoFar); if (SoFar == nullptr) return nullptr; @@ -2909,10 +2933,8 @@ template<typename Alloc> Node *Db<Alloc> } // ::= <prefix> <unqualified-name> - Node *N = parseUnqualifiedName(State); - if (N == nullptr) + if (!PushComponent(parseUnqualifiedName(State))) return nullptr; - PushComponent(N); Subs.push_back(SoFar); } @@ -3025,6 +3047,8 @@ template<typename Alloc> Node *Db<Alloc> if (TA == nullptr) return nullptr; SoFar = make<NameWithTemplateArgs>(SoFar, TA); + if (!SoFar) + return nullptr; } while (!consumeIf('E')) { @@ -3032,6 +3056,8 @@ template<typename Alloc> Node *Db<Alloc> if (Qual == nullptr) return nullptr; SoFar = make<QualifiedName>(SoFar, Qual); + if (!SoFar) + return nullptr; } Node *Base = parseBaseUnresolvedName(); @@ -3064,6 +3090,8 @@ template<typename Alloc> Node *Db<Alloc> SoFar = make<GlobalQualifiedName>(Qual); else SoFar = Qual; + if (!SoFar) + return nullptr; } while (!consumeIf('E')); } // sr <unresolved-type> <base-unresolved-name> @@ -3078,6 +3106,8 @@ template<typename Alloc> Node *Db<Alloc> if (TA == nullptr) return nullptr; SoFar = make<NameWithTemplateArgs>(SoFar, TA); + if (!SoFar) + return nullptr; } } @@ -3097,6 +3127,8 @@ template<typename Alloc> Node *Db<Alloc> if (SN.empty()) return nullptr; N = make<AbiTagAttr>(N, SN); + if (!N) + return nullptr; } return N; } @@ -3149,11 +3181,15 @@ template<typename Alloc> Node *Db<Alloc> Node *ExceptionSpec = nullptr; if (consumeIf("Do")) { ExceptionSpec = make<NameType>("noexcept"); + if (!ExceptionSpec) + return nullptr; } else if (consumeIf("DO")) { Node *E = parseExpr(); if (E == nullptr || !consumeIf('E')) return nullptr; ExceptionSpec = make<NoexceptSpec>(E); + if (!ExceptionSpec) + return nullptr; } else if (consumeIf("Dw")) { size_t SpecsBegin = Names.size(); while (!consumeIf('E')) { @@ -3164,6 +3200,8 @@ template<typename Alloc> Node *Db<Alloc> } ExceptionSpec = make<DynamicExceptionSpec>(popTrailingNodeArray(SpecsBegin)); + if (!ExceptionSpec) + return nullptr; } consumeIf("Dx"); // transaction safe @@ -4503,9 +4541,10 @@ template<typename Alloc> Node *Db<Alloc> return nullptr; Names.push_back(Arg); } - return make<EnclosingExpr>( - "sizeof... (", make<NodeArrayNode>(popTrailingNodeArray(ArgsBegin)), - ")"); + auto *Pack = make<NodeArrayNode>(popTrailingNodeArray(ArgsBegin)); + if (!Pack) + return nullptr; + return make<EnclosingExpr>("sizeof... (", Pack, ")"); } } return nullptr; @@ -4757,6 +4796,8 @@ template<typename Alloc> Node *Db<Alloc> Names.push_back(Arg); } Attrs = make<EnableIfAttr>(popTrailingNodeArray(BeforeArgs)); + if (!Attrs) + return nullptr; } Node *ReturnType = nullptr; @@ -4901,6 +4942,8 @@ template<typename Alloc> Node *Db<Alloc> default: return nullptr; } + if (!SpecialSub) + return nullptr; // Itanium C++ ABI 5.1.2: If a name that would use a built-in <substitution> // has ABI tags, the tags are appended to the substitution; the result is a // substitutable component. @@ -4953,8 +4996,13 @@ template<typename Alloc> Node *Db<Alloc> // <template-arg> further ahead in the mangled name (currently just conversion // operator types), then we should only look it up in the right context. if (PermitForwardTemplateReferences) { - ForwardTemplateRefs.push_back(make<ForwardTemplateReference>(Index)); - return ForwardTemplateRefs.back(); + Node *ForwardRef = make<ForwardTemplateReference>(Index); + if (!ForwardRef) + return nullptr; + assert(ForwardRef->getKind() == Node::KForwardTemplateReference); + ForwardTemplateRefs.push_back( + static_cast<ForwardTemplateReference *>(ForwardRef)); + return ForwardRef; } if (Index >= TemplateParams.size()) @@ -5030,6 +5078,8 @@ Node *Db<Alloc>::parseTemplateArgs(bool if (Arg->getKind() == Node::KTemplateArgumentPack) { TableEntry = make<ParameterPack>( static_cast<TemplateArgumentPack*>(TableEntry)->getElements()); + if (!TableEntry) + return nullptr; } TemplateParams.push_back(TableEntry); } else { _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits