diff options
author | Erik Pilkington <erik.pilkington@gmail.com> | 2018-03-26 15:34:36 +0000 |
---|---|---|
committer | Erik Pilkington <erik.pilkington@gmail.com> | 2018-03-26 15:34:36 +0000 |
commit | 615e753e09ff4d93ef067fb221433f5cb50b3c46 (patch) | |
tree | 1765677d904f9f9970a3f1c972aba86f42ad9ff1 /llvm/lib/Demangle/ItaniumDemangle.cpp | |
parent | 56f0fc4716ff7c86f41b07a74da887975094f7e2 (diff) | |
download | bcm5719-llvm-615e753e09ff4d93ef067fb221433f5cb50b3c46.tar.gz bcm5719-llvm-615e753e09ff4d93ef067fb221433f5cb50b3c46.zip |
[demangler] Fix a bug in r328464 found by oss-fuzz.
llvm-svn: 328507
Diffstat (limited to 'llvm/lib/Demangle/ItaniumDemangle.cpp')
-rw-r--r-- | llvm/lib/Demangle/ItaniumDemangle.cpp | 29 |
1 files changed, 27 insertions, 2 deletions
diff --git a/llvm/lib/Demangle/ItaniumDemangle.cpp b/llvm/lib/Demangle/ItaniumDemangle.cpp index c80b1c9ef2b..3f610a41422 100644 --- a/llvm/lib/Demangle/ItaniumDemangle.cpp +++ b/llvm/lib/Demangle/ItaniumDemangle.cpp @@ -1088,23 +1088,48 @@ struct ForwardTemplateReference : Node { size_t Index; Node *Ref = nullptr; + // If we're currently printing this node. It is possible (though invalid) for + // a forward template reference to refer to itself via a substitution. This + // creates a cyclic AST, which will stack overflow printing. To fix this, bail + // out if more than one print* function is active. + mutable bool Printing = false; + ForwardTemplateReference(size_t Index_) : Node(KForwardTemplateReference, Cache::Unknown, Cache::Unknown, Cache::Unknown), Index(Index_) {} bool hasRHSComponentSlow(OutputStream &S) const override { + if (Printing) + return false; + SwapAndRestore<bool> SavePrinting(Printing, true); return Ref->hasRHSComponent(S); } bool hasArraySlow(OutputStream &S) const override { + if (Printing) + return false; + SwapAndRestore<bool> SavePrinting(Printing, true); return Ref->hasArray(S); } bool hasFunctionSlow(OutputStream &S) const override { + if (Printing) + return false; + SwapAndRestore<bool> SavePrinting(Printing, true); return Ref->hasFunction(S); } - void printLeft(OutputStream &S) const override { Ref->printLeft(S); } - void printRight(OutputStream &S) const override { Ref->printRight(S); } + void printLeft(OutputStream &S) const override { + if (Printing) + return; + SwapAndRestore<bool> SavePrinting(Printing, true); + Ref->printLeft(S); + } + void printRight(OutputStream &S) const override { + if (Printing) + return; + SwapAndRestore<bool> SavePrinting(Printing, true); + Ref->printRight(S); + } }; class NameWithTemplateArgs final : public Node { |