Jonathan. Frech’s WebBlog

Crashing GC in 57 bytes (#287)

Jonathan Frech,

Terser than GCC’s C++ (cf. 235), Go’s stan­dard im­ple­men­ta­tion can be forced to doubt itself in a mere 57 bytes:

$ go version
go version go1.22.1 linux/amd64
$ printf 'package main;func main(){panic(0);x:=0;l:for{goto l};_=x}' >/tmp/ice.go
$ wc -c /tmp/ice.go
57 /tmp/ice.go
$ go run /tmp/ice.go
# command-line-arguments
CLOSURE [/tmp/ice.go:1:56:var x int]
<unknown line number>: internal compiler error: assertion failed

Please file a bug report including a short program that triggers the error.
https://go.dev/issue/new

Without having analyzed the com­pil­er, black-box behavioural poking revealed that truly fickly a panic has to be fol­low­ed with a variable declaration whose use entwines a label; else all one gets is an immediately-panicking or non-terminating executable:

package main

func main() {
	panic(0)

	x := 0

l:
	for {
		goto l
	}

	_ = x
}

At first, it irritates you, since⸺although you expect a plethora of compilation and test failures whilst developing⸺the error looks off. At closer inspection, a joyful rush grips you as you might be the first human being engaging in this specific dialogue with your com­pil­er. So you stop everything else and golf away to extract an erroring nub. Whole swaths of code you rip out without a care for your program you once developed. The tiniest of changes⸺even ones which go in be­tween equivalent source formulations⸺make the com­pil­er snap out of its delusions, rendering it able to produce an executable. But you persevere, wanting the com­pil­er to fail again and again at compiling a program without any use.

Cf. Go issue #67661