Skip to content

x/tools/go/pointer: Pointer MayAlias reports false, when it should report true #46280

@chabbimilind

Description

@chabbimilind

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

$ go version
1.15.5

Does this issue reproduce with the latest release?

Did not check, but there were no fixes in the package addressing this issue.

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

go env Output
$ go env
go version go1.15.5 darwin/amd64
milind-C02X40F1HX8F:alias milind$ go env
GO111MODULE=""
GOARCH="amd64"
GOBIN=""
GOCACHE="/Users/milind/Library/Caches/go-build"
GOENV="/Users/milind/Library/Application Support/go/env"
GOEXE=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="darwin"
GOINSECURE=""
GOMODCACHE="/Users/milind/gocode/pkg/mod"
GONOPROXY=""
GONOSUMDB=""
GOOS="darwin"
GOPATH="/Users/milind/gocode"
GOPRIVATE=""
GOPROXY="https://proxy.golang.org,direct"
GOROOT="/usr/local/Cellar/go/1.15.5/libexec"
GOSUMDB="sum.golang.org"
GOTMPDIR=""
GOTOOLDIR="/usr/local/Cellar/go/1.15.5/libexec/pkg/tool/darwin_amd64"
GCCGO="gccgo"
AR="ar"
CC="clang"
CXX="clang++"
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 -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -fdebug-prefix-map=/var/folders/xr/hsc7mk1n5glg6vfqb4z5nlkh0000gn/T/go-build659129965=/tmp/go-build -gno-record-gcc-switches -fno-common"

What did you do?

I have the following code (you need https://github.com/uber-go/tally/ ) named bug.go in that attached repro.zip, which contains all files needed for reproducing.

package main

import (
        "fmt"
        "unsafe"
        tally "github.com/uber-go/tally")
)

func main() {
        x := tally.Scope.Counter
        lst := []unsafe.Pointer{(unsafe.Pointer)(&x)}
        fmt.Printf("&v", lst)
}

Scope is an interface in tally and Counter function looks like this

func (s *scope) Counter(name string) Counter {
	name = s.sanitizer.Name(name)
	if c, ok := s.counter(name); ok {
		return c
	}
	s.cm.Lock()
	defer s.cm.Unlock()
 ...

The reason to take the address of tally.Scope.Counter in main is only to make it appear as if the Counter function inside tally is reachable.

I have written a pointer analysis driver (pointsto_bug.go) (feed the above file to this driver) that is trying to check if the two instances of s.cm used inside Counter at Lock() and Unlock() "May Alias".

The driver collects all values on which the program may be calling Lock/Unlock/Rlock/RUnlock to feed to the Analyze() function of the pointer package.
Additionally, the two sync.Mutex values, on which Lock and Unlock are called, are also remembered (in p1 and p2).
Then, in the Result provided by Analyze(), I query if p1.MayAlias(p2).

However, the pointer analysis reports “false”.

What did you expect to see?

The expectation is that the MayAlias report true, in fact here they are the same objects.

What did you see instead?

MayAlias reports false

Addendum

Instead of using the large tally library, if you either create a small Scope interface inside themain package (example nobug.go)

, the function Counter is not listed in the set of ssautil.AllFunctions(prog). The same holds true if I carve out a small package with just a single Scope interface and a Counter function implementation.
repro.zip

Metadata

Metadata

Assignees

No one assigned

    Labels

    AnalysisIssues related to static analysis (vet, x/tools/go/analysis)FrozenDueToAgeNeedsInvestigationSomeone must examine and confirm this is a valid issue and not a duplicate of an existing one.ToolsThis 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