Skip to content

x/tools/go/analysis/passes/fieldalignment/cmd/fieldalignment incorrect size calculations, false positives #44877

Closed
@iamtakingiteasy

Description

@iamtakingiteasy

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

$ go version
go version go1.15.8 linux/amd64

Does this issue reproduce with the latest release?

Reproduces from upstream tools repository

What operating system and processor architecture are you using (go env)?

go env Output
$ go env
GO111MODULE=""
GOARCH="amd64"
GOBIN=""
GOCACHE="/home/user/.cache/go-build"
GOENV="/home/user/.config/go/env"
GOEXE=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="linux"
GOINSECURE=""
GOMODCACHE="/home/go/pkg/mod"
GOOS="linux"
GOPATH="/home/go"
GOPROXY="https://proxy.golang.org,direct"
GOROOT="/usr/lib/go"
GOSUMDB="sum.golang.org"
GOTMPDIR=""
GOTOOLDIR="/usr/lib/go/pkg/tool/linux_amd64"
GCCGO="gccgo"
AR="ar"
CC="gcc"
CXX="g++"
CGO_ENABLED="1"
GOMOD=""
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"
PKG_CONFIG="pkg-config"
GOGCCFLAGS="-fPIC -m64 -pthread -fmessage-length=0 -fdebug-prefix-map=/tmp/go-build474839094=/tmp/go-build -gno-record-gcc-switches"

What did you do?

running

./fieldalignment /tmp/z/foo.go on

package main

import (
	"fmt"
	"unsafe"
)

// (1)
type ex1A struct {
	S string
	F int32
}

type ex1B struct {
	F int32
	S string
}

// (2)
type ex2A struct {
	S string
	F *int32
}

type ex2B struct {
	F *int32
	S string
}

func main() {
	var (
		a1 ex1A
		b1 ex1B
		a2 ex2A
		b2 ex2B
		c  int32
		d  string
		e  *int32
	)

	fmt.Printf("%10s : %d\n", "a1", unsafe.Sizeof(a1))       // 24
	fmt.Printf("%10s : %d\n", "b1", unsafe.Sizeof(b1))       // 24
	fmt.Printf("%10s : %d\n", "a2", unsafe.Sizeof(a2))       // 24
	fmt.Printf("%10s : %d\n", "b2", unsafe.Sizeof(b2))       // 24
	fmt.Printf("%10s : %d\n", "int32, c", unsafe.Sizeof(c))  // 4
	fmt.Printf("%10s : %d\n", "string, d", unsafe.Sizeof(d)) // 16
	fmt.Printf("%10s : %d\n", "*int32, e", unsafe.Sizeof(e)) // 8
}

What did you expect to see?

(1) Since string alone is 16 bytes long, and int32 is 4 bytes long, report should read "struct with 24 pointer bytes could be 20" (16+4+4 | 16+4)
Maybe it also superfluous to report structures that cannot be made any smaller such as in this case, since 20 would still be aligned to 24. At very least this should be indicated in report.

(2) No error reported. Since string alone is 16 bytes long and *int32 is 8 bytes long, it would be 16+8 = 24 regardless of position of F.

What did you see instead?

/tmp/z/foo.go:14:11: struct with 16 pointer bytes could be 8
/tmp/z/foo.go:20:11: struct with 24 pointer bytes could be 16

Metadata

Metadata

Assignees

No one assigned

    Labels

    FrozenDueToAgeToolsThis label describes issues relating to any tools in the x/tools repository.

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions