diff options
author | Benjamin Kramer <benny.kra@googlemail.com> | 2013-08-03 22:43:29 +0000 |
---|---|---|
committer | Benjamin Kramer <benny.kra@googlemail.com> | 2013-08-03 22:43:29 +0000 |
commit | 72d45cc8469b9facfbc99ee032e38bd2983ad4e4 (patch) | |
tree | 71ddf0ec2b1c6a251723b874d6e473279961eb87 /llvm/lib/Target | |
parent | 5d62ad2aff582b20b17a0485cc560e29289daa1b (diff) | |
download | bcm5719-llvm-72d45cc8469b9facfbc99ee032e38bd2983ad4e4.tar.gz bcm5719-llvm-72d45cc8469b9facfbc99ee032e38bd2983ad4e4.zip |
PPCAsmParser: Stop leaking names.
Store them in a place that gets cleaned up properly.
llvm-svn: 187700
Diffstat (limited to 'llvm/lib/Target')
-rw-r--r-- | llvm/lib/Target/PowerPC/AsmParser/PPCAsmParser.cpp | 41 |
1 files changed, 31 insertions, 10 deletions
diff --git a/llvm/lib/Target/PowerPC/AsmParser/PPCAsmParser.cpp b/llvm/lib/Target/PowerPC/AsmParser/PPCAsmParser.cpp index 7d66cc68299..a8f750921e9 100644 --- a/llvm/lib/Target/PowerPC/AsmParser/PPCAsmParser.cpp +++ b/llvm/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 |