github.com/rsc/tmp@v0.0.0-20240517235954-6deaab19748b/bootstrap/internal/gc/typecheck.go (about)

     1  // Do not edit. Bootstrap copy of /Users/rsc/g/go/src/cmd/internal/gc/typecheck.go
     2  
     3  // Copyright 2009 The Go Authors. All rights reserved.
     4  // Use of this source code is governed by a BSD-style
     5  // license that can be found in the LICENSE file.
     6  
     7  package gc
     8  
     9  import (
    10  	"rsc.io/tmp/bootstrap/internal/obj"
    11  	"fmt"
    12  	"math"
    13  	"strings"
    14  )
    15  
    16  /*
    17   * type check the whole tree of an expression.
    18   * calculates expression types.
    19   * evaluates compile time constants.
    20   * marks variables that escape the local frame.
    21   * rewrites n->op to be more specific in some cases.
    22   */
    23  var typecheckdefstack *NodeList
    24  
    25  /*
    26   * resolve ONONAME to definition, if any.
    27   */
    28  func resolve(n *Node) *Node {
    29  	if n != nil && n.Op == ONONAME && n.Sym != nil {
    30  		r := n.Sym.Def
    31  		if r != nil {
    32  			if r.Op != OIOTA {
    33  				n = r
    34  			} else if n.Iota >= 0 {
    35  				n = Nodintconst(int64(n.Iota))
    36  			}
    37  		}
    38  	}
    39  
    40  	return n
    41  }
    42  
    43  func typechecklist(l *NodeList, top int) {
    44  	for ; l != nil; l = l.Next {
    45  		typecheck(&l.N, top)
    46  	}
    47  }
    48  
    49  var _typekind = []string{
    50  	TINT:        "int",
    51  	TUINT:       "uint",
    52  	TINT8:       "int8",
    53  	TUINT8:      "uint8",
    54  	TINT16:      "int16",
    55  	TUINT16:     "uint16",
    56  	TINT32:      "int32",
    57  	TUINT32:     "uint32",
    58  	TINT64:      "int64",
    59  	TUINT64:     "uint64",
    60  	TUINTPTR:    "uintptr",
    61  	TCOMPLEX64:  "complex64",
    62  	TCOMPLEX128: "complex128",
    63  	TFLOAT32:    "float32",
    64  	TFLOAT64:    "float64",
    65  	TBOOL:       "bool",
    66  	TSTRING:     "string",
    67  	TPTR32:      "pointer",
    68  	TPTR64:      "pointer",
    69  	TUNSAFEPTR:  "unsafe.Pointer",
    70  	TSTRUCT:     "struct",
    71  	TINTER:      "interface",
    72  	TCHAN:       "chan",
    73  	TMAP:        "map",
    74  	TARRAY:      "array",
    75  	TFUNC:       "func",
    76  	TNIL:        "nil",
    77  	TIDEAL:      "untyped number",
    78  }
    79  
    80  func typekind(t *Type) string {
    81  	if Isslice(t) {
    82  		return "slice"
    83  	}
    84  	et := int(t.Etype)
    85  	if 0 <= et && et < len(_typekind) {
    86  		s := _typekind[et]
    87  		if s != "" {
    88  			return s
    89  		}
    90  	}
    91  	return fmt.Sprintf("etype=%d", et)
    92  }
    93  
    94  /*
    95   * sprint_depchain prints a dependency chain
    96   * of nodes into fmt.
    97   * It is used by typecheck in the case of OLITERAL nodes
    98   * to print constant definition loops.
    99   */
   100  func sprint_depchain(fmt_ *string, stack *NodeList, cur *Node, first *Node) {
   101  	for l := stack; l != nil; l = l.Next {
   102  		if l.N.Op == cur.Op {
   103  			if l.N != first {
   104  				sprint_depchain(fmt_, l.Next, l.N, first)
   105  			}
   106  			*fmt_ += fmt.Sprintf("\n\t%v: %v uses %v", l.N.Line(), l.N, cur)
   107  			return
   108  		}
   109  	}
   110  }
   111  
   112  /*
   113   * type check node *np.
   114   * replaces *np with a new pointer in some cases.
   115   * returns the final value of *np as a convenience.
   116   */
   117  
   118  var typecheck_tcstack *NodeList
   119  var typecheck_tcfree *NodeList
   120  
   121  func typecheck(np **Node, top int) *Node {
   122  	// cannot type check until all the source has been parsed
   123  	if typecheckok == 0 {
   124  		Fatal("early typecheck")
   125  	}
   126  
   127  	n := *np
   128  	if n == nil {
   129  		return nil
   130  	}
   131  
   132  	lno := int(setlineno(n))
   133  
   134  	// Skip over parens.
   135  	for n.Op == OPAREN {
   136  		n = n.Left
   137  	}
   138  
   139  	// Resolve definition of name and value of iota lazily.
   140  	n = resolve(n)
   141  
   142  	*np = n
   143  
   144  	// Skip typecheck if already done.
   145  	// But re-typecheck ONAME/OTYPE/OLITERAL/OPACK node in case context has changed.
   146  	if n.Typecheck == 1 {
   147  		switch n.Op {
   148  		case ONAME, OTYPE, OLITERAL, OPACK:
   149  			break
   150  
   151  		default:
   152  			lineno = int32(lno)
   153  			return n
   154  		}
   155  	}
   156  
   157  	if n.Typecheck == 2 {
   158  		// Typechecking loop. Trying printing a meaningful message,
   159  		// otherwise a stack trace of typechecking.
   160  		var fmt_ string
   161  		switch n.Op {
   162  		// We can already diagnose variables used as types.
   163  		case ONAME:
   164  			if top&(Erv|Etype) == Etype {
   165  				Yyerror("%v is not a type", n)
   166  			}
   167  
   168  		case OLITERAL:
   169  			if top&(Erv|Etype) == Etype {
   170  				Yyerror("%v is not a type", n)
   171  				break
   172  			}
   173  
   174  			fmt_ = ""
   175  			sprint_depchain(&fmt_, typecheck_tcstack, n, n)
   176  			yyerrorl(int(n.Lineno), "constant definition loop%s", fmt_)
   177  		}
   178  
   179  		if nsavederrors+nerrors == 0 {
   180  			fmt_ = ""
   181  			for l := typecheck_tcstack; l != nil; l = l.Next {
   182  				fmt_ += fmt.Sprintf("\n\t%v %v", l.N.Line(), l.N)
   183  			}
   184  			Yyerror("typechecking loop involving %v%s", n, fmt_)
   185  		}
   186  
   187  		lineno = int32(lno)
   188  		return n
   189  	}
   190  
   191  	n.Typecheck = 2
   192  
   193  	var l *NodeList
   194  	if typecheck_tcfree != nil {
   195  		l = typecheck_tcfree
   196  		typecheck_tcfree = l.Next
   197  	} else {
   198  		l = new(NodeList)
   199  	}
   200  	l.Next = typecheck_tcstack
   201  	l.N = n
   202  	typecheck_tcstack = l
   203  
   204  	typecheck1(&n, top)
   205  	*np = n
   206  	n.Typecheck = 1
   207  
   208  	if typecheck_tcstack != l {
   209  		Fatal("typecheck stack out of sync")
   210  	}
   211  	typecheck_tcstack = l.Next
   212  	l.Next = typecheck_tcfree
   213  	typecheck_tcfree = l
   214  
   215  	lineno = int32(lno)
   216  	return n
   217  }
   218  
   219  /*
   220   * does n contain a call or receive operation?
   221   */
   222  func callrecv(n *Node) bool {
   223  	if n == nil {
   224  		return false
   225  	}
   226  
   227  	switch n.Op {
   228  	case OCALL,
   229  		OCALLMETH,
   230  		OCALLINTER,
   231  		OCALLFUNC,
   232  		ORECV,
   233  		OCAP,
   234  		OLEN,
   235  		OCOPY,
   236  		ONEW,
   237  		OAPPEND,
   238  		ODELETE:
   239  		return true
   240  	}
   241  
   242  	return callrecv(n.Left) || callrecv(n.Right) || callrecv(n.Ntest) || callrecv(n.Nincr) || callrecvlist(n.Ninit) || callrecvlist(n.Nbody) || callrecvlist(n.Nelse) || callrecvlist(n.List) || callrecvlist(n.Rlist)
   243  }
   244  
   245  func callrecvlist(l *NodeList) bool {
   246  	for ; l != nil; l = l.Next {
   247  		if callrecv(l.N) {
   248  			return true
   249  		}
   250  	}
   251  	return false
   252  }
   253  
   254  // indexlit implements typechecking of untyped values as
   255  // array/slice indexes. It is equivalent to defaultlit
   256  // except for constants of numerical kind, which are acceptable
   257  // whenever they can be represented by a value of type int.
   258  func indexlit(np **Node) {
   259  	n := *np
   260  	if n == nil || !isideal(n.Type) {
   261  		return
   262  	}
   263  	switch consttype(n) {
   264  	case CTINT, CTRUNE, CTFLT, CTCPLX:
   265  		defaultlit(np, Types[TINT])
   266  	}
   267  
   268  	defaultlit(np, nil)
   269  }
   270  
   271  func typecheck1(np **Node, top int) {
   272  	n := *np
   273  	defer func() {
   274  		*np = n
   275  	}()
   276  
   277  	if n.Sym != nil {
   278  		if n.Op == ONAME && n.Etype != 0 && top&Ecall == 0 {
   279  			Yyerror("use of builtin %v not in function call", n.Sym)
   280  			n.Type = nil
   281  			return
   282  		}
   283  
   284  		typecheckdef(n)
   285  		if n.Op == ONONAME {
   286  			n.Type = nil
   287  			return
   288  		}
   289  	}
   290  
   291  	ok := 0
   292  OpSwitch:
   293  	switch n.Op {
   294  	// until typecheck is complete, do nothing.
   295  	default:
   296  		Dump("typecheck", n)
   297  
   298  		Fatal("typecheck %v", Oconv(int(n.Op), 0))
   299  
   300  		/*
   301  		 * names
   302  		 */
   303  	case OLITERAL:
   304  		ok |= Erv
   305  
   306  		if n.Type == nil && n.Val.Ctype == CTSTR {
   307  			n.Type = idealstring
   308  		}
   309  		break OpSwitch
   310  
   311  	case ONONAME:
   312  		ok |= Erv
   313  		break OpSwitch
   314  
   315  	case ONAME:
   316  		if n.Decldepth == 0 {
   317  			n.Decldepth = decldepth
   318  		}
   319  		if n.Etype != 0 {
   320  			ok |= Ecall
   321  			break OpSwitch
   322  		}
   323  
   324  		if top&Easgn == 0 {
   325  			// not a write to the variable
   326  			if isblank(n) {
   327  				Yyerror("cannot use _ as value")
   328  				n.Type = nil
   329  				return
   330  			}
   331  
   332  			n.Used = true
   333  		}
   334  
   335  		if top&Ecall == 0 && isunsafebuiltin(n) {
   336  			Yyerror("%v is not an expression, must be called", n)
   337  			n.Type = nil
   338  			return
   339  		}
   340  
   341  		ok |= Erv
   342  		break OpSwitch
   343  
   344  	case OPACK:
   345  		Yyerror("use of package %v without selector", n.Sym)
   346  		n.Type = nil
   347  		return
   348  
   349  	case ODDD:
   350  		break
   351  
   352  		/*
   353  		 * types (OIND is with exprs)
   354  		 */
   355  	case OTYPE:
   356  		ok |= Etype
   357  
   358  		if n.Type == nil {
   359  			n.Type = nil
   360  			return
   361  		}
   362  
   363  	case OTARRAY:
   364  		ok |= Etype
   365  		t := typ(TARRAY)
   366  		l := n.Left
   367  		r := n.Right
   368  		if l == nil {
   369  			t.Bound = -1 // slice
   370  		} else if l.Op == ODDD {
   371  			t.Bound = -100 // to be filled in
   372  			if top&Ecomplit == 0 && n.Diag == 0 {
   373  				t.Broke = 1
   374  				n.Diag = 1
   375  				Yyerror("use of [...] array outside of array literal")
   376  			}
   377  		} else {
   378  			l := typecheck(&n.Left, Erv)
   379  			var v Val
   380  			switch consttype(l) {
   381  			case CTINT, CTRUNE:
   382  				v = l.Val
   383  
   384  			case CTFLT:
   385  				v = toint(l.Val)
   386  
   387  			default:
   388  				if l.Type != nil && Isint[l.Type.Etype] && l.Op != OLITERAL {
   389  					Yyerror("non-constant array bound %v", l)
   390  				} else {
   391  					Yyerror("invalid array bound %v", l)
   392  				}
   393  				n.Type = nil
   394  				return
   395  			}
   396  
   397  			t.Bound = Mpgetfix(v.U.Xval)
   398  			if doesoverflow(v, Types[TINT]) {
   399  				Yyerror("array bound is too large")
   400  				n.Type = nil
   401  				return
   402  			} else if t.Bound < 0 {
   403  				Yyerror("array bound must be non-negative")
   404  				n.Type = nil
   405  				return
   406  			}
   407  		}
   408  
   409  		typecheck(&r, Etype)
   410  		if r.Type == nil {
   411  			n.Type = nil
   412  			return
   413  		}
   414  		t.Type = r.Type
   415  		n.Op = OTYPE
   416  		n.Type = t
   417  		n.Left = nil
   418  		n.Right = nil
   419  		if t.Bound != -100 {
   420  			checkwidth(t)
   421  		}
   422  
   423  	case OTMAP:
   424  		ok |= Etype
   425  		l := typecheck(&n.Left, Etype)
   426  		r := typecheck(&n.Right, Etype)
   427  		if l.Type == nil || r.Type == nil {
   428  			n.Type = nil
   429  			return
   430  		}
   431  		n.Op = OTYPE
   432  		n.Type = maptype(l.Type, r.Type)
   433  		n.Left = nil
   434  		n.Right = nil
   435  
   436  	case OTCHAN:
   437  		ok |= Etype
   438  		l := typecheck(&n.Left, Etype)
   439  		if l.Type == nil {
   440  			n.Type = nil
   441  			return
   442  		}
   443  		t := typ(TCHAN)
   444  		t.Type = l.Type
   445  		t.Chan = n.Etype
   446  		n.Op = OTYPE
   447  		n.Type = t
   448  		n.Left = nil
   449  		n.Etype = 0
   450  
   451  	case OTSTRUCT:
   452  		ok |= Etype
   453  		n.Op = OTYPE
   454  		n.Type = tostruct(n.List)
   455  		if n.Type == nil || n.Type.Broke != 0 {
   456  			n.Type = nil
   457  			return
   458  		}
   459  		n.List = nil
   460  
   461  	case OTINTER:
   462  		ok |= Etype
   463  		n.Op = OTYPE
   464  		n.Type = tointerface(n.List)
   465  		if n.Type == nil {
   466  			n.Type = nil
   467  			return
   468  		}
   469  
   470  	case OTFUNC:
   471  		ok |= Etype
   472  		n.Op = OTYPE
   473  		n.Type = functype(n.Left, n.List, n.Rlist)
   474  		if n.Type == nil {
   475  			n.Type = nil
   476  			return
   477  		}
   478  
   479  		/*
   480  		 * type or expr
   481  		 */
   482  	case OIND:
   483  		ntop := Erv | Etype
   484  
   485  		if top&Eaddr == 0 { // The *x in &*x is not an indirect.
   486  			ntop |= Eindir
   487  		}
   488  		ntop |= top & Ecomplit
   489  		l := typecheck(&n.Left, ntop)
   490  		t := l.Type
   491  		if t == nil {
   492  			n.Type = nil
   493  			return
   494  		}
   495  		if l.Op == OTYPE {
   496  			ok |= Etype
   497  			n.Op = OTYPE
   498  			n.Type = Ptrto(l.Type)
   499  			n.Left = nil
   500  			break OpSwitch
   501  		}
   502  
   503  		if !Isptr[t.Etype] {
   504  			if top&(Erv|Etop) != 0 {
   505  				Yyerror("invalid indirect of %v", Nconv(n.Left, obj.FmtLong))
   506  				n.Type = nil
   507  				return
   508  			}
   509  
   510  			break OpSwitch
   511  		}
   512  
   513  		ok |= Erv
   514  		n.Type = t.Type
   515  		break OpSwitch
   516  
   517  		/*
   518  		 * arithmetic exprs
   519  		 */
   520  	case OASOP,
   521  		OADD,
   522  		OAND,
   523  		OANDAND,
   524  		OANDNOT,
   525  		ODIV,
   526  		OEQ,
   527  		OGE,
   528  		OGT,
   529  		OLE,
   530  		OLT,
   531  		OLSH,
   532  		ORSH,
   533  		OMOD,
   534  		OMUL,
   535  		ONE,
   536  		OOR,
   537  		OOROR,
   538  		OSUB,
   539  		OXOR:
   540  		var l *Node
   541  		var op int
   542  		var r *Node
   543  		if n.Op == OASOP {
   544  			ok |= Etop
   545  			l = typecheck(&n.Left, Erv)
   546  			r = typecheck(&n.Right, Erv)
   547  			checkassign(n, n.Left)
   548  			if l.Type == nil || r.Type == nil {
   549  				n.Type = nil
   550  				return
   551  			}
   552  			op = int(n.Etype)
   553  		} else {
   554  			ok |= Erv
   555  			l = typecheck(&n.Left, Erv|top&Eiota)
   556  			r = typecheck(&n.Right, Erv|top&Eiota)
   557  			if l.Type == nil || r.Type == nil {
   558  				n.Type = nil
   559  				return
   560  			}
   561  			op = int(n.Op)
   562  		}
   563  		if op == OLSH || op == ORSH {
   564  			defaultlit(&r, Types[TUINT])
   565  			n.Right = r
   566  			t := r.Type
   567  			if !Isint[t.Etype] || Issigned[t.Etype] {
   568  				Yyerror("invalid operation: %v (shift count type %v, must be unsigned integer)", n, r.Type)
   569  				n.Type = nil
   570  				return
   571  			}
   572  
   573  			t = l.Type
   574  			if t != nil && t.Etype != TIDEAL && !Isint[t.Etype] {
   575  				Yyerror("invalid operation: %v (shift of type %v)", n, t)
   576  				n.Type = nil
   577  				return
   578  			}
   579  
   580  			// no defaultlit for left
   581  			// the outer context gives the type
   582  			n.Type = l.Type
   583  
   584  			break OpSwitch
   585  		}
   586  
   587  		// ideal mixed with non-ideal
   588  		defaultlit2(&l, &r, 0)
   589  
   590  		n.Left = l
   591  		n.Right = r
   592  		if l.Type == nil || r.Type == nil {
   593  			n.Type = nil
   594  			return
   595  		}
   596  		t := l.Type
   597  		if t.Etype == TIDEAL {
   598  			t = r.Type
   599  		}
   600  		et := int(t.Etype)
   601  		if et == TIDEAL {
   602  			et = TINT
   603  		}
   604  		aop := 0
   605  		if iscmp[n.Op] && t.Etype != TIDEAL && !Eqtype(l.Type, r.Type) {
   606  			// comparison is okay as long as one side is
   607  			// assignable to the other.  convert so they have
   608  			// the same type.
   609  			//
   610  			// the only conversion that isn't a no-op is concrete == interface.
   611  			// in that case, check comparability of the concrete type.
   612  			// The conversion allocates, so only do it if the concrete type is huge.
   613  			if r.Type.Etype != TBLANK {
   614  				aop = assignop(l.Type, r.Type, nil)
   615  				if aop != 0 {
   616  					if Isinter(r.Type) && !Isinter(l.Type) && algtype1(l.Type, nil) == ANOEQ {
   617  						Yyerror("invalid operation: %v (operator %v not defined on %s)", n, Oconv(int(op), 0), typekind(l.Type))
   618  						n.Type = nil
   619  						return
   620  					}
   621  
   622  					dowidth(l.Type)
   623  					if Isinter(r.Type) == Isinter(l.Type) || l.Type.Width >= 1<<16 {
   624  						l = Nod(aop, l, nil)
   625  						l.Type = r.Type
   626  						l.Typecheck = 1
   627  						n.Left = l
   628  					}
   629  
   630  					t = r.Type
   631  					goto converted
   632  				}
   633  			}
   634  
   635  			if l.Type.Etype != TBLANK {
   636  				aop = assignop(r.Type, l.Type, nil)
   637  				if aop != 0 {
   638  					if Isinter(l.Type) && !Isinter(r.Type) && algtype1(r.Type, nil) == ANOEQ {
   639  						Yyerror("invalid operation: %v (operator %v not defined on %s)", n, Oconv(int(op), 0), typekind(r.Type))
   640  						n.Type = nil
   641  						return
   642  					}
   643  
   644  					dowidth(r.Type)
   645  					if Isinter(r.Type) == Isinter(l.Type) || r.Type.Width >= 1<<16 {
   646  						r = Nod(aop, r, nil)
   647  						r.Type = l.Type
   648  						r.Typecheck = 1
   649  						n.Right = r
   650  					}
   651  
   652  					t = l.Type
   653  				}
   654  			}
   655  
   656  		converted:
   657  			et = int(t.Etype)
   658  		}
   659  
   660  		if t.Etype != TIDEAL && !Eqtype(l.Type, r.Type) {
   661  			defaultlit2(&l, &r, 1)
   662  			if n.Op == OASOP && n.Implicit {
   663  				Yyerror("invalid operation: %v (non-numeric type %v)", n, l.Type)
   664  				n.Type = nil
   665  				return
   666  			}
   667  
   668  			if Isinter(r.Type) == Isinter(l.Type) || aop == 0 {
   669  				Yyerror("invalid operation: %v (mismatched types %v and %v)", n, l.Type, r.Type)
   670  				n.Type = nil
   671  				return
   672  			}
   673  		}
   674  
   675  		if !okfor[op][et] {
   676  			Yyerror("invalid operation: %v (operator %v not defined on %s)", n, Oconv(int(op), 0), typekind(t))
   677  			n.Type = nil
   678  			return
   679  		}
   680  
   681  		// okfor allows any array == array, map == map, func == func.
   682  		// restrict to slice/map/func == nil and nil == slice/map/func.
   683  		if Isfixedarray(l.Type) && algtype1(l.Type, nil) == ANOEQ {
   684  			Yyerror("invalid operation: %v (%v cannot be compared)", n, l.Type)
   685  			n.Type = nil
   686  			return
   687  		}
   688  
   689  		if Isslice(l.Type) && !isnil(l) && !isnil(r) {
   690  			Yyerror("invalid operation: %v (slice can only be compared to nil)", n)
   691  			n.Type = nil
   692  			return
   693  		}
   694  
   695  		if l.Type.Etype == TMAP && !isnil(l) && !isnil(r) {
   696  			Yyerror("invalid operation: %v (map can only be compared to nil)", n)
   697  			n.Type = nil
   698  			return
   699  		}
   700  
   701  		if l.Type.Etype == TFUNC && !isnil(l) && !isnil(r) {
   702  			Yyerror("invalid operation: %v (func can only be compared to nil)", n)
   703  			n.Type = nil
   704  			return
   705  		}
   706  
   707  		var badtype *Type
   708  		if l.Type.Etype == TSTRUCT && algtype1(l.Type, &badtype) == ANOEQ {
   709  			Yyerror("invalid operation: %v (struct containing %v cannot be compared)", n, badtype)
   710  			n.Type = nil
   711  			return
   712  		}
   713  
   714  		t = l.Type
   715  		if iscmp[n.Op] {
   716  			evconst(n)
   717  			t = idealbool
   718  			if n.Op != OLITERAL {
   719  				defaultlit2(&l, &r, 1)
   720  				n.Left = l
   721  				n.Right = r
   722  			}
   723  		} else if n.Op == OANDAND || n.Op == OOROR {
   724  			if l.Type == r.Type {
   725  				t = l.Type
   726  			} else if l.Type == idealbool {
   727  				t = r.Type
   728  			} else if r.Type == idealbool {
   729  				t = l.Type
   730  			}
   731  		} else
   732  		// non-comparison operators on ideal bools should make them lose their ideal-ness
   733  		if t == idealbool {
   734  			t = Types[TBOOL]
   735  		}
   736  
   737  		if et == TSTRING {
   738  			if iscmp[n.Op] {
   739  				n.Etype = n.Op
   740  				n.Op = OCMPSTR
   741  			} else if n.Op == OADD {
   742  				// create OADDSTR node with list of strings in x + y + z + (w + v) + ...
   743  				n.Op = OADDSTR
   744  
   745  				if l.Op == OADDSTR {
   746  					n.List = l.List
   747  				} else {
   748  					n.List = list1(l)
   749  				}
   750  				if r.Op == OADDSTR {
   751  					n.List = concat(n.List, r.List)
   752  				} else {
   753  					n.List = list(n.List, r)
   754  				}
   755  				n.Left = nil
   756  				n.Right = nil
   757  			}
   758  		}
   759  
   760  		if et == TINTER {
   761  			if l.Op == OLITERAL && l.Val.Ctype == CTNIL {
   762  				// swap for back end
   763  				n.Left = r
   764  
   765  				n.Right = l
   766  			} else if r.Op == OLITERAL && r.Val.Ctype == CTNIL {
   767  			} else // leave alone for back end
   768  			if Isinter(r.Type) == Isinter(l.Type) {
   769  				n.Etype = n.Op
   770  				n.Op = OCMPIFACE
   771  			}
   772  		}
   773  
   774  		if (op == ODIV || op == OMOD) && Isconst(r, CTINT) {
   775  			if mpcmpfixc(r.Val.U.Xval, 0) == 0 {
   776  				Yyerror("division by zero")
   777  				n.Type = nil
   778  				return
   779  			}
   780  		}
   781  
   782  		n.Type = t
   783  		break OpSwitch
   784  
   785  	case OCOM, OMINUS, ONOT, OPLUS:
   786  		ok |= Erv
   787  		l := typecheck(&n.Left, Erv|top&Eiota)
   788  		t := l.Type
   789  		if t == nil {
   790  			n.Type = nil
   791  			return
   792  		}
   793  		if !okfor[n.Op][t.Etype] {
   794  			Yyerror("invalid operation: %v %v", Oconv(int(n.Op), 0), t)
   795  			n.Type = nil
   796  			return
   797  		}
   798  
   799  		n.Type = t
   800  		break OpSwitch
   801  
   802  		/*
   803  		 * exprs
   804  		 */
   805  	case OADDR:
   806  		ok |= Erv
   807  
   808  		typecheck(&n.Left, Erv|Eaddr)
   809  		if n.Left.Type == nil {
   810  			n.Type = nil
   811  			return
   812  		}
   813  		checklvalue(n.Left, "take the address of")
   814  		r := outervalue(n.Left)
   815  		var l *Node
   816  		for l = n.Left; l != r; l = l.Left {
   817  			l.Addrtaken = true
   818  			if l.Closure != nil {
   819  				l.Closure.Addrtaken = true
   820  			}
   821  		}
   822  
   823  		if l.Orig != l && l.Op == ONAME {
   824  			Fatal("found non-orig name node %v", l)
   825  		}
   826  		l.Addrtaken = true
   827  		if l.Closure != nil {
   828  			l.Closure.Addrtaken = true
   829  		}
   830  		defaultlit(&n.Left, nil)
   831  		l = n.Left
   832  		t := l.Type
   833  		if t == nil {
   834  			n.Type = nil
   835  			return
   836  		}
   837  		n.Type = Ptrto(t)
   838  		break OpSwitch
   839  
   840  	case OCOMPLIT:
   841  		ok |= Erv
   842  		typecheckcomplit(&n)
   843  		if n.Type == nil {
   844  			n.Type = nil
   845  			return
   846  		}
   847  		break OpSwitch
   848  
   849  	case OXDOT, ODOT:
   850  		if n.Op == OXDOT {
   851  			n = adddot(n)
   852  			n.Op = ODOT
   853  			if n.Left == nil {
   854  				n.Type = nil
   855  				return
   856  			}
   857  		}
   858  
   859  		typecheck(&n.Left, Erv|Etype)
   860  
   861  		defaultlit(&n.Left, nil)
   862  		if n.Right.Op != ONAME {
   863  			Yyerror("rhs of . must be a name") // impossible
   864  			n.Type = nil
   865  			return
   866  		}
   867  
   868  		t := n.Left.Type
   869  		if t == nil {
   870  			adderrorname(n)
   871  			n.Type = nil
   872  			return
   873  		}
   874  
   875  		r := n.Right
   876  
   877  		if n.Left.Op == OTYPE {
   878  			if !looktypedot(n, t, 0) {
   879  				if looktypedot(n, t, 1) {
   880  					Yyerror("%v undefined (cannot refer to unexported method %v)", n, n.Right.Sym)
   881  				} else {
   882  					Yyerror("%v undefined (type %v has no method %v)", n, t, n.Right.Sym)
   883  				}
   884  				n.Type = nil
   885  				return
   886  			}
   887  
   888  			if n.Type.Etype != TFUNC || n.Type.Thistuple != 1 {
   889  				Yyerror("type %v has no method %v", n.Left.Type, Sconv(n.Right.Sym, obj.FmtShort))
   890  				n.Type = nil
   891  				n.Type = nil
   892  				return
   893  			}
   894  
   895  			n.Op = ONAME
   896  			n.Sym = n.Right.Sym
   897  			n.Type = methodfunc(n.Type, n.Left.Type)
   898  			n.Xoffset = 0
   899  			n.Class = PFUNC
   900  			ok = Erv
   901  			break OpSwitch
   902  		}
   903  
   904  		if Isptr[t.Etype] && t.Type.Etype != TINTER {
   905  			t = t.Type
   906  			if t == nil {
   907  				n.Type = nil
   908  				return
   909  			}
   910  			n.Op = ODOTPTR
   911  			checkwidth(t)
   912  		}
   913  
   914  		if isblank(n.Right) {
   915  			Yyerror("cannot refer to blank field or method")
   916  			n.Type = nil
   917  			return
   918  		}
   919  
   920  		if !lookdot(n, t, 0) {
   921  			if lookdot(n, t, 1) {
   922  				Yyerror("%v undefined (cannot refer to unexported field or method %v)", n, n.Right.Sym)
   923  			} else {
   924  				Yyerror("%v undefined (type %v has no field or method %v)", n, n.Left.Type, n.Right.Sym)
   925  			}
   926  			n.Type = nil
   927  			return
   928  		}
   929  
   930  		switch n.Op {
   931  		case ODOTINTER, ODOTMETH:
   932  			if top&Ecall != 0 {
   933  				ok |= Ecall
   934  			} else {
   935  				typecheckpartialcall(n, r)
   936  				ok |= Erv
   937  			}
   938  
   939  		default:
   940  			ok |= Erv
   941  		}
   942  
   943  		break OpSwitch
   944  
   945  	case ODOTTYPE:
   946  		ok |= Erv
   947  		typecheck(&n.Left, Erv)
   948  		defaultlit(&n.Left, nil)
   949  		l := n.Left
   950  		t := l.Type
   951  		if t == nil {
   952  			n.Type = nil
   953  			return
   954  		}
   955  		if !Isinter(t) {
   956  			Yyerror("invalid type assertion: %v (non-interface type %v on left)", n, t)
   957  			n.Type = nil
   958  			return
   959  		}
   960  
   961  		if n.Right != nil {
   962  			typecheck(&n.Right, Etype)
   963  			n.Type = n.Right.Type
   964  			n.Right = nil
   965  			if n.Type == nil {
   966  				n.Type = nil
   967  				return
   968  			}
   969  		}
   970  
   971  		if n.Type != nil && n.Type.Etype != TINTER {
   972  			var have *Type
   973  			var missing *Type
   974  			var ptr int
   975  			if !implements(n.Type, t, &missing, &have, &ptr) {
   976  				if have != nil && have.Sym == missing.Sym {
   977  					Yyerror("impossible type assertion:\n\t%v does not implement %v (wrong type for %v method)\n"+"\t\thave %v%v\n\t\twant %v%v", n.Type, t, missing.Sym, have.Sym, Tconv(have.Type, obj.FmtShort|obj.FmtByte), missing.Sym, Tconv(missing.Type, obj.FmtShort|obj.FmtByte))
   978  				} else if ptr != 0 {
   979  					Yyerror("impossible type assertion:\n\t%v does not implement %v (%v method has pointer receiver)", n.Type, t, missing.Sym)
   980  				} else if have != nil {
   981  					Yyerror("impossible type assertion:\n\t%v does not implement %v (missing %v method)\n"+"\t\thave %v%v\n\t\twant %v%v", n.Type, t, missing.Sym, have.Sym, Tconv(have.Type, obj.FmtShort|obj.FmtByte), missing.Sym, Tconv(missing.Type, obj.FmtShort|obj.FmtByte))
   982  				} else {
   983  					Yyerror("impossible type assertion:\n\t%v does not implement %v (missing %v method)", n.Type, t, missing.Sym)
   984  				}
   985  				n.Type = nil
   986  				return
   987  			}
   988  		}
   989  
   990  		break OpSwitch
   991  
   992  	case OINDEX:
   993  		ok |= Erv
   994  		typecheck(&n.Left, Erv)
   995  		defaultlit(&n.Left, nil)
   996  		implicitstar(&n.Left)
   997  		l := n.Left
   998  		typecheck(&n.Right, Erv)
   999  		r := n.Right
  1000  		t := l.Type
  1001  		if t == nil || r.Type == nil {
  1002  			n.Type = nil
  1003  			return
  1004  		}
  1005  		switch t.Etype {
  1006  		default:
  1007  			Yyerror("invalid operation: %v (type %v does not support indexing)", n, t)
  1008  			n.Type = nil
  1009  			return
  1010  
  1011  		case TSTRING, TARRAY:
  1012  			indexlit(&n.Right)
  1013  			if t.Etype == TSTRING {
  1014  				n.Type = Types[TUINT8]
  1015  			} else {
  1016  				n.Type = t.Type
  1017  			}
  1018  			why := "string"
  1019  			if t.Etype == TARRAY {
  1020  				if Isfixedarray(t) {
  1021  					why = "array"
  1022  				} else {
  1023  					why = "slice"
  1024  				}
  1025  			}
  1026  
  1027  			if n.Right.Type != nil && !Isint[n.Right.Type.Etype] {
  1028  				Yyerror("non-integer %s index %v", why, n.Right)
  1029  				break
  1030  			}
  1031  
  1032  			if Isconst(n.Right, CTINT) {
  1033  				x := Mpgetfix(n.Right.Val.U.Xval)
  1034  				if x < 0 {
  1035  					Yyerror("invalid %s index %v (index must be non-negative)", why, n.Right)
  1036  				} else if Isfixedarray(t) && t.Bound > 0 && x >= t.Bound {
  1037  					Yyerror("invalid array index %v (out of bounds for %d-element array)", n.Right, t.Bound)
  1038  				} else if Isconst(n.Left, CTSTR) && x >= int64(len(n.Left.Val.U.Sval)) {
  1039  					Yyerror("invalid string index %v (out of bounds for %d-byte string)", n.Right, len(n.Left.Val.U.Sval))
  1040  				} else if Mpcmpfixfix(n.Right.Val.U.Xval, Maxintval[TINT]) > 0 {
  1041  					Yyerror("invalid %s index %v (index too large)", why, n.Right)
  1042  				}
  1043  			}
  1044  
  1045  		case TMAP:
  1046  			n.Etype = 0
  1047  			defaultlit(&n.Right, t.Down)
  1048  			if n.Right.Type != nil {
  1049  				n.Right = assignconv(n.Right, t.Down, "map index")
  1050  			}
  1051  			n.Type = t.Type
  1052  			n.Op = OINDEXMAP
  1053  		}
  1054  
  1055  		break OpSwitch
  1056  
  1057  	case ORECV:
  1058  		ok |= Etop | Erv
  1059  		typecheck(&n.Left, Erv)
  1060  		defaultlit(&n.Left, nil)
  1061  		l := n.Left
  1062  		t := l.Type
  1063  		if t == nil {
  1064  			n.Type = nil
  1065  			return
  1066  		}
  1067  		if t.Etype != TCHAN {
  1068  			Yyerror("invalid operation: %v (receive from non-chan type %v)", n, t)
  1069  			n.Type = nil
  1070  			return
  1071  		}
  1072  
  1073  		if t.Chan&Crecv == 0 {
  1074  			Yyerror("invalid operation: %v (receive from send-only type %v)", n, t)
  1075  			n.Type = nil
  1076  			return
  1077  		}
  1078  
  1079  		n.Type = t.Type
  1080  		break OpSwitch
  1081  
  1082  	case OSEND:
  1083  		ok |= Etop
  1084  		l := typecheck(&n.Left, Erv)
  1085  		typecheck(&n.Right, Erv)
  1086  		defaultlit(&n.Left, nil)
  1087  		l = n.Left
  1088  		t := l.Type
  1089  		if t == nil {
  1090  			n.Type = nil
  1091  			return
  1092  		}
  1093  		if t.Etype != TCHAN {
  1094  			Yyerror("invalid operation: %v (send to non-chan type %v)", n, t)
  1095  			n.Type = nil
  1096  			return
  1097  		}
  1098  
  1099  		if t.Chan&Csend == 0 {
  1100  			Yyerror("invalid operation: %v (send to receive-only type %v)", n, t)
  1101  			n.Type = nil
  1102  			return
  1103  		}
  1104  
  1105  		defaultlit(&n.Right, t.Type)
  1106  		r := n.Right
  1107  		if r.Type == nil {
  1108  			n.Type = nil
  1109  			return
  1110  		}
  1111  		n.Right = assignconv(r, l.Type.Type, "send")
  1112  
  1113  		// TODO: more aggressive
  1114  		n.Etype = 0
  1115  
  1116  		n.Type = nil
  1117  		break OpSwitch
  1118  
  1119  	case OSLICE:
  1120  		ok |= Erv
  1121  		typecheck(&n.Left, top)
  1122  		typecheck(&n.Right.Left, Erv)
  1123  		typecheck(&n.Right.Right, Erv)
  1124  		defaultlit(&n.Left, nil)
  1125  		indexlit(&n.Right.Left)
  1126  		indexlit(&n.Right.Right)
  1127  		l := n.Left
  1128  		if Isfixedarray(l.Type) {
  1129  			if !islvalue(n.Left) {
  1130  				Yyerror("invalid operation %v (slice of unaddressable value)", n)
  1131  				n.Type = nil
  1132  				return
  1133  			}
  1134  
  1135  			n.Left = Nod(OADDR, n.Left, nil)
  1136  			n.Left.Implicit = true
  1137  			typecheck(&n.Left, Erv)
  1138  			l = n.Left
  1139  		}
  1140  
  1141  		t := l.Type
  1142  		if t == nil {
  1143  			n.Type = nil
  1144  			return
  1145  		}
  1146  		var tp *Type
  1147  		if Istype(t, TSTRING) {
  1148  			n.Type = t
  1149  			n.Op = OSLICESTR
  1150  		} else if Isptr[t.Etype] && Isfixedarray(t.Type) {
  1151  			tp = t.Type
  1152  			n.Type = typ(TARRAY)
  1153  			n.Type.Type = tp.Type
  1154  			n.Type.Bound = -1
  1155  			dowidth(n.Type)
  1156  			n.Op = OSLICEARR
  1157  		} else if Isslice(t) {
  1158  			n.Type = t
  1159  		} else {
  1160  			Yyerror("cannot slice %v (type %v)", l, t)
  1161  			n.Type = nil
  1162  			return
  1163  		}
  1164  
  1165  		lo := n.Right.Left
  1166  		if lo != nil && checksliceindex(l, lo, tp) < 0 {
  1167  			n.Type = nil
  1168  			return
  1169  		}
  1170  		hi := n.Right.Right
  1171  		if hi != nil && checksliceindex(l, hi, tp) < 0 {
  1172  			n.Type = nil
  1173  			return
  1174  		}
  1175  		if checksliceconst(lo, hi) < 0 {
  1176  			n.Type = nil
  1177  			return
  1178  		}
  1179  		break OpSwitch
  1180  
  1181  	case OSLICE3:
  1182  		ok |= Erv
  1183  		typecheck(&n.Left, top)
  1184  		typecheck(&n.Right.Left, Erv)
  1185  		typecheck(&n.Right.Right.Left, Erv)
  1186  		typecheck(&n.Right.Right.Right, Erv)
  1187  		defaultlit(&n.Left, nil)
  1188  		indexlit(&n.Right.Left)
  1189  		indexlit(&n.Right.Right.Left)
  1190  		indexlit(&n.Right.Right.Right)
  1191  		l := n.Left
  1192  		if Isfixedarray(l.Type) {
  1193  			if !islvalue(n.Left) {
  1194  				Yyerror("invalid operation %v (slice of unaddressable value)", n)
  1195  				n.Type = nil
  1196  				return
  1197  			}
  1198  
  1199  			n.Left = Nod(OADDR, n.Left, nil)
  1200  			n.Left.Implicit = true
  1201  			typecheck(&n.Left, Erv)
  1202  			l = n.Left
  1203  		}
  1204  
  1205  		t := l.Type
  1206  		if t == nil {
  1207  			n.Type = nil
  1208  			return
  1209  		}
  1210  		if Istype(t, TSTRING) {
  1211  			Yyerror("invalid operation %v (3-index slice of string)", n)
  1212  			n.Type = nil
  1213  			return
  1214  		}
  1215  
  1216  		var tp *Type
  1217  		if Isptr[t.Etype] && Isfixedarray(t.Type) {
  1218  			tp = t.Type
  1219  			n.Type = typ(TARRAY)
  1220  			n.Type.Type = tp.Type
  1221  			n.Type.Bound = -1
  1222  			dowidth(n.Type)
  1223  			n.Op = OSLICE3ARR
  1224  		} else if Isslice(t) {
  1225  			n.Type = t
  1226  		} else {
  1227  			Yyerror("cannot slice %v (type %v)", l, t)
  1228  			n.Type = nil
  1229  			return
  1230  		}
  1231  
  1232  		lo := n.Right.Left
  1233  		if lo != nil && checksliceindex(l, lo, tp) < 0 {
  1234  			n.Type = nil
  1235  			return
  1236  		}
  1237  		mid := n.Right.Right.Left
  1238  		if mid != nil && checksliceindex(l, mid, tp) < 0 {
  1239  			n.Type = nil
  1240  			return
  1241  		}
  1242  		hi := n.Right.Right.Right
  1243  		if hi != nil && checksliceindex(l, hi, tp) < 0 {
  1244  			n.Type = nil
  1245  			return
  1246  		}
  1247  		if checksliceconst(lo, hi) < 0 || checksliceconst(lo, mid) < 0 || checksliceconst(mid, hi) < 0 {
  1248  			n.Type = nil
  1249  			return
  1250  		}
  1251  		break OpSwitch
  1252  
  1253  		/*
  1254  		 * call and call like
  1255  		 */
  1256  	case OCALL:
  1257  		l := n.Left
  1258  
  1259  		if l.Op == ONAME {
  1260  			r := unsafenmagic(n)
  1261  			if r != nil {
  1262  				if n.Isddd {
  1263  					Yyerror("invalid use of ... with builtin %v", l)
  1264  				}
  1265  				n = r
  1266  				typecheck1(&n, top)
  1267  				return
  1268  			}
  1269  		}
  1270  
  1271  		typecheck(&n.Left, Erv|Etype|Ecall|top&Eproc)
  1272  		n.Diag |= n.Left.Diag
  1273  		l = n.Left
  1274  		if l.Op == ONAME && l.Etype != 0 {
  1275  			if n.Isddd && l.Etype != OAPPEND {
  1276  				Yyerror("invalid use of ... with builtin %v", l)
  1277  			}
  1278  
  1279  			// builtin: OLEN, OCAP, etc.
  1280  			n.Op = l.Etype
  1281  
  1282  			n.Left = n.Right
  1283  			n.Right = nil
  1284  			typecheck1(&n, top)
  1285  			return
  1286  		}
  1287  
  1288  		defaultlit(&n.Left, nil)
  1289  		l = n.Left
  1290  		if l.Op == OTYPE {
  1291  			if n.Isddd || l.Type.Bound == -100 {
  1292  				if l.Type.Broke == 0 {
  1293  					Yyerror("invalid use of ... in type conversion", l)
  1294  				}
  1295  				n.Diag = 1
  1296  			}
  1297  
  1298  			// pick off before type-checking arguments
  1299  			ok |= Erv
  1300  
  1301  			// turn CALL(type, arg) into CONV(arg) w/ type
  1302  			n.Left = nil
  1303  
  1304  			n.Op = OCONV
  1305  			n.Type = l.Type
  1306  			if onearg(n, "conversion to %v", l.Type) < 0 {
  1307  				n.Type = nil
  1308  				return
  1309  			}
  1310  			typecheck1(&n, top)
  1311  			return
  1312  		}
  1313  
  1314  		if count(n.List) == 1 && !n.Isddd {
  1315  			typecheck(&n.List.N, Erv|Efnstruct)
  1316  		} else {
  1317  			typechecklist(n.List, Erv)
  1318  		}
  1319  		t := l.Type
  1320  		if t == nil {
  1321  			n.Type = nil
  1322  			return
  1323  		}
  1324  		checkwidth(t)
  1325  
  1326  		switch l.Op {
  1327  		case ODOTINTER:
  1328  			n.Op = OCALLINTER
  1329  
  1330  		case ODOTMETH:
  1331  			n.Op = OCALLMETH
  1332  
  1333  			// typecheckaste was used here but there wasn't enough
  1334  			// information further down the call chain to know if we
  1335  			// were testing a method receiver for unexported fields.
  1336  			// It isn't necessary, so just do a sanity check.
  1337  			tp := getthisx(t).Type.Type
  1338  
  1339  			if l.Left == nil || !Eqtype(l.Left.Type, tp) {
  1340  				Fatal("method receiver")
  1341  			}
  1342  
  1343  		default:
  1344  			n.Op = OCALLFUNC
  1345  			if t.Etype != TFUNC {
  1346  				Yyerror("cannot call non-function %v (type %v)", l, t)
  1347  				n.Type = nil
  1348  				return
  1349  			}
  1350  		}
  1351  
  1352  		typecheckaste(OCALL, n.Left, n.Isddd, getinargx(t), n.List, func() string { return fmt.Sprintf("argument to %v", n.Left) })
  1353  		ok |= Etop
  1354  		if t.Outtuple == 0 {
  1355  			break OpSwitch
  1356  		}
  1357  		ok |= Erv
  1358  		if t.Outtuple == 1 {
  1359  			t := getoutargx(l.Type).Type
  1360  			if t == nil {
  1361  				n.Type = nil
  1362  				return
  1363  			}
  1364  			if t.Etype == TFIELD {
  1365  				t = t.Type
  1366  			}
  1367  			n.Type = t
  1368  
  1369  			if n.Op == OCALLFUNC && n.Left.Op == ONAME && (compiling_runtime != 0 || n.Left.Sym.Pkg == Runtimepkg) && n.Left.Sym.Name == "getg" {
  1370  				// Emit code for runtime.getg() directly instead of calling function.
  1371  				// Most such rewrites (for example the similar one for math.Sqrt) should be done in walk,
  1372  				// so that the ordering pass can make sure to preserve the semantics of the original code
  1373  				// (in particular, the exact time of the function call) by introducing temporaries.
  1374  				// In this case, we know getg() always returns the same result within a given function
  1375  				// and we want to avoid the temporaries, so we do the rewrite earlier than is typical.
  1376  				n.Op = OGETG
  1377  			}
  1378  
  1379  			break OpSwitch
  1380  		}
  1381  
  1382  		// multiple return
  1383  		if top&(Efnstruct|Etop) == 0 {
  1384  			Yyerror("multiple-value %v() in single-value context", l)
  1385  			break OpSwitch
  1386  		}
  1387  
  1388  		n.Type = getoutargx(l.Type)
  1389  
  1390  		break OpSwitch
  1391  
  1392  	case OCAP, OLEN, OREAL, OIMAG:
  1393  		ok |= Erv
  1394  		if onearg(n, "%v", Oconv(int(n.Op), 0)) < 0 {
  1395  			n.Type = nil
  1396  			return
  1397  		}
  1398  		typecheck(&n.Left, Erv)
  1399  		defaultlit(&n.Left, nil)
  1400  		implicitstar(&n.Left)
  1401  		l := n.Left
  1402  		t := l.Type
  1403  		if t == nil {
  1404  			n.Type = nil
  1405  			return
  1406  		}
  1407  		switch n.Op {
  1408  		case OCAP:
  1409  			if !okforcap[t.Etype] {
  1410  				goto badcall1
  1411  			}
  1412  
  1413  		case OLEN:
  1414  			if !okforlen[t.Etype] {
  1415  				goto badcall1
  1416  			}
  1417  
  1418  		case OREAL, OIMAG:
  1419  			if !Iscomplex[t.Etype] {
  1420  				goto badcall1
  1421  			}
  1422  			if Isconst(l, CTCPLX) {
  1423  				r := n
  1424  				if n.Op == OREAL {
  1425  					n = nodfltconst(&l.Val.U.Cval.Real)
  1426  				} else {
  1427  					n = nodfltconst(&l.Val.U.Cval.Imag)
  1428  				}
  1429  				n.Orig = r
  1430  			}
  1431  
  1432  			n.Type = Types[cplxsubtype(int(t.Etype))]
  1433  			break OpSwitch
  1434  		}
  1435  
  1436  		// might be constant
  1437  		switch t.Etype {
  1438  		case TSTRING:
  1439  			if Isconst(l, CTSTR) {
  1440  				r := Nod(OXXX, nil, nil)
  1441  				Nodconst(r, Types[TINT], int64(len(l.Val.U.Sval)))
  1442  				r.Orig = n
  1443  				n = r
  1444  			}
  1445  
  1446  		case TARRAY:
  1447  			if t.Bound < 0 { // slice
  1448  				break
  1449  			}
  1450  			if callrecv(l) { // has call or receive
  1451  				break
  1452  			}
  1453  			r := Nod(OXXX, nil, nil)
  1454  			Nodconst(r, Types[TINT], t.Bound)
  1455  			r.Orig = n
  1456  			n = r
  1457  		}
  1458  
  1459  		n.Type = Types[TINT]
  1460  		break OpSwitch
  1461  
  1462  	badcall1:
  1463  		Yyerror("invalid argument %v for %v", Nconv(n.Left, obj.FmtLong), Oconv(int(n.Op), 0))
  1464  		n.Type = nil
  1465  		return
  1466  
  1467  	case OCOMPLEX:
  1468  		ok |= Erv
  1469  		var r *Node
  1470  		var l *Node
  1471  		if count(n.List) == 1 {
  1472  			typechecklist(n.List, Efnstruct)
  1473  			if n.List.N.Op != OCALLFUNC && n.List.N.Op != OCALLMETH {
  1474  				Yyerror("invalid operation: complex expects two arguments")
  1475  				n.Type = nil
  1476  				return
  1477  			}
  1478  
  1479  			t := n.List.N.Left.Type
  1480  			if t.Outtuple != 2 {
  1481  				Yyerror("invalid operation: complex expects two arguments, %v returns %d results", n.List.N, t.Outtuple)
  1482  				n.Type = nil
  1483  				return
  1484  			}
  1485  
  1486  			t = n.List.N.Type.Type
  1487  			l = t.Nname
  1488  			r = t.Down.Nname
  1489  		} else {
  1490  			if twoarg(n) < 0 {
  1491  				n.Type = nil
  1492  				return
  1493  			}
  1494  			l = typecheck(&n.Left, Erv|top&Eiota)
  1495  			r = typecheck(&n.Right, Erv|top&Eiota)
  1496  			if l.Type == nil || r.Type == nil {
  1497  				n.Type = nil
  1498  				return
  1499  			}
  1500  			defaultlit2(&l, &r, 0)
  1501  			if l.Type == nil || r.Type == nil {
  1502  				n.Type = nil
  1503  				return
  1504  			}
  1505  			n.Left = l
  1506  			n.Right = r
  1507  		}
  1508  
  1509  		if !Eqtype(l.Type, r.Type) {
  1510  			Yyerror("invalid operation: %v (mismatched types %v and %v)", n, l.Type, r.Type)
  1511  			n.Type = nil
  1512  			return
  1513  		}
  1514  
  1515  		var t *Type
  1516  		switch l.Type.Etype {
  1517  		default:
  1518  			Yyerror("invalid operation: %v (arguments have type %v, expected floating-point)", n, l.Type, r.Type)
  1519  			n.Type = nil
  1520  			return
  1521  
  1522  		case TIDEAL:
  1523  			t = Types[TIDEAL]
  1524  
  1525  		case TFLOAT32:
  1526  			t = Types[TCOMPLEX64]
  1527  
  1528  		case TFLOAT64:
  1529  			t = Types[TCOMPLEX128]
  1530  		}
  1531  
  1532  		if l.Op == OLITERAL && r.Op == OLITERAL {
  1533  			// make it a complex literal
  1534  			r = nodcplxlit(l.Val, r.Val)
  1535  
  1536  			r.Orig = n
  1537  			n = r
  1538  		}
  1539  
  1540  		n.Type = t
  1541  		break OpSwitch
  1542  
  1543  	case OCLOSE:
  1544  		if onearg(n, "%v", Oconv(int(n.Op), 0)) < 0 {
  1545  			n.Type = nil
  1546  			return
  1547  		}
  1548  		typecheck(&n.Left, Erv)
  1549  		defaultlit(&n.Left, nil)
  1550  		l := n.Left
  1551  		t := l.Type
  1552  		if t == nil {
  1553  			n.Type = nil
  1554  			return
  1555  		}
  1556  		if t.Etype != TCHAN {
  1557  			Yyerror("invalid operation: %v (non-chan type %v)", n, t)
  1558  			n.Type = nil
  1559  			return
  1560  		}
  1561  
  1562  		if t.Chan&Csend == 0 {
  1563  			Yyerror("invalid operation: %v (cannot close receive-only channel)", n)
  1564  			n.Type = nil
  1565  			return
  1566  		}
  1567  
  1568  		ok |= Etop
  1569  		break OpSwitch
  1570  
  1571  	case ODELETE:
  1572  		args := n.List
  1573  		if args == nil {
  1574  			Yyerror("missing arguments to delete")
  1575  			n.Type = nil
  1576  			return
  1577  		}
  1578  
  1579  		if args.Next == nil {
  1580  			Yyerror("missing second (key) argument to delete")
  1581  			n.Type = nil
  1582  			return
  1583  		}
  1584  
  1585  		if args.Next.Next != nil {
  1586  			Yyerror("too many arguments to delete")
  1587  			n.Type = nil
  1588  			return
  1589  		}
  1590  
  1591  		ok |= Etop
  1592  		typechecklist(args, Erv)
  1593  		l := args.N
  1594  		r := args.Next.N
  1595  		if l.Type != nil && l.Type.Etype != TMAP {
  1596  			Yyerror("first argument to delete must be map; have %v", Tconv(l.Type, obj.FmtLong))
  1597  			n.Type = nil
  1598  			return
  1599  		}
  1600  
  1601  		args.Next.N = assignconv(r, l.Type.Down, "delete")
  1602  		break OpSwitch
  1603  
  1604  	case OAPPEND:
  1605  		ok |= Erv
  1606  		args := n.List
  1607  		if args == nil {
  1608  			Yyerror("missing arguments to append")
  1609  			n.Type = nil
  1610  			return
  1611  		}
  1612  
  1613  		if count(args) == 1 && !n.Isddd {
  1614  			typecheck(&args.N, Erv|Efnstruct)
  1615  		} else {
  1616  			typechecklist(args, Erv)
  1617  		}
  1618  
  1619  		t := args.N.Type
  1620  		if t == nil {
  1621  			n.Type = nil
  1622  			return
  1623  		}
  1624  
  1625  		// Unpack multiple-return result before type-checking.
  1626  		if Istype(t, TSTRUCT) && t.Funarg != 0 {
  1627  			t = t.Type
  1628  			if Istype(t, TFIELD) {
  1629  				t = t.Type
  1630  			}
  1631  		}
  1632  
  1633  		n.Type = t
  1634  		if !Isslice(t) {
  1635  			if Isconst(args.N, CTNIL) {
  1636  				Yyerror("first argument to append must be typed slice; have untyped nil", t)
  1637  				n.Type = nil
  1638  				return
  1639  			}
  1640  
  1641  			Yyerror("first argument to append must be slice; have %v", Tconv(t, obj.FmtLong))
  1642  			n.Type = nil
  1643  			return
  1644  		}
  1645  
  1646  		if n.Isddd {
  1647  			if args.Next == nil {
  1648  				Yyerror("cannot use ... on first argument to append")
  1649  				n.Type = nil
  1650  				return
  1651  			}
  1652  
  1653  			if args.Next.Next != nil {
  1654  				Yyerror("too many arguments to append")
  1655  				n.Type = nil
  1656  				return
  1657  			}
  1658  
  1659  			if Istype(t.Type, TUINT8) && Istype(args.Next.N.Type, TSTRING) {
  1660  				defaultlit(&args.Next.N, Types[TSTRING])
  1661  				break OpSwitch
  1662  			}
  1663  
  1664  			args.Next.N = assignconv(args.Next.N, t.Orig, "append")
  1665  			break OpSwitch
  1666  		}
  1667  
  1668  		for args = args.Next; args != nil; args = args.Next {
  1669  			if args.N.Type == nil {
  1670  				continue
  1671  			}
  1672  			args.N = assignconv(args.N, t.Type, "append")
  1673  		}
  1674  
  1675  		break OpSwitch
  1676  
  1677  	case OCOPY:
  1678  		ok |= Etop | Erv
  1679  		args := n.List
  1680  		if args == nil || args.Next == nil {
  1681  			Yyerror("missing arguments to copy")
  1682  			n.Type = nil
  1683  			return
  1684  		}
  1685  
  1686  		if args.Next.Next != nil {
  1687  			Yyerror("too many arguments to copy")
  1688  			n.Type = nil
  1689  			return
  1690  		}
  1691  
  1692  		n.Left = args.N
  1693  		n.Right = args.Next.N
  1694  		n.List = nil
  1695  		n.Type = Types[TINT]
  1696  		typecheck(&n.Left, Erv)
  1697  		typecheck(&n.Right, Erv)
  1698  		if n.Left.Type == nil || n.Right.Type == nil {
  1699  			n.Type = nil
  1700  			return
  1701  		}
  1702  		defaultlit(&n.Left, nil)
  1703  		defaultlit(&n.Right, nil)
  1704  		if n.Left.Type == nil || n.Right.Type == nil {
  1705  			n.Type = nil
  1706  			return
  1707  		}
  1708  
  1709  		// copy([]byte, string)
  1710  		if Isslice(n.Left.Type) && n.Right.Type.Etype == TSTRING {
  1711  			if Eqtype(n.Left.Type.Type, bytetype) {
  1712  				break OpSwitch
  1713  			}
  1714  			Yyerror("arguments to copy have different element types: %v and string", Tconv(n.Left.Type, obj.FmtLong))
  1715  			n.Type = nil
  1716  			return
  1717  		}
  1718  
  1719  		if !Isslice(n.Left.Type) || !Isslice(n.Right.Type) {
  1720  			if !Isslice(n.Left.Type) && !Isslice(n.Right.Type) {
  1721  				Yyerror("arguments to copy must be slices; have %v, %v", Tconv(n.Left.Type, obj.FmtLong), Tconv(n.Right.Type, obj.FmtLong))
  1722  			} else if !Isslice(n.Left.Type) {
  1723  				Yyerror("first argument to copy should be slice; have %v", Tconv(n.Left.Type, obj.FmtLong))
  1724  			} else {
  1725  				Yyerror("second argument to copy should be slice or string; have %v", Tconv(n.Right.Type, obj.FmtLong))
  1726  			}
  1727  			n.Type = nil
  1728  			return
  1729  		}
  1730  
  1731  		if !Eqtype(n.Left.Type.Type, n.Right.Type.Type) {
  1732  			Yyerror("arguments to copy have different element types: %v and %v", Tconv(n.Left.Type, obj.FmtLong), Tconv(n.Right.Type, obj.FmtLong))
  1733  			n.Type = nil
  1734  			return
  1735  		}
  1736  
  1737  		break OpSwitch
  1738  
  1739  	case OCONV:
  1740  		ok |= Erv
  1741  		saveorignode(n)
  1742  		typecheck(&n.Left, Erv|top&(Eindir|Eiota))
  1743  		convlit1(&n.Left, n.Type, true)
  1744  		t := n.Left.Type
  1745  		if t == nil || n.Type == nil {
  1746  			n.Type = nil
  1747  			return
  1748  		}
  1749  		var why string
  1750  		n.Op = uint8(convertop(t, n.Type, &why))
  1751  		if (n.Op) == 0 {
  1752  			if n.Diag == 0 && n.Type.Broke == 0 {
  1753  				Yyerror("cannot convert %v to type %v%s", Nconv(n.Left, obj.FmtLong), n.Type, why)
  1754  				n.Diag = 1
  1755  			}
  1756  
  1757  			n.Op = OCONV
  1758  		}
  1759  
  1760  		switch n.Op {
  1761  		case OCONVNOP:
  1762  			if n.Left.Op == OLITERAL && n.Type != Types[TBOOL] {
  1763  				r := Nod(OXXX, nil, nil)
  1764  				n.Op = OCONV
  1765  				n.Orig = r
  1766  				*r = *n
  1767  				n.Op = OLITERAL
  1768  				n.Val = n.Left.Val
  1769  			}
  1770  
  1771  			// do not use stringtoarraylit.
  1772  		// generated code and compiler memory footprint is better without it.
  1773  		case OSTRARRAYBYTE:
  1774  			break
  1775  
  1776  		case OSTRARRAYRUNE:
  1777  			if n.Left.Op == OLITERAL {
  1778  				stringtoarraylit(&n)
  1779  			}
  1780  		}
  1781  
  1782  		break OpSwitch
  1783  
  1784  	case OMAKE:
  1785  		ok |= Erv
  1786  		args := n.List
  1787  		if args == nil {
  1788  			Yyerror("missing argument to make")
  1789  			n.Type = nil
  1790  			return
  1791  		}
  1792  
  1793  		n.List = nil
  1794  		l := args.N
  1795  		args = args.Next
  1796  		typecheck(&l, Etype)
  1797  		t := l.Type
  1798  		if t == nil {
  1799  			n.Type = nil
  1800  			return
  1801  		}
  1802  
  1803  		switch t.Etype {
  1804  		default:
  1805  			Yyerror("cannot make type %v", t)
  1806  			n.Type = nil
  1807  			return
  1808  
  1809  		case TARRAY:
  1810  			if !Isslice(t) {
  1811  				Yyerror("cannot make type %v", t)
  1812  				n.Type = nil
  1813  				return
  1814  			}
  1815  
  1816  			if args == nil {
  1817  				Yyerror("missing len argument to make(%v)", t)
  1818  				n.Type = nil
  1819  				return
  1820  			}
  1821  
  1822  			l = args.N
  1823  			args = args.Next
  1824  			typecheck(&l, Erv)
  1825  			var r *Node
  1826  			if args != nil {
  1827  				r = args.N
  1828  				args = args.Next
  1829  				typecheck(&r, Erv)
  1830  			}
  1831  
  1832  			if l.Type == nil || (r != nil && r.Type == nil) {
  1833  				n.Type = nil
  1834  				return
  1835  			}
  1836  			et := obj.Bool2int(checkmake(t, "len", l) < 0)
  1837  			et |= obj.Bool2int(r != nil && checkmake(t, "cap", r) < 0)
  1838  			if et != 0 {
  1839  				n.Type = nil
  1840  				return
  1841  			}
  1842  			if Isconst(l, CTINT) && r != nil && Isconst(r, CTINT) && Mpcmpfixfix(l.Val.U.Xval, r.Val.U.Xval) > 0 {
  1843  				Yyerror("len larger than cap in make(%v)", t)
  1844  				n.Type = nil
  1845  				return
  1846  			}
  1847  
  1848  			n.Left = l
  1849  			n.Right = r
  1850  			n.Op = OMAKESLICE
  1851  
  1852  		case TMAP:
  1853  			if args != nil {
  1854  				l = args.N
  1855  				args = args.Next
  1856  				typecheck(&l, Erv)
  1857  				defaultlit(&l, Types[TINT])
  1858  				if l.Type == nil {
  1859  					n.Type = nil
  1860  					return
  1861  				}
  1862  				if checkmake(t, "size", l) < 0 {
  1863  					n.Type = nil
  1864  					return
  1865  				}
  1866  				n.Left = l
  1867  			} else {
  1868  				n.Left = Nodintconst(0)
  1869  			}
  1870  			n.Op = OMAKEMAP
  1871  
  1872  		case TCHAN:
  1873  			l = nil
  1874  			if args != nil {
  1875  				l = args.N
  1876  				args = args.Next
  1877  				typecheck(&l, Erv)
  1878  				defaultlit(&l, Types[TINT])
  1879  				if l.Type == nil {
  1880  					n.Type = nil
  1881  					return
  1882  				}
  1883  				if checkmake(t, "buffer", l) < 0 {
  1884  					n.Type = nil
  1885  					return
  1886  				}
  1887  				n.Left = l
  1888  			} else {
  1889  				n.Left = Nodintconst(0)
  1890  			}
  1891  			n.Op = OMAKECHAN
  1892  		}
  1893  
  1894  		if args != nil {
  1895  			Yyerror("too many arguments to make(%v)", t)
  1896  			n.Op = OMAKE
  1897  			n.Type = nil
  1898  			return
  1899  		}
  1900  
  1901  		n.Type = t
  1902  		break OpSwitch
  1903  
  1904  	case ONEW:
  1905  		ok |= Erv
  1906  		args := n.List
  1907  		if args == nil {
  1908  			Yyerror("missing argument to new")
  1909  			n.Type = nil
  1910  			return
  1911  		}
  1912  
  1913  		l := args.N
  1914  		typecheck(&l, Etype)
  1915  		t := l.Type
  1916  		if t == nil {
  1917  			n.Type = nil
  1918  			return
  1919  		}
  1920  		if args.Next != nil {
  1921  			Yyerror("too many arguments to new(%v)", t)
  1922  			n.Type = nil
  1923  			return
  1924  		}
  1925  
  1926  		n.Left = l
  1927  		n.Type = Ptrto(t)
  1928  		break OpSwitch
  1929  
  1930  	case OPRINT, OPRINTN:
  1931  		ok |= Etop
  1932  		typechecklist(n.List, Erv|Eindir) // Eindir: address does not escape
  1933  		for args := n.List; args != nil; args = args.Next {
  1934  			// Special case for print: int constant is int64, not int.
  1935  			if Isconst(args.N, CTINT) {
  1936  				defaultlit(&args.N, Types[TINT64])
  1937  			} else {
  1938  				defaultlit(&args.N, nil)
  1939  			}
  1940  		}
  1941  
  1942  		break OpSwitch
  1943  
  1944  	case OPANIC:
  1945  		ok |= Etop
  1946  		if onearg(n, "panic") < 0 {
  1947  			n.Type = nil
  1948  			return
  1949  		}
  1950  		typecheck(&n.Left, Erv)
  1951  		defaultlit(&n.Left, Types[TINTER])
  1952  		if n.Left.Type == nil {
  1953  			n.Type = nil
  1954  			return
  1955  		}
  1956  		break OpSwitch
  1957  
  1958  	case ORECOVER:
  1959  		ok |= Erv | Etop
  1960  		if n.List != nil {
  1961  			Yyerror("too many arguments to recover")
  1962  			n.Type = nil
  1963  			return
  1964  		}
  1965  
  1966  		n.Type = Types[TINTER]
  1967  		break OpSwitch
  1968  
  1969  	case OCLOSURE:
  1970  		ok |= Erv
  1971  		typecheckclosure(n, top)
  1972  		if n.Type == nil {
  1973  			n.Type = nil
  1974  			return
  1975  		}
  1976  		break OpSwitch
  1977  
  1978  	case OITAB:
  1979  		ok |= Erv
  1980  		typecheck(&n.Left, Erv)
  1981  		t := n.Left.Type
  1982  		if t == nil {
  1983  			n.Type = nil
  1984  			return
  1985  		}
  1986  		if t.Etype != TINTER {
  1987  			Fatal("OITAB of %v", t)
  1988  		}
  1989  		n.Type = Ptrto(Types[TUINTPTR])
  1990  		break OpSwitch
  1991  
  1992  	case OSPTR:
  1993  		ok |= Erv
  1994  		typecheck(&n.Left, Erv)
  1995  		t := n.Left.Type
  1996  		if t == nil {
  1997  			n.Type = nil
  1998  			return
  1999  		}
  2000  		if !Isslice(t) && t.Etype != TSTRING {
  2001  			Fatal("OSPTR of %v", t)
  2002  		}
  2003  		if t.Etype == TSTRING {
  2004  			n.Type = Ptrto(Types[TUINT8])
  2005  		} else {
  2006  			n.Type = Ptrto(t.Type)
  2007  		}
  2008  		break OpSwitch
  2009  
  2010  	case OCLOSUREVAR:
  2011  		ok |= Erv
  2012  		break OpSwitch
  2013  
  2014  	case OCFUNC:
  2015  		ok |= Erv
  2016  		typecheck(&n.Left, Erv)
  2017  		n.Type = Types[TUINTPTR]
  2018  		break OpSwitch
  2019  
  2020  	case OCONVNOP:
  2021  		ok |= Erv
  2022  		typecheck(&n.Left, Erv)
  2023  		break OpSwitch
  2024  
  2025  		/*
  2026  		 * statements
  2027  		 */
  2028  	case OAS:
  2029  		ok |= Etop
  2030  
  2031  		typecheckas(n)
  2032  
  2033  		// Code that creates temps does not bother to set defn, so do it here.
  2034  		if n.Left.Op == ONAME && strings.HasPrefix(n.Left.Sym.Name, "autotmp_") {
  2035  			n.Left.Defn = n
  2036  		}
  2037  		break OpSwitch
  2038  
  2039  	case OAS2:
  2040  		ok |= Etop
  2041  		typecheckas2(n)
  2042  		break OpSwitch
  2043  
  2044  	case OBREAK,
  2045  		OCONTINUE,
  2046  		ODCL,
  2047  		OEMPTY,
  2048  		OGOTO,
  2049  		OXFALL,
  2050  		OVARKILL:
  2051  		ok |= Etop
  2052  		break OpSwitch
  2053  
  2054  	case OLABEL:
  2055  		ok |= Etop
  2056  		decldepth++
  2057  		break OpSwitch
  2058  
  2059  	case ODEFER:
  2060  		ok |= Etop
  2061  		typecheck(&n.Left, Etop|Erv)
  2062  		if n.Left.Diag == 0 {
  2063  			checkdefergo(n)
  2064  		}
  2065  		break OpSwitch
  2066  
  2067  	case OPROC:
  2068  		ok |= Etop
  2069  		typecheck(&n.Left, Etop|Eproc|Erv)
  2070  		checkdefergo(n)
  2071  		break OpSwitch
  2072  
  2073  	case OFOR:
  2074  		ok |= Etop
  2075  		typechecklist(n.Ninit, Etop)
  2076  		decldepth++
  2077  		typecheck(&n.Ntest, Erv)
  2078  		if n.Ntest != nil {
  2079  			t := n.Ntest.Type
  2080  			if t != nil && t.Etype != TBOOL {
  2081  				Yyerror("non-bool %v used as for condition", Nconv(n.Ntest, obj.FmtLong))
  2082  			}
  2083  		}
  2084  		typecheck(&n.Nincr, Etop)
  2085  		typechecklist(n.Nbody, Etop)
  2086  		decldepth--
  2087  		break OpSwitch
  2088  
  2089  	case OIF:
  2090  		ok |= Etop
  2091  		typechecklist(n.Ninit, Etop)
  2092  		typecheck(&n.Ntest, Erv)
  2093  		if n.Ntest != nil {
  2094  			t := n.Ntest.Type
  2095  			if t != nil && t.Etype != TBOOL {
  2096  				Yyerror("non-bool %v used as if condition", Nconv(n.Ntest, obj.FmtLong))
  2097  			}
  2098  		}
  2099  		typechecklist(n.Nbody, Etop)
  2100  		typechecklist(n.Nelse, Etop)
  2101  		break OpSwitch
  2102  
  2103  	case ORETURN:
  2104  		ok |= Etop
  2105  		if count(n.List) == 1 {
  2106  			typechecklist(n.List, Erv|Efnstruct)
  2107  		} else {
  2108  			typechecklist(n.List, Erv)
  2109  		}
  2110  		if Curfn == nil {
  2111  			Yyerror("return outside function")
  2112  			n.Type = nil
  2113  			return
  2114  		}
  2115  
  2116  		if Curfn.Type.Outnamed != 0 && n.List == nil {
  2117  			break OpSwitch
  2118  		}
  2119  		typecheckaste(ORETURN, nil, false, getoutargx(Curfn.Type), n.List, func() string { return "return argument" })
  2120  		break OpSwitch
  2121  
  2122  	case ORETJMP:
  2123  		ok |= Etop
  2124  		break OpSwitch
  2125  
  2126  	case OSELECT:
  2127  		ok |= Etop
  2128  		typecheckselect(n)
  2129  		break OpSwitch
  2130  
  2131  	case OSWITCH:
  2132  		ok |= Etop
  2133  		typecheckswitch(n)
  2134  		break OpSwitch
  2135  
  2136  	case ORANGE:
  2137  		ok |= Etop
  2138  		typecheckrange(n)
  2139  		break OpSwitch
  2140  
  2141  	case OTYPESW:
  2142  		Yyerror("use of .(type) outside type switch")
  2143  		n.Type = nil
  2144  		return
  2145  
  2146  	case OXCASE:
  2147  		ok |= Etop
  2148  		typechecklist(n.List, Erv)
  2149  		typechecklist(n.Nbody, Etop)
  2150  		break OpSwitch
  2151  
  2152  	case ODCLFUNC:
  2153  		ok |= Etop
  2154  		typecheckfunc(n)
  2155  		break OpSwitch
  2156  
  2157  	case ODCLCONST:
  2158  		ok |= Etop
  2159  		typecheck(&n.Left, Erv)
  2160  		break OpSwitch
  2161  
  2162  	case ODCLTYPE:
  2163  		ok |= Etop
  2164  		typecheck(&n.Left, Etype)
  2165  		if incannedimport == 0 {
  2166  			checkwidth(n.Left.Type)
  2167  		}
  2168  		break OpSwitch
  2169  	}
  2170  
  2171  	t := n.Type
  2172  	if t != nil && t.Funarg == 0 && n.Op != OTYPE {
  2173  		switch t.Etype {
  2174  		case TFUNC, // might have TANY; wait until its called
  2175  			TANY,
  2176  			TFORW,
  2177  			TIDEAL,
  2178  			TNIL,
  2179  			TBLANK:
  2180  			break
  2181  
  2182  		default:
  2183  			checkwidth(t)
  2184  		}
  2185  	}
  2186  
  2187  	if safemode != 0 && incannedimport == 0 && importpkg == nil && compiling_wrappers == 0 && t != nil && t.Etype == TUNSAFEPTR {
  2188  		Yyerror("cannot use unsafe.Pointer")
  2189  	}
  2190  
  2191  	evconst(n)
  2192  	if n.Op == OTYPE && top&Etype == 0 {
  2193  		Yyerror("type %v is not an expression", n.Type)
  2194  		n.Type = nil
  2195  		return
  2196  	}
  2197  
  2198  	if top&(Erv|Etype) == Etype && n.Op != OTYPE {
  2199  		Yyerror("%v is not a type", n)
  2200  		n.Type = nil
  2201  		return
  2202  	}
  2203  
  2204  	// TODO(rsc): simplify
  2205  	if (top&(Ecall|Erv|Etype) != 0) && top&Etop == 0 && ok&(Erv|Etype|Ecall) == 0 {
  2206  		Yyerror("%v used as value", n)
  2207  		n.Type = nil
  2208  		return
  2209  	}
  2210  
  2211  	if (top&Etop != 0) && top&(Ecall|Erv|Etype) == 0 && ok&Etop == 0 {
  2212  		if n.Diag == 0 {
  2213  			Yyerror("%v evaluated but not used", n)
  2214  			n.Diag = 1
  2215  		}
  2216  
  2217  		n.Type = nil
  2218  		return
  2219  	}
  2220  
  2221  	/* TODO
  2222  	if(n->type == T)
  2223  		fatal("typecheck nil type");
  2224  	*/
  2225  }
  2226  
  2227  func checksliceindex(l *Node, r *Node, tp *Type) int {
  2228  	t := r.Type
  2229  	if t == nil {
  2230  		return -1
  2231  	}
  2232  	if !Isint[t.Etype] {
  2233  		Yyerror("invalid slice index %v (type %v)", r, t)
  2234  		return -1
  2235  	}
  2236  
  2237  	if r.Op == OLITERAL {
  2238  		if Mpgetfix(r.Val.U.Xval) < 0 {
  2239  			Yyerror("invalid slice index %v (index must be non-negative)", r)
  2240  			return -1
  2241  		} else if tp != nil && tp.Bound > 0 && Mpgetfix(r.Val.U.Xval) > tp.Bound {
  2242  			Yyerror("invalid slice index %v (out of bounds for %d-element array)", r, tp.Bound)
  2243  			return -1
  2244  		} else if Isconst(l, CTSTR) && Mpgetfix(r.Val.U.Xval) > int64(len(l.Val.U.Sval)) {
  2245  			Yyerror("invalid slice index %v (out of bounds for %d-byte string)", r, len(l.Val.U.Sval))
  2246  			return -1
  2247  		} else if Mpcmpfixfix(r.Val.U.Xval, Maxintval[TINT]) > 0 {
  2248  			Yyerror("invalid slice index %v (index too large)", r)
  2249  			return -1
  2250  		}
  2251  	}
  2252  
  2253  	return 0
  2254  }
  2255  
  2256  func checksliceconst(lo *Node, hi *Node) int {
  2257  	if lo != nil && hi != nil && lo.Op == OLITERAL && hi.Op == OLITERAL && Mpcmpfixfix(lo.Val.U.Xval, hi.Val.U.Xval) > 0 {
  2258  		Yyerror("invalid slice index: %v > %v", lo, hi)
  2259  		return -1
  2260  	}
  2261  
  2262  	return 0
  2263  }
  2264  
  2265  func checkdefergo(n *Node) {
  2266  	what := "defer"
  2267  	if n.Op == OPROC {
  2268  		what = "go"
  2269  	}
  2270  
  2271  	switch n.Left.Op {
  2272  	// ok
  2273  	case OCALLINTER,
  2274  		OCALLMETH,
  2275  		OCALLFUNC,
  2276  		OCLOSE,
  2277  		OCOPY,
  2278  		ODELETE,
  2279  		OPANIC,
  2280  		OPRINT,
  2281  		OPRINTN,
  2282  		ORECOVER:
  2283  		return
  2284  
  2285  	case OAPPEND,
  2286  		OCAP,
  2287  		OCOMPLEX,
  2288  		OIMAG,
  2289  		OLEN,
  2290  		OMAKE,
  2291  		OMAKESLICE,
  2292  		OMAKECHAN,
  2293  		OMAKEMAP,
  2294  		ONEW,
  2295  		OREAL,
  2296  		OLITERAL: // conversion or unsafe.Alignof, Offsetof, Sizeof
  2297  		if n.Left.Orig != nil && n.Left.Orig.Op == OCONV {
  2298  			break
  2299  		}
  2300  		Yyerror("%s discards result of %v", what, n.Left)
  2301  		return
  2302  	}
  2303  
  2304  	// type is broken or missing, most likely a method call on a broken type
  2305  	// we will warn about the broken type elsewhere. no need to emit a potentially confusing error
  2306  	if n.Left.Type == nil || n.Left.Type.Broke != 0 {
  2307  		return
  2308  	}
  2309  
  2310  	if n.Diag == 0 {
  2311  		// The syntax made sure it was a call, so this must be
  2312  		// a conversion.
  2313  		n.Diag = 1
  2314  
  2315  		Yyerror("%s requires function call, not conversion", what)
  2316  	}
  2317  }
  2318  
  2319  func implicitstar(nn **Node) {
  2320  	// insert implicit * if needed for fixed array
  2321  	n := *nn
  2322  
  2323  	t := n.Type
  2324  	if t == nil || !Isptr[t.Etype] {
  2325  		return
  2326  	}
  2327  	t = t.Type
  2328  	if t == nil {
  2329  		return
  2330  	}
  2331  	if !Isfixedarray(t) {
  2332  		return
  2333  	}
  2334  	n = Nod(OIND, n, nil)
  2335  	n.Implicit = true
  2336  	typecheck(&n, Erv)
  2337  	*nn = n
  2338  }
  2339  
  2340  func onearg(n *Node, f string, args ...interface{}) int {
  2341  	if n.Left != nil {
  2342  		return 0
  2343  	}
  2344  	if n.List == nil {
  2345  		p := fmt.Sprintf(f, args...)
  2346  		Yyerror("missing argument to %s: %v", p, n)
  2347  		return -1
  2348  	}
  2349  
  2350  	if n.List.Next != nil {
  2351  		p := fmt.Sprintf(f, args...)
  2352  		Yyerror("too many arguments to %s: %v", p, n)
  2353  		n.Left = n.List.N
  2354  		n.List = nil
  2355  		return -1
  2356  	}
  2357  
  2358  	n.Left = n.List.N
  2359  	n.List = nil
  2360  	return 0
  2361  }
  2362  
  2363  func twoarg(n *Node) int {
  2364  	if n.Left != nil {
  2365  		return 0
  2366  	}
  2367  	if n.List == nil {
  2368  		Yyerror("missing argument to %v - %v", Oconv(int(n.Op), 0), n)
  2369  		return -1
  2370  	}
  2371  
  2372  	n.Left = n.List.N
  2373  	if n.List.Next == nil {
  2374  		Yyerror("missing argument to %v - %v", Oconv(int(n.Op), 0), n)
  2375  		n.List = nil
  2376  		return -1
  2377  	}
  2378  
  2379  	if n.List.Next.Next != nil {
  2380  		Yyerror("too many arguments to %v - %v", Oconv(int(n.Op), 0), n)
  2381  		n.List = nil
  2382  		return -1
  2383  	}
  2384  
  2385  	n.Right = n.List.Next.N
  2386  	n.List = nil
  2387  	return 0
  2388  }
  2389  
  2390  func lookdot1(errnode *Node, s *Sym, t *Type, f *Type, dostrcmp int) *Type {
  2391  	var r *Type
  2392  	for ; f != nil; f = f.Down {
  2393  		if dostrcmp != 0 && f.Sym.Name == s.Name {
  2394  			return f
  2395  		}
  2396  		if f.Sym != s {
  2397  			continue
  2398  		}
  2399  		if r != nil {
  2400  			if errnode != nil {
  2401  				Yyerror("ambiguous selector %v", errnode)
  2402  			} else if Isptr[t.Etype] {
  2403  				Yyerror("ambiguous selector (%v).%v", t, s)
  2404  			} else {
  2405  				Yyerror("ambiguous selector %v.%v", t, s)
  2406  			}
  2407  			break
  2408  		}
  2409  
  2410  		r = f
  2411  	}
  2412  
  2413  	return r
  2414  }
  2415  
  2416  func looktypedot(n *Node, t *Type, dostrcmp int) bool {
  2417  	s := n.Right.Sym
  2418  
  2419  	if t.Etype == TINTER {
  2420  		f1 := lookdot1(n, s, t, t.Type, dostrcmp)
  2421  		if f1 == nil {
  2422  			return false
  2423  		}
  2424  
  2425  		n.Right = methodname(n.Right, t)
  2426  		n.Xoffset = f1.Width
  2427  		n.Type = f1.Type
  2428  		n.Op = ODOTINTER
  2429  		return true
  2430  	}
  2431  
  2432  	// Find the base type: methtype will fail if t
  2433  	// is not of the form T or *T.
  2434  	f2 := methtype(t, 0)
  2435  
  2436  	if f2 == nil {
  2437  		return false
  2438  	}
  2439  
  2440  	expandmeth(f2)
  2441  	f2 = lookdot1(n, s, f2, f2.Xmethod, dostrcmp)
  2442  	if f2 == nil {
  2443  		return false
  2444  	}
  2445  
  2446  	// disallow T.m if m requires *T receiver
  2447  	if Isptr[getthisx(f2.Type).Type.Type.Etype] && !Isptr[t.Etype] && f2.Embedded != 2 && !isifacemethod(f2.Type) {
  2448  		Yyerror("invalid method expression %v (needs pointer receiver: (*%v).%v)", n, t, Sconv(f2.Sym, obj.FmtShort))
  2449  		return false
  2450  	}
  2451  
  2452  	n.Right = methodname(n.Right, t)
  2453  	n.Xoffset = f2.Width
  2454  	n.Type = f2.Type
  2455  	n.Op = ODOTMETH
  2456  	return true
  2457  }
  2458  
  2459  func derefall(t *Type) *Type {
  2460  	for t != nil && int(t.Etype) == Tptr {
  2461  		t = t.Type
  2462  	}
  2463  	return t
  2464  }
  2465  
  2466  func lookdot(n *Node, t *Type, dostrcmp int) bool {
  2467  	s := n.Right.Sym
  2468  
  2469  	dowidth(t)
  2470  	var f1 *Type
  2471  	if t.Etype == TSTRUCT || t.Etype == TINTER {
  2472  		f1 = lookdot1(n, s, t, t.Type, dostrcmp)
  2473  	}
  2474  
  2475  	var f2 *Type
  2476  	if n.Left.Type == t || n.Left.Type.Sym == nil {
  2477  		f2 = methtype(t, 0)
  2478  		if f2 != nil {
  2479  			// Use f2->method, not f2->xmethod: adddot has
  2480  			// already inserted all the necessary embedded dots.
  2481  			f2 = lookdot1(n, s, f2, f2.Method, dostrcmp)
  2482  		}
  2483  	}
  2484  
  2485  	if f1 != nil {
  2486  		if f2 != nil {
  2487  			Yyerror("%v is both field and method", n.Right.Sym)
  2488  		}
  2489  		if f1.Width == BADWIDTH {
  2490  			Fatal("lookdot badwidth %v %p", f1, f1)
  2491  		}
  2492  		n.Xoffset = f1.Width
  2493  		n.Type = f1.Type
  2494  		n.Paramfld = f1
  2495  		if t.Etype == TINTER {
  2496  			if Isptr[n.Left.Type.Etype] {
  2497  				n.Left = Nod(OIND, n.Left, nil) // implicitstar
  2498  				n.Left.Implicit = true
  2499  				typecheck(&n.Left, Erv)
  2500  			}
  2501  
  2502  			n.Op = ODOTINTER
  2503  		}
  2504  
  2505  		return true
  2506  	}
  2507  
  2508  	if f2 != nil {
  2509  		tt := n.Left.Type
  2510  		dowidth(tt)
  2511  		rcvr := getthisx(f2.Type).Type.Type
  2512  		if !Eqtype(rcvr, tt) {
  2513  			if int(rcvr.Etype) == Tptr && Eqtype(rcvr.Type, tt) {
  2514  				checklvalue(n.Left, "call pointer method on")
  2515  				n.Left = Nod(OADDR, n.Left, nil)
  2516  				n.Left.Implicit = true
  2517  				typecheck(&n.Left, Etype|Erv)
  2518  			} else if int(tt.Etype) == Tptr && int(rcvr.Etype) != Tptr && Eqtype(tt.Type, rcvr) {
  2519  				n.Left = Nod(OIND, n.Left, nil)
  2520  				n.Left.Implicit = true
  2521  				typecheck(&n.Left, Etype|Erv)
  2522  			} else if int(tt.Etype) == Tptr && int(tt.Type.Etype) == Tptr && Eqtype(derefall(tt), derefall(rcvr)) {
  2523  				Yyerror("calling method %v with receiver %v requires explicit dereference", n.Right, Nconv(n.Left, obj.FmtLong))
  2524  				for int(tt.Etype) == Tptr {
  2525  					// Stop one level early for method with pointer receiver.
  2526  					if int(rcvr.Etype) == Tptr && int(tt.Type.Etype) != Tptr {
  2527  						break
  2528  					}
  2529  					n.Left = Nod(OIND, n.Left, nil)
  2530  					n.Left.Implicit = true
  2531  					typecheck(&n.Left, Etype|Erv)
  2532  					tt = tt.Type
  2533  				}
  2534  			} else {
  2535  				Fatal("method mismatch: %v for %v", rcvr, tt)
  2536  			}
  2537  		}
  2538  
  2539  		ll := n.Left
  2540  		for ll.Left != nil {
  2541  			ll = ll.Left
  2542  		}
  2543  		if ll.Implicit {
  2544  			if Isptr[ll.Type.Etype] && ll.Type.Sym != nil && ll.Type.Sym.Def != nil && ll.Type.Sym.Def.Op == OTYPE {
  2545  				// It is invalid to automatically dereference a named pointer type when selecting a method.
  2546  				// Make n->left == ll to clarify error message.
  2547  				n.Left = ll
  2548  				return false
  2549  			}
  2550  		}
  2551  
  2552  		n.Right = methodname(n.Right, n.Left.Type)
  2553  		n.Xoffset = f2.Width
  2554  		n.Type = f2.Type
  2555  
  2556  		//		print("lookdot found [%p] %T\n", f2->type, f2->type);
  2557  		n.Op = ODOTMETH
  2558  
  2559  		return true
  2560  	}
  2561  
  2562  	return false
  2563  }
  2564  
  2565  func nokeys(l *NodeList) bool {
  2566  	for ; l != nil; l = l.Next {
  2567  		if l.N.Op == OKEY {
  2568  			return false
  2569  		}
  2570  	}
  2571  	return true
  2572  }
  2573  
  2574  func hasddd(t *Type) bool {
  2575  	for tl := t.Type; tl != nil; tl = tl.Down {
  2576  		if tl.Isddd {
  2577  			return true
  2578  		}
  2579  	}
  2580  
  2581  	return false
  2582  }
  2583  
  2584  func downcount(t *Type) int {
  2585  	n := 0
  2586  	for tl := t.Type; tl != nil; tl = tl.Down {
  2587  		n++
  2588  	}
  2589  
  2590  	return n
  2591  }
  2592  
  2593  /*
  2594   * typecheck assignment: type list = expression list
  2595   */
  2596  func typecheckaste(op int, call *Node, isddd bool, tstruct *Type, nl *NodeList, desc func() string) {
  2597  	var t *Type
  2598  	var n *Node
  2599  	var n1 int
  2600  	var n2 int
  2601  
  2602  	lno := int(lineno)
  2603  
  2604  	if tstruct.Broke != 0 {
  2605  		goto out
  2606  	}
  2607  
  2608  	n = nil
  2609  	if nl != nil && nl.Next == nil {
  2610  		n = nl.N
  2611  		if n.Type != nil {
  2612  			if n.Type.Etype == TSTRUCT && n.Type.Funarg != 0 {
  2613  				if !hasddd(tstruct) {
  2614  					n1 := downcount(tstruct)
  2615  					n2 := downcount(n.Type)
  2616  					if n2 > n1 {
  2617  						goto toomany
  2618  					}
  2619  					if n2 < n1 {
  2620  						goto notenough
  2621  					}
  2622  				}
  2623  
  2624  				tn := n.Type.Type
  2625  				var why string
  2626  				for tl := tstruct.Type; tl != nil; tl = tl.Down {
  2627  					if tl.Isddd {
  2628  						for ; tn != nil; tn = tn.Down {
  2629  							if assignop(tn.Type, tl.Type.Type, &why) == 0 {
  2630  								if call != nil {
  2631  									Yyerror("cannot use %v as type %v in argument to %v%s", tn.Type, tl.Type.Type, call, why)
  2632  								} else {
  2633  									Yyerror("cannot use %v as type %v in %s%s", tn.Type, tl.Type.Type, desc(), why)
  2634  								}
  2635  							}
  2636  						}
  2637  
  2638  						goto out
  2639  					}
  2640  
  2641  					if tn == nil {
  2642  						goto notenough
  2643  					}
  2644  					if assignop(tn.Type, tl.Type, &why) == 0 {
  2645  						if call != nil {
  2646  							Yyerror("cannot use %v as type %v in argument to %v%s", tn.Type, tl.Type, call, why)
  2647  						} else {
  2648  							Yyerror("cannot use %v as type %v in %s%s", tn.Type, tl.Type, desc(), why)
  2649  						}
  2650  					}
  2651  
  2652  					tn = tn.Down
  2653  				}
  2654  
  2655  				if tn != nil {
  2656  					goto toomany
  2657  				}
  2658  				goto out
  2659  			}
  2660  		}
  2661  	}
  2662  
  2663  	n1 = downcount(tstruct)
  2664  	n2 = count(nl)
  2665  	if !hasddd(tstruct) {
  2666  		if n2 > n1 {
  2667  			goto toomany
  2668  		}
  2669  		if n2 < n1 {
  2670  			goto notenough
  2671  		}
  2672  	} else {
  2673  		if !isddd {
  2674  			if n2 < n1-1 {
  2675  				goto notenough
  2676  			}
  2677  		} else {
  2678  			if n2 > n1 {
  2679  				goto toomany
  2680  			}
  2681  			if n2 < n1 {
  2682  				goto notenough
  2683  			}
  2684  		}
  2685  	}
  2686  
  2687  	for tl := tstruct.Type; tl != nil; tl = tl.Down {
  2688  		t = tl.Type
  2689  		if tl.Isddd {
  2690  			if isddd {
  2691  				if nl == nil {
  2692  					goto notenough
  2693  				}
  2694  				if nl.Next != nil {
  2695  					goto toomany
  2696  				}
  2697  				n = nl.N
  2698  				setlineno(n)
  2699  				if n.Type != nil {
  2700  					nl.N = assignconvfn(n, t, desc)
  2701  				}
  2702  				goto out
  2703  			}
  2704  
  2705  			for ; nl != nil; nl = nl.Next {
  2706  				n = nl.N
  2707  				setlineno(nl.N)
  2708  				if n.Type != nil {
  2709  					nl.N = assignconvfn(n, t.Type, desc)
  2710  				}
  2711  			}
  2712  
  2713  			goto out
  2714  		}
  2715  
  2716  		if nl == nil {
  2717  			goto notenough
  2718  		}
  2719  		n = nl.N
  2720  		setlineno(n)
  2721  		if n.Type != nil {
  2722  			nl.N = assignconvfn(n, t, desc)
  2723  		}
  2724  		nl = nl.Next
  2725  	}
  2726  
  2727  	if nl != nil {
  2728  		goto toomany
  2729  	}
  2730  	if isddd {
  2731  		if call != nil {
  2732  			Yyerror("invalid use of ... in call to %v", call)
  2733  		} else {
  2734  			Yyerror("invalid use of ... in %v", Oconv(int(op), 0))
  2735  		}
  2736  	}
  2737  
  2738  out:
  2739  	lineno = int32(lno)
  2740  	return
  2741  
  2742  notenough:
  2743  	if n == nil || n.Diag == 0 {
  2744  		if call != nil {
  2745  			Yyerror("not enough arguments in call to %v", call)
  2746  		} else {
  2747  			Yyerror("not enough arguments to %v", Oconv(int(op), 0))
  2748  		}
  2749  		if n != nil {
  2750  			n.Diag = 1
  2751  		}
  2752  	}
  2753  
  2754  	goto out
  2755  
  2756  toomany:
  2757  	if call != nil {
  2758  		Yyerror("too many arguments in call to %v", call)
  2759  	} else {
  2760  		Yyerror("too many arguments to %v", Oconv(int(op), 0))
  2761  	}
  2762  	goto out
  2763  }
  2764  
  2765  /*
  2766   * type check composite
  2767   */
  2768  func fielddup(n *Node, hash map[string]bool) {
  2769  	if n.Op != ONAME {
  2770  		Fatal("fielddup: not ONAME")
  2771  	}
  2772  	name := n.Sym.Name
  2773  	if hash[name] {
  2774  		Yyerror("duplicate field name in struct literal: %s", name)
  2775  		return
  2776  	}
  2777  	hash[name] = true
  2778  }
  2779  
  2780  func keydup(n *Node, hash []*Node) {
  2781  	orign := n
  2782  	if n.Op == OCONVIFACE {
  2783  		n = n.Left
  2784  	}
  2785  	evconst(n)
  2786  	if n.Op != OLITERAL {
  2787  		return // we dont check variables
  2788  	}
  2789  
  2790  	var b uint32
  2791  	switch n.Val.Ctype {
  2792  	default: // unknown, bool, nil
  2793  		b = 23
  2794  
  2795  	case CTINT, CTRUNE:
  2796  		b = uint32(Mpgetfix(n.Val.U.Xval))
  2797  
  2798  	case CTFLT:
  2799  		d := mpgetflt(n.Val.U.Fval)
  2800  		x := math.Float64bits(d)
  2801  		for i := 0; i < 8; i++ {
  2802  			b = b*PRIME1 + uint32(x&0xFF)
  2803  			x >>= 8
  2804  		}
  2805  
  2806  	case CTSTR:
  2807  		b = 0
  2808  		s := n.Val.U.Sval
  2809  		for i := len(n.Val.U.Sval); i > 0; i-- {
  2810  			b = b*PRIME1 + uint32(s[0])
  2811  			s = s[1:]
  2812  		}
  2813  	}
  2814  
  2815  	h := uint(b % uint32(len(hash)))
  2816  	var cmp Node
  2817  	for a := hash[h]; a != nil; a = a.Ntest {
  2818  		cmp.Op = OEQ
  2819  		cmp.Left = n
  2820  		b = 0
  2821  		if a.Op == OCONVIFACE && orign.Op == OCONVIFACE {
  2822  			if Eqtype(a.Left.Type, n.Type) {
  2823  				cmp.Right = a.Left
  2824  				evconst(&cmp)
  2825  				b = uint32(obj.Bool2int(cmp.Val.U.Bval))
  2826  			}
  2827  		} else if Eqtype(a.Type, n.Type) {
  2828  			cmp.Right = a
  2829  			evconst(&cmp)
  2830  			b = uint32(obj.Bool2int(cmp.Val.U.Bval))
  2831  		}
  2832  
  2833  		if b != 0 {
  2834  			Yyerror("duplicate key %v in map literal", n)
  2835  			return
  2836  		}
  2837  	}
  2838  
  2839  	orign.Ntest = hash[h]
  2840  	hash[h] = orign
  2841  }
  2842  
  2843  func indexdup(n *Node, hash []*Node) {
  2844  	if n.Op != OLITERAL {
  2845  		Fatal("indexdup: not OLITERAL")
  2846  	}
  2847  
  2848  	b := uint32(Mpgetfix(n.Val.U.Xval))
  2849  	h := uint(b % uint32(len(hash)))
  2850  	var c uint32
  2851  	for a := hash[h]; a != nil; a = a.Ntest {
  2852  		c = uint32(Mpgetfix(a.Val.U.Xval))
  2853  		if b == c {
  2854  			Yyerror("duplicate index in array literal: %d", b)
  2855  			return
  2856  		}
  2857  	}
  2858  
  2859  	n.Ntest = hash[h]
  2860  	hash[h] = n
  2861  }
  2862  
  2863  func prime(h uint32, sr uint32) bool {
  2864  	for n := uint32(3); n <= sr; n += 2 {
  2865  		if h%n == 0 {
  2866  			return false
  2867  		}
  2868  	}
  2869  	return true
  2870  }
  2871  
  2872  func inithash(n *Node, autohash []*Node) []*Node {
  2873  	// count the number of entries
  2874  	h := uint32(0)
  2875  
  2876  	for ll := n.List; ll != nil; ll = ll.Next {
  2877  		h++
  2878  	}
  2879  
  2880  	// if the auto hash table is
  2881  	// large enough use it.
  2882  	if h <= uint32(len(autohash)) {
  2883  		for i := range autohash {
  2884  			autohash[i] = nil
  2885  		}
  2886  		return autohash
  2887  	}
  2888  
  2889  	// make hash size odd and 12% larger than entries
  2890  	h += h / 8
  2891  
  2892  	h |= 1
  2893  
  2894  	// calculate sqrt of h
  2895  	sr := h / 2
  2896  
  2897  	for i := 0; i < 5; i++ {
  2898  		sr = (sr + h/sr) / 2
  2899  	}
  2900  
  2901  	// check for primeality
  2902  	for !prime(h, sr) {
  2903  		h += 2
  2904  	}
  2905  
  2906  	// build and return a throw-away hash table
  2907  	return make([]*Node, h)
  2908  }
  2909  
  2910  func iscomptype(t *Type) bool {
  2911  	switch t.Etype {
  2912  	case TARRAY, TSTRUCT, TMAP:
  2913  		return true
  2914  
  2915  	case TPTR32, TPTR64:
  2916  		switch t.Type.Etype {
  2917  		case TARRAY, TSTRUCT, TMAP:
  2918  			return true
  2919  		}
  2920  	}
  2921  
  2922  	return false
  2923  }
  2924  
  2925  func pushtype(n *Node, t *Type) {
  2926  	if n == nil || n.Op != OCOMPLIT || !iscomptype(t) {
  2927  		return
  2928  	}
  2929  
  2930  	if n.Right == nil {
  2931  		n.Right = typenod(t)
  2932  		n.Implicit = true       // don't print
  2933  		n.Right.Implicit = true // * is okay
  2934  	} else if Debug['s'] != 0 {
  2935  		typecheck(&n.Right, Etype)
  2936  		if n.Right.Type != nil && Eqtype(n.Right.Type, t) {
  2937  			fmt.Printf("%v: redundant type: %v\n", n.Line(), t)
  2938  		}
  2939  	}
  2940  }
  2941  
  2942  func typecheckcomplit(np **Node) {
  2943  	n := *np
  2944  	lno := lineno
  2945  	defer func() {
  2946  		lineno = lno
  2947  		*np = n
  2948  	}()
  2949  
  2950  	if n.Right == nil {
  2951  		if n.List != nil {
  2952  			setlineno(n.List.N)
  2953  		}
  2954  		Yyerror("missing type in composite literal")
  2955  		n.Type = nil
  2956  		return
  2957  	}
  2958  
  2959  	// Save original node (including n->right)
  2960  	norig := Nod(int(n.Op), nil, nil)
  2961  
  2962  	*norig = *n
  2963  
  2964  	setlineno(n.Right)
  2965  	l := typecheck(&n.Right, Etype|Ecomplit) /* sic */
  2966  	t := l.Type
  2967  	if t == nil {
  2968  		n.Type = nil
  2969  		return
  2970  	}
  2971  	nerr := nerrors
  2972  	n.Type = t
  2973  
  2974  	if Isptr[t.Etype] {
  2975  		// For better or worse, we don't allow pointers as the composite literal type,
  2976  		// except when using the &T syntax, which sets implicit on the OIND.
  2977  		if !n.Right.Implicit {
  2978  			Yyerror("invalid pointer type %v for composite literal (use &%v instead)", t, t.Type)
  2979  			n.Type = nil
  2980  			return
  2981  		}
  2982  
  2983  		// Also, the underlying type must be a struct, map, slice, or array.
  2984  		if !iscomptype(t) {
  2985  			Yyerror("invalid pointer type %v for composite literal", t)
  2986  			n.Type = nil
  2987  			return
  2988  		}
  2989  
  2990  		t = t.Type
  2991  	}
  2992  
  2993  	var r *Node
  2994  	switch t.Etype {
  2995  	default:
  2996  		Yyerror("invalid type for composite literal: %v", t)
  2997  		n.Type = nil
  2998  
  2999  	case TARRAY:
  3000  		var autohash [101]*Node
  3001  		hash := inithash(n, autohash[:])
  3002  
  3003  		length := int64(0)
  3004  		i := 0
  3005  		var l *Node
  3006  		for ll := n.List; ll != nil; ll = ll.Next {
  3007  			l = ll.N
  3008  			setlineno(l)
  3009  			if l.Op != OKEY {
  3010  				l = Nod(OKEY, Nodintconst(int64(i)), l)
  3011  				l.Left.Type = Types[TINT]
  3012  				l.Left.Typecheck = 1
  3013  				ll.N = l
  3014  			}
  3015  
  3016  			typecheck(&l.Left, Erv)
  3017  			evconst(l.Left)
  3018  			i = nonnegconst(l.Left)
  3019  			if i < 0 && l.Left.Diag == 0 {
  3020  				Yyerror("array index must be non-negative integer constant")
  3021  				l.Left.Diag = 1
  3022  				i = -(1 << 30) // stay negative for a while
  3023  			}
  3024  
  3025  			if i >= 0 {
  3026  				indexdup(l.Left, hash)
  3027  			}
  3028  			i++
  3029  			if int64(i) > length {
  3030  				length = int64(i)
  3031  				if t.Bound >= 0 && length > t.Bound {
  3032  					setlineno(l)
  3033  					Yyerror("array index %d out of bounds [0:%d]", length-1, t.Bound)
  3034  					t.Bound = -1 // no more errors
  3035  				}
  3036  			}
  3037  
  3038  			r = l.Right
  3039  			pushtype(r, t.Type)
  3040  			typecheck(&r, Erv)
  3041  			defaultlit(&r, t.Type)
  3042  			l.Right = assignconv(r, t.Type, "array element")
  3043  		}
  3044  
  3045  		if t.Bound == -100 {
  3046  			t.Bound = length
  3047  		}
  3048  		if t.Bound < 0 {
  3049  			n.Right = Nodintconst(length)
  3050  		}
  3051  		n.Op = OARRAYLIT
  3052  
  3053  	case TMAP:
  3054  		var autohash [101]*Node
  3055  		hash := inithash(n, autohash[:])
  3056  
  3057  		var l *Node
  3058  		for ll := n.List; ll != nil; ll = ll.Next {
  3059  			l = ll.N
  3060  			setlineno(l)
  3061  			if l.Op != OKEY {
  3062  				typecheck(&ll.N, Erv)
  3063  				Yyerror("missing key in map literal")
  3064  				continue
  3065  			}
  3066  
  3067  			typecheck(&l.Left, Erv)
  3068  			defaultlit(&l.Left, t.Down)
  3069  			l.Left = assignconv(l.Left, t.Down, "map key")
  3070  			if l.Left.Op != OCONV {
  3071  				keydup(l.Left, hash)
  3072  			}
  3073  
  3074  			r = l.Right
  3075  			pushtype(r, t.Type)
  3076  			typecheck(&r, Erv)
  3077  			defaultlit(&r, t.Type)
  3078  			l.Right = assignconv(r, t.Type, "map value")
  3079  		}
  3080  
  3081  		n.Op = OMAPLIT
  3082  
  3083  	case TSTRUCT:
  3084  		bad := 0
  3085  		if n.List != nil && nokeys(n.List) {
  3086  			// simple list of variables
  3087  			f := t.Type
  3088  
  3089  			var s *Sym
  3090  			for ll := n.List; ll != nil; ll = ll.Next {
  3091  				setlineno(ll.N)
  3092  				typecheck(&ll.N, Erv)
  3093  				if f == nil {
  3094  					tmp12 := bad
  3095  					bad++
  3096  					if tmp12 == 0 {
  3097  						Yyerror("too many values in struct initializer")
  3098  					}
  3099  					continue
  3100  				}
  3101  
  3102  				s = f.Sym
  3103  				if s != nil && !exportname(s.Name) && s.Pkg != localpkg {
  3104  					Yyerror("implicit assignment of unexported field '%s' in %v literal", s.Name, t)
  3105  				}
  3106  
  3107  				// No pushtype allowed here.  Must name fields for that.
  3108  				ll.N = assignconv(ll.N, f.Type, "field value")
  3109  
  3110  				ll.N = Nod(OKEY, newname(f.Sym), ll.N)
  3111  				ll.N.Left.Type = f
  3112  				ll.N.Left.Typecheck = 1
  3113  				f = f.Down
  3114  			}
  3115  
  3116  			if f != nil {
  3117  				Yyerror("too few values in struct initializer")
  3118  			}
  3119  		} else {
  3120  			hash := make(map[string]bool)
  3121  
  3122  			// keyed list
  3123  			var s *Sym
  3124  			var f *Type
  3125  			var l *Node
  3126  			var s1 *Sym
  3127  			for ll := n.List; ll != nil; ll = ll.Next {
  3128  				l = ll.N
  3129  				setlineno(l)
  3130  				if l.Op != OKEY {
  3131  					tmp13 := bad
  3132  					bad++
  3133  					if tmp13 == 0 {
  3134  						Yyerror("mixture of field:value and value initializers")
  3135  					}
  3136  					typecheck(&ll.N, Erv)
  3137  					continue
  3138  				}
  3139  
  3140  				s = l.Left.Sym
  3141  				if s == nil {
  3142  					Yyerror("invalid field name %v in struct initializer", l.Left)
  3143  					typecheck(&l.Right, Erv)
  3144  					continue
  3145  				}
  3146  
  3147  				// Sym might have resolved to name in other top-level
  3148  				// package, because of import dot.  Redirect to correct sym
  3149  				// before we do the lookup.
  3150  				if s.Pkg != localpkg && exportname(s.Name) {
  3151  					s1 = Lookup(s.Name)
  3152  					if s1.Origpkg == s.Pkg {
  3153  						s = s1
  3154  					}
  3155  				}
  3156  
  3157  				f = lookdot1(nil, s, t, t.Type, 0)
  3158  				if f == nil {
  3159  					Yyerror("unknown %v field '%v' in struct literal", t, s)
  3160  					continue
  3161  				}
  3162  
  3163  				l.Left = newname(s)
  3164  				l.Left.Typecheck = 1
  3165  				l.Left.Type = f
  3166  				s = f.Sym
  3167  				fielddup(newname(s), hash)
  3168  				r = l.Right
  3169  
  3170  				// No pushtype allowed here.  Tried and rejected.
  3171  				typecheck(&r, Erv)
  3172  
  3173  				l.Right = assignconv(r, f.Type, "field value")
  3174  			}
  3175  		}
  3176  
  3177  		n.Op = OSTRUCTLIT
  3178  	}
  3179  
  3180  	if nerr != nerrors {
  3181  		n.Type = nil
  3182  		return
  3183  	}
  3184  
  3185  	n.Orig = norig
  3186  	if Isptr[n.Type.Etype] {
  3187  		n = Nod(OPTRLIT, n, nil)
  3188  		n.Typecheck = 1
  3189  		n.Type = n.Left.Type
  3190  		n.Left.Type = t
  3191  		n.Left.Typecheck = 1
  3192  	}
  3193  
  3194  	n.Orig = norig
  3195  	return
  3196  }
  3197  
  3198  /*
  3199   * lvalue etc
  3200   */
  3201  func islvalue(n *Node) bool {
  3202  	switch n.Op {
  3203  	case OINDEX:
  3204  		if Isfixedarray(n.Left.Type) {
  3205  			return islvalue(n.Left)
  3206  		}
  3207  		if n.Left.Type != nil && n.Left.Type.Etype == TSTRING {
  3208  			return false
  3209  		}
  3210  		fallthrough
  3211  
  3212  		// fall through
  3213  	case OIND, ODOTPTR, OCLOSUREVAR, OPARAM:
  3214  		return true
  3215  
  3216  	case ODOT:
  3217  		return islvalue(n.Left)
  3218  
  3219  	case ONAME:
  3220  		if n.Class == PFUNC {
  3221  			return false
  3222  		}
  3223  		return true
  3224  	}
  3225  
  3226  	return false
  3227  }
  3228  
  3229  func checklvalue(n *Node, verb string) {
  3230  	if !islvalue(n) {
  3231  		Yyerror("cannot %s %v", verb, n)
  3232  	}
  3233  }
  3234  
  3235  func checkassign(stmt *Node, n *Node) {
  3236  	// Variables declared in ORANGE are assigned on every iteration.
  3237  	if n.Defn != stmt || stmt.Op == ORANGE {
  3238  		r := outervalue(n)
  3239  		var l *Node
  3240  		for l = n; l != r; l = l.Left {
  3241  			l.Assigned = true
  3242  			if l.Closure != nil {
  3243  				l.Closure.Assigned = true
  3244  			}
  3245  		}
  3246  
  3247  		l.Assigned = true
  3248  		if l.Closure != nil {
  3249  			l.Closure.Assigned = true
  3250  		}
  3251  	}
  3252  
  3253  	if islvalue(n) {
  3254  		return
  3255  	}
  3256  	if n.Op == OINDEXMAP {
  3257  		n.Etype = 1
  3258  		return
  3259  	}
  3260  
  3261  	// have already complained about n being undefined
  3262  	if n.Op == ONONAME {
  3263  		return
  3264  	}
  3265  
  3266  	Yyerror("cannot assign to %v", n)
  3267  }
  3268  
  3269  func checkassignlist(stmt *Node, l *NodeList) {
  3270  	for ; l != nil; l = l.Next {
  3271  		checkassign(stmt, l.N)
  3272  	}
  3273  }
  3274  
  3275  // Check whether l and r are the same side effect-free expression,
  3276  // so that it is safe to reuse one instead of computing both.
  3277  func samesafeexpr(l *Node, r *Node) bool {
  3278  	if l.Op != r.Op || !Eqtype(l.Type, r.Type) {
  3279  		return false
  3280  	}
  3281  
  3282  	switch l.Op {
  3283  	case ONAME, OCLOSUREVAR:
  3284  		return l == r
  3285  
  3286  	case ODOT, ODOTPTR:
  3287  		return l.Right != nil && r.Right != nil && l.Right.Sym == r.Right.Sym && samesafeexpr(l.Left, r.Left)
  3288  
  3289  	case OIND:
  3290  		return samesafeexpr(l.Left, r.Left)
  3291  
  3292  	case OINDEX:
  3293  		return samesafeexpr(l.Left, r.Left) && samesafeexpr(l.Right, r.Right)
  3294  	}
  3295  
  3296  	return false
  3297  }
  3298  
  3299  /*
  3300   * type check assignment.
  3301   * if this assignment is the definition of a var on the left side,
  3302   * fill in the var's type.
  3303   */
  3304  func typecheckas(n *Node) {
  3305  	// delicate little dance.
  3306  	// the definition of n may refer to this assignment
  3307  	// as its definition, in which case it will call typecheckas.
  3308  	// in that case, do not call typecheck back, or it will cycle.
  3309  	// if the variable has a type (ntype) then typechecking
  3310  	// will not look at defn, so it is okay (and desirable,
  3311  	// so that the conversion below happens).
  3312  	n.Left = resolve(n.Left)
  3313  
  3314  	if n.Left.Defn != n || n.Left.Ntype != nil {
  3315  		typecheck(&n.Left, Erv|Easgn)
  3316  	}
  3317  
  3318  	typecheck(&n.Right, Erv)
  3319  	checkassign(n, n.Left)
  3320  	if n.Right != nil && n.Right.Type != nil {
  3321  		if n.Left.Type != nil {
  3322  			n.Right = assignconv(n.Right, n.Left.Type, "assignment")
  3323  		}
  3324  	}
  3325  
  3326  	if n.Left.Defn == n && n.Left.Ntype == nil {
  3327  		defaultlit(&n.Right, nil)
  3328  		n.Left.Type = n.Right.Type
  3329  	}
  3330  
  3331  	// second half of dance.
  3332  	// now that right is done, typecheck the left
  3333  	// just to get it over with.  see dance above.
  3334  	n.Typecheck = 1
  3335  
  3336  	if n.Left.Typecheck == 0 {
  3337  		typecheck(&n.Left, Erv|Easgn)
  3338  	}
  3339  
  3340  	// Recognize slices being updated in place, for better code generation later.
  3341  	// Don't rewrite if using race detector, to avoid needing to teach race detector
  3342  	// about this optimization.
  3343  	if n.Left != nil && n.Left.Op != OINDEXMAP && n.Right != nil && flag_race == 0 {
  3344  		switch n.Right.Op {
  3345  		// For x = x[0:y], x can be updated in place, without touching pointer.
  3346  		// TODO(rsc): Reenable once it is actually updated in place without touching the pointer.
  3347  		case OSLICE, OSLICE3, OSLICESTR:
  3348  			if false && samesafeexpr(n.Left, n.Right.Left) && (n.Right.Right.Left == nil || iszero(n.Right.Right.Left)) {
  3349  				n.Right.Reslice = true
  3350  			}
  3351  
  3352  			// For x = append(x, ...), x can be updated in place when there is capacity,
  3353  		// without touching the pointer; otherwise the emitted code to growslice
  3354  		// can take care of updating the pointer, and only in that case.
  3355  		// TODO(rsc): Reenable once the emitted code does update the pointer.
  3356  		case OAPPEND:
  3357  			if false && n.Right.List != nil && samesafeexpr(n.Left, n.Right.List.N) {
  3358  				n.Right.Reslice = true
  3359  			}
  3360  		}
  3361  	}
  3362  }
  3363  
  3364  func checkassignto(src *Type, dst *Node) {
  3365  	var why string
  3366  
  3367  	if assignop(src, dst.Type, &why) == 0 {
  3368  		Yyerror("cannot assign %v to %v in multiple assignment%s", src, Nconv(dst, obj.FmtLong), why)
  3369  		return
  3370  	}
  3371  }
  3372  
  3373  func typecheckas2(n *Node) {
  3374  	for ll := n.List; ll != nil; ll = ll.Next {
  3375  		// delicate little dance.
  3376  		ll.N = resolve(ll.N)
  3377  
  3378  		if ll.N.Defn != n || ll.N.Ntype != nil {
  3379  			typecheck(&ll.N, Erv|Easgn)
  3380  		}
  3381  	}
  3382  
  3383  	cl := count(n.List)
  3384  	cr := count(n.Rlist)
  3385  	if cl > 1 && cr == 1 {
  3386  		typecheck(&n.Rlist.N, Erv|Efnstruct)
  3387  	} else {
  3388  		typechecklist(n.Rlist, Erv)
  3389  	}
  3390  	checkassignlist(n, n.List)
  3391  
  3392  	var l *Node
  3393  	var r *Node
  3394  	if cl == cr {
  3395  		// easy
  3396  		ll := n.List
  3397  		lr := n.Rlist
  3398  		for ; ll != nil; ll, lr = ll.Next, lr.Next {
  3399  			if ll.N.Type != nil && lr.N.Type != nil {
  3400  				lr.N = assignconv(lr.N, ll.N.Type, "assignment")
  3401  			}
  3402  			if ll.N.Defn == n && ll.N.Ntype == nil {
  3403  				defaultlit(&lr.N, nil)
  3404  				ll.N.Type = lr.N.Type
  3405  			}
  3406  		}
  3407  
  3408  		goto out
  3409  	}
  3410  
  3411  	l = n.List.N
  3412  	r = n.Rlist.N
  3413  
  3414  	// x,y,z = f()
  3415  	if cr == 1 {
  3416  		if r.Type == nil {
  3417  			goto out
  3418  		}
  3419  		switch r.Op {
  3420  		case OCALLMETH, OCALLINTER, OCALLFUNC:
  3421  			if r.Type.Etype != TSTRUCT || r.Type.Funarg == 0 {
  3422  				break
  3423  			}
  3424  			cr = structcount(r.Type)
  3425  			if cr != cl {
  3426  				goto mismatch
  3427  			}
  3428  			n.Op = OAS2FUNC
  3429  			var s Iter
  3430  			t := Structfirst(&s, &r.Type)
  3431  			for ll := n.List; ll != nil; ll = ll.Next {
  3432  				if t.Type != nil && ll.N.Type != nil {
  3433  					checkassignto(t.Type, ll.N)
  3434  				}
  3435  				if ll.N.Defn == n && ll.N.Ntype == nil {
  3436  					ll.N.Type = t.Type
  3437  				}
  3438  				t = structnext(&s)
  3439  			}
  3440  
  3441  			goto out
  3442  		}
  3443  	}
  3444  
  3445  	// x, ok = y
  3446  	if cl == 2 && cr == 1 {
  3447  		if r.Type == nil {
  3448  			goto out
  3449  		}
  3450  		switch r.Op {
  3451  		case OINDEXMAP, ORECV, ODOTTYPE:
  3452  			switch r.Op {
  3453  			case OINDEXMAP:
  3454  				n.Op = OAS2MAPR
  3455  
  3456  			case ORECV:
  3457  				n.Op = OAS2RECV
  3458  
  3459  			case ODOTTYPE:
  3460  				n.Op = OAS2DOTTYPE
  3461  				r.Op = ODOTTYPE2
  3462  			}
  3463  
  3464  			if l.Type != nil {
  3465  				checkassignto(r.Type, l)
  3466  			}
  3467  			if l.Defn == n {
  3468  				l.Type = r.Type
  3469  			}
  3470  			l := n.List.Next.N
  3471  			if l.Type != nil && l.Type.Etype != TBOOL {
  3472  				checkassignto(Types[TBOOL], l)
  3473  			}
  3474  			if l.Defn == n && l.Ntype == nil {
  3475  				l.Type = Types[TBOOL]
  3476  			}
  3477  			goto out
  3478  		}
  3479  	}
  3480  
  3481  mismatch:
  3482  	Yyerror("assignment count mismatch: %d = %d", cl, cr)
  3483  
  3484  	// second half of dance
  3485  out:
  3486  	n.Typecheck = 1
  3487  
  3488  	for ll := n.List; ll != nil; ll = ll.Next {
  3489  		if ll.N.Typecheck == 0 {
  3490  			typecheck(&ll.N, Erv|Easgn)
  3491  		}
  3492  	}
  3493  }
  3494  
  3495  /*
  3496   * type check function definition
  3497   */
  3498  func typecheckfunc(n *Node) {
  3499  	typecheck(&n.Nname, Erv|Easgn)
  3500  	t := n.Nname.Type
  3501  	if t == nil {
  3502  		return
  3503  	}
  3504  	n.Type = t
  3505  	t.Nname = n.Nname
  3506  	rcvr := getthisx(t).Type
  3507  	if rcvr != nil && n.Func.Shortname != nil && !isblank(n.Func.Shortname) {
  3508  		addmethod(n.Func.Shortname.Sym, t, true, n.Nname.Nointerface)
  3509  	}
  3510  
  3511  	for l := n.Func.Dcl; l != nil; l = l.Next {
  3512  		if l.N.Op == ONAME && (l.N.Class == PPARAM || l.N.Class == PPARAMOUT) {
  3513  			l.N.Decldepth = 1
  3514  		}
  3515  	}
  3516  }
  3517  
  3518  func stringtoarraylit(np **Node) {
  3519  	n := *np
  3520  	if n.Left.Op != OLITERAL || n.Left.Val.Ctype != CTSTR {
  3521  		Fatal("stringtoarraylit %N", n)
  3522  	}
  3523  
  3524  	s := n.Left.Val.U.Sval
  3525  	var l *NodeList
  3526  	if n.Type.Type.Etype == TUINT8 {
  3527  		// []byte
  3528  		for i := 0; i < len(s); i++ {
  3529  			l = list(l, Nod(OKEY, Nodintconst(int64(i)), Nodintconst(int64(s[0]))))
  3530  		}
  3531  	} else {
  3532  		// []rune
  3533  		i := 0
  3534  		for _, r := range s {
  3535  			l = list(l, Nod(OKEY, Nodintconst(int64(i)), Nodintconst(int64(r))))
  3536  			i++
  3537  		}
  3538  	}
  3539  
  3540  	nn := Nod(OCOMPLIT, nil, typenod(n.Type))
  3541  	nn.List = l
  3542  	typecheck(&nn, Erv)
  3543  	*np = nn
  3544  }
  3545  
  3546  var ntypecheckdeftype int
  3547  
  3548  var methodqueue *NodeList
  3549  
  3550  func domethod(n *Node) {
  3551  	nt := n.Type.Nname
  3552  	typecheck(&nt, Etype)
  3553  	if nt.Type == nil {
  3554  		// type check failed; leave empty func
  3555  		n.Type.Etype = TFUNC
  3556  
  3557  		n.Type.Nod = nil
  3558  		return
  3559  	}
  3560  
  3561  	// If we have
  3562  	//	type I interface {
  3563  	//		M(_ int)
  3564  	//	}
  3565  	// then even though I.M looks like it doesn't care about the
  3566  	// value of its argument, a specific implementation of I may
  3567  	// care.  The _ would suppress the assignment to that argument
  3568  	// while generating a call, so remove it.
  3569  	for t := getinargx(nt.Type).Type; t != nil; t = t.Down {
  3570  		if t.Sym != nil && t.Sym.Name == "_" {
  3571  			t.Sym = nil
  3572  		}
  3573  	}
  3574  
  3575  	*n.Type = *nt.Type
  3576  	n.Type.Nod = nil
  3577  	checkwidth(n.Type)
  3578  }
  3579  
  3580  var mapqueue *NodeList
  3581  
  3582  func copytype(n *Node, t *Type) {
  3583  	if t.Etype == TFORW {
  3584  		// This type isn't computed yet; when it is, update n.
  3585  		t.Copyto = list(t.Copyto, n)
  3586  
  3587  		return
  3588  	}
  3589  
  3590  	maplineno := int(n.Type.Maplineno)
  3591  	embedlineno := int(n.Type.Embedlineno)
  3592  
  3593  	l := n.Type.Copyto
  3594  	*n.Type = *t
  3595  
  3596  	t = n.Type
  3597  	t.Sym = n.Sym
  3598  	t.Local = n.Local
  3599  	t.Vargen = n.Vargen
  3600  	t.Siggen = 0
  3601  	t.Method = nil
  3602  	t.Xmethod = nil
  3603  	t.Nod = nil
  3604  	t.Printed = 0
  3605  	t.Deferwidth = 0
  3606  	t.Copyto = nil
  3607  
  3608  	// Update nodes waiting on this type.
  3609  	for ; l != nil; l = l.Next {
  3610  		copytype(l.N, t)
  3611  	}
  3612  
  3613  	// Double-check use of type as embedded type.
  3614  	lno := int(lineno)
  3615  
  3616  	if embedlineno != 0 {
  3617  		lineno = int32(embedlineno)
  3618  		if Isptr[t.Etype] {
  3619  			Yyerror("embedded type cannot be a pointer")
  3620  		}
  3621  	}
  3622  
  3623  	lineno = int32(lno)
  3624  
  3625  	// Queue check for map until all the types are done settling.
  3626  	if maplineno != 0 {
  3627  		t.Maplineno = int32(maplineno)
  3628  		mapqueue = list(mapqueue, n)
  3629  	}
  3630  }
  3631  
  3632  func typecheckdeftype(n *Node) {
  3633  	ntypecheckdeftype++
  3634  	lno := int(lineno)
  3635  	setlineno(n)
  3636  	n.Type.Sym = n.Sym
  3637  	n.Typecheck = 1
  3638  	typecheck(&n.Ntype, Etype)
  3639  	t := n.Ntype.Type
  3640  	if t == nil {
  3641  		n.Diag = 1
  3642  		n.Type = nil
  3643  		goto ret
  3644  	}
  3645  
  3646  	if n.Type == nil {
  3647  		n.Diag = 1
  3648  		goto ret
  3649  	}
  3650  
  3651  	// copy new type and clear fields
  3652  	// that don't come along.
  3653  	// anything zeroed here must be zeroed in
  3654  	// typedcl2 too.
  3655  	copytype(n, t)
  3656  
  3657  ret:
  3658  	lineno = int32(lno)
  3659  
  3660  	// if there are no type definitions going on, it's safe to
  3661  	// try to resolve the method types for the interfaces
  3662  	// we just read.
  3663  	if ntypecheckdeftype == 1 {
  3664  		var l *NodeList
  3665  		for {
  3666  			l = methodqueue
  3667  			if l == nil {
  3668  				break
  3669  			}
  3670  			methodqueue = nil
  3671  			for ; l != nil; l = l.Next {
  3672  				domethod(l.N)
  3673  			}
  3674  		}
  3675  
  3676  		for l := mapqueue; l != nil; l = l.Next {
  3677  			lineno = l.N.Type.Maplineno
  3678  			maptype(l.N.Type, Types[TBOOL])
  3679  		}
  3680  
  3681  		lineno = int32(lno)
  3682  	}
  3683  
  3684  	ntypecheckdeftype--
  3685  }
  3686  
  3687  func queuemethod(n *Node) {
  3688  	if ntypecheckdeftype == 0 {
  3689  		domethod(n)
  3690  		return
  3691  	}
  3692  
  3693  	methodqueue = list(methodqueue, n)
  3694  }
  3695  
  3696  func typecheckdef(n *Node) *Node {
  3697  	lno := int(lineno)
  3698  	setlineno(n)
  3699  
  3700  	if n.Op == ONONAME {
  3701  		if n.Diag == 0 {
  3702  			n.Diag = 1
  3703  			if n.Lineno != 0 {
  3704  				lineno = n.Lineno
  3705  			}
  3706  
  3707  			// Note: adderrorname looks for this string and
  3708  			// adds context about the outer expression
  3709  			Yyerror("undefined: %v", n.Sym)
  3710  		}
  3711  
  3712  		return n
  3713  	}
  3714  
  3715  	if n.Walkdef == 1 {
  3716  		return n
  3717  	}
  3718  
  3719  	l := new(NodeList)
  3720  	l.N = n
  3721  	l.Next = typecheckdefstack
  3722  	typecheckdefstack = l
  3723  
  3724  	if n.Walkdef == 2 {
  3725  		Flusherrors()
  3726  		fmt.Printf("typecheckdef loop:")
  3727  		for l := typecheckdefstack; l != nil; l = l.Next {
  3728  			fmt.Printf(" %v", l.N.Sym)
  3729  		}
  3730  		fmt.Printf("\n")
  3731  		Fatal("typecheckdef loop")
  3732  	}
  3733  
  3734  	n.Walkdef = 2
  3735  
  3736  	if n.Type != nil || n.Sym == nil { // builtin or no name
  3737  		goto ret
  3738  	}
  3739  
  3740  	switch n.Op {
  3741  	default:
  3742  		Fatal("typecheckdef %v", Oconv(int(n.Op), 0))
  3743  
  3744  		// not really syms
  3745  	case OGOTO, OLABEL:
  3746  		break
  3747  
  3748  	case OLITERAL:
  3749  		if n.Ntype != nil {
  3750  			typecheck(&n.Ntype, Etype)
  3751  			n.Type = n.Ntype.Type
  3752  			n.Ntype = nil
  3753  			if n.Type == nil {
  3754  				n.Diag = 1
  3755  				goto ret
  3756  			}
  3757  		}
  3758  
  3759  		e := n.Defn
  3760  		n.Defn = nil
  3761  		if e == nil {
  3762  			lineno = n.Lineno
  3763  			Dump("typecheckdef nil defn", n)
  3764  			Yyerror("xxx")
  3765  		}
  3766  
  3767  		typecheck(&e, Erv|Eiota)
  3768  		if Isconst(e, CTNIL) {
  3769  			Yyerror("const initializer cannot be nil")
  3770  			goto ret
  3771  		}
  3772  
  3773  		if e.Type != nil && e.Op != OLITERAL || !isgoconst(e) {
  3774  			if e.Diag == 0 {
  3775  				Yyerror("const initializer %v is not a constant", e)
  3776  				e.Diag = 1
  3777  			}
  3778  
  3779  			goto ret
  3780  		}
  3781  
  3782  		t := n.Type
  3783  		if t != nil {
  3784  			if !okforconst[t.Etype] {
  3785  				Yyerror("invalid constant type %v", t)
  3786  				goto ret
  3787  			}
  3788  
  3789  			if !isideal(e.Type) && !Eqtype(t, e.Type) {
  3790  				Yyerror("cannot use %v as type %v in const initializer", Nconv(e, obj.FmtLong), t)
  3791  				goto ret
  3792  			}
  3793  
  3794  			Convlit(&e, t)
  3795  		}
  3796  
  3797  		n.Val = e.Val
  3798  		n.Type = e.Type
  3799  
  3800  	case ONAME:
  3801  		if n.Ntype != nil {
  3802  			typecheck(&n.Ntype, Etype)
  3803  			n.Type = n.Ntype.Type
  3804  
  3805  			if n.Type == nil {
  3806  				n.Diag = 1
  3807  				goto ret
  3808  			}
  3809  		}
  3810  
  3811  		if n.Type != nil {
  3812  			break
  3813  		}
  3814  		if n.Defn == nil {
  3815  			if n.Etype != 0 { // like OPRINTN
  3816  				break
  3817  			}
  3818  			if nsavederrors+nerrors > 0 {
  3819  				// Can have undefined variables in x := foo
  3820  				// that make x have an n->ndefn == nil.
  3821  				// If there are other errors anyway, don't
  3822  				// bother adding to the noise.
  3823  				break
  3824  			}
  3825  
  3826  			Fatal("var without type, init: %v", n.Sym)
  3827  		}
  3828  
  3829  		if n.Defn.Op == ONAME {
  3830  			typecheck(&n.Defn, Erv)
  3831  			n.Type = n.Defn.Type
  3832  			break
  3833  		}
  3834  
  3835  		typecheck(&n.Defn, Etop) // fills in n->type
  3836  
  3837  	case OTYPE:
  3838  		if Curfn != nil {
  3839  			defercheckwidth()
  3840  		}
  3841  		n.Walkdef = 1
  3842  		n.Type = typ(TFORW)
  3843  		n.Type.Sym = n.Sym
  3844  		nerrors0 := nerrors
  3845  		typecheckdeftype(n)
  3846  		if n.Type.Etype == TFORW && nerrors > nerrors0 {
  3847  			// Something went wrong during type-checking,
  3848  			// but it was reported. Silence future errors.
  3849  			n.Type.Broke = 1
  3850  		}
  3851  
  3852  		if Curfn != nil {
  3853  			resumecheckwidth()
  3854  		}
  3855  
  3856  		// nothing to see here
  3857  	case OPACK:
  3858  		break
  3859  	}
  3860  
  3861  ret:
  3862  	if n.Op != OLITERAL && n.Type != nil && isideal(n.Type) {
  3863  		Fatal("got %v for %v", n.Type, n)
  3864  	}
  3865  	if typecheckdefstack.N != n {
  3866  		Fatal("typecheckdefstack mismatch")
  3867  	}
  3868  	l = typecheckdefstack
  3869  	typecheckdefstack = l.Next
  3870  
  3871  	lineno = int32(lno)
  3872  	n.Walkdef = 1
  3873  	return n
  3874  }
  3875  
  3876  func checkmake(t *Type, arg string, n *Node) int {
  3877  	if n.Op == OLITERAL {
  3878  		switch n.Val.Ctype {
  3879  		case CTINT, CTRUNE, CTFLT, CTCPLX:
  3880  			n.Val = toint(n.Val)
  3881  			if mpcmpfixc(n.Val.U.Xval, 0) < 0 {
  3882  				Yyerror("negative %s argument in make(%v)", arg, t)
  3883  				return -1
  3884  			}
  3885  
  3886  			if Mpcmpfixfix(n.Val.U.Xval, Maxintval[TINT]) > 0 {
  3887  				Yyerror("%s argument too large in make(%v)", arg, t)
  3888  				return -1
  3889  			}
  3890  
  3891  			// Delay defaultlit until after we've checked range, to avoid
  3892  			// a redundant "constant NNN overflows int" error.
  3893  			defaultlit(&n, Types[TINT])
  3894  
  3895  			return 0
  3896  
  3897  		default:
  3898  			break
  3899  		}
  3900  	}
  3901  
  3902  	if !Isint[n.Type.Etype] && n.Type.Etype != TIDEAL {
  3903  		Yyerror("non-integer %s argument in make(%v) - %v", arg, t, n.Type)
  3904  		return -1
  3905  	}
  3906  
  3907  	// Defaultlit still necessary for non-constant: n might be 1<<k.
  3908  	defaultlit(&n, Types[TINT])
  3909  
  3910  	return 0
  3911  }
  3912  
  3913  func markbreak(n *Node, implicit *Node) {
  3914  	if n == nil {
  3915  		return
  3916  	}
  3917  
  3918  	switch n.Op {
  3919  	case OBREAK:
  3920  		if n.Left == nil {
  3921  			if implicit != nil {
  3922  				implicit.Hasbreak = true
  3923  			}
  3924  		} else {
  3925  			lab := n.Left.Sym.Label
  3926  			if lab != nil {
  3927  				lab.Def.Hasbreak = true
  3928  			}
  3929  		}
  3930  
  3931  	case OFOR,
  3932  		OSWITCH,
  3933  		OTYPESW,
  3934  		OSELECT,
  3935  		ORANGE:
  3936  		implicit = n
  3937  		fallthrough
  3938  
  3939  		// fall through
  3940  	default:
  3941  		markbreak(n.Left, implicit)
  3942  
  3943  		markbreak(n.Right, implicit)
  3944  		markbreak(n.Ntest, implicit)
  3945  		markbreak(n.Nincr, implicit)
  3946  		markbreaklist(n.Ninit, implicit)
  3947  		markbreaklist(n.Nbody, implicit)
  3948  		markbreaklist(n.Nelse, implicit)
  3949  		markbreaklist(n.List, implicit)
  3950  		markbreaklist(n.Rlist, implicit)
  3951  	}
  3952  }
  3953  
  3954  func markbreaklist(l *NodeList, implicit *Node) {
  3955  	var n *Node
  3956  	var lab *Label
  3957  
  3958  	for ; l != nil; l = l.Next {
  3959  		n = l.N
  3960  		if n.Op == OLABEL && l.Next != nil && n.Defn == l.Next.N {
  3961  			switch n.Defn.Op {
  3962  			case OFOR,
  3963  				OSWITCH,
  3964  				OTYPESW,
  3965  				OSELECT,
  3966  				ORANGE:
  3967  				lab = new(Label)
  3968  				lab.Def = n.Defn
  3969  				n.Left.Sym.Label = lab
  3970  				markbreak(n.Defn, n.Defn)
  3971  				n.Left.Sym.Label = nil
  3972  				l = l.Next
  3973  				continue
  3974  			}
  3975  		}
  3976  
  3977  		markbreak(n, implicit)
  3978  	}
  3979  }
  3980  
  3981  func isterminating(l *NodeList, top int) bool {
  3982  	if l == nil {
  3983  		return false
  3984  	}
  3985  	if top != 0 {
  3986  		for l.Next != nil && l.N.Op != OLABEL {
  3987  			l = l.Next
  3988  		}
  3989  		markbreaklist(l, nil)
  3990  	}
  3991  
  3992  	for l.Next != nil {
  3993  		l = l.Next
  3994  	}
  3995  	n := l.N
  3996  
  3997  	if n == nil {
  3998  		return false
  3999  	}
  4000  
  4001  	switch n.Op {
  4002  	// NOTE: OLABEL is treated as a separate statement,
  4003  	// not a separate prefix, so skipping to the last statement
  4004  	// in the block handles the labeled statement case by
  4005  	// skipping over the label. No case OLABEL here.
  4006  
  4007  	case OBLOCK:
  4008  		return isterminating(n.List, 0)
  4009  
  4010  	case OGOTO,
  4011  		ORETURN,
  4012  		ORETJMP,
  4013  		OPANIC,
  4014  		OXFALL:
  4015  		return true
  4016  
  4017  	case OFOR:
  4018  		if n.Ntest != nil {
  4019  			return false
  4020  		}
  4021  		if n.Hasbreak {
  4022  			return false
  4023  		}
  4024  		return true
  4025  
  4026  	case OIF:
  4027  		return isterminating(n.Nbody, 0) && isterminating(n.Nelse, 0)
  4028  
  4029  	case OSWITCH, OTYPESW, OSELECT:
  4030  		if n.Hasbreak {
  4031  			return false
  4032  		}
  4033  		def := 0
  4034  		for l = n.List; l != nil; l = l.Next {
  4035  			if !isterminating(l.N.Nbody, 0) {
  4036  				return false
  4037  			}
  4038  			if l.N.List == nil { // default
  4039  				def = 1
  4040  			}
  4041  		}
  4042  
  4043  		if n.Op != OSELECT && def == 0 {
  4044  			return false
  4045  		}
  4046  		return true
  4047  	}
  4048  
  4049  	return false
  4050  }
  4051  
  4052  func checkreturn(fn *Node) {
  4053  	if fn.Type.Outtuple != 0 && fn.Nbody != nil {
  4054  		if !isterminating(fn.Nbody, 1) {
  4055  			yyerrorl(int(fn.Func.Endlineno), "missing return at end of function")
  4056  		}
  4057  	}
  4058  }