Black Lives Matter. Support the Equal Justice Initiative.

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

Documentation: cmd/compile/internal/typecheck

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

View as plain text