From af00feb1a6af78fbb07c4deca6e9e30a49cdcd15 Mon Sep 17 00:00:00 2001 From: Benjamin Kramer Date: Sat, 3 Aug 2013 22:43:29 +0000 Subject: PPCAsmParser: Stop leaking names. Store them in a place that gets cleaned up properly. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@187700 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/PowerPC/AsmParser/PPCAsmParser.cpp | 41 ++++++++++++++++++++------- 1 file changed, 31 insertions(+), 10 deletions(-) (limited to 'lib/Target/PowerPC/AsmParser') diff --git a/lib/Target/PowerPC/AsmParser/PPCAsmParser.cpp b/lib/Target/PowerPC/AsmParser/PPCAsmParser.cpp index 7d66cc6829..a8f750921e 100644 --- a/lib/Target/PowerPC/AsmParser/PPCAsmParser.cpp +++ b/lib/Target/PowerPC/AsmParser/PPCAsmParser.cpp @@ -488,6 +488,20 @@ public: return Op; } + static PPCOperand *CreateTokenWithStringCopy(StringRef Str, SMLoc S, + bool IsPPC64) { + // Allocate extra memory for the string and copy it. + void *Mem = ::operator new(sizeof(PPCOperand) + Str.size()); + PPCOperand *Op = new (Mem) PPCOperand(Token); + Op->Tok.Data = (const char *)(Op + 1); + Op->Tok.Length = Str.size(); + std::memcpy((char *)(Op + 1), Str.data(), Str.size()); + Op->StartLoc = S; + Op->EndLoc = S; + Op->IsPPC64 = IsPPC64; + return Op; + } + static PPCOperand *CreateImm(int64_t Val, SMLoc S, SMLoc E, bool IsPPC64) { PPCOperand *Op = new PPCOperand(Immediate); Op->Imm.Val = Val; @@ -1184,29 +1198,36 @@ ParseInstruction(ParseInstructionInfo &Info, StringRef Name, SMLoc NameLoc, // The first operand is the token for the instruction name. // If the next character is a '+' or '-', we need to add it to the // instruction name, to match what TableGen is doing. + std::string NewOpcode; if (getLexer().is(AsmToken::Plus)) { getLexer().Lex(); - char *NewOpcode = new char[Name.size() + 1]; - memcpy(NewOpcode, Name.data(), Name.size()); - NewOpcode[Name.size()] = '+'; - Name = StringRef(NewOpcode, Name.size() + 1); + NewOpcode = Name; + NewOpcode += '+'; + Name = NewOpcode; } if (getLexer().is(AsmToken::Minus)) { getLexer().Lex(); - char *NewOpcode = new char[Name.size() + 1]; - memcpy(NewOpcode, Name.data(), Name.size()); - NewOpcode[Name.size()] = '-'; - Name = StringRef(NewOpcode, Name.size() + 1); + NewOpcode = Name; + NewOpcode += '-'; + Name = NewOpcode; } // If the instruction ends in a '.', we need to create a separate // token for it, to match what TableGen is doing. size_t Dot = Name.find('.'); StringRef Mnemonic = Name.slice(0, Dot); - Operands.push_back(PPCOperand::CreateToken(Mnemonic, NameLoc, isPPC64())); + if (!NewOpcode.empty()) // Underlying memory for Name is volatile. + Operands.push_back( + PPCOperand::CreateTokenWithStringCopy(Mnemonic, NameLoc, isPPC64())); + else + Operands.push_back(PPCOperand::CreateToken(Mnemonic, NameLoc, isPPC64())); if (Dot != StringRef::npos) { SMLoc DotLoc = SMLoc::getFromPointer(NameLoc.getPointer() + Dot); StringRef DotStr = Name.slice(Dot, StringRef::npos); - Operands.push_back(PPCOperand::CreateToken(DotStr, DotLoc, isPPC64())); + if (!NewOpcode.empty()) // Underlying memory for Name is volatile. + Operands.push_back( + PPCOperand::CreateTokenWithStringCopy(DotStr, DotLoc, isPPC64())); + else + Operands.push_back(PPCOperand::CreateToken(DotStr, DotLoc, isPPC64())); } // If there are no more operands then finish -- cgit v1.2.3