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

cmd/vet: vet is reporting lock value copying on composite literal assignment #13675

Open
fsouza opened this issue Dec 18, 2015 · 8 comments
Open
Labels
Analysis Issues related to static analysis (vet, x/tools/go/analysis)
Milestone

Comments

@fsouza
Copy link
Contributor

fsouza commented Dec 18, 2015

The code is the following:

    r := hipacheRouter{prefix: "hipache"}
    err := r.AddBackend("tip")
    c.Assert(err, check.IsNil)
    config.Set("hipache:redis-server", "127.0.0.1:6380")
    defer config.Unset("hipache:redis-server")
    r = hipacheRouter{prefix: "hipache"}

go vet is reporting "assignment copies lock value to r: hipache.hipacheRouter" in the last line. The type hipacheRouter indeed contains a lock:

type hipacheRouter struct {
    sync.Mutex
    prefix string
    pool   *redis.Pool
}

But as stated in the code, I'm copying a composite literal to r, so go vet should not complain about that. Changing the variable to r2 and the attribution to a declaration makes vet happy. I've also tried to make the mutex a named field, and it didn't help.

I tried to reproduce it with a simple Go program and failed to do so. I have the impression that there's another violation going on, and vet is reporting lock copying.

It works on Go 1.5.2, and fails on Go 1.6beta1, both on linux_amd64 and darwin_amd64. Details are available on Travis:

@ianlancetaylor
Copy link
Contributor

It's easy to recreate this:

package p

import "sync"

type S struct {
    mu sync.Mutex
}

func F() {
    r := S{}
    r = S{}
    _ = r
}

There is currently no composite literal exception to the lock check. The declaration of r is considered OK by vet. The assignment to r is not.

We could change vet to permit the copy in the case of a composite literal where the uncopyable value is uninitialized. But I'm not sure if we should make that change, since I would probably tell somebody doing this to rewrite the code.

@ianlancetaylor ianlancetaylor added this to the Unplanned milestone Dec 18, 2015
@fsouza
Copy link
Contributor Author

fsouza commented Dec 18, 2015

If you think that the code should be rewritten, maybe the tool could report an error on the reason why it should be rewritten? BTW, what's the reason? The risk to orphan a locked mutex on reassign?

I'm changing the code, thanks!

fsouza pushed a commit to tsuru/tsuru that referenced this issue Dec 18, 2015
@ianlancetaylor
Copy link
Contributor

I would recommend rewriting because the code is copying a sync.Mutex value, which is forbidden. That copy is occurring whether the value is hidden in a composite literal or not. It happens to be OK to copy the zero value of a sync.Mutex, which is why the code works. But at least to me it still seems better to not copy.

@fsouza
Copy link
Contributor Author

fsouza commented Dec 18, 2015

@ianlancetaylor assigning values is copying, even when I'm declaring and assigning, so the first line in the function F should be invalid as well?

@ianlancetaylor
Copy link
Contributor

Yes, but we let it slide because anything else would be too painful.

@fsouza
Copy link
Contributor Author

fsouza commented Dec 18, 2015

@ianlancetaylor I see, thanks for the clarification! I've updated my code already.

Please feel free to close this issue as invalid if you think that's appropriate.

Mjolnir42 added a commit to 1and1/soma that referenced this issue Oct 25, 2016
config.go:
- malformatted json tag for PokeBatchSize
- unexported url has json tag declaration

logrotate.go:
- format string in Print statement

soma_guide_post__validate.go:
- no format string in Errorf statement

soma_handler_tree_keeper__order.go:
- format string in Println statement

soma_handler_supervisor.go:
This file is changed to clean the `go vet` output. Generally, it is
not allowed to copy a lock by value. It is however safe to copy a
zero value lock by value, as a special case and the only one that does
not lead to strange results.
This is what was done here, the locks were copied in the return of the
.newXXX() functions that allocated them; this was not a bug. But it is
a weird special case that I also only learned by consulting the great
tome of google in reference to this error output.
Issue golang/go#13675 explains the zero value
special case.
To avoid this confusion, make the functions return pointers and update
the resulting types.
@bigblind
Copy link

I'm having a similar issue, where go vet is reporting a copied mutex, when I'm not actually copying anything as far as I can tell: https://stackoverflow.com/questions/45083715/go-vet-is-telling-me-im-copying-a-lock-when-i-dont-think-iam?noredirect=1#comment77140731_45083715

@bradfitz
Copy link
Contributor

@bigblind, please post a self-contained minimal repro. (not just a few lines)

bossjones pushed a commit to bossjones/go-chatbot-lab that referenced this issue Feb 10, 2018
bossjones added a commit to bossjones/go-chatbot-lab that referenced this issue Mar 19, 2020
* chg: new code settings

* New: golang emitter

* wip: chat-room package

* wip: temporary disable mainly because of golang/go#13675 in chat-room.go

* chg: make build params update

Co-authored-by: Malcolm Jones <malcolm@adobe.com>
@adonovan adonovan added the Analysis Issues related to static analysis (vet, x/tools/go/analysis) label Apr 23, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Analysis Issues related to static analysis (vet, x/tools/go/analysis)
Projects
None yet
Development

No branches or pull requests

5 participants