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

x/tools/go/analysis/passes/nilness: incorrect "impossible condition: nil != nil"; missing tautological error #70381

Open
hut8 opened this issue Nov 15, 2024 · 1 comment
Labels
Tools This label describes issues relating to any tools in the x/tools repository.
Milestone

Comments

@hut8
Copy link

hut8 commented Nov 15, 2024

Go version

go version go1.23.0 linux/amd64

Output of go env in your module/workspace:

GO111MODULE=''
GOARCH='amd64'
GOBIN=''
GOCACHE='/home/liam/.cache/go-build'
GOENV='/home/liam/.config/go/env'
GOEXE=''
GOEXPERIMENT=''
GOFLAGS=''
GOHOSTARCH='amd64'
GOHOSTOS='linux'
GOINSECURE=''
GOMODCACHE='/home/liam/go/pkg/mod'
GONOPROXY=''
GONOSUMDB=''
GOOS='linux'
GOPATH='/home/liam/go'
GOPRIVATE=''
GOPROXY='https://proxy.golang.org,direct'
GOROOT='/usr/local/go'
GOSUMDB='sum.golang.org'
GOTMPDIR=''
GOTOOLCHAIN='auto'
GOTOOLDIR='/usr/local/go/pkg/tool/linux_amd64'
GOVCS=''
GOVERSION='go1.23.0'
GODEBUG=''
GOTELEMETRY='local'
GOTELEMETRYDIR='/home/liam/.config/go/telemetry'
GCCGO='gccgo'
GOAMD64='v1'
AR='ar'
CC='gcc'
CXX='g++'
CGO_ENABLED='1'
GOMOD='/home/liam/nilness-bug/go.mod'
GOWORK=''
CGO_CFLAGS='-O2 -g'
CGO_CPPFLAGS=''
CGO_CXXFLAGS='-O2 -g'
CGO_FFLAGS='-O2 -g'
CGO_LDFLAGS='-O2 -g'
PKG_CONFIG='pkg-config'
GOGCCFLAGS='-fPIC -m64 -pthread -Wl,--no-gc-sections -fmessage-length=0 -ffile-prefix-map=/tmp/go-build1057087488=/tmp/go-build -gno-record-gcc-switches'

What did you do?

I believe there is a bug in the nilness checker that incorrectly reports an impossible "nil != nil" and also omits an error in a different location about a tautological comparison. This code demonstrates it:

package main

import "fmt"

func TriggerBug(a *struct{}) {
	hasA := a != nil // "impossible condition: nil != nil"
	if hasA {
		fmt.Println("A is not nil")
		return
	}
	if !hasA {
		fmt.Println("A is nil")
	}
}

I checked here: https://github.com/golang/go/issues?page=1&q=is%3Aissue+is%3Aopen+nilness and I can't find anything that matches.

What did you see happen?

	hasA := a != nil // "impossible condition: nil != nil"

Here is a screenshot for clarity:

image

What did you expect to see?

The above error implies that a is always nil and therefore a != nil will never happen. That is not true. However, there still is a problem with the code. Because of the return, then the if !hasA is tautological -- although, that's a different error, and it's not reported, and the error that is reported is not only erroneous but also in the wrong place.

This, for example, correctly reports no errors:

func TriggerBug(a *struct{}) {
	hasA := a != nil
	if hasA {
		fmt.Println("A is not nil")
		return
	}

	fmt.Println("A is nil")
}

So I would expect to see something like this:

func TriggerBug(a *struct{}) {
	hasA := a != nil
	if hasA {
		fmt.Println("A is not nil")
		return
	}
	// at this point, hasA is definitely false
	if !hasA { //  "tautological condition: nil == nil"
		fmt.Println("A is nil")
	}
}

Interestingly, if I just get rid of hasA and put the expression directly in the if statement, I get:

func TriggerBug(a *struct{}) {
	if a != nil {
		fmt.Println("A is not nil")
		return
	}
	if a == nil { // tautological condition: nil == nil
		fmt.Println("A is nil")
	}
}

image

That's what I would expect to see whether or not I have the boolean value broken out into a different variable.

@gopherbot gopherbot added the Tools This label describes issues relating to any tools in the x/tools repository. label Nov 15, 2024
@gopherbot gopherbot added this to the Unreleased milestone Nov 15, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Tools This label describes issues relating to any tools in the x/tools repository.
Projects
None yet
Development

No branches or pull requests

3 participants