diff --git a/tools/checklocks/analysis.go b/tools/checklocks/analysis.go index e342ac8c6d..541def1c5c 100644 --- a/tools/checklocks/analysis.go +++ b/tools/checklocks/analysis.go @@ -731,17 +731,25 @@ func (pc *passContext) checkBasicBlock(fn *ssa.Function, block *ssa.BasicBlock, rv, rls = pc.checkInstruction(inst, lff, ls) if rls != nil { failed := false + + // if there is no line information attached to the return + // instruction, use the line info of the function itself + pos := rv.Pos() + if (pos == token.NoPos) { + pos = rv.Parent().Pos() + } + // Validate held locks. for fieldName, fg := range lff.HeldOnExit { r := fg.Resolver.resolveStatic(pc, ls, fn, rv) if !r.valid() { // This cannot be forced, since we have no reference. - pc.maybeFail(rv.Pos(), "lock %s cannot be resolved", fieldName) + pc.maybeFail(pos, "lock %s cannot be resolved", fieldName) continue } if s, ok := rls.isHeld(r, fg.Exclusive); !ok { if _, ok := pc.forced[pc.positionKey(rv.Pos())]; !ok && !lff.Ignore { - pc.maybeFail(rv.Pos(), "lock %s (%s) not held %s (locks: %s)", fieldName, s, exclusiveStr(fg.Exclusive), rls.String()) + pc.maybeFail(pos, "lock %s (%s) not held %s (locks: %s)", fieldName, s, exclusiveStr(fg.Exclusive), rls.String()) failed = true } else { // Force the lock to be acquired. @@ -751,7 +759,7 @@ func (pc *passContext) checkBasicBlock(fn *ssa.Function, block *ssa.BasicBlock, } // Check for other locks, but only if the above didn't trip. if !failed && rls.count() != len(lff.HeldOnExit) && !lff.Ignore { - pc.maybeFail(rv.Pos(), "return with unexpected locks held (locks: %s)", rls.String()) + pc.maybeFail(pos, "return with unexpected locks held (locks: %s)", rls.String()) } } }