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 | af00feb1a6af78fbb07c4deca6e9e30a49cdcd15 (patch) | |
tree | 97c8621a08903cab35ece5296d76aeef19329eaf /lib/Target/PowerPC/AsmParser | |
parent | bd194ced30c9fc86bb73313574bd96208e660b4c (diff) | |
download | external_llvm-af00feb1a6af78fbb07c4deca6e9e30a49cdcd15.zip external_llvm-af00feb1a6af78fbb07c4deca6e9e30a49cdcd15.tar.gz external_llvm-af00feb1a6af78fbb07c4deca6e9e30a49cdcd15.tar.bz2 |
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
Diffstat (limited to 'lib/Target/PowerPC/AsmParser')
-rw-r--r-- | lib/Target/PowerPC/AsmParser/PPCAsmParser.cpp | 41 |
1 files changed, 31 insertions, 10 deletions
diff --git a/lib/Target/PowerPC/AsmParser/PPCAsmParser.cpp b/lib/Target/PowerPC/AsmParser/PPCAsmParser.cpp index 7d66cc6..a8f7509 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 |