Source file src/cmd/compile/internal/typecheck/typecheck.go

     1  // Copyright 2009 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package typecheck
     6  
     7  import (
     8  	"fmt"
     9  	"go/constant"
    10  	"go/token"
    11  	"strings"
    12  
    13  	"cmd/compile/internal/base"
    14  	"cmd/compile/internal/ir"
    15  	"cmd/compile/internal/types"
    16  	"cmd/internal/src"
    17  )
    18  
    19  // Function collecting autotmps generated during typechecking,
    20  // to be included in the package-level init function.
    21  var InitTodoFunc = ir.NewFunc(base.Pos)
    22  
    23  var inimport bool // set during import
    24  
    25  var TypecheckAllowed bool
    26  
    27  var (
    28  	NeedRuntimeType = func(*types.Type) {}
    29  )
    30  
    31  func AssignExpr(n ir.Node) ir.Node { return typecheck(n, ctxExpr|ctxAssign) }
    32  func Expr(n ir.Node) ir.Node       { return typecheck(n, ctxExpr) }
    33  func Stmt(n ir.Node) ir.Node       { return typecheck(n, ctxStmt) }
    34  
    35  func Exprs(exprs []ir.Node) { typecheckslice(exprs, ctxExpr) }
    36  func Stmts(stmts []ir.Node) { typecheckslice(stmts, ctxStmt) }
    37  
    38  func Call(pos src.XPos, callee ir.Node, args []ir.Node, dots bool) ir.Node {
    39  	call := ir.NewCallExpr(pos, ir.OCALL, callee, args)
    40  	call.IsDDD = dots
    41  	return typecheck(call, ctxStmt|ctxExpr)
    42  }
    43  
    44  func Callee(n ir.Node) ir.Node {
    45  	return typecheck(n, ctxExpr|ctxCallee)
    46  }
    47  
    48  func FuncBody(n *ir.Func) {
    49  	ir.CurFunc = n
    50  	errorsBefore := base.Errors()
    51  	Stmts(n.Body)
    52  	CheckUnused(n)
    53  	CheckReturn(n)
    54  	if ir.IsBlank(n.Nname) || base.Errors() > errorsBefore {
    55  		n.Body = nil // blank function or type errors; do not compile
    56  	}
    57  }
    58  
    59  var importlist []*ir.Func
    60  
    61  // AllImportedBodies reads in the bodies of all imported functions and typechecks
    62  // them, if needed.
    63  func AllImportedBodies() {
    64  	for _, n := range importlist {
    65  		if n.Inl != nil {
    66  			ImportedBody(n)
    67  		}
    68  	}
    69  }
    70  
    71  var traceIndent []byte
    72  
    73  func tracePrint(title string, n ir.Node) func(np *ir.Node) {
    74  	indent := traceIndent
    75  
    76  	// guard against nil
    77  	var pos, op string
    78  	var tc uint8
    79  	if n != nil {
    80  		pos = base.FmtPos(n.Pos())
    81  		op = n.Op().String()
    82  		tc = n.Typecheck()
    83  	}
    84  
    85  	types.SkipSizeForTracing = true
    86  	defer func() { types.SkipSizeForTracing = false }()
    87  	fmt.Printf("%s: %s%s %p %s %v tc=%d\n", pos, indent, title, n, op, n, tc)
    88  	traceIndent = append(traceIndent, ". "...)
    89  
    90  	return func(np *ir.Node) {
    91  		traceIndent = traceIndent[:len(traceIndent)-2]
    92  
    93  		// if we have a result, use that
    94  		if np != nil {
    95  			n = *np
    96  		}
    97  
    98  		// guard against nil
    99  		// use outer pos, op so we don't get empty pos/op if n == nil (nicer output)
   100  		var tc uint8
   101  		var typ *types.Type
   102  		if n != nil {
   103  			pos = base.FmtPos(n.Pos())
   104  			op = n.Op().String()
   105  			tc = n.Typecheck()
   106  			typ = n.Type()
   107  		}
   108  
   109  		types.SkipSizeForTracing = true
   110  		defer func() { types.SkipSizeForTracing = false }()
   111  		fmt.Printf("%s: %s=> %p %s %v tc=%d type=%L\n", pos, indent, n, op, n, tc, typ)
   112  	}
   113  }
   114  
   115  const (
   116  	ctxStmt    = 1 << iota // evaluated at statement level
   117  	ctxExpr                // evaluated in value context
   118  	ctxType                // evaluated in type context
   119  	ctxCallee              // call-only expressions are ok
   120  	ctxMultiOK             // multivalue function returns are ok
   121  	ctxAssign              // assigning to expression
   122  )
   123  
   124  // type checks the whole tree of an expression.
   125  // calculates expression types.
   126  // evaluates compile time constants.
   127  // marks variables that escape the local frame.
   128  // rewrites n.Op to be more specific in some cases.
   129  
   130  var typecheckdefstack []*ir.Name
   131  
   132  // Resolve resolves an ONONAME node to a definition, if any. If n is not an ONONAME node,
   133  // Resolve returns n unchanged. If n is an ONONAME node and not in the same package,
   134  // then n.Sym() is resolved using import data. Otherwise, Resolve returns
   135  // n.Sym().Def. An ONONAME node can be created using ir.NewIdent(), so an imported
   136  // symbol can be resolved via Resolve(ir.NewIdent(src.NoXPos, sym)).
   137  func Resolve(n ir.Node) (res ir.Node) {
   138  	if n == nil || n.Op() != ir.ONONAME {
   139  		return n
   140  	}
   141  
   142  	// only trace if there's work to do
   143  	if base.EnableTrace && base.Flag.LowerT {
   144  		defer tracePrint("resolve", n)(&res)
   145  	}
   146  
   147  	if sym := n.Sym(); sym.Pkg != types.LocalPkg {
   148  		// We might have an ir.Ident from oldname or importDot.
   149  		if id, ok := n.(*ir.Ident); ok {
   150  			if pkgName := DotImportRefs[id]; pkgName != nil {
   151  				pkgName.Used = true
   152  			}
   153  		}
   154  
   155  		return expandDecl(n)
   156  	}
   157  
   158  	r := ir.AsNode(n.Sym().Def)
   159  	if r == nil {
   160  		return n
   161  	}
   162  
   163  	if r.Op() == ir.OIOTA {
   164  		if x := getIotaValue(); x >= 0 {
   165  			return ir.NewInt(x)
   166  		}
   167  		return n
   168  	}
   169  
   170  	return r
   171  }
   172  
   173  func typecheckslice(l []ir.Node, top int) {
   174  	for i := range l {
   175  		l[i] = typecheck(l[i], top)
   176  	}
   177  }
   178  
   179  var _typekind = []string{
   180  	types.TINT:        "int",
   181  	types.TUINT:       "uint",
   182  	types.TINT8:       "int8",
   183  	types.TUINT8:      "uint8",
   184  	types.TINT16:      "int16",
   185  	types.TUINT16:     "uint16",
   186  	types.TINT32:      "int32",
   187  	types.TUINT32:     "uint32",
   188  	types.TINT64:      "int64",
   189  	types.TUINT64:     "uint64",
   190  	types.TUINTPTR:    "uintptr",
   191  	types.TCOMPLEX64:  "complex64",
   192  	types.TCOMPLEX128: "complex128",
   193  	types.TFLOAT32:    "float32",
   194  	types.TFLOAT64:    "float64",
   195  	types.TBOOL:       "bool",
   196  	types.TSTRING:     "string",
   197  	types.TPTR:        "pointer",
   198  	types.TUNSAFEPTR:  "unsafe.Pointer",
   199  	types.TSTRUCT:     "struct",
   200  	types.TINTER:      "interface",
   201  	types.TCHAN:       "chan",
   202  	types.TMAP:        "map",
   203  	types.TARRAY:      "array",
   204  	types.TSLICE:      "slice",
   205  	types.TFUNC:       "func",
   206  	types.TNIL:        "nil",
   207  	types.TIDEAL:      "untyped number",
   208  }
   209  
   210  func typekind(t *types.Type) string {
   211  	if t.IsUntyped() {
   212  		return fmt.Sprintf("%v", t)
   213  	}
   214  	et := t.Kind()
   215  	if int(et) < len(_typekind) {
   216  		s := _typekind[et]
   217  		if s != "" {
   218  			return s
   219  		}
   220  	}
   221  	return fmt.Sprintf("etype=%d", et)
   222  }
   223  
   224  func cycleFor(start ir.Node) []ir.Node {
   225  	// Find the start node in typecheck_tcstack.
   226  	// We know that it must exist because each time we mark
   227  	// a node with n.SetTypecheck(2) we push it on the stack,
   228  	// and each time we mark a node with n.SetTypecheck(2) we
   229  	// pop it from the stack. We hit a cycle when we encounter
   230  	// a node marked 2 in which case is must be on the stack.
   231  	i := len(typecheck_tcstack) - 1
   232  	for i > 0 && typecheck_tcstack[i] != start {
   233  		i--
   234  	}
   235  
   236  	// collect all nodes with same Op
   237  	var cycle []ir.Node
   238  	for _, n := range typecheck_tcstack[i:] {
   239  		if n.Op() == start.Op() {
   240  			cycle = append(cycle, n)
   241  		}
   242  	}
   243  
   244  	return cycle
   245  }
   246  
   247  func cycleTrace(cycle []ir.Node) string {
   248  	var s string
   249  	for i, n := range cycle {
   250  		s += fmt.Sprintf("\n\t%v: %v uses %v", ir.Line(n), n, cycle[(i+1)%len(cycle)])
   251  	}
   252  	return s
   253  }
   254  
   255  var typecheck_tcstack []ir.Node
   256  
   257  func Func(fn *ir.Func) {
   258  	new := Stmt(fn)
   259  	if new != fn {
   260  		base.Fatalf("typecheck changed func")
   261  	}
   262  }
   263  
   264  func typecheckNtype(n ir.Ntype) ir.Ntype {
   265  	return typecheck(n, ctxType).(ir.Ntype)
   266  }
   267  
   268  // typecheck type checks node n.
   269  // The result of typecheck MUST be assigned back to n, e.g.
   270  // 	n.Left = typecheck(n.Left, top)
   271  func typecheck(n ir.Node, top int) (res ir.Node) {
   272  	// cannot type check until all the source has been parsed
   273  	if !TypecheckAllowed {
   274  		base.Fatalf("early typecheck")
   275  	}
   276  
   277  	if n == nil {
   278  		return nil
   279  	}
   280  
   281  	// only trace if there's work to do
   282  	if base.EnableTrace && base.Flag.LowerT {
   283  		defer tracePrint("typecheck", n)(&res)
   284  	}
   285  
   286  	lno := ir.SetPos(n)
   287  
   288  	// Skip over parens.
   289  	for n.Op() == ir.OPAREN {
   290  		n = n.(*ir.ParenExpr).X
   291  	}
   292  
   293  	// Resolve definition of name and value of iota lazily.
   294  	n = Resolve(n)
   295  
   296  	// Skip typecheck if already done.
   297  	// But re-typecheck ONAME/OTYPE/OLITERAL/OPACK node in case context has changed.
   298  	if n.Typecheck() == 1 || n.Typecheck() == 3 {
   299  		switch n.Op() {
   300  		case ir.ONAME, ir.OTYPE, ir.OLITERAL, ir.OPACK:
   301  			break
   302  
   303  		default:
   304  			base.Pos = lno
   305  			return n
   306  		}
   307  	}
   308  
   309  	if n.Typecheck() == 2 {
   310  		// Typechecking loop. Trying printing a meaningful message,
   311  		// otherwise a stack trace of typechecking.
   312  		switch n.Op() {
   313  		// We can already diagnose variables used as types.
   314  		case ir.ONAME:
   315  			n := n.(*ir.Name)
   316  			if top&(ctxExpr|ctxType) == ctxType {
   317  				base.Errorf("%v is not a type", n)
   318  			}
   319  
   320  		case ir.OTYPE:
   321  			// Only report a type cycle if we are expecting a type.
   322  			// Otherwise let other code report an error.
   323  			if top&ctxType == ctxType {
   324  				// A cycle containing only alias types is an error
   325  				// since it would expand indefinitely when aliases
   326  				// are substituted.
   327  				cycle := cycleFor(n)
   328  				for _, n1 := range cycle {
   329  					if n1.Name() != nil && !n1.Name().Alias() {
   330  						// Cycle is ok. But if n is an alias type and doesn't
   331  						// have a type yet, we have a recursive type declaration
   332  						// with aliases that we can't handle properly yet.
   333  						// Report an error rather than crashing later.
   334  						if n.Name() != nil && n.Name().Alias() && n.Type() == nil {
   335  							base.Pos = n.Pos()
   336  							base.Fatalf("cannot handle alias type declaration (issue #25838): %v", n)
   337  						}
   338  						base.Pos = lno
   339  						return n
   340  					}
   341  				}
   342  				base.ErrorfAt(n.Pos(), "invalid recursive type alias %v%s", n, cycleTrace(cycle))
   343  			}
   344  
   345  		case ir.OLITERAL:
   346  			if top&(ctxExpr|ctxType) == ctxType {
   347  				base.Errorf("%v is not a type", n)
   348  				break
   349  			}
   350  			base.ErrorfAt(n.Pos(), "constant definition loop%s", cycleTrace(cycleFor(n)))
   351  		}
   352  
   353  		if base.Errors() == 0 {
   354  			var trace string
   355  			for i := len(typecheck_tcstack) - 1; i >= 0; i-- {
   356  				x := typecheck_tcstack[i]
   357  				trace += fmt.Sprintf("\n\t%v %v", ir.Line(x), x)
   358  			}
   359  			base.Errorf("typechecking loop involving %v%s", n, trace)
   360  		}
   361  
   362  		base.Pos = lno
   363  		return n
   364  	}
   365  
   366  	typecheck_tcstack = append(typecheck_tcstack, n)
   367  
   368  	n.SetTypecheck(2)
   369  	n = typecheck1(n, top)
   370  	n.SetTypecheck(1)
   371  
   372  	last := len(typecheck_tcstack) - 1
   373  	typecheck_tcstack[last] = nil
   374  	typecheck_tcstack = typecheck_tcstack[:last]
   375  
   376  	_, isExpr := n.(ir.Expr)
   377  	_, isStmt := n.(ir.Stmt)
   378  	isMulti := false
   379  	switch n.Op() {
   380  	case ir.OCALLFUNC, ir.OCALLINTER, ir.OCALLMETH:
   381  		n := n.(*ir.CallExpr)
   382  		if t := n.X.Type(); t != nil && t.Kind() == types.TFUNC {
   383  			nr := t.NumResults()
   384  			isMulti = nr > 1
   385  			if nr == 0 {
   386  				isExpr = false
   387  			}
   388  		}
   389  	case ir.OAPPEND:
   390  		// Must be used (and not BinaryExpr/UnaryExpr).
   391  		isStmt = false
   392  	case ir.OCLOSE, ir.ODELETE, ir.OPANIC, ir.OPRINT, ir.OPRINTN, ir.OVARKILL, ir.OVARLIVE:
   393  		// Must not be used.
   394  		isExpr = false
   395  		isStmt = true
   396  	case ir.OCOPY, ir.ORECOVER, ir.ORECV:
   397  		// Can be used or not.
   398  		isStmt = true
   399  	}
   400  
   401  	t := n.Type()
   402  	if t != nil && !t.IsFuncArgStruct() && n.Op() != ir.OTYPE {
   403  		switch t.Kind() {
   404  		case types.TFUNC, // might have TANY; wait until it's called
   405  			types.TANY, types.TFORW, types.TIDEAL, types.TNIL, types.TBLANK:
   406  			break
   407  
   408  		default:
   409  			types.CheckSize(t)
   410  		}
   411  	}
   412  	if t != nil {
   413  		n = EvalConst(n)
   414  		t = n.Type()
   415  	}
   416  
   417  	// TODO(rsc): Lots of the complexity here is because typecheck can
   418  	// see OTYPE, ONAME, and OLITERAL nodes multiple times.
   419  	// Once we make the IR a proper tree, we should be able to simplify
   420  	// this code a bit, especially the final case.
   421  	switch {
   422  	case top&(ctxStmt|ctxExpr) == ctxExpr && !isExpr && n.Op() != ir.OTYPE && !isMulti:
   423  		if !n.Diag() {
   424  			base.Errorf("%v used as value", n)
   425  			n.SetDiag(true)
   426  		}
   427  		if t != nil {
   428  			n.SetType(nil)
   429  		}
   430  
   431  	case top&ctxType == 0 && n.Op() == ir.OTYPE && t != nil:
   432  		if !n.Type().Broke() {
   433  			base.Errorf("type %v is not an expression", n.Type())
   434  			n.SetDiag(true)
   435  		}
   436  
   437  	case top&(ctxStmt|ctxExpr) == ctxStmt && !isStmt && t != nil:
   438  		if !n.Diag() {
   439  			base.Errorf("%v evaluated but not used", n)
   440  			n.SetDiag(true)
   441  		}
   442  		n.SetType(nil)
   443  
   444  	case top&(ctxType|ctxExpr) == ctxType && n.Op() != ir.OTYPE && n.Op() != ir.ONONAME && (t != nil || n.Op() == ir.ONAME):
   445  		base.Errorf("%v is not a type", n)
   446  		if t != nil {
   447  			if n.Op() == ir.ONAME {
   448  				t.SetBroke(true)
   449  			} else {
   450  				n.SetType(nil)
   451  			}
   452  		}
   453  
   454  	}
   455  
   456  	base.Pos = lno
   457  	return n
   458  }
   459  
   460  // indexlit implements typechecking of untyped values as
   461  // array/slice indexes. It is almost equivalent to DefaultLit
   462  // but also accepts untyped numeric values representable as
   463  // value of type int (see also checkmake for comparison).
   464  // The result of indexlit MUST be assigned back to n, e.g.
   465  // 	n.Left = indexlit(n.Left)
   466  func indexlit(n ir.Node) ir.Node {
   467  	if n != nil && n.Type() != nil && n.Type().Kind() == types.TIDEAL {
   468  		return DefaultLit(n, types.Types[types.TINT])
   469  	}
   470  	return n
   471  }
   472  
   473  // typecheck1 should ONLY be called from typecheck.
   474  func typecheck1(n ir.Node, top int) ir.Node {
   475  	if n, ok := n.(*ir.Name); ok {
   476  		typecheckdef(n)
   477  	}
   478  
   479  	switch n.Op() {
   480  	default:
   481  		ir.Dump("typecheck", n)
   482  		base.Fatalf("typecheck %v", n.Op())
   483  		panic("unreachable")
   484  
   485  	case ir.OLITERAL:
   486  		if n.Sym() == nil && n.Type() == nil {
   487  			if !n.Diag() {
   488  				base.Fatalf("literal missing type: %v", n)
   489  			}
   490  		}
   491  		return n
   492  
   493  	case ir.ONIL:
   494  		return n
   495  
   496  	// names
   497  	case ir.ONONAME:
   498  		if !n.Diag() {
   499  			// Note: adderrorname looks for this string and
   500  			// adds context about the outer expression
   501  			base.ErrorfAt(n.Pos(), "undefined: %v", n.Sym())
   502  			n.SetDiag(true)
   503  		}
   504  		n.SetType(nil)
   505  		return n
   506  
   507  	case ir.ONAME:
   508  		n := n.(*ir.Name)
   509  		if n.BuiltinOp != 0 {
   510  			if top&ctxCallee == 0 {
   511  				base.Errorf("use of builtin %v not in function call", n.Sym())
   512  				n.SetType(nil)
   513  				return n
   514  			}
   515  			return n
   516  		}
   517  		if top&ctxAssign == 0 {
   518  			// not a write to the variable
   519  			if ir.IsBlank(n) {
   520  				base.Errorf("cannot use _ as value")
   521  				n.SetType(nil)
   522  				return n
   523  			}
   524  			n.SetUsed(true)
   525  		}
   526  		return n
   527  
   528  	case ir.OLINKSYMOFFSET:
   529  		// type already set
   530  		return n
   531  
   532  	case ir.OPACK:
   533  		n := n.(*ir.PkgName)
   534  		base.Errorf("use of package %v without selector", n.Sym())
   535  		n.SetDiag(true)
   536  		return n
   537  
   538  	// types (ODEREF is with exprs)
   539  	case ir.OTYPE:
   540  		return n
   541  
   542  	case ir.OTSLICE:
   543  		n := n.(*ir.SliceType)
   544  		return tcSliceType(n)
   545  
   546  	case ir.OTARRAY:
   547  		n := n.(*ir.ArrayType)
   548  		return tcArrayType(n)
   549  
   550  	case ir.OTMAP:
   551  		n := n.(*ir.MapType)
   552  		return tcMapType(n)
   553  
   554  	case ir.OTCHAN:
   555  		n := n.(*ir.ChanType)
   556  		return tcChanType(n)
   557  
   558  	case ir.OTSTRUCT:
   559  		n := n.(*ir.StructType)
   560  		return tcStructType(n)
   561  
   562  	case ir.OTINTER:
   563  		n := n.(*ir.InterfaceType)
   564  		return tcInterfaceType(n)
   565  
   566  	case ir.OTFUNC:
   567  		n := n.(*ir.FuncType)
   568  		return tcFuncType(n)
   569  	// type or expr
   570  	case ir.ODEREF:
   571  		n := n.(*ir.StarExpr)
   572  		return tcStar(n, top)
   573  
   574  	// x op= y
   575  	case ir.OASOP:
   576  		n := n.(*ir.AssignOpStmt)
   577  		n.X, n.Y = Expr(n.X), Expr(n.Y)
   578  		checkassign(n, n.X)
   579  		if n.IncDec && !okforarith[n.X.Type().Kind()] {
   580  			base.Errorf("invalid operation: %v (non-numeric type %v)", n, n.X.Type())
   581  			return n
   582  		}
   583  		switch n.AsOp {
   584  		case ir.OLSH, ir.ORSH:
   585  			n.X, n.Y, _ = tcShift(n, n.X, n.Y)
   586  		case ir.OADD, ir.OAND, ir.OANDNOT, ir.ODIV, ir.OMOD, ir.OMUL, ir.OOR, ir.OSUB, ir.OXOR:
   587  			n.X, n.Y, _ = tcArith(n, n.AsOp, n.X, n.Y)
   588  		default:
   589  			base.Fatalf("invalid assign op: %v", n.AsOp)
   590  		}
   591  		return n
   592  
   593  	// logical operators
   594  	case ir.OANDAND, ir.OOROR:
   595  		n := n.(*ir.LogicalExpr)
   596  		n.X, n.Y = Expr(n.X), Expr(n.Y)
   597  		if n.X.Type() == nil || n.Y.Type() == nil {
   598  			n.SetType(nil)
   599  			return n
   600  		}
   601  		// For "x == x && len(s)", it's better to report that "len(s)" (type int)
   602  		// can't be used with "&&" than to report that "x == x" (type untyped bool)
   603  		// can't be converted to int (see issue #41500).
   604  		if !n.X.Type().IsBoolean() {
   605  			base.Errorf("invalid operation: %v (operator %v not defined on %s)", n, n.Op(), typekind(n.X.Type()))
   606  			n.SetType(nil)
   607  			return n
   608  		}
   609  		if !n.Y.Type().IsBoolean() {
   610  			base.Errorf("invalid operation: %v (operator %v not defined on %s)", n, n.Op(), typekind(n.Y.Type()))
   611  			n.SetType(nil)
   612  			return n
   613  		}
   614  		l, r, t := tcArith(n, n.Op(), n.X, n.Y)
   615  		n.X, n.Y = l, r
   616  		n.SetType(t)
   617  		return n
   618  
   619  	// shift operators
   620  	case ir.OLSH, ir.ORSH:
   621  		n := n.(*ir.BinaryExpr)
   622  		n.X, n.Y = Expr(n.X), Expr(n.Y)
   623  		l, r, t := tcShift(n, n.X, n.Y)
   624  		n.X, n.Y = l, r
   625  		n.SetType(t)
   626  		return n
   627  
   628  	// comparison operators
   629  	case ir.OEQ, ir.OGE, ir.OGT, ir.OLE, ir.OLT, ir.ONE:
   630  		n := n.(*ir.BinaryExpr)
   631  		n.X, n.Y = Expr(n.X), Expr(n.Y)
   632  		l, r, t := tcArith(n, n.Op(), n.X, n.Y)
   633  		if t != nil {
   634  			n.X, n.Y = l, r
   635  			n.SetType(types.UntypedBool)
   636  			if con := EvalConst(n); con.Op() == ir.OLITERAL {
   637  				return con
   638  			}
   639  			n.X, n.Y = defaultlit2(l, r, true)
   640  		}
   641  		return n
   642  
   643  	// binary operators
   644  	case ir.OADD, ir.OAND, ir.OANDNOT, ir.ODIV, ir.OMOD, ir.OMUL, ir.OOR, ir.OSUB, ir.OXOR:
   645  		n := n.(*ir.BinaryExpr)
   646  		n.X, n.Y = Expr(n.X), Expr(n.Y)
   647  		l, r, t := tcArith(n, n.Op(), n.X, n.Y)
   648  		if t != nil && t.Kind() == types.TSTRING && n.Op() == ir.OADD {
   649  			// create or update OADDSTR node with list of strings in x + y + z + (w + v) + ...
   650  			var add *ir.AddStringExpr
   651  			if l.Op() == ir.OADDSTR {
   652  				add = l.(*ir.AddStringExpr)
   653  				add.SetPos(n.Pos())
   654  			} else {
   655  				add = ir.NewAddStringExpr(n.Pos(), []ir.Node{l})
   656  			}
   657  			if r.Op() == ir.OADDSTR {
   658  				r := r.(*ir.AddStringExpr)
   659  				add.List.Append(r.List.Take()...)
   660  			} else {
   661  				add.List.Append(r)
   662  			}
   663  			add.SetType(t)
   664  			return add
   665  		}
   666  		n.X, n.Y = l, r
   667  		n.SetType(t)
   668  		return n
   669  
   670  	case ir.OBITNOT, ir.ONEG, ir.ONOT, ir.OPLUS:
   671  		n := n.(*ir.UnaryExpr)
   672  		return tcUnaryArith(n)
   673  
   674  	// exprs
   675  	case ir.OADDR:
   676  		n := n.(*ir.AddrExpr)
   677  		return tcAddr(n)
   678  
   679  	case ir.OCOMPLIT:
   680  		return tcCompLit(n.(*ir.CompLitExpr))
   681  
   682  	case ir.OXDOT, ir.ODOT:
   683  		n := n.(*ir.SelectorExpr)
   684  		return tcDot(n, top)
   685  
   686  	case ir.ODOTTYPE:
   687  		n := n.(*ir.TypeAssertExpr)
   688  		return tcDotType(n)
   689  
   690  	case ir.OINDEX:
   691  		n := n.(*ir.IndexExpr)
   692  		return tcIndex(n)
   693  
   694  	case ir.ORECV:
   695  		n := n.(*ir.UnaryExpr)
   696  		return tcRecv(n)
   697  
   698  	case ir.OSEND:
   699  		n := n.(*ir.SendStmt)
   700  		return tcSend(n)
   701  
   702  	case ir.OSLICEHEADER:
   703  		n := n.(*ir.SliceHeaderExpr)
   704  		return tcSliceHeader(n)
   705  
   706  	case ir.OMAKESLICECOPY:
   707  		n := n.(*ir.MakeExpr)
   708  		return tcMakeSliceCopy(n)
   709  
   710  	case ir.OSLICE, ir.OSLICE3:
   711  		n := n.(*ir.SliceExpr)
   712  		return tcSlice(n)
   713  
   714  	// call and call like
   715  	case ir.OCALL:
   716  		n := n.(*ir.CallExpr)
   717  		return tcCall(n, top)
   718  
   719  	case ir.OALIGNOF, ir.OOFFSETOF, ir.OSIZEOF:
   720  		n := n.(*ir.UnaryExpr)
   721  		n.SetType(types.Types[types.TUINTPTR])
   722  		return n
   723  
   724  	case ir.OCAP, ir.OLEN:
   725  		n := n.(*ir.UnaryExpr)
   726  		return tcLenCap(n)
   727  
   728  	case ir.OREAL, ir.OIMAG:
   729  		n := n.(*ir.UnaryExpr)
   730  		return tcRealImag(n)
   731  
   732  	case ir.OCOMPLEX:
   733  		n := n.(*ir.BinaryExpr)
   734  		return tcComplex(n)
   735  
   736  	case ir.OCLOSE:
   737  		n := n.(*ir.UnaryExpr)
   738  		return tcClose(n)
   739  
   740  	case ir.ODELETE:
   741  		n := n.(*ir.CallExpr)
   742  		return tcDelete(n)
   743  
   744  	case ir.OAPPEND:
   745  		n := n.(*ir.CallExpr)
   746  		return tcAppend(n)
   747  
   748  	case ir.OCOPY:
   749  		n := n.(*ir.BinaryExpr)
   750  		return tcCopy(n)
   751  
   752  	case ir.OCONV:
   753  		n := n.(*ir.ConvExpr)
   754  		return tcConv(n)
   755  
   756  	case ir.OMAKE:
   757  		n := n.(*ir.CallExpr)
   758  		return tcMake(n)
   759  
   760  	case ir.ONEW:
   761  		n := n.(*ir.UnaryExpr)
   762  		return tcNew(n)
   763  
   764  	case ir.OPRINT, ir.OPRINTN:
   765  		n := n.(*ir.CallExpr)
   766  		return tcPrint(n)
   767  
   768  	case ir.OPANIC:
   769  		n := n.(*ir.UnaryExpr)
   770  		return tcPanic(n)
   771  
   772  	case ir.ORECOVER:
   773  		n := n.(*ir.CallExpr)
   774  		return tcRecover(n)
   775  
   776  	case ir.ORECOVERFP:
   777  		n := n.(*ir.CallExpr)
   778  		return tcRecoverFP(n)
   779  
   780  	case ir.OUNSAFEADD:
   781  		n := n.(*ir.BinaryExpr)
   782  		return tcUnsafeAdd(n)
   783  
   784  	case ir.OUNSAFESLICE:
   785  		n := n.(*ir.BinaryExpr)
   786  		return tcUnsafeSlice(n)
   787  
   788  	case ir.OCLOSURE:
   789  		n := n.(*ir.ClosureExpr)
   790  		return tcClosure(n, top)
   791  
   792  	case ir.OITAB:
   793  		n := n.(*ir.UnaryExpr)
   794  		return tcITab(n)
   795  
   796  	case ir.OIDATA:
   797  		// Whoever creates the OIDATA node must know a priori the concrete type at that moment,
   798  		// usually by just having checked the OITAB.
   799  		n := n.(*ir.UnaryExpr)
   800  		base.Fatalf("cannot typecheck interface data %v", n)
   801  		panic("unreachable")
   802  
   803  	case ir.OSPTR:
   804  		n := n.(*ir.UnaryExpr)
   805  		return tcSPtr(n)
   806  
   807  	case ir.OCFUNC:
   808  		n := n.(*ir.UnaryExpr)
   809  		n.X = Expr(n.X)
   810  		n.SetType(types.Types[types.TUINTPTR])
   811  		return n
   812  
   813  	case ir.OGETCALLERPC, ir.OGETCALLERSP:
   814  		n := n.(*ir.CallExpr)
   815  		if len(n.Args) != 0 {
   816  			base.FatalfAt(n.Pos(), "unexpected arguments: %v", n)
   817  		}
   818  		n.SetType(types.Types[types.TUINTPTR])
   819  		return n
   820  
   821  	case ir.OCONVNOP:
   822  		n := n.(*ir.ConvExpr)
   823  		n.X = Expr(n.X)
   824  		return n
   825  
   826  	// statements
   827  	case ir.OAS:
   828  		n := n.(*ir.AssignStmt)
   829  		tcAssign(n)
   830  
   831  		// Code that creates temps does not bother to set defn, so do it here.
   832  		if n.X.Op() == ir.ONAME && ir.IsAutoTmp(n.X) {
   833  			n.X.Name().Defn = n
   834  		}
   835  		return n
   836  
   837  	case ir.OAS2:
   838  		tcAssignList(n.(*ir.AssignListStmt))
   839  		return n
   840  
   841  	case ir.OBREAK,
   842  		ir.OCONTINUE,
   843  		ir.ODCL,
   844  		ir.OGOTO,
   845  		ir.OFALL,
   846  		ir.OVARKILL,
   847  		ir.OVARLIVE:
   848  		return n
   849  
   850  	case ir.OBLOCK:
   851  		n := n.(*ir.BlockStmt)
   852  		Stmts(n.List)
   853  		return n
   854  
   855  	case ir.OLABEL:
   856  		if n.Sym().IsBlank() {
   857  			// Empty identifier is valid but useless.
   858  			// Eliminate now to simplify life later.
   859  			// See issues 7538, 11589, 11593.
   860  			n = ir.NewBlockStmt(n.Pos(), nil)
   861  		}
   862  		return n
   863  
   864  	case ir.ODEFER, ir.OGO:
   865  		n := n.(*ir.GoDeferStmt)
   866  		n.Call = typecheck(n.Call, ctxStmt|ctxExpr)
   867  		if !n.Call.Diag() {
   868  			tcGoDefer(n)
   869  		}
   870  		return n
   871  
   872  	case ir.OFOR, ir.OFORUNTIL:
   873  		n := n.(*ir.ForStmt)
   874  		return tcFor(n)
   875  
   876  	case ir.OIF:
   877  		n := n.(*ir.IfStmt)
   878  		return tcIf(n)
   879  
   880  	case ir.ORETURN:
   881  		n := n.(*ir.ReturnStmt)
   882  		return tcReturn(n)
   883  
   884  	case ir.OTAILCALL:
   885  		n := n.(*ir.TailCallStmt)
   886  		n.Call = typecheck(n.Call, ctxStmt|ctxExpr).(*ir.CallExpr)
   887  		return n
   888  
   889  	case ir.OCHECKNIL:
   890  		n := n.(*ir.UnaryExpr)
   891  		return tcCheckNil(n)
   892  
   893  	case ir.OSELECT:
   894  		tcSelect(n.(*ir.SelectStmt))
   895  		return n
   896  
   897  	case ir.OSWITCH:
   898  		tcSwitch(n.(*ir.SwitchStmt))
   899  		return n
   900  
   901  	case ir.ORANGE:
   902  		tcRange(n.(*ir.RangeStmt))
   903  		return n
   904  
   905  	case ir.OTYPESW:
   906  		n := n.(*ir.TypeSwitchGuard)
   907  		base.Errorf("use of .(type) outside type switch")
   908  		n.SetDiag(true)
   909  		return n
   910  
   911  	case ir.ODCLFUNC:
   912  		tcFunc(n.(*ir.Func))
   913  		return n
   914  
   915  	case ir.ODCLCONST:
   916  		n := n.(*ir.Decl)
   917  		n.X = Expr(n.X).(*ir.Name)
   918  		return n
   919  
   920  	case ir.ODCLTYPE:
   921  		n := n.(*ir.Decl)
   922  		n.X = typecheck(n.X, ctxType).(*ir.Name)
   923  		types.CheckSize(n.X.Type())
   924  		return n
   925  	}
   926  
   927  	// No return n here!
   928  	// Individual cases can type-assert n, introducing a new one.
   929  	// Each must execute its own return n.
   930  }
   931  
   932  func typecheckargs(n ir.InitNode) {
   933  	var list []ir.Node
   934  	switch n := n.(type) {
   935  	default:
   936  		base.Fatalf("typecheckargs %+v", n.Op())
   937  	case *ir.CallExpr:
   938  		list = n.Args
   939  		if n.IsDDD {
   940  			Exprs(list)
   941  			return
   942  		}
   943  	case *ir.ReturnStmt:
   944  		list = n.Results
   945  	}
   946  	if len(list) != 1 {
   947  		Exprs(list)
   948  		return
   949  	}
   950  
   951  	typecheckslice(list, ctxExpr|ctxMultiOK)
   952  	t := list[0].Type()
   953  	if t == nil || !t.IsFuncArgStruct() {
   954  		return
   955  	}
   956  
   957  	// Save n as n.Orig for fmt.go.
   958  	if ir.Orig(n) == n {
   959  		n.(ir.OrigNode).SetOrig(ir.SepCopy(n))
   960  	}
   961  
   962  	// Rewrite f(g()) into t1, t2, ... = g(); f(t1, t2, ...).
   963  	RewriteMultiValueCall(n, list[0])
   964  }
   965  
   966  // RewriteMultiValueCall rewrites multi-valued f() to use temporaries,
   967  // so the backend wouldn't need to worry about tuple-valued expressions.
   968  func RewriteMultiValueCall(n ir.InitNode, call ir.Node) {
   969  	// If we're outside of function context, then this call will
   970  	// be executed during the generated init function. However,
   971  	// init.go hasn't yet created it. Instead, associate the
   972  	// temporary variables with  InitTodoFunc for now, and init.go
   973  	// will reassociate them later when it's appropriate.
   974  	static := ir.CurFunc == nil
   975  	if static {
   976  		ir.CurFunc = InitTodoFunc
   977  	}
   978  
   979  	as := ir.NewAssignListStmt(base.Pos, ir.OAS2, nil, []ir.Node{call})
   980  	results := call.Type().FieldSlice()
   981  	list := make([]ir.Node, len(results))
   982  	for i, result := range results {
   983  		tmp := Temp(result.Type)
   984  		as.PtrInit().Append(ir.NewDecl(base.Pos, ir.ODCL, tmp))
   985  		as.Lhs.Append(tmp)
   986  		list[i] = tmp
   987  	}
   988  	if static {
   989  		ir.CurFunc = nil
   990  	}
   991  
   992  	n.PtrInit().Append(Stmt(as))
   993  
   994  	switch n := n.(type) {
   995  	default:
   996  		base.Fatalf("rewriteMultiValueCall %+v", n.Op())
   997  	case *ir.CallExpr:
   998  		n.Args = list
   999  	case *ir.ReturnStmt:
  1000  		n.Results = list
  1001  	case *ir.AssignListStmt:
  1002  		if n.Op() != ir.OAS2FUNC {
  1003  			base.Fatalf("rewriteMultiValueCall: invalid op %v", n.Op())
  1004  		}
  1005  		as.SetOp(ir.OAS2FUNC)
  1006  		n.SetOp(ir.OAS2)
  1007  		n.Rhs = make([]ir.Node, len(list))
  1008  		for i, tmp := range list {
  1009  			n.Rhs[i] = AssignConv(tmp, n.Lhs[i].Type(), "assignment")
  1010  		}
  1011  	}
  1012  }
  1013  
  1014  func checksliceindex(l ir.Node, r ir.Node, tp *types.Type) bool {
  1015  	t := r.Type()
  1016  	if t == nil {
  1017  		return false
  1018  	}
  1019  	if !t.IsInteger() {
  1020  		base.Errorf("invalid slice index %v (type %v)", r, t)
  1021  		return false
  1022  	}
  1023  
  1024  	if r.Op() == ir.OLITERAL {
  1025  		x := r.Val()
  1026  		if constant.Sign(x) < 0 {
  1027  			base.Errorf("invalid slice index %v (index must be non-negative)", r)
  1028  			return false
  1029  		} else if tp != nil && tp.NumElem() >= 0 && constant.Compare(x, token.GTR, constant.MakeInt64(tp.NumElem())) {
  1030  			base.Errorf("invalid slice index %v (out of bounds for %d-element array)", r, tp.NumElem())
  1031  			return false
  1032  		} else if ir.IsConst(l, constant.String) && constant.Compare(x, token.GTR, constant.MakeInt64(int64(len(ir.StringVal(l))))) {
  1033  			base.Errorf("invalid slice index %v (out of bounds for %d-byte string)", r, len(ir.StringVal(l)))
  1034  			return false
  1035  		} else if ir.ConstOverflow(x, types.Types[types.TINT]) {
  1036  			base.Errorf("invalid slice index %v (index too large)", r)
  1037  			return false
  1038  		}
  1039  	}
  1040  
  1041  	return true
  1042  }
  1043  
  1044  func checksliceconst(lo ir.Node, hi ir.Node) bool {
  1045  	if lo != nil && hi != nil && lo.Op() == ir.OLITERAL && hi.Op() == ir.OLITERAL && constant.Compare(lo.Val(), token.GTR, hi.Val()) {
  1046  		base.Errorf("invalid slice index: %v > %v", lo, hi)
  1047  		return false
  1048  	}
  1049  
  1050  	return true
  1051  }
  1052  
  1053  // The result of implicitstar MUST be assigned back to n, e.g.
  1054  // 	n.Left = implicitstar(n.Left)
  1055  func implicitstar(n ir.Node) ir.Node {
  1056  	// insert implicit * if needed for fixed array
  1057  	t := n.Type()
  1058  	if t == nil || !t.IsPtr() {
  1059  		return n
  1060  	}
  1061  	t = t.Elem()
  1062  	if t == nil {
  1063  		return n
  1064  	}
  1065  	if !t.IsArray() {
  1066  		return n
  1067  	}
  1068  	star := ir.NewStarExpr(base.Pos, n)
  1069  	star.SetImplicit(true)
  1070  	return Expr(star)
  1071  }
  1072  
  1073  func needOneArg(n *ir.CallExpr, f string, args ...interface{}) (ir.Node, bool) {
  1074  	if len(n.Args) == 0 {
  1075  		p := fmt.Sprintf(f, args...)
  1076  		base.Errorf("missing argument to %s: %v", p, n)
  1077  		return nil, false
  1078  	}
  1079  
  1080  	if len(n.Args) > 1 {
  1081  		p := fmt.Sprintf(f, args...)
  1082  		base.Errorf("too many arguments to %s: %v", p, n)
  1083  		return n.Args[0], false
  1084  	}
  1085  
  1086  	return n.Args[0], true
  1087  }
  1088  
  1089  func needTwoArgs(n *ir.CallExpr) (ir.Node, ir.Node, bool) {
  1090  	if len(n.Args) != 2 {
  1091  		if len(n.Args) < 2 {
  1092  			base.Errorf("not enough arguments in call to %v", n)
  1093  		} else {
  1094  			base.Errorf("too many arguments in call to %v", n)
  1095  		}
  1096  		return nil, nil, false
  1097  	}
  1098  	return n.Args[0], n.Args[1], true
  1099  }
  1100  
  1101  // Lookdot1 looks up the specified method s in the list fs of methods, returning
  1102  // the matching field or nil. If dostrcmp is 0, it matches the symbols. If
  1103  // dostrcmp is 1, it matches by name exactly. If dostrcmp is 2, it matches names
  1104  // with case folding.
  1105  func Lookdot1(errnode ir.Node, s *types.Sym, t *types.Type, fs *types.Fields, dostrcmp int) *types.Field {
  1106  	var r *types.Field
  1107  	for _, f := range fs.Slice() {
  1108  		if dostrcmp != 0 && f.Sym.Name == s.Name {
  1109  			return f
  1110  		}
  1111  		if dostrcmp == 2 && strings.EqualFold(f.Sym.Name, s.Name) {
  1112  			return f
  1113  		}
  1114  		if f.Sym != s {
  1115  			continue
  1116  		}
  1117  		if r != nil {
  1118  			if errnode != nil {
  1119  				base.Errorf("ambiguous selector %v", errnode)
  1120  			} else if t.IsPtr() {
  1121  				base.Errorf("ambiguous selector (%v).%v", t, s)
  1122  			} else {
  1123  				base.Errorf("ambiguous selector %v.%v", t, s)
  1124  			}
  1125  			break
  1126  		}
  1127  
  1128  		r = f
  1129  	}
  1130  
  1131  	return r
  1132  }
  1133  
  1134  // typecheckMethodExpr checks selector expressions (ODOT) where the
  1135  // base expression is a type expression (OTYPE).
  1136  func typecheckMethodExpr(n *ir.SelectorExpr) (res ir.Node) {
  1137  	if base.EnableTrace && base.Flag.LowerT {
  1138  		defer tracePrint("typecheckMethodExpr", n)(&res)
  1139  	}
  1140  
  1141  	t := n.X.Type()
  1142  
  1143  	// Compute the method set for t.
  1144  	var ms *types.Fields
  1145  	if t.IsInterface() {
  1146  		ms = t.AllMethods()
  1147  	} else {
  1148  		mt := types.ReceiverBaseType(t)
  1149  		if mt == nil {
  1150  			base.Errorf("%v undefined (type %v has no method %v)", n, t, n.Sel)
  1151  			n.SetType(nil)
  1152  			return n
  1153  		}
  1154  		CalcMethods(mt)
  1155  		ms = mt.AllMethods()
  1156  
  1157  		// The method expression T.m requires a wrapper when T
  1158  		// is different from m's declared receiver type. We
  1159  		// normally generate these wrappers while writing out
  1160  		// runtime type descriptors, which is always done for
  1161  		// types declared at package scope. However, we need
  1162  		// to make sure to generate wrappers for anonymous
  1163  		// receiver types too.
  1164  		if mt.Sym() == nil {
  1165  			NeedRuntimeType(t)
  1166  		}
  1167  	}
  1168  
  1169  	s := n.Sel
  1170  	m := Lookdot1(n, s, t, ms, 0)
  1171  	if m == nil {
  1172  		if Lookdot1(n, s, t, ms, 1) != nil {
  1173  			base.Errorf("%v undefined (cannot refer to unexported method %v)", n, s)
  1174  		} else if _, ambig := dotpath(s, t, nil, false); ambig {
  1175  			base.Errorf("%v undefined (ambiguous selector)", n) // method or field
  1176  		} else {
  1177  			base.Errorf("%v undefined (type %v has no method %v)", n, t, s)
  1178  		}
  1179  		n.SetType(nil)
  1180  		return n
  1181  	}
  1182  
  1183  	if !types.IsMethodApplicable(t, m) {
  1184  		base.Errorf("invalid method expression %v (needs pointer receiver: (*%v).%S)", n, t, s)
  1185  		n.SetType(nil)
  1186  		return n
  1187  	}
  1188  
  1189  	n.SetOp(ir.OMETHEXPR)
  1190  	n.Selection = m
  1191  	n.SetType(NewMethodType(m.Type, n.X.Type()))
  1192  	return n
  1193  }
  1194  
  1195  func derefall(t *types.Type) *types.Type {
  1196  	for t != nil && t.IsPtr() {
  1197  		t = t.Elem()
  1198  	}
  1199  	return t
  1200  }
  1201  
  1202  // Lookdot looks up field or method n.Sel in the type t and returns the matching
  1203  // field. It transforms the op of node n to ODOTINTER or ODOTMETH, if appropriate.
  1204  // It also may add a StarExpr node to n.X as needed for access to non-pointer
  1205  // methods. If dostrcmp is 0, it matches the field/method with the exact symbol
  1206  // as n.Sel (appropriate for exported fields). If dostrcmp is 1, it matches by name
  1207  // exactly. If dostrcmp is 2, it matches names with case folding.
  1208  func Lookdot(n *ir.SelectorExpr, t *types.Type, dostrcmp int) *types.Field {
  1209  	s := n.Sel
  1210  
  1211  	types.CalcSize(t)
  1212  	var f1 *types.Field
  1213  	if t.IsStruct() {
  1214  		f1 = Lookdot1(n, s, t, t.Fields(), dostrcmp)
  1215  	} else if t.IsInterface() {
  1216  		f1 = Lookdot1(n, s, t, t.AllMethods(), dostrcmp)
  1217  	}
  1218  
  1219  	var f2 *types.Field
  1220  	if n.X.Type() == t || n.X.Type().Sym() == nil {
  1221  		mt := types.ReceiverBaseType(t)
  1222  		if mt != nil {
  1223  			f2 = Lookdot1(n, s, mt, mt.Methods(), dostrcmp)
  1224  		}
  1225  	}
  1226  
  1227  	if f1 != nil {
  1228  		if dostrcmp > 1 || f1.Broke() {
  1229  			// Already in the process of diagnosing an error.
  1230  			return f1
  1231  		}
  1232  		if f2 != nil {
  1233  			base.Errorf("%v is both field and method", n.Sel)
  1234  		}
  1235  		if f1.Offset == types.BADWIDTH {
  1236  			base.Fatalf("Lookdot badwidth t=%v, f1=%v@%p", t, f1, f1)
  1237  		}
  1238  		n.Selection = f1
  1239  		n.SetType(f1.Type)
  1240  		if t.IsInterface() {
  1241  			if n.X.Type().IsPtr() {
  1242  				star := ir.NewStarExpr(base.Pos, n.X)
  1243  				star.SetImplicit(true)
  1244  				n.X = Expr(star)
  1245  			}
  1246  
  1247  			n.SetOp(ir.ODOTINTER)
  1248  		}
  1249  		return f1
  1250  	}
  1251  
  1252  	if f2 != nil {
  1253  		if dostrcmp > 1 {
  1254  			// Already in the process of diagnosing an error.
  1255  			return f2
  1256  		}
  1257  		orig := n.X
  1258  		tt := n.X.Type()
  1259  		types.CalcSize(tt)
  1260  		rcvr := f2.Type.Recv().Type
  1261  		if !types.Identical(rcvr, tt) {
  1262  			if rcvr.IsPtr() && types.Identical(rcvr.Elem(), tt) {
  1263  				checklvalue(n.X, "call pointer method on")
  1264  				addr := NodAddr(n.X)
  1265  				addr.SetImplicit(true)
  1266  				n.X = typecheck(addr, ctxType|ctxExpr)
  1267  			} else if tt.IsPtr() && (!rcvr.IsPtr() || rcvr.IsPtr() && rcvr.Elem().NotInHeap()) && types.Identical(tt.Elem(), rcvr) {
  1268  				star := ir.NewStarExpr(base.Pos, n.X)
  1269  				star.SetImplicit(true)
  1270  				n.X = typecheck(star, ctxType|ctxExpr)
  1271  			} else if tt.IsPtr() && tt.Elem().IsPtr() && types.Identical(derefall(tt), derefall(rcvr)) {
  1272  				base.Errorf("calling method %v with receiver %L requires explicit dereference", n.Sel, n.X)
  1273  				for tt.IsPtr() {
  1274  					// Stop one level early for method with pointer receiver.
  1275  					if rcvr.IsPtr() && !tt.Elem().IsPtr() {
  1276  						break
  1277  					}
  1278  					star := ir.NewStarExpr(base.Pos, n.X)
  1279  					star.SetImplicit(true)
  1280  					n.X = typecheck(star, ctxType|ctxExpr)
  1281  					tt = tt.Elem()
  1282  				}
  1283  			} else {
  1284  				base.Fatalf("method mismatch: %v for %v", rcvr, tt)
  1285  			}
  1286  		}
  1287  
  1288  		// Check that we haven't implicitly dereferenced any defined pointer types.
  1289  		for x := n.X; ; {
  1290  			var inner ir.Node
  1291  			implicit := false
  1292  			switch x := x.(type) {
  1293  			case *ir.AddrExpr:
  1294  				inner, implicit = x.X, x.Implicit()
  1295  			case *ir.SelectorExpr:
  1296  				inner, implicit = x.X, x.Implicit()
  1297  			case *ir.StarExpr:
  1298  				inner, implicit = x.X, x.Implicit()
  1299  			}
  1300  			if !implicit {
  1301  				break
  1302  			}
  1303  			if inner.Type().Sym() != nil && (x.Op() == ir.ODEREF || x.Op() == ir.ODOTPTR) {
  1304  				// Found an implicit dereference of a defined pointer type.
  1305  				// Restore n.X for better error message.
  1306  				n.X = orig
  1307  				return nil
  1308  			}
  1309  			x = inner
  1310  		}
  1311  
  1312  		n.Selection = f2
  1313  		n.SetType(f2.Type)
  1314  		n.SetOp(ir.ODOTMETH)
  1315  
  1316  		return f2
  1317  	}
  1318  
  1319  	return nil
  1320  }
  1321  
  1322  func nokeys(l ir.Nodes) bool {
  1323  	for _, n := range l {
  1324  		if n.Op() == ir.OKEY || n.Op() == ir.OSTRUCTKEY {
  1325  			return false
  1326  		}
  1327  	}
  1328  	return true
  1329  }
  1330  
  1331  func hasddd(t *types.Type) bool {
  1332  	for _, tl := range t.Fields().Slice() {
  1333  		if tl.IsDDD() {
  1334  			return true
  1335  		}
  1336  	}
  1337  
  1338  	return false
  1339  }
  1340  
  1341  // typecheck assignment: type list = expression list
  1342  func typecheckaste(op ir.Op, call ir.Node, isddd bool, tstruct *types.Type, nl ir.Nodes, desc func() string) {
  1343  	var t *types.Type
  1344  	var i int
  1345  
  1346  	lno := base.Pos
  1347  	defer func() { base.Pos = lno }()
  1348  
  1349  	if tstruct.Broke() {
  1350  		return
  1351  	}
  1352  
  1353  	var n ir.Node
  1354  	if len(nl) == 1 {
  1355  		n = nl[0]
  1356  	}
  1357  
  1358  	n1 := tstruct.NumFields()
  1359  	n2 := len(nl)
  1360  	if !hasddd(tstruct) {
  1361  		if isddd {
  1362  			goto invalidddd
  1363  		}
  1364  		if n2 > n1 {
  1365  			goto toomany
  1366  		}
  1367  		if n2 < n1 {
  1368  			goto notenough
  1369  		}
  1370  	} else {
  1371  		if !isddd {
  1372  			if n2 < n1-1 {
  1373  				goto notenough
  1374  			}
  1375  		} else {
  1376  			if n2 > n1 {
  1377  				goto toomany
  1378  			}
  1379  			if n2 < n1 {
  1380  				goto notenough
  1381  			}
  1382  		}
  1383  	}
  1384  
  1385  	i = 0
  1386  	for _, tl := range tstruct.Fields().Slice() {
  1387  		t = tl.Type
  1388  		if tl.IsDDD() {
  1389  			if isddd {
  1390  				if i >= len(nl) {
  1391  					goto notenough
  1392  				}
  1393  				if len(nl)-i > 1 {
  1394  					goto toomany
  1395  				}
  1396  				n = nl[i]
  1397  				ir.SetPos(n)
  1398  				if n.Type() != nil {
  1399  					nl[i] = assignconvfn(n, t, desc)
  1400  				}
  1401  				return
  1402  			}
  1403  
  1404  			// TODO(mdempsky): Make into ... call with implicit slice.
  1405  			for ; i < len(nl); i++ {
  1406  				n = nl[i]
  1407  				ir.SetPos(n)
  1408  				if n.Type() != nil {
  1409  					nl[i] = assignconvfn(n, t.Elem(), desc)
  1410  				}
  1411  			}
  1412  			return
  1413  		}
  1414  
  1415  		if i >= len(nl) {
  1416  			goto notenough
  1417  		}
  1418  		n = nl[i]
  1419  		ir.SetPos(n)
  1420  		if n.Type() != nil {
  1421  			nl[i] = assignconvfn(n, t, desc)
  1422  		}
  1423  		i++
  1424  	}
  1425  
  1426  	if i < len(nl) {
  1427  		goto toomany
  1428  	}
  1429  
  1430  invalidddd:
  1431  	if isddd {
  1432  		if call != nil {
  1433  			base.Errorf("invalid use of ... in call to %v", call)
  1434  		} else {
  1435  			base.Errorf("invalid use of ... in %v", op)
  1436  		}
  1437  	}
  1438  	return
  1439  
  1440  notenough:
  1441  	if n == nil || (!n.Diag() && n.Type() != nil) {
  1442  		details := errorDetails(nl, tstruct, isddd)
  1443  		if call != nil {
  1444  			// call is the expression being called, not the overall call.
  1445  			// Method expressions have the form T.M, and the compiler has
  1446  			// rewritten those to ONAME nodes but left T in Left.
  1447  			if call.Op() == ir.OMETHEXPR {
  1448  				call := call.(*ir.SelectorExpr)
  1449  				base.Errorf("not enough arguments in call to method expression %v%s", call, details)
  1450  			} else {
  1451  				base.Errorf("not enough arguments in call to %v%s", call, details)
  1452  			}
  1453  		} else {
  1454  			base.Errorf("not enough arguments to %v%s", op, details)
  1455  		}
  1456  		if n != nil {
  1457  			n.SetDiag(true)
  1458  		}
  1459  	}
  1460  	return
  1461  
  1462  toomany:
  1463  	details := errorDetails(nl, tstruct, isddd)
  1464  	if call != nil {
  1465  		base.Errorf("too many arguments in call to %v%s", call, details)
  1466  	} else {
  1467  		base.Errorf("too many arguments to %v%s", op, details)
  1468  	}
  1469  }
  1470  
  1471  func errorDetails(nl ir.Nodes, tstruct *types.Type, isddd bool) string {
  1472  	// Suppress any return message signatures if:
  1473  	//
  1474  	// (1) We don't know any type at a call site (see #19012).
  1475  	// (2) Any node has an unknown type.
  1476  	// (3) Invalid type for variadic parameter (see #46957).
  1477  	if tstruct == nil {
  1478  		return "" // case 1
  1479  	}
  1480  
  1481  	if isddd && !nl[len(nl)-1].Type().IsSlice() {
  1482  		return "" // case 3
  1483  	}
  1484  
  1485  	for _, n := range nl {
  1486  		if n.Type() == nil {
  1487  			return "" // case 2
  1488  		}
  1489  	}
  1490  	return fmt.Sprintf("\n\thave %s\n\twant %v", fmtSignature(nl, isddd), tstruct)
  1491  }
  1492  
  1493  // sigrepr is a type's representation to the outside world,
  1494  // in string representations of return signatures
  1495  // e.g in error messages about wrong arguments to return.
  1496  func sigrepr(t *types.Type, isddd bool) string {
  1497  	switch t {
  1498  	case types.UntypedString:
  1499  		return "string"
  1500  	case types.UntypedBool:
  1501  		return "bool"
  1502  	}
  1503  
  1504  	if t.Kind() == types.TIDEAL {
  1505  		// "untyped number" is not commonly used
  1506  		// outside of the compiler, so let's use "number".
  1507  		// TODO(mdempsky): Revisit this.
  1508  		return "number"
  1509  	}
  1510  
  1511  	// Turn []T... argument to ...T for clearer error message.
  1512  	if isddd {
  1513  		if !t.IsSlice() {
  1514  			base.Fatalf("bad type for ... argument: %v", t)
  1515  		}
  1516  		return "..." + t.Elem().String()
  1517  	}
  1518  	return t.String()
  1519  }
  1520  
  1521  // sigerr returns the signature of the types at the call or return.
  1522  func fmtSignature(nl ir.Nodes, isddd bool) string {
  1523  	if len(nl) < 1 {
  1524  		return "()"
  1525  	}
  1526  
  1527  	var typeStrings []string
  1528  	for i, n := range nl {
  1529  		isdddArg := isddd && i == len(nl)-1
  1530  		typeStrings = append(typeStrings, sigrepr(n.Type(), isdddArg))
  1531  	}
  1532  
  1533  	return fmt.Sprintf("(%s)", strings.Join(typeStrings, ", "))
  1534  }
  1535  
  1536  // type check composite
  1537  func fielddup(name string, hash map[string]bool) {
  1538  	if hash[name] {
  1539  		base.Errorf("duplicate field name in struct literal: %s", name)
  1540  		return
  1541  	}
  1542  	hash[name] = true
  1543  }
  1544  
  1545  // iscomptype reports whether type t is a composite literal type.
  1546  func iscomptype(t *types.Type) bool {
  1547  	switch t.Kind() {
  1548  	case types.TARRAY, types.TSLICE, types.TSTRUCT, types.TMAP:
  1549  		return true
  1550  	default:
  1551  		return false
  1552  	}
  1553  }
  1554  
  1555  // pushtype adds elided type information for composite literals if
  1556  // appropriate, and returns the resulting expression.
  1557  func pushtype(nn ir.Node, t *types.Type) ir.Node {
  1558  	if nn == nil || nn.Op() != ir.OCOMPLIT {
  1559  		return nn
  1560  	}
  1561  	n := nn.(*ir.CompLitExpr)
  1562  	if n.Ntype != nil {
  1563  		return n
  1564  	}
  1565  
  1566  	switch {
  1567  	case iscomptype(t):
  1568  		// For T, return T{...}.
  1569  		n.Ntype = ir.TypeNode(t)
  1570  
  1571  	case t.IsPtr() && iscomptype(t.Elem()):
  1572  		// For *T, return &T{...}.
  1573  		n.Ntype = ir.TypeNode(t.Elem())
  1574  
  1575  		addr := NodAddrAt(n.Pos(), n)
  1576  		addr.SetImplicit(true)
  1577  		return addr
  1578  	}
  1579  	return n
  1580  }
  1581  
  1582  // typecheckarraylit type-checks a sequence of slice/array literal elements.
  1583  func typecheckarraylit(elemType *types.Type, bound int64, elts []ir.Node, ctx string) int64 {
  1584  	// If there are key/value pairs, create a map to keep seen
  1585  	// keys so we can check for duplicate indices.
  1586  	var indices map[int64]bool
  1587  	for _, elt := range elts {
  1588  		if elt.Op() == ir.OKEY {
  1589  			indices = make(map[int64]bool)
  1590  			break
  1591  		}
  1592  	}
  1593  
  1594  	var key, length int64
  1595  	for i, elt := range elts {
  1596  		ir.SetPos(elt)
  1597  		r := elts[i]
  1598  		var kv *ir.KeyExpr
  1599  		if elt.Op() == ir.OKEY {
  1600  			elt := elt.(*ir.KeyExpr)
  1601  			elt.Key = Expr(elt.Key)
  1602  			key = IndexConst(elt.Key)
  1603  			if key < 0 {
  1604  				if !elt.Key.Diag() {
  1605  					if key == -2 {
  1606  						base.Errorf("index too large")
  1607  					} else {
  1608  						base.Errorf("index must be non-negative integer constant")
  1609  					}
  1610  					elt.Key.SetDiag(true)
  1611  				}
  1612  				key = -(1 << 30) // stay negative for a while
  1613  			}
  1614  			kv = elt
  1615  			r = elt.Value
  1616  		}
  1617  
  1618  		r = pushtype(r, elemType)
  1619  		r = Expr(r)
  1620  		r = AssignConv(r, elemType, ctx)
  1621  		if kv != nil {
  1622  			kv.Value = r
  1623  		} else {
  1624  			elts[i] = r
  1625  		}
  1626  
  1627  		if key >= 0 {
  1628  			if indices != nil {
  1629  				if indices[key] {
  1630  					base.Errorf("duplicate index in %s: %d", ctx, key)
  1631  				} else {
  1632  					indices[key] = true
  1633  				}
  1634  			}
  1635  
  1636  			if bound >= 0 && key >= bound {
  1637  				base.Errorf("array index %d out of bounds [0:%d]", key, bound)
  1638  				bound = -1
  1639  			}
  1640  		}
  1641  
  1642  		key++
  1643  		if key > length {
  1644  			length = key
  1645  		}
  1646  	}
  1647  
  1648  	return length
  1649  }
  1650  
  1651  // visible reports whether sym is exported or locally defined.
  1652  func visible(sym *types.Sym) bool {
  1653  	return sym != nil && (types.IsExported(sym.Name) || sym.Pkg == types.LocalPkg)
  1654  }
  1655  
  1656  // nonexported reports whether sym is an unexported field.
  1657  func nonexported(sym *types.Sym) bool {
  1658  	return sym != nil && !types.IsExported(sym.Name)
  1659  }
  1660  
  1661  func checklvalue(n ir.Node, verb string) {
  1662  	if !ir.IsAddressable(n) {
  1663  		base.Errorf("cannot %s %v", verb, n)
  1664  	}
  1665  }
  1666  
  1667  func checkassign(stmt ir.Node, n ir.Node) {
  1668  	// have already complained about n being invalid
  1669  	if n.Type() == nil {
  1670  		if base.Errors() == 0 {
  1671  			base.Fatalf("expected an error about %v", n)
  1672  		}
  1673  		return
  1674  	}
  1675  
  1676  	if ir.IsAddressable(n) {
  1677  		return
  1678  	}
  1679  	if n.Op() == ir.OINDEXMAP {
  1680  		n := n.(*ir.IndexExpr)
  1681  		n.Assigned = true
  1682  		return
  1683  	}
  1684  
  1685  	defer n.SetType(nil)
  1686  	if n.Diag() {
  1687  		return
  1688  	}
  1689  	switch {
  1690  	case n.Op() == ir.ODOT && n.(*ir.SelectorExpr).X.Op() == ir.OINDEXMAP:
  1691  		base.Errorf("cannot assign to struct field %v in map", n)
  1692  	case (n.Op() == ir.OINDEX && n.(*ir.IndexExpr).X.Type().IsString()) || n.Op() == ir.OSLICESTR:
  1693  		base.Errorf("cannot assign to %v (strings are immutable)", n)
  1694  	case n.Op() == ir.OLITERAL && n.Sym() != nil && ir.IsConstNode(n):
  1695  		base.Errorf("cannot assign to %v (declared const)", n)
  1696  	default:
  1697  		base.Errorf("cannot assign to %v", n)
  1698  	}
  1699  }
  1700  
  1701  func checkassignto(src *types.Type, dst ir.Node) {
  1702  	// TODO(mdempsky): Handle all untyped types correctly.
  1703  	if src == types.UntypedBool && dst.Type().IsBoolean() {
  1704  		return
  1705  	}
  1706  
  1707  	if op, why := Assignop(src, dst.Type()); op == ir.OXXX {
  1708  		base.Errorf("cannot assign %v to %L in multiple assignment%s", src, dst, why)
  1709  		return
  1710  	}
  1711  }
  1712  
  1713  // The result of stringtoruneslit MUST be assigned back to n, e.g.
  1714  // 	n.Left = stringtoruneslit(n.Left)
  1715  func stringtoruneslit(n *ir.ConvExpr) ir.Node {
  1716  	if n.X.Op() != ir.OLITERAL || n.X.Val().Kind() != constant.String {
  1717  		base.Fatalf("stringtoarraylit %v", n)
  1718  	}
  1719  
  1720  	var l []ir.Node
  1721  	i := 0
  1722  	for _, r := range ir.StringVal(n.X) {
  1723  		l = append(l, ir.NewKeyExpr(base.Pos, ir.NewInt(int64(i)), ir.NewInt(int64(r))))
  1724  		i++
  1725  	}
  1726  
  1727  	nn := ir.NewCompLitExpr(base.Pos, ir.OCOMPLIT, ir.TypeNode(n.Type()), nil)
  1728  	nn.List = l
  1729  	return Expr(nn)
  1730  }
  1731  
  1732  var mapqueue []*ir.MapType
  1733  
  1734  func CheckMapKeys() {
  1735  	for _, n := range mapqueue {
  1736  		k := n.Type().MapType().Key
  1737  		if !k.Broke() && !types.IsComparable(k) {
  1738  			base.ErrorfAt(n.Pos(), "invalid map key type %v", k)
  1739  		}
  1740  	}
  1741  	mapqueue = nil
  1742  }
  1743  
  1744  func typecheckdeftype(n *ir.Name) {
  1745  	if base.EnableTrace && base.Flag.LowerT {
  1746  		defer tracePrint("typecheckdeftype", n)(nil)
  1747  	}
  1748  
  1749  	t := types.NewNamed(n)
  1750  	if n.Curfn != nil {
  1751  		t.SetVargen()
  1752  	}
  1753  
  1754  	if n.Pragma()&ir.NotInHeap != 0 {
  1755  		t.SetNotInHeap(true)
  1756  	}
  1757  
  1758  	n.SetType(t)
  1759  	n.SetTypecheck(1)
  1760  	n.SetWalkdef(1)
  1761  
  1762  	types.DeferCheckSize()
  1763  	errorsBefore := base.Errors()
  1764  	n.Ntype = typecheckNtype(n.Ntype)
  1765  	if underlying := n.Ntype.Type(); underlying != nil {
  1766  		t.SetUnderlying(underlying)
  1767  	} else {
  1768  		n.SetDiag(true)
  1769  		n.SetType(nil)
  1770  	}
  1771  	if t.Kind() == types.TFORW && base.Errors() > errorsBefore {
  1772  		// Something went wrong during type-checking,
  1773  		// but it was reported. Silence future errors.
  1774  		t.SetBroke(true)
  1775  	}
  1776  	types.ResumeCheckSize()
  1777  }
  1778  
  1779  func typecheckdef(n *ir.Name) {
  1780  	if base.EnableTrace && base.Flag.LowerT {
  1781  		defer tracePrint("typecheckdef", n)(nil)
  1782  	}
  1783  
  1784  	if n.Walkdef() == 1 {
  1785  		return
  1786  	}
  1787  
  1788  	if n.Type() != nil { // builtin
  1789  		// Mark as Walkdef so that if n.SetType(nil) is called later, we
  1790  		// won't try walking again.
  1791  		if got := n.Walkdef(); got != 0 {
  1792  			base.Fatalf("unexpected walkdef: %v", got)
  1793  		}
  1794  		n.SetWalkdef(1)
  1795  		return
  1796  	}
  1797  
  1798  	lno := ir.SetPos(n)
  1799  	typecheckdefstack = append(typecheckdefstack, n)
  1800  	if n.Walkdef() == 2 {
  1801  		base.FlushErrors()
  1802  		fmt.Printf("typecheckdef loop:")
  1803  		for i := len(typecheckdefstack) - 1; i >= 0; i-- {
  1804  			n := typecheckdefstack[i]
  1805  			fmt.Printf(" %v", n.Sym())
  1806  		}
  1807  		fmt.Printf("\n")
  1808  		base.Fatalf("typecheckdef loop")
  1809  	}
  1810  
  1811  	n.SetWalkdef(2)
  1812  
  1813  	switch n.Op() {
  1814  	default:
  1815  		base.Fatalf("typecheckdef %v", n.Op())
  1816  
  1817  	case ir.OLITERAL:
  1818  		if n.Ntype != nil {
  1819  			n.Ntype = typecheckNtype(n.Ntype)
  1820  			n.SetType(n.Ntype.Type())
  1821  			n.Ntype = nil
  1822  			if n.Type() == nil {
  1823  				n.SetDiag(true)
  1824  				goto ret
  1825  			}
  1826  		}
  1827  
  1828  		e := n.Defn
  1829  		n.Defn = nil
  1830  		if e == nil {
  1831  			ir.Dump("typecheckdef nil defn", n)
  1832  			base.ErrorfAt(n.Pos(), "xxx")
  1833  		}
  1834  
  1835  		e = Expr(e)
  1836  		if e.Type() == nil {
  1837  			goto ret
  1838  		}
  1839  		if !ir.IsConstNode(e) {
  1840  			if !e.Diag() {
  1841  				if e.Op() == ir.ONIL {
  1842  					base.ErrorfAt(n.Pos(), "const initializer cannot be nil")
  1843  				} else {
  1844  					base.ErrorfAt(n.Pos(), "const initializer %v is not a constant", e)
  1845  				}
  1846  				e.SetDiag(true)
  1847  			}
  1848  			goto ret
  1849  		}
  1850  
  1851  		t := n.Type()
  1852  		if t != nil {
  1853  			if !ir.OKForConst[t.Kind()] {
  1854  				base.ErrorfAt(n.Pos(), "invalid constant type %v", t)
  1855  				goto ret
  1856  			}
  1857  
  1858  			if !e.Type().IsUntyped() && !types.Identical(t, e.Type()) {
  1859  				base.ErrorfAt(n.Pos(), "cannot use %L as type %v in const initializer", e, t)
  1860  				goto ret
  1861  			}
  1862  
  1863  			e = convlit(e, t)
  1864  		}
  1865  
  1866  		n.SetType(e.Type())
  1867  		if n.Type() != nil {
  1868  			n.SetVal(e.Val())
  1869  		}
  1870  
  1871  	case ir.ONAME:
  1872  		if n.Ntype != nil {
  1873  			n.Ntype = typecheckNtype(n.Ntype)
  1874  			n.SetType(n.Ntype.Type())
  1875  			if n.Type() == nil {
  1876  				n.SetDiag(true)
  1877  				goto ret
  1878  			}
  1879  		}
  1880  
  1881  		if n.Type() != nil {
  1882  			break
  1883  		}
  1884  		if n.Defn == nil {
  1885  			if n.BuiltinOp != 0 { // like OPRINTN
  1886  				break
  1887  			}
  1888  			if base.Errors() > 0 {
  1889  				// Can have undefined variables in x := foo
  1890  				// that make x have an n.name.Defn == nil.
  1891  				// If there are other errors anyway, don't
  1892  				// bother adding to the noise.
  1893  				break
  1894  			}
  1895  
  1896  			base.Fatalf("var without type, init: %v", n.Sym())
  1897  		}
  1898  
  1899  		if n.Defn.Op() == ir.ONAME {
  1900  			n.Defn = Expr(n.Defn)
  1901  			n.SetType(n.Defn.Type())
  1902  			break
  1903  		}
  1904  
  1905  		n.Defn = Stmt(n.Defn) // fills in n.Type
  1906  
  1907  	case ir.OTYPE:
  1908  		if n.Alias() {
  1909  			// Type alias declaration: Simply use the rhs type - no need
  1910  			// to create a new type.
  1911  			// If we have a syntax error, name.Ntype may be nil.
  1912  			if n.Ntype != nil {
  1913  				n.Ntype = typecheckNtype(n.Ntype)
  1914  				n.SetType(n.Ntype.Type())
  1915  				if n.Type() == nil {
  1916  					n.SetDiag(true)
  1917  					goto ret
  1918  				}
  1919  			}
  1920  			break
  1921  		}
  1922  
  1923  		// regular type declaration
  1924  		typecheckdeftype(n)
  1925  	}
  1926  
  1927  ret:
  1928  	if n.Op() != ir.OLITERAL && n.Type() != nil && n.Type().IsUntyped() {
  1929  		base.Fatalf("got %v for %v", n.Type(), n)
  1930  	}
  1931  	last := len(typecheckdefstack) - 1
  1932  	if typecheckdefstack[last] != n {
  1933  		base.Fatalf("typecheckdefstack mismatch")
  1934  	}
  1935  	typecheckdefstack[last] = nil
  1936  	typecheckdefstack = typecheckdefstack[:last]
  1937  
  1938  	base.Pos = lno
  1939  	n.SetWalkdef(1)
  1940  }
  1941  
  1942  func checkmake(t *types.Type, arg string, np *ir.Node) bool {
  1943  	n := *np
  1944  	if !n.Type().IsInteger() && n.Type().Kind() != types.TIDEAL {
  1945  		base.Errorf("non-integer %s argument in make(%v) - %v", arg, t, n.Type())
  1946  		return false
  1947  	}
  1948  
  1949  	// Do range checks for constants before DefaultLit
  1950  	// to avoid redundant "constant NNN overflows int" errors.
  1951  	if n.Op() == ir.OLITERAL {
  1952  		v := toint(n.Val())
  1953  		if constant.Sign(v) < 0 {
  1954  			base.Errorf("negative %s argument in make(%v)", arg, t)
  1955  			return false
  1956  		}
  1957  		if ir.ConstOverflow(v, types.Types[types.TINT]) {
  1958  			base.Errorf("%s argument too large in make(%v)", arg, t)
  1959  			return false
  1960  		}
  1961  	}
  1962  
  1963  	// DefaultLit is necessary for non-constants too: n might be 1.1<<k.
  1964  	// TODO(gri) The length argument requirements for (array/slice) make
  1965  	// are the same as for index expressions. Factor the code better;
  1966  	// for instance, indexlit might be called here and incorporate some
  1967  	// of the bounds checks done for make.
  1968  	n = DefaultLit(n, types.Types[types.TINT])
  1969  	*np = n
  1970  
  1971  	return true
  1972  }
  1973  
  1974  // checkunsafeslice is like checkmake but for unsafe.Slice.
  1975  func checkunsafeslice(np *ir.Node) bool {
  1976  	n := *np
  1977  	if !n.Type().IsInteger() && n.Type().Kind() != types.TIDEAL {
  1978  		base.Errorf("non-integer len argument in unsafe.Slice - %v", n.Type())
  1979  		return false
  1980  	}
  1981  
  1982  	// Do range checks for constants before DefaultLit
  1983  	// to avoid redundant "constant NNN overflows int" errors.
  1984  	if n.Op() == ir.OLITERAL {
  1985  		v := toint(n.Val())
  1986  		if constant.Sign(v) < 0 {
  1987  			base.Errorf("negative len argument in unsafe.Slice")
  1988  			return false
  1989  		}
  1990  		if ir.ConstOverflow(v, types.Types[types.TINT]) {
  1991  			base.Errorf("len argument too large in unsafe.Slice")
  1992  			return false
  1993  		}
  1994  	}
  1995  
  1996  	// DefaultLit is necessary for non-constants too: n might be 1.1<<k.
  1997  	n = DefaultLit(n, types.Types[types.TINT])
  1998  	*np = n
  1999  
  2000  	return true
  2001  }
  2002  
  2003  // markBreak marks control statements containing break statements with SetHasBreak(true).
  2004  func markBreak(fn *ir.Func) {
  2005  	var labels map[*types.Sym]ir.Node
  2006  	var implicit ir.Node
  2007  
  2008  	var mark func(ir.Node) bool
  2009  	mark = func(n ir.Node) bool {
  2010  		switch n.Op() {
  2011  		default:
  2012  			ir.DoChildren(n, mark)
  2013  
  2014  		case ir.OBREAK:
  2015  			n := n.(*ir.BranchStmt)
  2016  			if n.Label == nil {
  2017  				setHasBreak(implicit)
  2018  			} else {
  2019  				setHasBreak(labels[n.Label])
  2020  			}
  2021  
  2022  		case ir.OFOR, ir.OFORUNTIL, ir.OSWITCH, ir.OSELECT, ir.ORANGE:
  2023  			old := implicit
  2024  			implicit = n
  2025  			var sym *types.Sym
  2026  			switch n := n.(type) {
  2027  			case *ir.ForStmt:
  2028  				sym = n.Label
  2029  			case *ir.RangeStmt:
  2030  				sym = n.Label
  2031  			case *ir.SelectStmt:
  2032  				sym = n.Label
  2033  			case *ir.SwitchStmt:
  2034  				sym = n.Label
  2035  			}
  2036  			if sym != nil {
  2037  				if labels == nil {
  2038  					// Map creation delayed until we need it - most functions don't.
  2039  					labels = make(map[*types.Sym]ir.Node)
  2040  				}
  2041  				labels[sym] = n
  2042  			}
  2043  			ir.DoChildren(n, mark)
  2044  			if sym != nil {
  2045  				delete(labels, sym)
  2046  			}
  2047  			implicit = old
  2048  		}
  2049  		return false
  2050  	}
  2051  
  2052  	mark(fn)
  2053  }
  2054  
  2055  func controlLabel(n ir.Node) *types.Sym {
  2056  	switch n := n.(type) {
  2057  	default:
  2058  		base.Fatalf("controlLabel %+v", n.Op())
  2059  		return nil
  2060  	case *ir.ForStmt:
  2061  		return n.Label
  2062  	case *ir.RangeStmt:
  2063  		return n.Label
  2064  	case *ir.SelectStmt:
  2065  		return n.Label
  2066  	case *ir.SwitchStmt:
  2067  		return n.Label
  2068  	}
  2069  }
  2070  
  2071  func setHasBreak(n ir.Node) {
  2072  	switch n := n.(type) {
  2073  	default:
  2074  		base.Fatalf("setHasBreak %+v", n.Op())
  2075  	case nil:
  2076  		// ignore
  2077  	case *ir.ForStmt:
  2078  		n.HasBreak = true
  2079  	case *ir.RangeStmt:
  2080  		n.HasBreak = true
  2081  	case *ir.SelectStmt:
  2082  		n.HasBreak = true
  2083  	case *ir.SwitchStmt:
  2084  		n.HasBreak = true
  2085  	}
  2086  }
  2087  
  2088  // isTermNodes reports whether the Nodes list ends with a terminating statement.
  2089  func isTermNodes(l ir.Nodes) bool {
  2090  	s := l
  2091  	c := len(s)
  2092  	if c == 0 {
  2093  		return false
  2094  	}
  2095  	return isTermNode(s[c-1])
  2096  }
  2097  
  2098  // isTermNode reports whether the node n, the last one in a
  2099  // statement list, is a terminating statement.
  2100  func isTermNode(n ir.Node) bool {
  2101  	switch n.Op() {
  2102  	// NOTE: OLABEL is treated as a separate statement,
  2103  	// not a separate prefix, so skipping to the last statement
  2104  	// in the block handles the labeled statement case by
  2105  	// skipping over the label. No case OLABEL here.
  2106  
  2107  	case ir.OBLOCK:
  2108  		n := n.(*ir.BlockStmt)
  2109  		return isTermNodes(n.List)
  2110  
  2111  	case ir.OGOTO, ir.ORETURN, ir.OTAILCALL, ir.OPANIC, ir.OFALL:
  2112  		return true
  2113  
  2114  	case ir.OFOR, ir.OFORUNTIL:
  2115  		n := n.(*ir.ForStmt)
  2116  		if n.Cond != nil {
  2117  			return false
  2118  		}
  2119  		if n.HasBreak {
  2120  			return false
  2121  		}
  2122  		return true
  2123  
  2124  	case ir.OIF:
  2125  		n := n.(*ir.IfStmt)
  2126  		return isTermNodes(n.Body) && isTermNodes(n.Else)
  2127  
  2128  	case ir.OSWITCH:
  2129  		n := n.(*ir.SwitchStmt)
  2130  		if n.HasBreak {
  2131  			return false
  2132  		}
  2133  		def := false
  2134  		for _, cas := range n.Cases {
  2135  			if !isTermNodes(cas.Body) {
  2136  				return false
  2137  			}
  2138  			if len(cas.List) == 0 { // default
  2139  				def = true
  2140  			}
  2141  		}
  2142  		return def
  2143  
  2144  	case ir.OSELECT:
  2145  		n := n.(*ir.SelectStmt)
  2146  		if n.HasBreak {
  2147  			return false
  2148  		}
  2149  		for _, cas := range n.Cases {
  2150  			if !isTermNodes(cas.Body) {
  2151  				return false
  2152  			}
  2153  		}
  2154  		return true
  2155  	}
  2156  
  2157  	return false
  2158  }
  2159  
  2160  // CheckUnused checks for any declared variables that weren't used.
  2161  func CheckUnused(fn *ir.Func) {
  2162  	// Only report unused variables if we haven't seen any type-checking
  2163  	// errors yet.
  2164  	if base.Errors() != 0 {
  2165  		return
  2166  	}
  2167  
  2168  	// Propagate the used flag for typeswitch variables up to the NONAME in its definition.
  2169  	for _, ln := range fn.Dcl {
  2170  		if ln.Op() == ir.ONAME && ln.Class == ir.PAUTO && ln.Used() {
  2171  			if guard, ok := ln.Defn.(*ir.TypeSwitchGuard); ok {
  2172  				guard.Used = true
  2173  			}
  2174  		}
  2175  	}
  2176  
  2177  	for _, ln := range fn.Dcl {
  2178  		if ln.Op() != ir.ONAME || ln.Class != ir.PAUTO || ln.Used() {
  2179  			continue
  2180  		}
  2181  		if defn, ok := ln.Defn.(*ir.TypeSwitchGuard); ok {
  2182  			if defn.Used {
  2183  				continue
  2184  			}
  2185  			base.ErrorfAt(defn.Tag.Pos(), "%v declared but not used", ln.Sym())
  2186  			defn.Used = true // suppress repeats
  2187  		} else {
  2188  			base.ErrorfAt(ln.Pos(), "%v declared but not used", ln.Sym())
  2189  		}
  2190  	}
  2191  }
  2192  
  2193  // CheckReturn makes sure that fn terminates appropriately.
  2194  func CheckReturn(fn *ir.Func) {
  2195  	if fn.Type() != nil && fn.Type().NumResults() != 0 && len(fn.Body) != 0 {
  2196  		markBreak(fn)
  2197  		if !isTermNodes(fn.Body) {
  2198  			base.ErrorfAt(fn.Endlineno, "missing return at end of function")
  2199  		}
  2200  	}
  2201  }
  2202  
  2203  // getIotaValue returns the current value for "iota",
  2204  // or -1 if not within a ConstSpec.
  2205  func getIotaValue() int64 {
  2206  	if i := len(typecheckdefstack); i > 0 {
  2207  		if x := typecheckdefstack[i-1]; x.Op() == ir.OLITERAL {
  2208  			return x.Iota()
  2209  		}
  2210  	}
  2211  
  2212  	if ir.CurFunc != nil && ir.CurFunc.Iota >= 0 {
  2213  		return ir.CurFunc.Iota
  2214  	}
  2215  
  2216  	return -1
  2217  }
  2218  
  2219  // curpkg returns the current package, based on Curfn.
  2220  func curpkg() *types.Pkg {
  2221  	fn := ir.CurFunc
  2222  	if fn == nil {
  2223  		// Initialization expressions for package-scope variables.
  2224  		return types.LocalPkg
  2225  	}
  2226  	return fnpkg(fn.Nname)
  2227  }
  2228  
  2229  func Conv(n ir.Node, t *types.Type) ir.Node {
  2230  	if types.Identical(n.Type(), t) {
  2231  		return n
  2232  	}
  2233  	n = ir.NewConvExpr(base.Pos, ir.OCONV, nil, n)
  2234  	n.SetType(t)
  2235  	n = Expr(n)
  2236  	return n
  2237  }
  2238  
  2239  // ConvNop converts node n to type t using the OCONVNOP op
  2240  // and typechecks the result with ctxExpr.
  2241  func ConvNop(n ir.Node, t *types.Type) ir.Node {
  2242  	if types.Identical(n.Type(), t) {
  2243  		return n
  2244  	}
  2245  	n = ir.NewConvExpr(base.Pos, ir.OCONVNOP, nil, n)
  2246  	n.SetType(t)
  2247  	n = Expr(n)
  2248  	return n
  2249  }
  2250  

View as plain text