github.com/rsc/go@v0.0.0-20150416155037-e040fd465409/src/cmd/internal/gc/typecheck.go (about)

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