diff --git a/parser/flags.go b/parser/flags.go index 2ad04a4..8da15b4 100644 --- a/parser/flags.go +++ b/parser/flags.go @@ -62,8 +62,10 @@ var flagOrder = []struct { {"ABIWRAPPER", 4096}, } -// flagsRun prepares one flags operand for evaluation: the comments are -// dropped, they are layout the expression never sees. +// flagsRun strips the comments from one flags operand. A comment on a +// directive line is always its trailing text (a comment mid-line is the +// statement boundary the statement reader makes of it), so what the +// operand split hands over carries it at the tail at most. func flagsRun(g []token.Token) []token.Token { out := make([]token.Token, 0, len(g)) for _, t := range g { diff --git a/parser/flags_test.go b/parser/flags_test.go index dc6d7fc..33bee7c 100644 --- a/parser/flags_test.go +++ b/parser/flags_test.go @@ -226,3 +226,16 @@ func TestGloblFlagsOperand(t *testing.T) { t.Errorf("failed operand must carry no value") } } + +// TestTrailingCommentInHeader covers the comment a directive line carries: +// it is the line's trailing text, the operand split hands the frame over +// before it, and the header parses exactly as it would without it. +func TestTrailingCommentInHeader(t *testing.T) { + txt := parseTextHeader(t, "TEXT \u00b7f(SB), NOSPLIT, $0 /* d */") + if !slices.Equal(txt.Flags, []string{"NOSPLIT"}) { + t.Errorf("flags = %v, want [NOSPLIT]", txt.Flags) + } + if txt.FlagVal != 4 || txt.Frame == nil || !txt.Frame.Imm.HasVal || txt.Frame.Imm.Val != 0 { + t.Errorf("val = %d frame = %+v, want 4 and $0", txt.FlagVal, txt.Frame) + } +} diff --git a/parser/parser.go b/parser/parser.go index a6c6e8e..325faba 100644 --- a/parser/parser.go +++ b/parser/parser.go @@ -255,13 +255,15 @@ func (p *state) parseText(line []token.Token) { // two, the first is the flags expression and the last the frame; with // three or more, the toolchain's own complaint. One operand is the // frame alone, whatever it starts with, so a malformed frame takes the - // frame diagnostic and never reads as flags. + // frame diagnostic and never reads as flags. A trailing comment ends + // the operands and never joins them; a comment mid-header is the + // statement boundary the statement reader has always made of it. rest = skipComma(rest) ops := splitOperands(rest) var frame []token.Token switch { case len(ops) >= 2: - text.Flags, text.FlagVal = p.evalFlags(flagsRun(ops[0]), false, "TEXT") + text.Flags, text.FlagVal = p.evalFlags(ops[0], false, "TEXT") frame = ops[1] if len(ops) > 2 { p.errorf(line[0].Pos, "expect two or three operands for TEXT") @@ -355,7 +357,7 @@ func (p *state) parseGlobl(line []token.Token) *ast.Globl { ops := splitOperands(rest) switch { case len(ops) >= 2: - g.Flags, g.FlagVal = p.evalFlags(flagsRun(ops[0]), true, "GLOBL") + g.Flags, g.FlagVal = p.evalFlags(ops[0], true, "GLOBL") g.Size = parseOperand(ops[1], false) case len(ops) == 1: g.Size = parseOperand(ops[0], false)