Skip to content

cmd/compile: go1.26.0-1.26.5 miscompile a local array literal indexed by a range variable assigned to a struct string field (darwin/arm64) #80706

Description

@sunholo-voight-kampff

Go version

go version go1.26.5 darwin/arm64 (also reproduced on go1.26.0, go1.26.3, go1.26.4)

Output of go env

GOOS=darwin
GOARCH=arm64
GOVERSION=go1.26.4
CGO_ENABLED=1

What did you do?

A local array literal indexed by a range index variable, assigned into a struct string field that is not at offset 0, inside a composite literal that also performs an interface method call after the array access, is miscompiled.

Dependency-free, 52 lines, no -race, no cgo, plain go build:

package main

import "fmt"

type Row struct {
	N      int
	Field  string
	Reason string
}

type Stringer interface{ Str() string }

type myStr string

func (s myStr) Str() string { return string(s) }

func worldsShape() []Row {
	var rows []Row
	texts := []string{"w", ""}
	fields := [...]string{"worldRef", "stateRoot"}
	for i, text := range texts {
		if len(text) == 0 {
			v := Stringer(myStr("empty"))
			rows = append(rows, Row{
				Field: fields[i], Reason: v.Str(),
			})
			break
		}
	}
	return rows
}

func main() {
	got := worldsShape()
	if len(got) != 1 {
		fmt.Println("BUG: len(rows) =", len(got))
		return
	}
	r := got[0]
	// Check the length BEFORE printing: on an affected toolchain the string
	// header can be corrupt, and printing it segfaults instead of reporting.
	if n := len(r.Field); n > 1000 {
		fmt.Printf("BUG: len(Field)=%d (corrupt string header)\n", n)
		return
	}
	if r.Field != "stateRoot" {
		fmt.Printf("BUG: Field=%q want %q\n", r.Field, "stateRoot")
		return
	}
	fmt.Println("OK")
}

What did you expect to see?

OK

What did you see instead?

BUG: Field="" want "stateRoot"

Reason, assigned from the same composite literal in the same loop iteration, is correct. fields is a two-element string array literal indexed by the range variable, so an empty Field should be unreachable.

Bisection of affected versions

Each row is a go build of the program above, run via GOTOOLCHAIN=<version>:

Toolchain Result
go1.24.9 OK
go1.25.6 OK
go1.26.0 BUG: Field="" want "stateRoot"
go1.26.3 BUG
go1.26.4 BUG
go1.26.5 BUG

So it appears in 1.26.0 and is still present in 1.26.5, with no fixed release to move forward to.

It is an optimizer issue, not inlining

Same program, same go1.26.4:

  • go build -gcflags=all=-NOK
  • go build -gcflags=all=-lBUG

Platform scope

Reproduced on darwin/arm64 (Apple M4 Max, macOS).

Not reproduced on linux/amd64: all four affected toolchains return OK on a GitHub Actions ubuntu-latest runner. That measurement is from a CI run of the same harness, so the platform difference is observed rather than inferred.

Why the struct layout matters

Depending on the surrounding struct's layout, the symptom is either an empty string or a genuinely corrupt string header (nil data pointer, garbage length) — in the latter case simply printing the field segfaults, which is why the reproducer checks len first. That reads as memory corruption rather than a wrong-value logic bug.

Real-world impact

Found in a production Go project, where the same shape at two sites in one file produced two distinct symptoms under -race: one test failing deterministically with an empty string field, and another hanging. -gcflags=all=-N on that single package cleared both. Zero DATA RACE warnings were reported in either case — the race detector was not the cause, it only perturbed the layout enough to make the miscompilation visible.

A re-runnable harness with its own known-positive and known-negative controls (it fails loudly rather than silently passing if no affected toolchain reproduces) is at
https://github.com/sunholo-data/ailang-world/tree/dev/design_docs/verification/w-race-gate-blindspot

Metadata

Metadata

Assignees

Labels

NeedsInvestigationSomeone must examine and confirm this is a valid issue and not a duplicate of an existing one.compiler/runtimeIssues related to the Go compiler and/or runtime.

Type

No type

Projects

Status
Done

Relationships

None yet

Development

No branches or pull requests

Issue actions