{"y+56(FP)", "y+56(FP)"},
{"·AddUint32(SB)", "\"\".AddUint32(SB)"},
{"·callReflect(SB)", "\"\".callReflect(SB)"},
+ {"[):[o-FP", ""}, // Issue 12469 - asm hung parsing the o-FP range on non ARM platforms.
}
var x86OperandTests = []operandTest{
{"x+4(FP)", "x+4(FP)"},
{"·AddUint32(SB)", "\"\".AddUint32(SB)"},
{"·reflectcall(SB)", "\"\".reflectcall(SB)"},
+ {"[):[o-FP", ""}, // Issue 12469 - asm hung parsing the o-FP range on non ARM platforms.
}
var armOperandTests = []operandTest{
{"runtime·_sfloat2(SB)", "runtime._sfloat2(SB)"},
{"·AddUint32(SB)", "\"\".AddUint32(SB)"},
{"(R1, R3)", "(R1, R3)"},
- {"[R0,R1,g,R15", ""}, // Issue 11764 - previously asm just hung parsing ']' missing register lists
+ {"[R0,R1,g,R15", ""}, // Issue 11764 - asm hung parsing ']' missing register lists.
+ {"[):[o-FP", ""}, // Issue 12469 - there was no infinite loop for ARM; these are just sanity checks.
+ {"[):[R0-FP", ""},
}
var ppc64OperandTests = []operandTest{
{"runtime·abort(SB)", "runtime.abort(SB)"},
{"·AddUint32(SB)", "\"\".AddUint32(SB)"},
{"·trunc(SB)", "\"\".trunc(SB)"},
+ {"[):[o-FP", ""}, // Issue 12469 - asm hung parsing the o-FP range on non ARM platforms.
}
var arm64OperandTests = []operandTest{
{"ZR", "ZR"},
{"(ZR)", "(ZR)"},
{"(R29, RSP)", "(R29, RSP)"},
+ {"[):[o-FP", ""}, // Issue 12469 - asm hung parsing the o-FP range on non ARM platforms.
}
// The opening bracket has been consumed.
func (p *Parser) registerList(a *obj.Addr) {
// One range per loop.
+ const maxReg = 16
var bits uint16
ListLoop:
for {
p.errorf("missing ']' in register list")
return
}
+ // Parse the upper and lower bounds.
lo := p.registerNumber(tok.String())
hi := lo
if p.peek() == '-' {
if hi < lo {
lo, hi = hi, lo
}
- for lo <= hi {
+ // Check there are no duplicates in the register list.
+ for i := 0; lo <= hi && i < maxReg; i++ {
if bits&(1<<lo) != 0 {
p.errorf("register R%d already in list", lo)
}
}
if name[0] != 'R' {
p.errorf("expected g or R0 through R15; found %s", name)
+ return 0
}
r, ok := p.registerReference(name)
if !ok {
return 0
}
- return uint16(r - p.arch.Register["R0"])
+ reg := r - p.arch.Register["R0"]
+ if reg < 0 {
+ // Could happen for an architecture having other registers prefixed by R
+ p.errorf("expected g or R0 through R15; found %s", name)
+ return 0
+ }
+ return uint16(reg)
}
// Note: There are two changes in the expression handling here