aboutsummaryrefslogtreecommitdiffstats
path: root/lib/Target/PowerPC/AsmParser
diff options
context:
space:
mode:
authorBenjamin Kramer <benny.kra@googlemail.com>2013-08-03 22:43:29 +0000
committerBenjamin Kramer <benny.kra@googlemail.com>2013-08-03 22:43:29 +0000
commitaf00feb1a6af78fbb07c4deca6e9e30a49cdcd15 (patch)
tree97c8621a08903cab35ece5296d76aeef19329eaf /lib/Target/PowerPC/AsmParser
parentbd194ced30c9fc86bb73313574bd96208e660b4c (diff)
downloadexternal_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.cpp41
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