go/types: calls setScopePos on dot-imported objects #32154
Labels
FrozenDueToAge
NeedsInvestigation
Someone must examine and confirm this is a valid issue and not a duplicate of an existing one.
release-blocker
Milestone
When dot importing a package, the type checker adds the exported objects of the imported package to the importing file's scope (go/types/resolver.go:298 as of 1ab063c) by calling Checker.declare. declare calls object.setScopePos, which sets the object's scopePos_ field unconditionally. Not only does this seem inherently wrong, changing the object's original scopePos_, it is also racy when loading multiple packages in parallel. This issue seems to have been introduced in d63c42d.
Since the only use of scopePos_ is in the following comparison
it seems unlikely that this will have caused any incorrect computations. This makes writing a hermetic minimal reproducible example difficult. However, the race condition is real. The following example exhibits a race in go/types due to setting scopePos_:
Where sandbox/bar is a package in GOPATH, as follows:
this first loads fmt (and its transitive dependencies). It then loads sandbox/bar twice (the normal package and the test package) in parallel, which will cause the racy write of scopePos_:
I'm marking this for Go 1.13 as it makes thread-safe use of go/types difficult (or at least inefficient). Go tool development has picked up speed thanks to go/packages and gopls, and it'd be nice if we didn't have a race in the stdlib for the next 6 months (even though it has existed for years, and can also be exercised with the old go/loader package in a similar manner.)
/cc @griesemer as the owner of go/types
/cc @ianthehat in case he's interested.
The text was updated successfully, but these errors were encountered: