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/gopls: incorrect size computation in fieldalignment analyzer #51016

Closed
hyangah opened this issue Feb 4, 2022 · 11 comments
Closed

x/tools/gopls: incorrect size computation in fieldalignment analyzer #51016

hyangah opened this issue Feb 4, 2022 · 11 comments
Assignees
Labels
FrozenDueToAge gopls/analysis Issues related to running analysis in gopls gopls Issues related to the Go language server, gopls. Tools This label describes issues relating to any tools in the x/tools repository.
Milestone

Comments

@hyangah
Copy link
Contributor

hyangah commented Feb 4, 2022

gopls version

v0.7.5 compiled with go1.18beta2

go version

go version go1.18beta2 darwin/amd64

What did you do?

gopls with fieldalignment analyzer enabled "ui.diagnostic.analyses": { "fieldalignment": true }

type X struct {
	a time.Time
	b byte
	c int32
	e byte
}

What did you expect to see?

fieldalignment diagnostic message with correct struct size (40 according to unsafe.Sizeof).

What did you see instead?

diagnostic message with incorrect size info

	"owner": "_generated_diagnostic_collection_name_#1",
	"severity": 4,
	"message": "struct of size 12 could be 8",
	"source": "fieldalignment",
@gopherbot gopherbot added Tools This label describes issues relating to any tools in the x/tools repository. gopls Issues related to the Go language server, gopls. labels Feb 4, 2022
@gopherbot gopherbot added this to the Unreleased milestone Feb 4, 2022
@findleyr
Copy link
Contributor

findleyr commented Feb 4, 2022

This is a consequence of AST trimming that gopls does to reduce memory. There are other similar issues (for example #50196).

IIRC AST trimming provides modest but not major benefit to most users (~25% memory reduction). I am not sure that is worth the loss in precision. I would like to remove our AST trimming in favor of teaching gopls to load fewer packages, but have hesitated to simply remove it before we have offsetting optimizations. Maybe we should.

@findleyr findleyr modified the milestones: Unreleased, gopls/on-deck Feb 7, 2022
@findleyr findleyr added the gopls/analysis Issues related to running analysis in gopls label Apr 11, 2022
@ainar-g
Copy link
Contributor

ainar-g commented Jun 28, 2022

We've found a case in which there is a conflict between fieldalignment the analyser and fieldalignment the tool:

type t struct {
	a *int
	b netip.AddrPort
}

The analyser complains with struct of size 16 could be 8, but the tool sees nothing wrong. On the other hand, if we move a down, the analyser remains silent while the tool correctly notes: struct with 40 pointer bytes could be 32. This is using golang.org/x/tools/gopls@v0.0.0-20220628132954-2a900561e78a and fieldalignment at v0.1.12-0.20220628132954-2a900561e78a as well.

Is there a way to disable the AST trimming optimization? If not, could adding that option or fixing the analyser receive a higher priority from the gopls team? Thanks.

@findleyr
Copy link
Contributor

There is no option, but we can add such an option with higher priority.

It will take us longer to disable trimming entirely (we'd like to offset with other optimizations).

@gopherbot
Copy link

Change https://go.dev/cl/415503 mentions this issue: internal/lsp/cache: don't trim unexported struct fields

@ainar-g
Copy link
Contributor

ainar-g commented Jul 6, 2022

I've checked out change 415503, built it, cleared the cache, and tried using the new gopls on the example I provided before:

git fetch https://go.googlesource.com/tools refs/changes/03/415503/5 && git checkout -b change-415503 FETCH_HEAD
cd ./gopls/
go install
go clean -cache
nvim ~/tmp/main.go

Yet, the incorrect warning is still there. Is there any other cache I need to remove? I haven't found anything that would seem like it belongs to gopls in ~/.cache, and the troubleshooting guide doesn't mention any separate cache either. gopls version shows (devel).

Am I doing something wrong?

@findleyr
Copy link
Contributor

@ainar-g thanks for testing this out.

Unfortunately this CL addresses only half of the problem: the other half is that we don't compute analysis facts for the imported packages: https://go.dev/issue/48738. We are going to work on that soon, as well.

@adonovan
Copy link
Member

Unfortunately this CL addresses only half of the problem

Indeed, I meant to use "updates" not "fixes" in the CL description to relate it to this issue. Fixed (I mean updated) now.

And thanks @ainar-g for testing it out.

@findleyr findleyr modified the milestones: gopls/v0.9.1, gopls/v0.9.2 Jul 13, 2022
gopherbot pushed a commit to golang/tools that referenced this issue Jul 13, 2022
The trimming optimization deletes parts of the syntax tree
that don't affect the type checking of package-level declarations.
It used to remove unexported struct fields, but this had
observable consequences: it would affect the offset of later
fields, and the size and aligment of structs, causing the
'fieldalignment' analyzer to report incorrect findings.
Also, it required a complex workaround in the UI element
for hovering over a type to account for the missing parts.

This change restores unexported fields.
The logic of recordFieldsUses has been inlined and specialized
for each case (params+results, struct fields, interface
methods) as they are more different than alike.

BenchmarkMemStats on k8s shows +4% HeapAlloc:
a lot, but a small part of the 32% saving of the trimming
optimization as a whole.

Also:
- trimAST: delete func bodies without visiting them.
- minor clarifications.

Updates golang/go#51016

Change-Id: Ifae15564a8fb86af3ea186af351a2a92eb9deb22
Reviewed-on: https://go-review.googlesource.com/c/tools/+/415503
gopls-CI: kokoro <noreply+kokoro@google.com>
Run-TryBot: Alan Donovan <adonovan@google.com>
Auto-Submit: Alan Donovan <adonovan@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Robert Findley <rfindley@google.com>
@findleyr findleyr modified the milestones: gopls/v0.9.2, gopls/v0.10.0 Aug 1, 2022
@findleyr
Copy link
Contributor

findleyr commented Aug 1, 2022

Computing analysis facts is a large project. I have tentatively moved this to v0.10.0, just so it stays among our top priorities, but the likely reality is that it will take us ~months to have proper analysis facts.

Proper analysis facts are one of the major outstanding priorities for gopls.

@findleyr
Copy link
Contributor

@adonovan is this fixed now that you've landed your new analysis driver?

@adonovan
Copy link
Member

Yes, I just verified that the original example now works. I was thinking of adding a test, but it's the exact same mechanism tested by the existing test of facts using the printf driver, so it doesn't seem necessary.

@findleyr
Copy link
Contributor

For anyone who finds this issue: be aware that the new analysis driver is a big change to gopls' execution model (we're now doing analysis using an on-disk cache of export data and facts). There will be a temporary performance overhead due to double-type-checking, which we plan to mitigate before the next release. There also may be bugs.

@golang golang locked and limited conversation to collaborators Dec 20, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
FrozenDueToAge gopls/analysis Issues related to running analysis in gopls gopls Issues related to the Go language server, gopls. Tools This label describes issues relating to any tools in the x/tools repository.
Projects
None yet
Development

No branches or pull requests

6 participants