Skip to content

go/printer: incorrect *Config.Format results with +build comments and the SourcePos mode #64976

Open
@cixel

Description

@cixel

What version of Go are you using (go version)?

8db1310 (tip, as of time of writing)

What did you do?

Here is an example reproducer: https://go.dev/play/p/sphL42iaX_a

I think it's a pretty obscure issue which requires a few things:

  1. the SourcePos mode enabled
  2. one or more // +build constraints, and no //go:build comments
  3. a change in the AST before the first //+build comment which offsets position such that the printer has to emit a //line directive

As far as I can tell, here's what's going wrong:

  • the call to printer.*Config.Fprint will fully print the given node (a File) and then call fixGoBuildLines to consolidate build directives and translate "plus builds" to the current //go:build format
  • when printing comments, build constraints are special-cased: the current position of the writer is recorded to p.plusBuild, then the comment is written with p.writeString
  • writeString checks if SourcePos is enabled and, if necessary, emits a line directive before writing its arg string to the output buffer

After printing, fixGoBuildLines turns //+build comments into //go:build by iterating the positions in p.plusBuild and parsing the constraints at each:

for _, pos := range p.plusBuild {
	y, err := constraint.Parse(p.commentTextAt(pos))
	if err != nil {
		x = nil
		break
	}
    ...

Because of SourcePos, the offsets recorded to p.plusBuild can incorrectly point to a //line comment, rather than a valid build constraint, so parsing fails, the loop exits, and subsequent plusBuild lines are ignored and the inserted block will be incomplete/incorrect.

What did you expect to see?

  • //+build constraints should have been preserved and/or translated to //go:build
  • I'm not sure if there's any value in a line directive on the build constraint comment -- perhaps that can be omitted.

What did you see instead?

In the reproducer, one of the build constraints is omitted and a seemingly unnecessary line directive is printed ts the top of the file.

Metadata

Metadata

Assignees

Labels

NeedsInvestigationSomeone must examine and confirm this is a valid issue and not a duplicate of an existing one.

Type

No type

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions