golangci-lint icon indicating copy to clipboard operation
golangci-lint copied to clipboard

"fmt" imported and not used (typecheck) with CGO_ENABLED=1

Open iameli opened this issue 2 years ago • 5 comments

Welcome

  • [X] Yes, I'm using a binary release within 2 latest major releases. Only such installations are supported.
  • [X] Yes, I've searched similar issues on GitHub and didn't find any.
  • [X] Yes, I've included all information below (version, config, etc.).
  • [X] Yes, I've tried with the standalone linter if available (e.g., gocritic, go vet, etc.). (https://golangci-lint.run/usage/linters/)

Description of the problem

I've got an extremely minimal file here.

package state

import (
	"fmt"

	"github.com/livepeer/catalyst-api/events"
	v0 "github.com/livepeer/catalyst-api/schema/v0"
)

func HandleEvent(e *events.SignedEvent) error {
	switch act := e.Action.(type) {

	case *v0.ChannelDefinition:
		return nil

	default:
		return fmt.Errorf("unknown action type: %s", act)
	}
}

Linting it makes the curious claim that fmt is not used, even though it is:

▶ curl -LO https://github.com/golangci/golangci-lint/releases/download/v1.52.2/golangci-lint-1.52.2-darwin-arm64.tar.gz

▶ tar xzvf golangci-lint-1.52.2-darwin-arm64.tar.gz
x golangci-lint-1.52.2-darwin-arm64/LICENSE
x golangci-lint-1.52.2-darwin-arm64/README.md
x golangci-lint-1.52.2-darwin-arm64/golangci-lint

▶ golangci-lint-1.52.2-darwin-arm64/golangci-lint run ./state.go
state.go:4:2: "fmt" imported and not used (typecheck)
	"fmt"
	^

CGO_ENABLED=0 works around the problem:

▶ CGO_ENABLED=0 ./golangci-lint-1.52.2-darwin-arm64/golangci-lint run state.go
▶ echo $?
0

Version of golangci-lint

./golangci-lint-1.52.2-darwin-arm64/golangci-lint version
golangci-lint has version 1.52.2 built with go1.20.2 from da04413a on 2023-03-25T18:11:28Z

Configuration file

none present

Go environment

▶ go version && go env
go version go1.20.3 darwin/arm64
GO111MODULE=""
GOARCH="arm64"
GOBIN=""
GOCACHE="/Users/iameli/Library/Caches/go-build"
GOENV="/Users/iameli/Library/Application Support/go/env"
GOEXE=""
GOEXPERIMENT=""
GOFLAGS=""
GOHOSTARCH="arm64"
GOHOSTOS="darwin"
GOINSECURE=""
GOMODCACHE="/Users/iameli/code/go/pkg/mod"
GONOPROXY=""
GONOSUMDB=""
GOOS="darwin"
GOPATH="/Users/iameli/code/go"
GOPRIVATE=""
GOPROXY="https://proxy.golang.org,direct"
GOROOT="/usr/local/go"
GOSUMDB="sum.golang.org"
GOTMPDIR=""
GOTOOLDIR="/usr/local/go/pkg/tool/darwin_arm64"
GOVCS=""
GOVERSION="go1.20.3"
GCCGO="gccgo"
AR="ar"
CC="clang"
CXX="clang++"
CGO_ENABLED="1"
GOMOD="/Users/iameli/nodetest/golint-ci/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 -arch arm64 -pthread -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -fdebug-prefix-map=/var/folders/0b/3ctslbn55w59lvls6498plgc0000gn/T/go-build1244796343=/tmp/go-build -gno-record-gcc-switches -fno-common"

Verbose output of running

▶ ./golangci-lint-1.52.2-darwin-arm64/golangci-lint cache clean
▶ ./golangci-lint-1.52.2-darwin-arm64/golangci-lint run state.go -v
INFO [config_reader] Config search paths: [./ /Users/iameli/nodetest/golint-ci /Users/iameli/nodetest /Users/iameli /Users /]
INFO [lintersdb] Active 7 linters: [errcheck gosimple govet ineffassign staticcheck typecheck unused]
INFO [loader] Go packages loading at mode 575 (types_sizes|compiled_files|deps|exports_file|files|imports|name) took 1.711078708s
INFO [runner/filename_unadjuster] Pre-built 0 adjustments in 1.91525ms
INFO [linters_context/goanalysis] analyzers took 12.20793387s with top 10 stages: buildir: 8.447885212s, fact_deprecated: 701.837528ms, ctrlflow: 665.153677ms, inspect: 649.164711ms, printf: 569.491626ms, fact_purity: 388.853328ms, nilness: 337.780163ms, SA5012: 228.748828ms, typedness: 218.028427ms, directives: 67.459µs
INFO [runner] Issues before processing: 141, after processing: 1
INFO [runner] Processors filtering stat (out/in): nolint: 141/141, max_from_linter: 1/1, source_code: 1/1, path_shortener: 1/1, fixer: 1/1, sort_results: 1/1, exclude-rules: 141/141, skip_files: 141/141, max_same_issues: 1/1, severity-rules: 1/1, path_prettifier: 141/141, path_prefixer: 1/1, diff: 1/1, filename_unadjuster: 141/141, skip_dirs: 141/141, autogenerated_exclude: 141/141, identifier_marker: 141/141, exclude: 141/141, uniq_by_line: 1/141, max_per_file_from_linter: 1/1, cgo: 141/141
INFO [runner] processing took 1.725082ms with stages: identifier_marker: 745.499µs, exclude-rules: 695.291µs, path_prettifier: 131.334µs, nolint: 99.792µs, source_code: 18.041µs, skip_dirs: 13.501µs, autogenerated_exclude: 6.625µs, cgo: 4.209µs, uniq_by_line: 4µs, filename_unadjuster: 3.084µs, max_same_issues: 958ns, path_shortener: 666ns, max_from_linter: 416ns, skip_files: 334ns, max_per_file_from_linter: 333ns, fixer: 249ns, diff: 209ns, exclude: 208ns, severity-rules: 166ns, sort_results: 126ns, path_prefixer: 41ns
INFO [runner] linters took 2.291110458s with stages: goanalysis_metalinter: 2.289284083s
state.go:4:2: "fmt" imported and not used (typecheck)
	"fmt"
	^
INFO File cache stats: 1 entries of total size 319B
INFO Memory: 42 samples, avg is 230.0MB, max is 502.9MB
INFO Execution took 4.013530333s

Code example or link to a public repository

https://github.com/livepeer/golangci-lint-bug

iameli avatar May 03 '23 10:05 iameli

Hey, thank you for opening your first Issue ! 🙂 If you would like to contribute we have a guide for contributors.

boring-cyborg[bot] avatar May 03 '23 10:05 boring-cyborg[bot]

Hello,

It's probably related to your CGO environment (missing C compiler, missing system dependencies, etc.).

With my computer I'm not not able to reproduce your issue.

But If I use an environment without GCC (for example) I can reproduce it.

I updated your example:

state.go
package main

import (
	"fmt"

	"github.com/livepeer/catalyst-api/events"
	v0 "github.com/livepeer/catalyst-api/schema/v0"
)

func main(){}

func HandleEvent(e *events.SignedEvent) error {
	switch act := e.Action.(type) {

	case *v0.ChannelDefinition:
		return nil

	default:
		return fmt.Errorf("unknown action type: %s", act)
	}
}

If you try to do a go run you will see the problem.

$ docker run --rm -it golang:1.20-alpine sh

/go # apk add curl
fetch https://dl-cdn.alpinelinux.org/alpine/v3.17/main/x86_64/APKINDEX.tar.gz
fetch https://dl-cdn.alpinelinux.org/alpine/v3.17/community/x86_64/APKINDEX.tar.gz
(1/4) Installing brotli-libs (1.0.9-r9)
(2/4) Installing nghttp2-libs (1.51.0-r0)
(3/4) Installing libcurl (8.0.1-r0)
(4/4) Installing curl (8.0.1-r0)
Executing busybox-1.35.0-r29.trigger
OK: 9 MiB in 20 packages

/go # curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b $(go env GOPATH)/bin v1.52.2
golangci/golangci-lint info checking GitHub for tag 'v1.52.2'
golangci/golangci-lint info found version: 1.52.2 for v1.52.2/linux/amd64
golangci/golangci-lint info installed /go/bin/golangci-lint

/go # golangci-lint version
golangci-lint has version 1.52.2 built with go1.20.2 from da04413a on 2023-03-25T18:11:28Z

/go # apk add git
(1/3) Installing libexpat (2.5.0-r0)
(2/3) Installing pcre2 (10.42-r0)
(3/3) Installing git (2.38.5-r0)
Executing busybox-1.35.0-r29.trigger
OK: 16 MiB in 23 packages

/go # git clone https://github.com/livepeer/golangci-lint-bug.git
Cloning into 'golangci-lint-bug'...
remote: Enumerating objects: 8, done.
remote: Counting objects: 100% (8/8), done.
remote: Compressing objects: 100% (5/5), done.
remote: Total 8 (delta 3), reused 8 (delta 3), pack-reused 0
Receiving objects: 100% (8/8), 72.00 KiB | 1.89 MiB/s, done.
Resolving deltas: 100% (3/3), done.

/go # go env CGO_ENABLED
0

/go # cd golangci-lint-bug 

/go/golangci-lint-bug # golangci-lint run -v
INFO [config_reader] Config search paths: [./ /go/golangci-lint-bug /go / /root] 
INFO [lintersdb] Active 7 linters: [errcheck gosimple govet ineffassign staticcheck typecheck unused] 
INFO [loader] Go packages loading at mode 575 (compiled_files|exports_file|files|name|types_sizes|deps|imports) took 149.112299ms 
INFO [runner/filename_unadjuster] Pre-built 0 adjustments in 107.787µs 
INFO [linters_context/goanalysis] analyzers took 12.661526581s with top 10 stages: buildir: 9.98276413s, inspect: 508.280216ms, fact_deprecated: 498.816725ms, ctrlflow: 428.430002ms, printf: 340.210852ms, nilness: 258.962336ms, fact_purity: 245.912104ms, SA5012: 243.242959ms, typedness: 153.015528ms, copylocks: 100.051µs 
INFO [runner] processing took 2.247µs with stages: skip_dirs: 323ns, nolint: 290ns, max_same_issues: 273ns, max_from_linter: 129ns, cgo: 125ns, autogenerated_exclude: 123ns, fixer: 122ns, source_code: 119ns, path_prettifier: 119ns, skip_files: 118ns, filename_unadjuster: 115ns, identifier_marker: 115ns, diff: 34ns, sort_results: 31ns, exclude: 31ns, path_shortener: 31ns, exclude-rules: 31ns, max_per_file_from_linter: 30ns, uniq_by_line: 30ns, severity-rules: 30ns, path_prefixer: 28ns 
INFO [runner] linters took 2.264754685s with stages: goanalysis_metalinter: 2.264714482s 
INFO File cache stats: 0 entries of total size 0B 
INFO Memory: 26 samples, avg is 448.3MB, max is 640.1MB 
INFO Execution took 2.416810464s

/go/golangci-lint-bug # golangci-lint cache clean
 
/go/golangci-lint-bug # CGO_ENABLED=1 golangci-lint run -v
INFO [config_reader] Config search paths: [./ /go/golangci-lint-bug /go / /root] 
INFO [lintersdb] Active 7 linters: [errcheck gosimple govet ineffassign staticcheck typecheck unused] 
INFO [loader] Go packages loading at mode 575 (deps|imports|name|types_sizes|compiled_files|exports_file|files) took 1.235883814s 
INFO [runner/filename_unadjuster] Pre-built 0 adjustments in 103.987µs 
INFO [linters_context/goanalysis] analyzers took 8.842466045s with top 10 stages: buildir: 6.373144121s, inspect: 666.716343ms, fact_deprecated: 541.468666ms, ctrlflow: 372.916357ms, printf: 220.741183ms, fact_purity: 203.343687ms, nilness: 194.792094ms, SA5012: 141.218564ms, typedness: 126.124713ms, SA1012: 101.801µs 
INFO [runner] Issues before processing: 141, after processing: 1 
INFO [runner] Processors filtering stat (out/in): max_same_issues: 1/1, sort_results: 1/1, skip_dirs: 141/141, nolint: 141/141, uniq_by_line: 1/141, path_prefixer: 1/1, cgo: 141/141, diff: 1/1, fixer: 1/1, severity-rules: 1/1, filename_unadjuster: 141/141, skip_files: 141/141, source_code: 1/1, exclude: 141/141, exclude-rules: 141/141, max_per_file_from_linter: 1/1, max_from_linter: 1/1, path_shortener: 1/1, path_prettifier: 141/141, autogenerated_exclude: 141/141, identifier_marker: 141/141 
INFO [runner] processing took 1.469434ms with stages: identifier_marker: 744.961µs, exclude-rules: 566.949µs, nolint: 81.649µs, path_prettifier: 33.921µs, filename_unadjuster: 9.705µs, source_code: 9.158µs, skip_dirs: 9.024µs, cgo: 3.63µs, uniq_by_line: 3.497µs, autogenerated_exclude: 2.987µs, max_same_issues: 941ns, fixer: 610ns, path_shortener: 545ns, max_from_linter: 419ns, max_per_file_from_linter: 395ns, skip_files: 282ns, exclude: 189ns, severity-rules: 167ns, path_prefixer: 149ns, diff: 149ns, sort_results: 107ns 
INFO [runner] linters took 1.638316181s with stages: goanalysis_metalinter: 1.636799732s 
state.go:4:2: "fmt" imported and not used (typecheck)
        "fmt"
        ^
INFO File cache stats: 1 entries of total size 319B 
INFO Memory: 30 samples, avg is 246.4MB, max is 619.8MB 
INFO Execution took 2.877801233s

# Edition of the state.go file to have main.

/go/golangci-lint-bug # CGO_ENABLED=1 go run ./state.go 
# runtime/cgo
cgo: C compiler "gcc" not found: exec: "gcc": executable file not found in $PATH

ldez avatar May 03 '23 11:05 ldez

@ldez Totally! I'm pretty sure it's impossible to build that project without CGO_ENABLED=0 due to some ffmpeg dependencies that I need to do a better job isolating. So CGO_ENABLED=0 is an acceptable workaround for my case. But this still counts as a bug, yeah? golangci-lint is reporting "fmt" imported and not used when the problem is completely unrelated?

iameli avatar May 03 '23 12:05 iameli

But this still counts as a bug, yeah? golangci-lint is reporting "fmt" imported and not used when the problem is completely unrelated?

No, because in this situation the analysis (done with Go tooling) is not able to perform a better analysis.

ldez avatar May 03 '23 12:05 ldez

Hmm. Somewhere in the universe there is some code that's telling me a lie about fmt. I'll try and figure out where it is.

iameli avatar May 03 '23 13:05 iameli