mark(fn)
}
-func controlLabel(n ir.Node) *types.Sym {
- switch n := n.(type) {
- default:
- base.Fatalf("controlLabel %+v", n.Op())
- return nil
- case *ir.ForStmt:
- return n.Label
- case *ir.RangeStmt:
- return n.Label
- case *ir.SelectStmt:
- return n.Label
- case *ir.SwitchStmt:
- return n.Label
- }
-}
-
func setHasBreak(n ir.Node) {
switch n := n.(type) {
default:
return false
}
-// CheckUnused checks for any declared variables that weren't used.
-func CheckUnused(fn *ir.Func) {
- // Only report unused variables if we haven't seen any type-checking
- // errors yet.
- if base.Errors() != 0 {
- return
- }
-
- // Propagate the used flag for typeswitch variables up to the NONAME in its definition.
- for _, ln := range fn.Dcl {
- if ln.Op() == ir.ONAME && ln.Class == ir.PAUTO && ln.Used() {
- if guard, ok := ln.Defn.(*ir.TypeSwitchGuard); ok {
- guard.Used = true
- }
- }
- }
-
- for _, ln := range fn.Dcl {
- if ln.Op() != ir.ONAME || ln.Class != ir.PAUTO || ln.Used() {
- continue
- }
- if defn, ok := ln.Defn.(*ir.TypeSwitchGuard); ok {
- if defn.Used {
- continue
- }
- base.ErrorfAt(defn.Tag.Pos(), "%v declared but not used", ln.Sym())
- defn.Used = true // suppress repeats
- } else {
- base.ErrorfAt(ln.Pos(), "%v declared but not used", ln.Sym())
- }
- }
-}
-
-// CheckReturn makes sure that fn terminates appropriately.
-func CheckReturn(fn *ir.Func) {
- if fn.Type() != nil && fn.Type().NumResults() != 0 && len(fn.Body) != 0 {
- markBreak(fn)
- if !isTermNodes(fn.Body) {
- base.ErrorfAt(fn.Endlineno, "missing return at end of function")
- }
- }
-}
-
-// curpkg returns the current package, based on Curfn.
-func curpkg() *types.Pkg {
- fn := ir.CurFunc
- if fn == nil {
- // Initialization expressions for package-scope variables.
- return types.LocalPkg
- }
- return fnpkg(fn.Nname)
-}
-
func Conv(n ir.Node, t *types.Type) ir.Node {
if types.Identical(n.Type(), t) {
return n