[llvm][SystemZ] Fix parsing of .cfi_undefined with percent-less registers. (#107032)

This is just e3d658b applied to SystemZ.

An example of this being used in the wild:
https://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/s390/s390-64/start.S;h=59eeb7e998227bdf32029cd074f0876c450404ea;hb=HEAD#l63
This commit is contained in:
Alex Rønne Petersen
2024-09-05 19:45:19 +02:00
committed by GitHub
parent 3815f478bb
commit ebc7f55780
3 changed files with 161 additions and 26 deletions

View File

@@ -416,7 +416,8 @@ private:
return static_cast<SystemZTargetStreamer &>(TS);
}
bool parseRegister(Register &Reg, bool RestoreOnFailure = false);
bool parseRegister(Register &Reg, bool RequirePercent,
bool RestoreOnFailure = false);
bool parseIntegerRegister(Register &Reg, RegisterGroup Group);
@@ -495,7 +496,7 @@ public:
ParseStatus parseDirective(AsmToken DirectiveID) override;
bool parseRegister(MCRegister &Reg, SMLoc &StartLoc, SMLoc &EndLoc) override;
bool ParseRegister(MCRegister &RegNo, SMLoc &StartLoc, SMLoc &EndLoc,
bool RestoreOnFailure);
bool RequirePercent, bool RestoreOnFailure);
ParseStatus tryParseRegister(MCRegister &Reg, SMLoc &StartLoc,
SMLoc &EndLoc) override;
bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
@@ -756,26 +757,32 @@ void SystemZOperand::print(raw_ostream &OS) const {
}
// Parse one register of the form %<prefix><number>.
bool SystemZAsmParser::parseRegister(Register &Reg, bool RestoreOnFailure) {
Reg.StartLoc = Parser.getTok().getLoc();
// Eat the % prefix.
if (Parser.getTok().isNot(AsmToken::Percent))
return Error(Parser.getTok().getLoc(), "register expected");
bool SystemZAsmParser::parseRegister(Register &Reg, bool RequirePercent,
bool RestoreOnFailure) {
const AsmToken &PercentTok = Parser.getTok();
Parser.Lex();
bool HasPercent = PercentTok.is(AsmToken::Percent);
Reg.StartLoc = PercentTok.getLoc();
if (RequirePercent && PercentTok.isNot(AsmToken::Percent))
return Error(PercentTok.getLoc(), "register expected");
if (HasPercent) {
Parser.Lex(); // Eat percent token.
}
// Expect a register name.
if (Parser.getTok().isNot(AsmToken::Identifier)) {
if (RestoreOnFailure)
if (RestoreOnFailure && HasPercent)
getLexer().UnLex(PercentTok);
return Error(Reg.StartLoc, "invalid register");
return Error(Reg.StartLoc,
HasPercent ? "invalid register" : "register expected");
}
// Check that there's a prefix.
StringRef Name = Parser.getTok().getString();
if (Name.size() < 2) {
if (RestoreOnFailure)
if (RestoreOnFailure && HasPercent)
getLexer().UnLex(PercentTok);
return Error(Reg.StartLoc, "invalid register");
}
@@ -783,7 +790,7 @@ bool SystemZAsmParser::parseRegister(Register &Reg, bool RestoreOnFailure) {
// Treat the rest of the register name as a register number.
if (Name.substr(1).getAsInteger(10, Reg.Num)) {
if (RestoreOnFailure)
if (RestoreOnFailure && HasPercent)
getLexer().UnLex(PercentTok);
return Error(Reg.StartLoc, "invalid register");
}
@@ -800,7 +807,7 @@ bool SystemZAsmParser::parseRegister(Register &Reg, bool RestoreOnFailure) {
else if (Prefix == 'c' && Reg.Num < 16)
Reg.Group = RegCR;
else {
if (RestoreOnFailure)
if (RestoreOnFailure && HasPercent)
getLexer().UnLex(PercentTok);
return Error(Reg.StartLoc, "invalid register");
}
@@ -842,7 +849,7 @@ ParseStatus SystemZAsmParser::parseRegister(OperandVector &Operands,
// Handle register names of the form %<prefix><number>
if (isParsingATT() && Parser.getTok().is(AsmToken::Percent)) {
if (parseRegister(Reg))
if (parseRegister(Reg, /*RequirePercent=*/true))
return ParseStatus::Failure;
// Check the parsed register group "Reg.Group" with the expected "Group"
@@ -918,7 +925,7 @@ ParseStatus SystemZAsmParser::parseAnyRegister(OperandVector &Operands) {
return ParseStatus::NoMatch;
Register Reg;
if (parseRegister(Reg))
if (parseRegister(Reg, /*RequirePercent=*/true))
return ParseStatus::Failure;
if (Reg.Num > 15)
@@ -1025,7 +1032,7 @@ bool SystemZAsmParser::parseAddress(bool &HaveReg1, Register &Reg1,
if (isParsingATT() && getLexer().is(AsmToken::Percent)) {
// Parse the first register.
HaveReg1 = true;
if (parseRegister(Reg1))
if (parseRegister(Reg1, /*RequirePercent=*/true))
return true;
}
// So if we have an integer as the first token in ([tok1], ..), it could:
@@ -1065,7 +1072,7 @@ bool SystemZAsmParser::parseAddress(bool &HaveReg1, Register &Reg1,
if (parseIntegerRegister(Reg2, RegGR))
return true;
} else {
if (isParsingATT() && parseRegister(Reg2))
if (isParsingATT() && parseRegister(Reg2, /*RequirePercent=*/true))
return true;
}
}
@@ -1355,9 +1362,10 @@ bool SystemZAsmParser::ParseGNUAttribute(SMLoc L) {
}
bool SystemZAsmParser::ParseRegister(MCRegister &RegNo, SMLoc &StartLoc,
SMLoc &EndLoc, bool RestoreOnFailure) {
SMLoc &EndLoc, bool RequirePercent,
bool RestoreOnFailure) {
Register Reg;
if (parseRegister(Reg, RestoreOnFailure))
if (parseRegister(Reg, RequirePercent, RestoreOnFailure))
return true;
if (Reg.Group == RegGR)
RegNo = SystemZMC::GR64Regs[Reg.Num];
@@ -1376,12 +1384,14 @@ bool SystemZAsmParser::ParseRegister(MCRegister &RegNo, SMLoc &StartLoc,
bool SystemZAsmParser::parseRegister(MCRegister &Reg, SMLoc &StartLoc,
SMLoc &EndLoc) {
return ParseRegister(Reg, StartLoc, EndLoc, /*RestoreOnFailure=*/false);
return ParseRegister(Reg, StartLoc, EndLoc, /*RequirePercent=*/false,
/*RestoreOnFailure=*/false);
}
ParseStatus SystemZAsmParser::tryParseRegister(MCRegister &Reg, SMLoc &StartLoc,
SMLoc &EndLoc) {
bool Result = ParseRegister(Reg, StartLoc, EndLoc, /*RestoreOnFailure=*/true);
bool Result = ParseRegister(Reg, StartLoc, EndLoc, /*RequirePercent=*/false,
/*RestoreOnFailure=*/true);
bool PendingErrors = getParser().hasPendingError();
getParser().clearPendingErrors();
if (PendingErrors)
@@ -1482,7 +1492,7 @@ bool SystemZAsmParser::parseOperand(OperandVector &Operands,
// the instruction isn't recognized.
if (isParsingATT() && Parser.getTok().is(AsmToken::Percent)) {
Register Reg;
if (parseRegister(Reg))
if (parseRegister(Reg, /*RequirePercent=*/true))
return true;
Operands.push_back(SystemZOperand::createInvalid(Reg.StartLoc, Reg.EndLoc));
return false;

View File

@@ -262,8 +262,6 @@
# Test general register parsing, with no predetermined class in mind.
#
#CHECK: error: register expected
#CHECK: .cfi_offset r0,0
#CHECK: error: invalid register
#CHECK: .cfi_offset %,0
#CHECK: error: invalid register
@@ -289,7 +287,6 @@
#CHECK: error: invalid register
#CHECK: .cfi_offset %arid,0
.cfi_offset r0,0
.cfi_offset %,0
.cfi_offset %r,0
.cfi_offset %f,0

View File

@@ -176,6 +176,70 @@
st 0, 4095(1,15)
st 0, 4095(15,1)
#CHECK: .cfi_offset %r0, 0
#CHECK: .cfi_offset %r1, 8
#CHECK: .cfi_offset %r2, 16
#CHECK: .cfi_offset %r3, 24
#CHECK: .cfi_offset %r4, 32
#CHECK: .cfi_offset %r5, 40
#CHECK: .cfi_offset %r6, 48
#CHECK: .cfi_offset %r7, 56
#CHECK: .cfi_offset %r8, 64
#CHECK: .cfi_offset %r9, 72
#CHECK: .cfi_offset %r10, 80
#CHECK: .cfi_offset %r11, 88
#CHECK: .cfi_offset %r12, 96
#CHECK: .cfi_offset %r13, 104
#CHECK: .cfi_offset %r14, 112
#CHECK: .cfi_offset %r15, 120
#CHECK: .cfi_offset %f0, 128
#CHECK: .cfi_offset %f1, 136
#CHECK: .cfi_offset %f2, 144
#CHECK: .cfi_offset %f3, 152
#CHECK: .cfi_offset %f4, 160
#CHECK: .cfi_offset %f5, 168
#CHECK: .cfi_offset %f6, 176
#CHECK: .cfi_offset %f7, 184
#CHECK: .cfi_offset %f8, 192
#CHECK: .cfi_offset %f9, 200
#CHECK: .cfi_offset %f10, 208
#CHECK: .cfi_offset %f11, 216
#CHECK: .cfi_offset %f12, 224
#CHECK: .cfi_offset %f13, 232
#CHECK: .cfi_offset %f14, 240
#CHECK: .cfi_offset %f15, 248
#CHECK: .cfi_offset %a0, 256
#CHECK: .cfi_offset %a1, 260
#CHECK: .cfi_offset %a2, 264
#CHECK: .cfi_offset %a3, 268
#CHECK: .cfi_offset %a4, 272
#CHECK: .cfi_offset %a5, 276
#CHECK: .cfi_offset %a6, 280
#CHECK: .cfi_offset %a7, 284
#CHECK: .cfi_offset %a8, 288
#CHECK: .cfi_offset %r9, 292
#CHECK: .cfi_offset %a10, 296
#CHECK: .cfi_offset %a11, 300
#CHECK: .cfi_offset %a12, 304
#CHECK: .cfi_offset %a13, 308
#CHECK: .cfi_offset %a14, 312
#CHECK: .cfi_offset %a15, 316
#CHECK: .cfi_offset %c0, 318
#CHECK: .cfi_offset %c1, 326
#CHECK: .cfi_offset %c2, 334
#CHECK: .cfi_offset %c3, 342
#CHECK: .cfi_offset %c4, 350
#CHECK: .cfi_offset %c5, 358
#CHECK: .cfi_offset %c6, 366
#CHECK: .cfi_offset %c7, 374
#CHECK: .cfi_offset %c8, 382
#CHECK: .cfi_offset %c9, 390
#CHECK: .cfi_offset %c10, 398
#CHECK: .cfi_offset %c11, 406
#CHECK: .cfi_offset %c12, 414
#CHECK: .cfi_offset %c13, 422
#CHECK: .cfi_offset %c14, 430
#CHECK: .cfi_offset %c15, 438
#CHECK: .cfi_offset %r0, 0
#CHECK: .cfi_offset %r1, 8
#CHECK: .cfi_offset %r2, 16
@@ -306,4 +370,68 @@
.cfi_offset %c13,422
.cfi_offset %c14,430
.cfi_offset %c15,438
.cfi_offset r0,0
.cfi_offset r1,8
.cfi_offset r2,16
.cfi_offset r3,24
.cfi_offset r4,32
.cfi_offset r5,40
.cfi_offset r6,48
.cfi_offset r7,56
.cfi_offset r8,64
.cfi_offset r9,72
.cfi_offset r10,80
.cfi_offset r11,88
.cfi_offset r12,96
.cfi_offset r13,104
.cfi_offset r14,112
.cfi_offset r15,120
.cfi_offset f0,128
.cfi_offset f1,136
.cfi_offset f2,144
.cfi_offset f3,152
.cfi_offset f4,160
.cfi_offset f5,168
.cfi_offset f6,176
.cfi_offset f7,184
.cfi_offset f8,192
.cfi_offset f9,200
.cfi_offset f10,208
.cfi_offset f11,216
.cfi_offset f12,224
.cfi_offset f13,232
.cfi_offset f14,240
.cfi_offset f15,248
.cfi_offset a0,256
.cfi_offset a1,260
.cfi_offset a2,264
.cfi_offset a3,268
.cfi_offset a4,272
.cfi_offset a5,276
.cfi_offset a6,280
.cfi_offset a7,284
.cfi_offset a8,288
.cfi_offset r9,292
.cfi_offset a10,296
.cfi_offset a11,300
.cfi_offset a12,304
.cfi_offset a13,308
.cfi_offset a14,312
.cfi_offset a15,316
.cfi_offset c0,318
.cfi_offset c1,326
.cfi_offset c2,334
.cfi_offset c3,342
.cfi_offset c4,350
.cfi_offset c5,358
.cfi_offset c6,366
.cfi_offset c7,374
.cfi_offset c8,382
.cfi_offset c9,390
.cfi_offset c10,398
.cfi_offset c11,406
.cfi_offset c12,414
.cfi_offset c13,422
.cfi_offset c14,430
.cfi_offset c15,438
.cfi_endproc