Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

cmd/compile, types2: incorrect computation of unsafe.Sizeof() #45390

Closed
danscales opened this issue Apr 5, 2021 · 4 comments
Closed

cmd/compile, types2: incorrect computation of unsafe.Sizeof() #45390

danscales opened this issue Apr 5, 2021 · 4 comments
Milestone

Comments

@danscales
Copy link
Contributor

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

Current master (pre-release Go 1.17)

What did you do?

After building current master with ./make.bash, run:

go test -test.count 1 -short -gcflags="all=-G=3" bytes

I expected that to run normally, but I get this error:

# runtime
runtime/stack.go:1316:39: internal compiler error: got 8 from types2, but want 0

goroutine 1 [running]:
runtime/debug.Stack(0xf9b860, 0xc00000e018, 0x0)
        /usr/local/google/home/danscales/gerrit/go/src/runtime/debug/stack.go:24 +0x9f
cmd/compile/internal/base.FatalfAt(0x5242700000000e, 0xe631df, 0x1f, 0xc00125cf30, 0x2, 0x2)
        /usr/local/google/home/danscales/gerrit/go/src/cmd/compile/internal/base/print.go:227 +0x1ea
cmd/compile/internal/noder.(*irgen).validateBuiltin(0xc00145de60, 0xc000e8e600, 0x6, 0xc000e93840)
        /usr/local/google/home/danscales/gerrit/go/src/cmd/compile/internal/noder/validate.go:83 +0x2e5
cmd/compile/internal/noder.(*irgen).validate(0xc00145de60, 0xf9fdc8, 0xc000e93840)
        /usr/local/google/home/danscales/gerrit/go/src/cmd/compile/internal/noder/validate.go:62 +0x170
cmd/compile/internal/noder.(*irgen).generate.func1(0xf9fdc8, 0xc000e93840, 0xfa0000)
        /usr/local/google/home/danscales/gerrit/go/src/cmd/compile/internal/noder/irgen.go:180 +0x3e
cmd/compile/internal/syntax.(*walker).node(0xc00125d6f8, 0xf9fdc8, 0xc000e93840)
        /usr/local/google/home/danscales/gerrit/go/src/cmd/compile/internal/syntax/walk.go:35 +0x6a
cmd/compile/internal/syntax.(*walker).node(0xc00125d6f8, 0xfa01d8, 0xc000e93880)
        /usr/local/google/home/danscales/gerrit/go/src/cmd/compile/internal/syntax/walk.go:135 +0x1918
cmd/compile/internal/syntax.(*walker).node(0xc00125d6f8, 0xfa01d8, 0xc000e93800)
        /usr/local/google/home/danscales/gerrit/go/src/cmd/compile/internal/syntax/walk.go:137 +0x1970
cmd/compile/internal/syntax.(*walker).node(0xc00125d6f8, 0xfa01d8, 0xc000e938c0)
        /usr/local/google/home/danscales/gerrit/go/src/cmd/compile/internal/syntax/walk.go:135 +0x1918
cmd/compile/internal/syntax.(*walker).node(0xc00125d6f8, 0xfa0070, 0xc000bff540)
        /usr/local/google/home/danscales/gerrit/go/src/cmd/compile/internal/syntax/walk.go:232 +0x1aab
cmd/compile/internal/syntax.(*walker).stmtList(0xc00125d6f8, 0xc000621800, 0xd, 0x10)
        /usr/local/google/home/danscales/gerrit/go/src/cmd/compile/internal/syntax/walk.go:304 +0x9a
cmd/compile/internal/syntax.(*walker).node(0xc00125d6f8, 0xf9fd78, 0xc000e8dd00)
        /usr/local/google/home/danscales/gerrit/go/src/cmd/compile/internal/syntax/walk.go:196 +0x19dc
cmd/compile/internal/syntax.(*walker).node(0xc00125d6f8, 0xf9fff8, 0xc000bf2b40)
        /usr/local/google/home/danscales/gerrit/go/src/cmd/compile/internal/syntax/walk.go:83 +0xc0e
cmd/compile/internal/syntax.(*walker).declList(0xc00125d6f8, 0xc000be4800, 0x47, 0x80)
        /usr/local/google/home/danscales/gerrit/go/src/cmd/compile/internal/syntax/walk.go:292 +0x9a
cmd/compile/internal/syntax.(*walker).node(0xc00125d6f8, 0xf9ffa8, 0xc0008b58b0)
        /usr/local/google/home/danscales/gerrit/go/src/cmd/compile/internal/syntax/walk.go:43 +0x148e
cmd/compile/internal/syntax.Walk(...)
        /usr/local/google/home/danscales/gerrit/go/src/cmd/compile/internal/syntax/walk.go:23
cmd/compile/internal/noder.(*irgen).generate(0xc00145de60, 0xc000061400, 0x80, 0x80)
        /usr/local/google/home/danscales/gerrit/go/src/cmd/compile/internal/noder/irgen.go:179 +0x278
cmd/compile/internal/noder.check2(0xc000061400, 0x80, 0x80)
        /usr/local/google/home/danscales/gerrit/go/src/cmd/compile/internal/noder/irgen.go:79 +0x717
cmd/compile/internal/noder.LoadPackage(0xc00001ebb0, 0x80, 0x95)
        /usr/local/google/home/danscales/gerrit/go/src/cmd/compile/internal/noder/noder.go:80 +0x3b6
cmd/compile/internal/gc.Main(0xe7ba00)
        /usr/local/google/home/danscales/gerrit/go/src/cmd/compile/internal/gc/main.go:188 +0xca5
main.main()
        /usr/local/google/home/danscales/gerrit/go/src/cmd/compile/main.go:54 +0x155

FAIL    bytes [build failed]

This is from validation code in noder2. It looks like types2 is calculating unsafe.Sizeof(abi.RegArgs{}) as 8, when it should be zero. This only started failing when runtime/stack.go:1316 was added:

	if GOARCH == "amd64" && unsafe.Sizeof(abi.RegArgs{}) > 0 && frame.argmap != nil {

so the bug may have been around for a while (i.e. it wasn't a recent change in types2 that caused it to show up).

@danscales danscales added this to the Go1.17 milestone Apr 5, 2021
@griesemer
Copy link
Contributor

Stand-alone reproducer:

package main

import "unsafe"

func main() {
	println(unsafe.Sizeof(RegArgs{}))
}

type RegArgs struct {
	Ints   [IntArgRegs]uintptr  // untyped integer registers
	Floats [FloatArgRegs]uint64 // untyped float registers

	// Fields above this point are known to assembly.

	// Ptrs is a space that duplicates Ints but with pointer type,
	// used to make pointers passed or returned  in registers
	// visible to the GC by making the type unsafe.Pointer.
	Ptrs [IntArgRegs]unsafe.Pointer

	// ReturnIsPtr is a bitmap that indicates which registers
	// contain or will contain pointers on the return path from
	// a reflectcall. The i'th bit indicates whether the i'th
	// register contains or will contain a valid Go pointer.
	ReturnIsPtr IntArgRegBitmap
}

// IntArgRegBitmap is a bitmap large enough to hold one bit per
// integer argument/return register.
type IntArgRegBitmap [(IntArgRegs + 7) / 8]uint8

const IntArgRegs = 0
const FloatArgRegs = 0

Running it:

$ go run -gcflags=-G=3 y.go
# command-line-arguments
./y.go:12:23: internal compiler error: got 8 from types2, but want 0

goroutine 1 [running]:
runtime/debug.Stack(0x1b9a520, 0xc0000be008, 0x0)
	/Users/gri/goroot/src/runtime/debug/stack.go:24 +0x9f
cmd/compile/internal/base.FatalfAt(0xc17000000002, 0x1a60f7d, 0x1f, 0xc0003b5058, 0x2, 0x2)
	/Users/gri/goroot/src/cmd/compile/internal/base/print.go:227 +0x1ea
cmd/compile/internal/noder.(*irgen).validateBuiltin(0xc0003bc000, 0xc000026140, 0x6, 0xc00007e100)
	/Users/gri/goroot/src/cmd/compile/internal/noder/validate.go:83 +0x2e5
cmd/compile/internal/noder.(*irgen).validate(0xc0003bc000, 0x1b9ea28, 0xc00007e100)
	/Users/gri/goroot/src/cmd/compile/internal/noder/validate.go:62 +0x170
cmd/compile/internal/noder.(*irgen).generate.func1(0x1b9ea28, 0xc00007e100, 0xc0003b5170)
	/Users/gri/goroot/src/cmd/compile/internal/noder/irgen.go:179 +0x3e
cmd/compile/internal/syntax.(*walker).node(0xc0003b56f8, 0x1b9ea28, 0xc00007e100)
	/Users/gri/goroot/src/cmd/compile/internal/syntax/walk.go:35 +0x6a
cmd/compile/internal/syntax.(*walker).exprList(0xc0003b56f8, 0xc000062050, 0x1, 0x1)
	/Users/gri/goroot/src/cmd/compile/internal/syntax/walk.go:298 +0x9a
cmd/compile/internal/syntax.(*walker).node(0xc0003b56f8, 0x1b9ea28, 0xc00007e0c0)
	/Users/gri/goroot/src/cmd/compile/internal/syntax/walk.go:142 +0x12ab
cmd/compile/internal/syntax.(*walker).node(0xc0003b56f8, 0x1b9ebb8, 0xc00007c0c0)
	/Users/gri/goroot/src/cmd/compile/internal/syntax/walk.go:199 +0x1897
cmd/compile/internal/syntax.(*walker).stmtList(0xc0003b56f8, 0xc000062060, 0x1, 0x1)
	/Users/gri/goroot/src/cmd/compile/internal/syntax/walk.go:304 +0x9a
cmd/compile/internal/syntax.(*walker).node(0xc0003b56f8, 0x1b9e9d8, 0xc00007e080)
	/Users/gri/goroot/src/cmd/compile/internal/syntax/walk.go:196 +0x19dc
cmd/compile/internal/syntax.(*walker).node(0xc0003b56f8, 0x1b9ec58, 0xc0000300c0)
	/Users/gri/goroot/src/cmd/compile/internal/syntax/walk.go:83 +0xc0e
cmd/compile/internal/syntax.(*walker).declList(0xc0003b56f8, 0xc00039c000, 0x6, 0x8)
	/Users/gri/goroot/src/cmd/compile/internal/syntax/walk.go:292 +0x9a
cmd/compile/internal/syntax.(*walker).node(0xc0003b56f8, 0x1b9ec08, 0xc00007a000)
	/Users/gri/goroot/src/cmd/compile/internal/syntax/walk.go:43 +0x148e
cmd/compile/internal/syntax.Walk(...)
	/Users/gri/goroot/src/cmd/compile/internal/syntax/walk.go:23
cmd/compile/internal/noder.(*irgen).generate(0xc0003bc000, 0xc00009e800, 0x2, 0x2)
	/Users/gri/goroot/src/cmd/compile/internal/noder/irgen.go:178 +0x278
cmd/compile/internal/noder.check2(0xc00009e800, 0x2, 0x2)
	/Users/gri/goroot/src/cmd/compile/internal/noder/irgen.go:78 +0x717
cmd/compile/internal/noder.LoadPackage(0xc0000c4120, 0x2, 0x2)
	/Users/gri/goroot/src/cmd/compile/internal/noder/noder.go:80 +0x3b6
cmd/compile/internal/gc.Main(0x1a796d8)
	/Users/gri/goroot/src/cmd/compile/internal/gc/main.go:188 +0xca5
main.main()
	/Users/gri/goroot/src/cmd/compile/main.go:54 +0x155

The relevant code is in cmd/compile/internal/noder/sizes.go, specifically lines 118ff:

		// gc: The last field of a struct is not allowed to
		// have size 0.
		last := s.Sizeof(fields[n-1].Type())
		if last == 0 {
			last = 1
		}

This looks like an inconsistency in the compiler/compiler validation code.

@griesemer
Copy link
Contributor

See also #9401 for background info.

@griesemer
Copy link
Contributor

Commenting out those lines (cmd/compile/internal/noder/sizes.go:118) avoids the crash, confirming that this is the code used for computing the sizes reported by types2.

@griesemer griesemer assigned danscales and unassigned griesemer Apr 5, 2021
@gopherbot
Copy link

Change https://golang.org/cl/307549 mentions this issue: cmd/compile: fix gcSizes.Sizeof for a zero-sized struct

@golang golang locked and limited conversation to collaborators Apr 6, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

3 participants