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