// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package gc

import (
	"cmd/internal/obj"
	"fmt"
	"math"
	"strings"
)

/*
 * type check the whole tree of an expression.
 * calculates expression types.
 * evaluates compile time constants.
 * marks variables that escape the local frame.
 * rewrites n->op to be more specific in some cases.
 */
var typecheckdefstack *NodeList

/*
 * resolve ONONAME to definition, if any.
 */
func resolve(n *Node) *Node {
	if n != nil && n.Op == ONONAME && n.Sym != nil {
		r := n.Sym.Def
		if r != nil {
			if r.Op != OIOTA {
				n = r
			} else if n.Iota >= 0 {
				n = Nodintconst(int64(n.Iota))
			}
		}
	}

	return n
}

func typechecklist(l *NodeList, top int) {
	for ; l != nil; l = l.Next {
		typecheck(&l.N, top)
	}
}

var _typekind = []string{
	TINT:        "int",
	TUINT:       "uint",
	TINT8:       "int8",
	TUINT8:      "uint8",
	TINT16:      "int16",
	TUINT16:     "uint16",
	TINT32:      "int32",
	TUINT32:     "uint32",
	TINT64:      "int64",
	TUINT64:     "uint64",
	TUINTPTR:    "uintptr",
	TCOMPLEX64:  "complex64",
	TCOMPLEX128: "complex128",
	TFLOAT32:    "float32",
	TFLOAT64:    "float64",
	TBOOL:       "bool",
	TSTRING:     "string",
	TPTR32:      "pointer",
	TPTR64:      "pointer",
	TUNSAFEPTR:  "unsafe.Pointer",
	TSTRUCT:     "struct",
	TINTER:      "interface",
	TCHAN:       "chan",
	TMAP:        "map",
	TARRAY:      "array",
	TFUNC:       "func",
	TNIL:        "nil",
	TIDEAL:      "untyped number",
}

var typekind_buf string

func typekind(t *Type) string {
	if Isslice(t) {
		return "slice"
	}
	et := int(t.Etype)
	if 0 <= et && et < len(_typekind) {
		s := _typekind[et]
		if s != "" {
			return s
		}
	}
	typekind_buf = fmt.Sprintf("etype=%d", et)
	return typekind_buf
}

/*
 * sprint_depchain prints a dependency chain
 * of nodes into fmt.
 * It is used by typecheck in the case of OLITERAL nodes
 * to print constant definition loops.
 */
func sprint_depchain(fmt_ *string, stack *NodeList, cur *Node, first *Node) {
	for l := stack; l != nil; l = l.Next {
		if l.N.Op == cur.Op {
			if l.N != first {
				sprint_depchain(fmt_, l.Next, l.N, first)
			}
			*fmt_ += fmt.Sprintf("\n\t%v: %v uses %v", l.N.Line(), Nconv(l.N, 0), Nconv(cur, 0))
			return
		}
	}
}

/*
 * type check node *np.
 * replaces *np with a new pointer in some cases.
 * returns the final value of *np as a convenience.
 */

var typecheck_tcstack *NodeList
var typecheck_tcfree *NodeList

func typecheck(np **Node, top int) *Node {
	// cannot type check until all the source has been parsed
	if typecheckok == 0 {
		Fatal("early typecheck")
	}

	n := *np
	if n == nil {
		return nil
	}

	lno := int(setlineno(n))

	// Skip over parens.
	for n.Op == OPAREN {
		n = n.Left
	}

	// Resolve definition of name and value of iota lazily.
	n = resolve(n)

	*np = n

	// Skip typecheck if already done.
	// But re-typecheck ONAME/OTYPE/OLITERAL/OPACK node in case context has changed.
	if n.Typecheck == 1 {
		switch n.Op {
		case ONAME,
			OTYPE,
			OLITERAL,
			OPACK:
			break

		default:
			lineno = int32(lno)
			return n
		}
	}

	if n.Typecheck == 2 {
		// Typechecking loop. Trying printing a meaningful message,
		// otherwise a stack trace of typechecking.
		var fmt_ string
		switch n.Op {
		// We can already diagnose variables used as types.
		case ONAME:
			if top&(Erv|Etype) == Etype {
				Yyerror("%v is not a type", Nconv(n, 0))
			}

		case OLITERAL:
			if top&(Erv|Etype) == Etype {
				Yyerror("%v is not a type", Nconv(n, 0))
				break
			}

			fmt_ = ""
			sprint_depchain(&fmt_, typecheck_tcstack, n, n)
			yyerrorl(int(n.Lineno), "constant definition loop%s", fmt_)
		}

		if nsavederrors+nerrors == 0 {
			fmt_ = ""
			for l := typecheck_tcstack; l != nil; l = l.Next {
				fmt_ += fmt.Sprintf("\n\t%v %v", l.N.Line(), Nconv(l.N, 0))
			}
			Yyerror("typechecking loop involving %v%s", Nconv(n, 0), fmt_)
		}

		lineno = int32(lno)
		return n
	}

	n.Typecheck = 2

	var l *NodeList
	if typecheck_tcfree != nil {
		l = typecheck_tcfree
		typecheck_tcfree = l.Next
	} else {
		l = new(NodeList)
	}
	l.Next = typecheck_tcstack
	l.N = n
	typecheck_tcstack = l

	typecheck1(&n, top)
	*np = n
	n.Typecheck = 1

	if typecheck_tcstack != l {
		Fatal("typecheck stack out of sync")
	}
	typecheck_tcstack = l.Next
	l.Next = typecheck_tcfree
	typecheck_tcfree = l

	lineno = int32(lno)
	return n
}

/*
 * does n contain a call or receive operation?
 */
func callrecv(n *Node) bool {
	if n == nil {
		return false
	}

	switch n.Op {
	case OCALL,
		OCALLMETH,
		OCALLINTER,
		OCALLFUNC,
		ORECV,
		OCAP,
		OLEN,
		OCOPY,
		ONEW,
		OAPPEND,
		ODELETE:
		return true
	}

	return callrecv(n.Left) || callrecv(n.Right) || callrecv(n.Ntest) || callrecv(n.Nincr) || callrecvlist(n.Ninit) || callrecvlist(n.Nbody) || callrecvlist(n.Nelse) || callrecvlist(n.List) || callrecvlist(n.Rlist)
}

func callrecvlist(l *NodeList) bool {
	for ; l != nil; l = l.Next {
		if callrecv(l.N) {
			return true
		}
	}
	return false
}

// indexlit implements typechecking of untyped values as
// array/slice indexes. It is equivalent to defaultlit
// except for constants of numerical kind, which are acceptable
// whenever they can be represented by a value of type int.
func indexlit(np **Node) {
	n := *np
	if n == nil || !isideal(n.Type) {
		return
	}
	switch consttype(n) {
	case CTINT,
		CTRUNE,
		CTFLT,
		CTCPLX:
		defaultlit(np, Types[TINT])
	}

	defaultlit(np, nil)
}

func typecheck1(np **Node, top int) {
	var et int
	var aop int
	var op int
	var ptr int
	var l *Node
	var r *Node
	var lo *Node
	var mid *Node
	var hi *Node
	var ok int
	var ntop int
	var t *Type
	var tp *Type
	var missing *Type
	var have *Type
	var badtype *Type
	var v Val
	var why string
	var x int64

	n := *np

	if n.Sym != nil {
		if n.Op == ONAME && n.Etype != 0 && top&Ecall == 0 {
			Yyerror("use of builtin %v not in function call", Sconv(n.Sym, 0))
			goto error
		}

		typecheckdef(n)
		if n.Op == ONONAME {
			goto error
		}
	}

	*np = n

reswitch:
	ok = 0
	switch n.Op {
	// until typecheck is complete, do nothing.
	default:
		Dump("typecheck", n)

		Fatal("typecheck %v", Oconv(int(n.Op), 0))

		/*
		 * names
		 */
	case OLITERAL:
		ok |= Erv

		if n.Type == nil && n.Val.Ctype == CTSTR {
			n.Type = idealstring
		}
		goto ret

	case ONONAME:
		ok |= Erv
		goto ret

	case ONAME:
		if n.Decldepth == 0 {
			n.Decldepth = decldepth
		}
		if n.Etype != 0 {
			ok |= Ecall
			goto ret
		}

		if top&Easgn == 0 {
			// not a write to the variable
			if isblank(n) {
				Yyerror("cannot use _ as value")
				goto error
			}

			n.Used = 1
		}

		if top&Ecall == 0 && isunsafebuiltin(n) {
			Yyerror("%v is not an expression, must be called", Nconv(n, 0))
			goto error
		}

		ok |= Erv
		goto ret

	case OPACK:
		Yyerror("use of package %v without selector", Sconv(n.Sym, 0))
		goto error

	case ODDD:
		break

		/*
		 * types (OIND is with exprs)
		 */
	case OTYPE:
		ok |= Etype

		if n.Type == nil {
			goto error
		}

	case OTARRAY:
		ok |= Etype
		t = typ(TARRAY)
		l = n.Left
		r = n.Right
		if l == nil {
			t.Bound = -1 // slice
		} else if l.Op == ODDD {
			t.Bound = -100 // to be filled in
			if top&Ecomplit == 0 && n.Diag == 0 {
				t.Broke = 1
				n.Diag = 1
				Yyerror("use of [...] array outside of array literal")
			}
		} else {
			l = typecheck(&n.Left, Erv)
			switch consttype(l) {
			case CTINT,
				CTRUNE:
				v = l.Val

			case CTFLT:
				v = toint(l.Val)

			default:
				if l.Type != nil && Isint[l.Type.Etype] != 0 && l.Op != OLITERAL {
					Yyerror("non-constant array bound %v", Nconv(l, 0))
				} else {
					Yyerror("invalid array bound %v", Nconv(l, 0))
				}
				goto error
			}

			t.Bound = Mpgetfix(v.U.Xval)
			if doesoverflow(v, Types[TINT]) {
				Yyerror("array bound is too large")
				goto error
			} else if t.Bound < 0 {
				Yyerror("array bound must be non-negative")
				goto error
			}
		}

		typecheck(&r, Etype)
		if r.Type == nil {
			goto error
		}
		t.Type = r.Type
		n.Op = OTYPE
		n.Type = t
		n.Left = nil
		n.Right = nil
		if t.Bound != -100 {
			checkwidth(t)
		}

	case OTMAP:
		ok |= Etype
		l = typecheck(&n.Left, Etype)
		r = typecheck(&n.Right, Etype)
		if l.Type == nil || r.Type == nil {
			goto error
		}
		n.Op = OTYPE
		n.Type = maptype(l.Type, r.Type)
		n.Left = nil
		n.Right = nil

	case OTCHAN:
		ok |= Etype
		l = typecheck(&n.Left, Etype)
		if l.Type == nil {
			goto error
		}
		t = typ(TCHAN)
		t.Type = l.Type
		t.Chan = n.Etype
		n.Op = OTYPE
		n.Type = t
		n.Left = nil
		n.Etype = 0

	case OTSTRUCT:
		ok |= Etype
		n.Op = OTYPE
		n.Type = tostruct(n.List)
		if n.Type == nil || n.Type.Broke != 0 {
			goto error
		}
		n.List = nil

	case OTINTER:
		ok |= Etype
		n.Op = OTYPE
		n.Type = tointerface(n.List)
		if n.Type == nil {
			goto error
		}

	case OTFUNC:
		ok |= Etype
		n.Op = OTYPE
		n.Type = functype(n.Left, n.List, n.Rlist)
		if n.Type == nil {
			goto error
		}

		/*
		 * type or expr
		 */
	case OIND:
		ntop = Erv | Etype

		if top&Eaddr == 0 {
			ntop |= Eindir
		}
		ntop |= top & Ecomplit
		l = typecheck(&n.Left, ntop)
		t = l.Type
		if t == nil {
			goto error
		}
		if l.Op == OTYPE {
			ok |= Etype
			n.Op = OTYPE
			n.Type = Ptrto(l.Type)
			n.Left = nil
			goto ret
		}

		if Isptr[t.Etype] == 0 {
			if top&(Erv|Etop) != 0 {
				Yyerror("invalid indirect of %v", Nconv(n.Left, obj.FmtLong))
				goto error
			}

			goto ret
		}

		ok |= Erv
		n.Type = t.Type
		goto ret

		/*
		 * arithmetic exprs
		 */
	case OASOP:
		ok |= Etop

		l = typecheck(&n.Left, Erv)
		r = typecheck(&n.Right, Erv)
		checkassign(n, n.Left)
		if l.Type == nil || r.Type == nil {
			goto error
		}
		op = int(n.Etype)
		goto arith

	case OADD,
		OAND,
		OANDAND,
		OANDNOT,
		ODIV,
		OEQ,
		OGE,
		OGT,
		OLE,
		OLT,
		OLSH,
		ORSH,
		OMOD,
		OMUL,
		ONE,
		OOR,
		OOROR,
		OSUB,
		OXOR:
		ok |= Erv
		l = typecheck(&n.Left, Erv|top&Eiota)
		r = typecheck(&n.Right, Erv|top&Eiota)
		if l.Type == nil || r.Type == nil {
			goto error
		}
		op = int(n.Op)
		goto arith

	case OCOM,
		OMINUS,
		ONOT,
		OPLUS:
		ok |= Erv
		l = typecheck(&n.Left, Erv|top&Eiota)
		t = l.Type
		if t == nil {
			goto error
		}
		if okfor[n.Op][t.Etype] == 0 {
			Yyerror("invalid operation: %v %v", Oconv(int(n.Op), 0), Tconv(t, 0))
			goto error
		}

		n.Type = t
		goto ret

		/*
		 * exprs
		 */
	case OADDR:
		ok |= Erv

		typecheck(&n.Left, Erv|Eaddr)
		if n.Left.Type == nil {
			goto error
		}
		checklvalue(n.Left, "take the address of")
		r = outervalue(n.Left)
		for l = n.Left; l != r; l = l.Left {
			l.Addrtaken = 1
			if l.Closure != nil {
				l.Closure.Addrtaken = 1
			}
		}

		if l.Orig != l && l.Op == ONAME {
			Fatal("found non-orig name node %v", Nconv(l, 0))
		}
		l.Addrtaken = 1
		if l.Closure != nil {
			l.Closure.Addrtaken = 1
		}
		defaultlit(&n.Left, nil)
		l = n.Left
		t = l.Type
		if t == nil {
			goto error
		}
		n.Type = Ptrto(t)
		goto ret

	case OCOMPLIT:
		ok |= Erv
		typecheckcomplit(&n)
		if n.Type == nil {
			goto error
		}
		goto ret

	case OXDOT:
		n = adddot(n)
		n.Op = ODOT
		if n.Left == nil {
			goto error
		}
		fallthrough

		// fall through
	case ODOT:
		typecheck(&n.Left, Erv|Etype)

		defaultlit(&n.Left, nil)
		if n.Right.Op != ONAME {
			Yyerror("rhs of . must be a name") // impossible
			goto error
		}

		t = n.Left.Type
		if t == nil {
			adderrorname(n)
			goto error
		}

		r = n.Right

		if n.Left.Op == OTYPE {
			if !looktypedot(n, t, 0) {
				if looktypedot(n, t, 1) {
					Yyerror("%v undefined (cannot refer to unexported method %v)", Nconv(n, 0), Sconv(n.Right.Sym, 0))
				} else {
					Yyerror("%v undefined (type %v has no method %v)", Nconv(n, 0), Tconv(t, 0), Sconv(n.Right.Sym, 0))
				}
				goto error
			}

			if n.Type.Etype != TFUNC || n.Type.Thistuple != 1 {
				Yyerror("type %v has no method %v", Tconv(n.Left.Type, 0), Sconv(n.Right.Sym, obj.FmtShort))
				n.Type = nil
				goto error
			}

			n.Op = ONAME
			n.Sym = n.Right.Sym
			n.Type = methodfunc(n.Type, n.Left.Type)
			n.Xoffset = 0
			n.Class = PFUNC
			ok = Erv
			goto ret
		}

		if Isptr[t.Etype] != 0 && t.Type.Etype != TINTER {
			t = t.Type
			if t == nil {
				goto error
			}
			n.Op = ODOTPTR
			checkwidth(t)
		}

		if isblank(n.Right) {
			Yyerror("cannot refer to blank field or method")
			goto error
		}

		if !lookdot(n, t, 0) {
			if lookdot(n, t, 1) {
				Yyerror("%v undefined (cannot refer to unexported field or method %v)", Nconv(n, 0), Sconv(n.Right.Sym, 0))
			} else {
				Yyerror("%v undefined (type %v has no field or method %v)", Nconv(n, 0), Tconv(n.Left.Type, 0), Sconv(n.Right.Sym, 0))
			}
			goto error
		}

		switch n.Op {
		case ODOTINTER,
			ODOTMETH:
			if top&Ecall != 0 {
				ok |= Ecall
			} else {
				typecheckpartialcall(n, r)
				ok |= Erv
			}

		default:
			ok |= Erv
		}

		goto ret

	case ODOTTYPE:
		ok |= Erv
		typecheck(&n.Left, Erv)
		defaultlit(&n.Left, nil)
		l = n.Left
		t = l.Type
		if t == nil {
			goto error
		}
		if !Isinter(t) {
			Yyerror("invalid type assertion: %v (non-interface type %v on left)", Nconv(n, 0), Tconv(t, 0))
			goto error
		}

		if n.Right != nil {
			typecheck(&n.Right, Etype)
			n.Type = n.Right.Type
			n.Right = nil
			if n.Type == nil {
				goto error
			}
		}

		if n.Type != nil && n.Type.Etype != TINTER {
			if !implements(n.Type, t, &missing, &have, &ptr) {
				if have != nil && have.Sym == missing.Sym {
					Yyerror("impossible type assertion:\n\t%v does not implement %v (wrong type for %v method)\n"+"\t\thave %v%v\n\t\twant %v%v", Tconv(n.Type, 0), Tconv(t, 0), Sconv(missing.Sym, 0), Sconv(have.Sym, 0), Tconv(have.Type, obj.FmtShort|obj.FmtByte), Sconv(missing.Sym, 0), Tconv(missing.Type, obj.FmtShort|obj.FmtByte))
				} else if ptr != 0 {
					Yyerror("impossible type assertion:\n\t%v does not implement %v (%v method has pointer receiver)", Tconv(n.Type, 0), Tconv(t, 0), Sconv(missing.Sym, 0))
				} else if have != nil {
					Yyerror("impossible type assertion:\n\t%v does not implement %v (missing %v method)\n"+"\t\thave %v%v\n\t\twant %v%v", Tconv(n.Type, 0), Tconv(t, 0), Sconv(missing.Sym, 0), Sconv(have.Sym, 0), Tconv(have.Type, obj.FmtShort|obj.FmtByte), Sconv(missing.Sym, 0), Tconv(missing.Type, obj.FmtShort|obj.FmtByte))
				} else {
					Yyerror("impossible type assertion:\n\t%v does not implement %v (missing %v method)", Tconv(n.Type, 0), Tconv(t, 0), Sconv(missing.Sym, 0))
				}
				goto error
			}
		}

		goto ret

	case OINDEX:
		ok |= Erv
		typecheck(&n.Left, Erv)
		defaultlit(&n.Left, nil)
		implicitstar(&n.Left)
		l = n.Left
		typecheck(&n.Right, Erv)
		r = n.Right
		t = l.Type
		if t == nil || r.Type == nil {
			goto error
		}
		switch t.Etype {
		default:
			Yyerror("invalid operation: %v (type %v does not support indexing)", Nconv(n, 0), Tconv(t, 0))
			goto error

		case TSTRING,
			TARRAY:
			indexlit(&n.Right)
			if t.Etype == TSTRING {
				n.Type = Types[TUINT8]
			} else {
				n.Type = t.Type
			}
			why = "string"
			if t.Etype == TARRAY {
				if Isfixedarray(t) {
					why = "array"
				} else {
					why = "slice"
				}
			}

			if n.Right.Type != nil && Isint[n.Right.Type.Etype] == 0 {
				Yyerror("non-integer %s index %v", why, Nconv(n.Right, 0))
				break
			}

			if Isconst(n.Right, CTINT) {
				x = Mpgetfix(n.Right.Val.U.Xval)
				if x < 0 {
					Yyerror("invalid %s index %v (index must be non-negative)", why, Nconv(n.Right, 0))
				} else if Isfixedarray(t) && t.Bound > 0 && x >= t.Bound {
					Yyerror("invalid array index %v (out of bounds for %d-element array)", Nconv(n.Right, 0), t.Bound)
				} else if Isconst(n.Left, CTSTR) && x >= int64(len(n.Left.Val.U.Sval.S)) {
					Yyerror("invalid string index %v (out of bounds for %d-byte string)", Nconv(n.Right, 0), len(n.Left.Val.U.Sval.S))
				} else if Mpcmpfixfix(n.Right.Val.U.Xval, Maxintval[TINT]) > 0 {
					Yyerror("invalid %s index %v (index too large)", why, Nconv(n.Right, 0))
				}
			}

		case TMAP:
			n.Etype = 0
			defaultlit(&n.Right, t.Down)
			if n.Right.Type != nil {
				n.Right = assignconv(n.Right, t.Down, "map index")
			}
			n.Type = t.Type
			n.Op = OINDEXMAP
		}

		goto ret

	case ORECV:
		ok |= Etop | Erv
		typecheck(&n.Left, Erv)
		defaultlit(&n.Left, nil)
		l = n.Left
		t = l.Type
		if t == nil {
			goto error
		}
		if t.Etype != TCHAN {
			Yyerror("invalid operation: %v (receive from non-chan type %v)", Nconv(n, 0), Tconv(t, 0))
			goto error
		}

		if t.Chan&Crecv == 0 {
			Yyerror("invalid operation: %v (receive from send-only type %v)", Nconv(n, 0), Tconv(t, 0))
			goto error
		}

		n.Type = t.Type
		goto ret

	case OSEND:
		ok |= Etop
		l = typecheck(&n.Left, Erv)
		typecheck(&n.Right, Erv)
		defaultlit(&n.Left, nil)
		l = n.Left
		t = l.Type
		if t == nil {
			goto error
		}
		if t.Etype != TCHAN {
			Yyerror("invalid operation: %v (send to non-chan type %v)", Nconv(n, 0), Tconv(t, 0))
			goto error
		}

		if t.Chan&Csend == 0 {
			Yyerror("invalid operation: %v (send to receive-only type %v)", Nconv(n, 0), Tconv(t, 0))
			goto error
		}

		defaultlit(&n.Right, t.Type)
		r = n.Right
		if r.Type == nil {
			goto error
		}
		n.Right = assignconv(r, l.Type.Type, "send")

		// TODO: more aggressive
		n.Etype = 0

		n.Type = nil
		goto ret

	case OSLICE:
		ok |= Erv
		typecheck(&n.Left, top)
		typecheck(&n.Right.Left, Erv)
		typecheck(&n.Right.Right, Erv)
		defaultlit(&n.Left, nil)
		indexlit(&n.Right.Left)
		indexlit(&n.Right.Right)
		l = n.Left
		if Isfixedarray(l.Type) {
			if !islvalue(n.Left) {
				Yyerror("invalid operation %v (slice of unaddressable value)", Nconv(n, 0))
				goto error
			}

			n.Left = Nod(OADDR, n.Left, nil)
			n.Left.Implicit = 1
			typecheck(&n.Left, Erv)
			l = n.Left
		}

		t = l.Type
		if t == nil {
			goto error
		}
		tp = nil
		if Istype(t, TSTRING) {
			n.Type = t
			n.Op = OSLICESTR
		} else if Isptr[t.Etype] != 0 && Isfixedarray(t.Type) {
			tp = t.Type
			n.Type = typ(TARRAY)
			n.Type.Type = tp.Type
			n.Type.Bound = -1
			dowidth(n.Type)
			n.Op = OSLICEARR
		} else if Isslice(t) {
			n.Type = t
		} else {
			Yyerror("cannot slice %v (type %v)", Nconv(l, 0), Tconv(t, 0))
			goto error
		}

		lo = n.Right.Left
		if lo != nil && checksliceindex(l, lo, tp) < 0 {
			goto error
		}
		hi = n.Right.Right
		if hi != nil && checksliceindex(l, hi, tp) < 0 {
			goto error
		}
		if checksliceconst(lo, hi) < 0 {
			goto error
		}
		goto ret

	case OSLICE3:
		ok |= Erv
		typecheck(&n.Left, top)
		typecheck(&n.Right.Left, Erv)
		typecheck(&n.Right.Right.Left, Erv)
		typecheck(&n.Right.Right.Right, Erv)
		defaultlit(&n.Left, nil)
		indexlit(&n.Right.Left)
		indexlit(&n.Right.Right.Left)
		indexlit(&n.Right.Right.Right)
		l = n.Left
		if Isfixedarray(l.Type) {
			if !islvalue(n.Left) {
				Yyerror("invalid operation %v (slice of unaddressable value)", Nconv(n, 0))
				goto error
			}

			n.Left = Nod(OADDR, n.Left, nil)
			n.Left.Implicit = 1
			typecheck(&n.Left, Erv)
			l = n.Left
		}

		t = l.Type
		if t == nil {
			goto error
		}
		tp = nil
		if Istype(t, TSTRING) {
			Yyerror("invalid operation %v (3-index slice of string)", Nconv(n, 0))
			goto error
		}

		if Isptr[t.Etype] != 0 && Isfixedarray(t.Type) {
			tp = t.Type
			n.Type = typ(TARRAY)
			n.Type.Type = tp.Type
			n.Type.Bound = -1
			dowidth(n.Type)
			n.Op = OSLICE3ARR
		} else if Isslice(t) {
			n.Type = t
		} else {
			Yyerror("cannot slice %v (type %v)", Nconv(l, 0), Tconv(t, 0))
			goto error
		}

		lo = n.Right.Left
		if lo != nil && checksliceindex(l, lo, tp) < 0 {
			goto error
		}
		mid = n.Right.Right.Left
		if mid != nil && checksliceindex(l, mid, tp) < 0 {
			goto error
		}
		hi = n.Right.Right.Right
		if hi != nil && checksliceindex(l, hi, tp) < 0 {
			goto error
		}
		if checksliceconst(lo, hi) < 0 || checksliceconst(lo, mid) < 0 || checksliceconst(mid, hi) < 0 {
			goto error
		}
		goto ret

		/*
		 * call and call like
		 */
	case OCALL:
		l = n.Left

		if l.Op == ONAME {
			r = unsafenmagic(n)
			if r != nil {
				if n.Isddd != 0 {
					Yyerror("invalid use of ... with builtin %v", Nconv(l, 0))
				}
				n = r
				goto reswitch
			}
		}

		typecheck(&n.Left, Erv|Etype|Ecall|top&Eproc)
		n.Diag |= n.Left.Diag
		l = n.Left
		if l.Op == ONAME && l.Etype != 0 {
			if n.Isddd != 0 && l.Etype != OAPPEND {
				Yyerror("invalid use of ... with builtin %v", Nconv(l, 0))
			}

			// builtin: OLEN, OCAP, etc.
			n.Op = l.Etype

			n.Left = n.Right
			n.Right = nil
			goto reswitch
		}

		defaultlit(&n.Left, nil)
		l := n.Left
		if l.Op == OTYPE {
			if n.Isddd != 0 || l.Type.Bound == -100 {
				if l.Type.Broke == 0 {
					Yyerror("invalid use of ... in type conversion", l)
				}
				n.Diag = 1
			}

			// pick off before type-checking arguments
			ok |= Erv

			// turn CALL(type, arg) into CONV(arg) w/ type
			n.Left = nil

			n.Op = OCONV
			n.Type = l.Type
			if onearg(n, "conversion to %v", Tconv(l.Type, 0)) < 0 {
				goto error
			}
			goto doconv
		}

		if count(n.List) == 1 && n.Isddd == 0 {
			typecheck(&n.List.N, Erv|Efnstruct)
		} else {
			typechecklist(n.List, Erv)
		}
		t := l.Type
		if t == nil {
			goto error
		}
		checkwidth(t)

		switch l.Op {
		case ODOTINTER:
			n.Op = OCALLINTER

		case ODOTMETH:
			n.Op = OCALLMETH

			// typecheckaste was used here but there wasn't enough
			// information further down the call chain to know if we
			// were testing a method receiver for unexported fields.
			// It isn't necessary, so just do a sanity check.
			tp := getthisx(t).Type.Type

			if l.Left == nil || !Eqtype(l.Left.Type, tp) {
				Fatal("method receiver")
			}

		default:
			n.Op = OCALLFUNC
			if t.Etype != TFUNC {
				Yyerror("cannot call non-function %v (type %v)", Nconv(l, 0), Tconv(t, 0))
				goto error
			}
		}

		descbuf := fmt.Sprintf("argument to %v", Nconv(n.Left, 0))
		desc := descbuf
		typecheckaste(OCALL, n.Left, int(n.Isddd), getinargx(t), n.List, desc)
		ok |= Etop
		if t.Outtuple == 0 {
			goto ret
		}
		ok |= Erv
		if t.Outtuple == 1 {
			t := getoutargx(l.Type).Type
			if t == nil {
				goto error
			}
			if t.Etype == TFIELD {
				t = t.Type
			}
			n.Type = t
			goto ret
		}

		// multiple return
		if top&(Efnstruct|Etop) == 0 {
			Yyerror("multiple-value %v() in single-value context", Nconv(l, 0))
			goto ret
		}

		n.Type = getoutargx(l.Type)
		goto ret

	case OCAP,
		OLEN,
		OREAL,
		OIMAG:
		ok |= Erv
		if onearg(n, "%v", Oconv(int(n.Op), 0)) < 0 {
			goto error
		}
		typecheck(&n.Left, Erv)
		defaultlit(&n.Left, nil)
		implicitstar(&n.Left)
		l := n.Left
		t := l.Type
		if t == nil {
			goto error
		}
		switch n.Op {
		case OCAP:
			if okforcap[t.Etype] == 0 {
				goto badcall1
			}

		case OLEN:
			if okforlen[t.Etype] == 0 {
				goto badcall1
			}

		case OREAL,
			OIMAG:
			if Iscomplex[t.Etype] == 0 {
				goto badcall1
			}
			if Isconst(l, CTCPLX) {
				r := n
				if n.Op == OREAL {
					n = nodfltconst(&l.Val.U.Cval.Real)
				} else {
					n = nodfltconst(&l.Val.U.Cval.Imag)
				}
				n.Orig = r
			}

			n.Type = Types[cplxsubtype(int(t.Etype))]
			goto ret
		}

		// might be constant
		switch t.Etype {
		case TSTRING:
			if Isconst(l, CTSTR) {
				r := Nod(OXXX, nil, nil)
				Nodconst(r, Types[TINT], int64(len(l.Val.U.Sval.S)))
				r.Orig = n
				n = r
			}

		case TARRAY:
			if t.Bound < 0 { // slice
				break
			}
			if callrecv(l) { // has call or receive
				break
			}
			r := Nod(OXXX, nil, nil)
			Nodconst(r, Types[TINT], t.Bound)
			r.Orig = n
			n = r
		}

		n.Type = Types[TINT]
		goto ret

	case OCOMPLEX:
		ok |= Erv
		var r *Node
		var l *Node
		if count(n.List) == 1 {
			typechecklist(n.List, Efnstruct)
			if n.List.N.Op != OCALLFUNC && n.List.N.Op != OCALLMETH {
				Yyerror("invalid operation: complex expects two arguments")
				goto error
			}

			t := n.List.N.Left.Type
			if t.Outtuple != 2 {
				Yyerror("invalid operation: complex expects two arguments, %v returns %d results", Nconv(n.List.N, 0), t.Outtuple)
				goto error
			}

			t = n.List.N.Type.Type
			l = t.Nname
			r = t.Down.Nname
		} else {
			if twoarg(n) < 0 {
				goto error
			}
			l = typecheck(&n.Left, Erv|top&Eiota)
			r = typecheck(&n.Right, Erv|top&Eiota)
			if l.Type == nil || r.Type == nil {
				goto error
			}
			defaultlit2(&l, &r, 0)
			if l.Type == nil || r.Type == nil {
				goto error
			}
			n.Left = l
			n.Right = r
		}

		if !Eqtype(l.Type, r.Type) {
			Yyerror("invalid operation: %v (mismatched types %v and %v)", Nconv(n, 0), Tconv(l.Type, 0), Tconv(r.Type, 0))
			goto error
		}

		var t *Type
		switch l.Type.Etype {
		default:
			Yyerror("invalid operation: %v (arguments have type %v, expected floating-point)", Nconv(n, 0), Tconv(l.Type, 0), r.Type)
			goto error

		case TIDEAL:
			t = Types[TIDEAL]

		case TFLOAT32:
			t = Types[TCOMPLEX64]

		case TFLOAT64:
			t = Types[TCOMPLEX128]
		}

		if l.Op == OLITERAL && r.Op == OLITERAL {
			// make it a complex literal
			r = nodcplxlit(l.Val, r.Val)

			r.Orig = n
			n = r
		}

		n.Type = t
		goto ret

	case OCLOSE:
		if onearg(n, "%v", Oconv(int(n.Op), 0)) < 0 {
			goto error
		}
		typecheck(&n.Left, Erv)
		defaultlit(&n.Left, nil)
		l := n.Left
		t := l.Type
		if t == nil {
			goto error
		}
		if t.Etype != TCHAN {
			Yyerror("invalid operation: %v (non-chan type %v)", Nconv(n, 0), Tconv(t, 0))
			goto error
		}

		if t.Chan&Csend == 0 {
			Yyerror("invalid operation: %v (cannot close receive-only channel)", Nconv(n, 0))
			goto error
		}

		ok |= Etop
		goto ret

	case ODELETE:
		args := n.List
		if args == nil {
			Yyerror("missing arguments to delete")
			goto error
		}

		if args.Next == nil {
			Yyerror("missing second (key) argument to delete")
			goto error
		}

		if args.Next.Next != nil {
			Yyerror("too many arguments to delete")
			goto error
		}

		ok |= Etop
		typechecklist(args, Erv)
		l := args.N
		r := args.Next.N
		if l.Type != nil && l.Type.Etype != TMAP {
			Yyerror("first argument to delete must be map; have %v", Tconv(l.Type, obj.FmtLong))
			goto error
		}

		args.Next.N = assignconv(r, l.Type.Down, "delete")
		goto ret

	case OAPPEND:
		ok |= Erv
		args := n.List
		if args == nil {
			Yyerror("missing arguments to append")
			goto error
		}

		if count(args) == 1 && n.Isddd == 0 {
			typecheck(&args.N, Erv|Efnstruct)
		} else {
			typechecklist(args, Erv)
		}

		t := args.N.Type
		if t == nil {
			goto error
		}

		// Unpack multiple-return result before type-checking.
		if Istype(t, TSTRUCT) && t.Funarg != 0 {
			t = t.Type
			if Istype(t, TFIELD) {
				t = t.Type
			}
		}

		n.Type = t
		if !Isslice(t) {
			if Isconst(args.N, CTNIL) {
				Yyerror("first argument to append must be typed slice; have untyped nil", t)
				goto error
			}

			Yyerror("first argument to append must be slice; have %v", Tconv(t, obj.FmtLong))
			goto error
		}

		if n.Isddd != 0 {
			if args.Next == nil {
				Yyerror("cannot use ... on first argument to append")
				goto error
			}

			if args.Next.Next != nil {
				Yyerror("too many arguments to append")
				goto error
			}

			if Istype(t.Type, TUINT8) && Istype(args.Next.N.Type, TSTRING) {
				defaultlit(&args.Next.N, Types[TSTRING])
				goto ret
			}

			args.Next.N = assignconv(args.Next.N, t.Orig, "append")
			goto ret
		}

		for args = args.Next; args != nil; args = args.Next {
			if args.N.Type == nil {
				continue
			}
			args.N = assignconv(args.N, t.Type, "append")
		}

		goto ret

	case OCOPY:
		ok |= Etop | Erv
		args := n.List
		if args == nil || args.Next == nil {
			Yyerror("missing arguments to copy")
			goto error
		}

		if args.Next.Next != nil {
			Yyerror("too many arguments to copy")
			goto error
		}

		n.Left = args.N
		n.Right = args.Next.N
		n.List = nil
		n.Type = Types[TINT]
		typecheck(&n.Left, Erv)
		typecheck(&n.Right, Erv)
		if n.Left.Type == nil || n.Right.Type == nil {
			goto error
		}
		defaultlit(&n.Left, nil)
		defaultlit(&n.Right, nil)
		if n.Left.Type == nil || n.Right.Type == nil {
			goto error
		}

		// copy([]byte, string)
		if Isslice(n.Left.Type) && n.Right.Type.Etype == TSTRING {
			if Eqtype(n.Left.Type.Type, bytetype) {
				goto ret
			}
			Yyerror("arguments to copy have different element types: %v and string", Tconv(n.Left.Type, obj.FmtLong))
			goto error
		}

		if !Isslice(n.Left.Type) || !Isslice(n.Right.Type) {
			if !Isslice(n.Left.Type) && !Isslice(n.Right.Type) {
				Yyerror("arguments to copy must be slices; have %v, %v", Tconv(n.Left.Type, obj.FmtLong), Tconv(n.Right.Type, obj.FmtLong))
			} else if !Isslice(n.Left.Type) {
				Yyerror("first argument to copy should be slice; have %v", Tconv(n.Left.Type, obj.FmtLong))
			} else {
				Yyerror("second argument to copy should be slice or string; have %v", Tconv(n.Right.Type, obj.FmtLong))
			}
			goto error
		}

		if !Eqtype(n.Left.Type.Type, n.Right.Type.Type) {
			Yyerror("arguments to copy have different element types: %v and %v", Tconv(n.Left.Type, obj.FmtLong), Tconv(n.Right.Type, obj.FmtLong))
			goto error
		}

		goto ret

	case OCONV:
		goto doconv

	case OMAKE:
		ok |= Erv
		args := n.List
		if args == nil {
			Yyerror("missing argument to make")
			goto error
		}

		n.List = nil
		l := args.N
		args = args.Next
		typecheck(&l, Etype)
		t := l.Type
		if t == nil {
			goto error
		}

		switch t.Etype {
		default:
			Yyerror("cannot make type %v", Tconv(t, 0))
			goto error

		case TARRAY:
			if !Isslice(t) {
				Yyerror("cannot make type %v", Tconv(t, 0))
				goto error
			}

			if args == nil {
				Yyerror("missing len argument to make(%v)", Tconv(t, 0))
				goto error
			}

			l = args.N
			args = args.Next
			typecheck(&l, Erv)
			r := (*Node)(nil)
			if args != nil {
				r = args.N
				args = args.Next
				typecheck(&r, Erv)
			}

			if l.Type == nil || (r != nil && r.Type == nil) {
				goto error
			}
			et := bool2int(checkmake(t, "len", l) < 0)
			et |= bool2int(r != nil && checkmake(t, "cap", r) < 0)
			if et != 0 {
				goto error
			}
			if Isconst(l, CTINT) && r != nil && Isconst(r, CTINT) && Mpcmpfixfix(l.Val.U.Xval, r.Val.U.Xval) > 0 {
				Yyerror("len larger than cap in make(%v)", Tconv(t, 0))
				goto error
			}

			n.Left = l
			n.Right = r
			n.Op = OMAKESLICE

		case TMAP:
			if args != nil {
				l = args.N
				args = args.Next
				typecheck(&l, Erv)
				defaultlit(&l, Types[TINT])
				if l.Type == nil {
					goto error
				}
				if checkmake(t, "size", l) < 0 {
					goto error
				}
				n.Left = l
			} else {
				n.Left = Nodintconst(0)
			}
			n.Op = OMAKEMAP

		case TCHAN:
			l = nil
			if args != nil {
				l = args.N
				args = args.Next
				typecheck(&l, Erv)
				defaultlit(&l, Types[TINT])
				if l.Type == nil {
					goto error
				}
				if checkmake(t, "buffer", l) < 0 {
					goto error
				}
				n.Left = l
			} else {
				n.Left = Nodintconst(0)
			}
			n.Op = OMAKECHAN
		}

		if args != nil {
			Yyerror("too many arguments to make(%v)", Tconv(t, 0))
			n.Op = OMAKE
			goto error
		}

		n.Type = t
		goto ret

	case ONEW:
		ok |= Erv
		args := n.List
		if args == nil {
			Yyerror("missing argument to new")
			goto error
		}

		l := args.N
		typecheck(&l, Etype)
		t := l.Type
		if t == nil {
			goto error
		}
		if args.Next != nil {
			Yyerror("too many arguments to new(%v)", Tconv(t, 0))
			goto error
		}

		n.Left = l
		n.Type = Ptrto(t)
		goto ret

	case OPRINT,
		OPRINTN:
		ok |= Etop
		typechecklist(n.List, Erv|Eindir) // Eindir: address does not escape
		for args := n.List; args != nil; args = args.Next {
			// Special case for print: int constant is int64, not int.
			if Isconst(args.N, CTINT) {
				defaultlit(&args.N, Types[TINT64])
			} else {
				defaultlit(&args.N, nil)
			}
		}

		goto ret

	case OPANIC:
		ok |= Etop
		if onearg(n, "panic") < 0 {
			goto error
		}
		typecheck(&n.Left, Erv)
		defaultlit(&n.Left, Types[TINTER])
		if n.Left.Type == nil {
			goto error
		}
		goto ret

	case ORECOVER:
		ok |= Erv | Etop
		if n.List != nil {
			Yyerror("too many arguments to recover")
			goto error
		}

		n.Type = Types[TINTER]
		goto ret

	case OCLOSURE:
		ok |= Erv
		typecheckclosure(n, top)
		if n.Type == nil {
			goto error
		}
		goto ret

	case OITAB:
		ok |= Erv
		typecheck(&n.Left, Erv)
		t := n.Left.Type
		if t == nil {
			goto error
		}
		if t.Etype != TINTER {
			Fatal("OITAB of %v", Tconv(t, 0))
		}
		n.Type = Ptrto(Types[TUINTPTR])
		goto ret

	case OSPTR:
		ok |= Erv
		typecheck(&n.Left, Erv)
		t := n.Left.Type
		if t == nil {
			goto error
		}
		if !Isslice(t) && t.Etype != TSTRING {
			Fatal("OSPTR of %v", Tconv(t, 0))
		}
		if t.Etype == TSTRING {
			n.Type = Ptrto(Types[TUINT8])
		} else {
			n.Type = Ptrto(t.Type)
		}
		goto ret

	case OCLOSUREVAR:
		ok |= Erv
		goto ret

	case OCFUNC:
		ok |= Erv
		typecheck(&n.Left, Erv)
		n.Type = Types[TUINTPTR]
		goto ret

	case OCONVNOP:
		ok |= Erv
		typecheck(&n.Left, Erv)
		goto ret

		/*
		 * statements
		 */
	case OAS:
		ok |= Etop

		typecheckas(n)

		// Code that creates temps does not bother to set defn, so do it here.
		if n.Left.Op == ONAME && strings.HasPrefix(n.Left.Sym.Name, "autotmp_") {
			n.Left.Defn = n
		}
		goto ret

	case OAS2:
		ok |= Etop
		typecheckas2(n)
		goto ret

	case OBREAK,
		OCONTINUE,
		ODCL,
		OEMPTY,
		OGOTO,
		OXFALL,
		OVARKILL:
		ok |= Etop
		goto ret

	case OLABEL:
		ok |= Etop
		decldepth++
		goto ret

	case ODEFER:
		ok |= Etop
		typecheck(&n.Left, Etop|Erv)
		if n.Left.Diag == 0 {
			checkdefergo(n)
		}
		goto ret

	case OPROC:
		ok |= Etop
		typecheck(&n.Left, Etop|Eproc|Erv)
		checkdefergo(n)
		goto ret

	case OFOR:
		ok |= Etop
		typechecklist(n.Ninit, Etop)
		decldepth++
		typecheck(&n.Ntest, Erv)
		if n.Ntest != nil {
			t := n.Ntest.Type
			if t != nil && t.Etype != TBOOL {
				Yyerror("non-bool %v used as for condition", Nconv(n.Ntest, obj.FmtLong))
			}
		}
		typecheck(&n.Nincr, Etop)
		typechecklist(n.Nbody, Etop)
		decldepth--
		goto ret

	case OIF:
		ok |= Etop
		typechecklist(n.Ninit, Etop)
		typecheck(&n.Ntest, Erv)
		if n.Ntest != nil {
			t := n.Ntest.Type
			if t != nil && t.Etype != TBOOL {
				Yyerror("non-bool %v used as if condition", Nconv(n.Ntest, obj.FmtLong))
			}
		}
		typechecklist(n.Nbody, Etop)
		typechecklist(n.Nelse, Etop)
		goto ret

	case ORETURN:
		ok |= Etop
		if count(n.List) == 1 {
			typechecklist(n.List, Erv|Efnstruct)
		} else {
			typechecklist(n.List, Erv)
		}
		if Curfn == nil {
			Yyerror("return outside function")
			goto error
		}

		if Curfn.Type.Outnamed != 0 && n.List == nil {
			goto ret
		}
		typecheckaste(ORETURN, nil, 0, getoutargx(Curfn.Type), n.List, "return argument")
		goto ret

	case ORETJMP:
		ok |= Etop
		goto ret

	case OSELECT:
		ok |= Etop
		typecheckselect(n)
		goto ret

	case OSWITCH:
		ok |= Etop
		typecheckswitch(n)
		goto ret

	case ORANGE:
		ok |= Etop
		typecheckrange(n)
		goto ret

	case OTYPESW:
		Yyerror("use of .(type) outside type switch")
		goto error

	case OXCASE:
		ok |= Etop
		typechecklist(n.List, Erv)
		typechecklist(n.Nbody, Etop)
		goto ret

	case ODCLFUNC:
		ok |= Etop
		typecheckfunc(n)
		goto ret

	case ODCLCONST:
		ok |= Etop
		typecheck(&n.Left, Erv)
		goto ret

	case ODCLTYPE:
		ok |= Etop
		typecheck(&n.Left, Etype)
		if incannedimport == 0 {
			checkwidth(n.Left.Type)
		}
		goto ret
	}

	goto ret

arith:
	if op == OLSH || op == ORSH {
		goto shift
	}

	// ideal mixed with non-ideal
	defaultlit2(&l, &r, 0)

	n.Left = l
	n.Right = r
	if l.Type == nil || r.Type == nil {
		goto error
	}
	t = l.Type
	if t.Etype == TIDEAL {
		t = r.Type
	}
	et = int(t.Etype)
	if et == TIDEAL {
		et = TINT
	}
	aop = 0
	if iscmp[n.Op] != 0 && t.Etype != TIDEAL && !Eqtype(l.Type, r.Type) {
		// comparison is okay as long as one side is
		// assignable to the other.  convert so they have
		// the same type.
		//
		// the only conversion that isn't a no-op is concrete == interface.
		// in that case, check comparability of the concrete type.
		// The conversion allocates, so only do it if the concrete type is huge.
		if r.Type.Etype != TBLANK {
			aop = assignop(l.Type, r.Type, nil)
			if aop != 0 {
				if Isinter(r.Type) && !Isinter(l.Type) && algtype1(l.Type, nil) == ANOEQ {
					Yyerror("invalid operation: %v (operator %v not defined on %s)", Nconv(n, 0), Oconv(int(op), 0), typekind(l.Type))
					goto error
				}

				dowidth(l.Type)
				if Isinter(r.Type) == Isinter(l.Type) || l.Type.Width >= 1<<16 {
					l = Nod(aop, l, nil)
					l.Type = r.Type
					l.Typecheck = 1
					n.Left = l
				}

				t = r.Type
				goto converted
			}
		}

		if l.Type.Etype != TBLANK {
			aop = assignop(r.Type, l.Type, nil)
			if aop != 0 {
				if Isinter(l.Type) && !Isinter(r.Type) && algtype1(r.Type, nil) == ANOEQ {
					Yyerror("invalid operation: %v (operator %v not defined on %s)", Nconv(n, 0), Oconv(int(op), 0), typekind(r.Type))
					goto error
				}

				dowidth(r.Type)
				if Isinter(r.Type) == Isinter(l.Type) || r.Type.Width >= 1<<16 {
					r = Nod(aop, r, nil)
					r.Type = l.Type
					r.Typecheck = 1
					n.Right = r
				}

				t = l.Type
			}
		}

	converted:
		et = int(t.Etype)
	}

	if t.Etype != TIDEAL && !Eqtype(l.Type, r.Type) {
		defaultlit2(&l, &r, 1)
		if n.Op == OASOP && n.Implicit != 0 {
			Yyerror("invalid operation: %v (non-numeric type %v)", Nconv(n, 0), Tconv(l.Type, 0))
			goto error
		}

		if Isinter(r.Type) == Isinter(l.Type) || aop == 0 {
			Yyerror("invalid operation: %v (mismatched types %v and %v)", Nconv(n, 0), Tconv(l.Type, 0), Tconv(r.Type, 0))
			goto error
		}
	}

	if okfor[op][et] == 0 {
		Yyerror("invalid operation: %v (operator %v not defined on %s)", Nconv(n, 0), Oconv(int(op), 0), typekind(t))
		goto error
	}

	// okfor allows any array == array, map == map, func == func.
	// restrict to slice/map/func == nil and nil == slice/map/func.
	if Isfixedarray(l.Type) && algtype1(l.Type, nil) == ANOEQ {
		Yyerror("invalid operation: %v (%v cannot be compared)", Nconv(n, 0), Tconv(l.Type, 0))
		goto error
	}

	if Isslice(l.Type) && !isnil(l) && !isnil(r) {
		Yyerror("invalid operation: %v (slice can only be compared to nil)", Nconv(n, 0))
		goto error
	}

	if l.Type.Etype == TMAP && !isnil(l) && !isnil(r) {
		Yyerror("invalid operation: %v (map can only be compared to nil)", Nconv(n, 0))
		goto error
	}

	if l.Type.Etype == TFUNC && !isnil(l) && !isnil(r) {
		Yyerror("invalid operation: %v (func can only be compared to nil)", Nconv(n, 0))
		goto error
	}

	if l.Type.Etype == TSTRUCT && algtype1(l.Type, &badtype) == ANOEQ {
		Yyerror("invalid operation: %v (struct containing %v cannot be compared)", Nconv(n, 0), Tconv(badtype, 0))
		goto error
	}

	t = l.Type
	if iscmp[n.Op] != 0 {
		evconst(n)
		t = idealbool
		if n.Op != OLITERAL {
			defaultlit2(&l, &r, 1)
			n.Left = l
			n.Right = r
		}
	} else if n.Op == OANDAND || n.Op == OOROR {
		if l.Type == r.Type {
			t = l.Type
		} else if l.Type == idealbool {
			t = r.Type
		} else if r.Type == idealbool {
			t = l.Type
		}
	} else
	// non-comparison operators on ideal bools should make them lose their ideal-ness
	if t == idealbool {
		t = Types[TBOOL]
	}

	if et == TSTRING {
		if iscmp[n.Op] != 0 {
			n.Etype = n.Op
			n.Op = OCMPSTR
		} else if n.Op == OADD {
			// create OADDSTR node with list of strings in x + y + z + (w + v) + ...
			n.Op = OADDSTR

			if l.Op == OADDSTR {
				n.List = l.List
			} else {
				n.List = list1(l)
			}
			if r.Op == OADDSTR {
				n.List = concat(n.List, r.List)
			} else {
				n.List = list(n.List, r)
			}
			n.Left = nil
			n.Right = nil
		}
	}

	if et == TINTER {
		if l.Op == OLITERAL && l.Val.Ctype == CTNIL {
			// swap for back end
			n.Left = r

			n.Right = l
		} else if r.Op == OLITERAL && r.Val.Ctype == CTNIL {
		} else // leave alone for back end
		if Isinter(r.Type) == Isinter(l.Type) {
			n.Etype = n.Op
			n.Op = OCMPIFACE
		}
	}

	if (op == ODIV || op == OMOD) && Isconst(r, CTINT) {
		if mpcmpfixc(r.Val.U.Xval, 0) == 0 {
			Yyerror("division by zero")
			goto error
		}
	}

	n.Type = t
	goto ret

shift:
	defaultlit(&r, Types[TUINT])
	n.Right = r
	t = r.Type
	if Isint[t.Etype] == 0 || Issigned[t.Etype] != 0 {
		Yyerror("invalid operation: %v (shift count type %v, must be unsigned integer)", Nconv(n, 0), Tconv(r.Type, 0))
		goto error
	}

	t = l.Type
	if t != nil && t.Etype != TIDEAL && Isint[t.Etype] == 0 {
		Yyerror("invalid operation: %v (shift of type %v)", Nconv(n, 0), Tconv(t, 0))
		goto error
	}

	// no defaultlit for left
	// the outer context gives the type
	n.Type = l.Type

	goto ret

doconv:
	ok |= Erv
	saveorignode(n)
	typecheck(&n.Left, Erv|top&(Eindir|Eiota))
	convlit1(&n.Left, n.Type, true)
	t = n.Left.Type
	if t == nil || n.Type == nil {
		goto error
	}
	n.Op = uint8(convertop(t, n.Type, &why))
	if (n.Op) == 0 {
		if n.Diag == 0 && n.Type.Broke == 0 {
			Yyerror("cannot convert %v to type %v%s", Nconv(n.Left, obj.FmtLong), Tconv(n.Type, 0), why)
			n.Diag = 1
		}

		n.Op = OCONV
	}

	switch n.Op {
	case OCONVNOP:
		if n.Left.Op == OLITERAL && n.Type != Types[TBOOL] {
			r := Nod(OXXX, nil, nil)
			n.Op = OCONV
			n.Orig = r
			*r = *n
			n.Op = OLITERAL
			n.Val = n.Left.Val
		}

		// do not use stringtoarraylit.
	// generated code and compiler memory footprint is better without it.
	case OSTRARRAYBYTE:
		break

	case OSTRARRAYRUNE:
		if n.Left.Op == OLITERAL {
			stringtoarraylit(&n)
		}
	}

	goto ret

ret:
	t = n.Type
	if t != nil && t.Funarg == 0 && n.Op != OTYPE {
		switch t.Etype {
		case TFUNC, // might have TANY; wait until its called
			TANY,
			TFORW,
			TIDEAL,
			TNIL,
			TBLANK:
			break

		default:
			checkwidth(t)
		}
	}

	if safemode != 0 && incannedimport == 0 && importpkg == nil && compiling_wrappers == 0 && t != nil && t.Etype == TUNSAFEPTR {
		Yyerror("cannot use unsafe.Pointer")
	}

	evconst(n)
	if n.Op == OTYPE && top&Etype == 0 {
		Yyerror("type %v is not an expression", Tconv(n.Type, 0))
		goto error
	}

	if top&(Erv|Etype) == Etype && n.Op != OTYPE {
		Yyerror("%v is not a type", Nconv(n, 0))
		goto error
	}

	// TODO(rsc): simplify
	if (top&(Ecall|Erv|Etype) != 0) && top&Etop == 0 && ok&(Erv|Etype|Ecall) == 0 {
		Yyerror("%v used as value", Nconv(n, 0))
		goto error
	}

	if (top&Etop != 0) && top&(Ecall|Erv|Etype) == 0 && ok&Etop == 0 {
		if n.Diag == 0 {
			Yyerror("%v evaluated but not used", Nconv(n, 0))
			n.Diag = 1
		}

		goto error
	}

	/* TODO
	if(n->type == T)
		fatal("typecheck nil type");
	*/
	goto out

badcall1:
	Yyerror("invalid argument %v for %v", Nconv(n.Left, obj.FmtLong), Oconv(int(n.Op), 0))
	goto error

error:
	n.Type = nil

out:
	*np = n
}

func checksliceindex(l *Node, r *Node, tp *Type) int {
	t := r.Type
	if t == nil {
		return -1
	}
	if Isint[t.Etype] == 0 {
		Yyerror("invalid slice index %v (type %v)", Nconv(r, 0), Tconv(t, 0))
		return -1
	}

	if r.Op == OLITERAL {
		if Mpgetfix(r.Val.U.Xval) < 0 {
			Yyerror("invalid slice index %v (index must be non-negative)", Nconv(r, 0))
			return -1
		} else if tp != nil && tp.Bound > 0 && Mpgetfix(r.Val.U.Xval) > tp.Bound {
			Yyerror("invalid slice index %v (out of bounds for %d-element array)", Nconv(r, 0), tp.Bound)
			return -1
		} else if Isconst(l, CTSTR) && Mpgetfix(r.Val.U.Xval) > int64(len(l.Val.U.Sval.S)) {
			Yyerror("invalid slice index %v (out of bounds for %d-byte string)", Nconv(r, 0), len(l.Val.U.Sval.S))
			return -1
		} else if Mpcmpfixfix(r.Val.U.Xval, Maxintval[TINT]) > 0 {
			Yyerror("invalid slice index %v (index too large)", Nconv(r, 0))
			return -1
		}
	}

	return 0
}

func checksliceconst(lo *Node, hi *Node) int {
	if lo != nil && hi != nil && lo.Op == OLITERAL && hi.Op == OLITERAL && Mpcmpfixfix(lo.Val.U.Xval, hi.Val.U.Xval) > 0 {
		Yyerror("invalid slice index: %v > %v", Nconv(lo, 0), Nconv(hi, 0))
		return -1
	}

	return 0
}

func checkdefergo(n *Node) {
	what := "defer"
	if n.Op == OPROC {
		what = "go"
	}

	switch n.Left.Op {
	// ok
	case OCALLINTER,
		OCALLMETH,
		OCALLFUNC,
		OCLOSE,
		OCOPY,
		ODELETE,
		OPANIC,
		OPRINT,
		OPRINTN,
		ORECOVER:
		return

	case OAPPEND,
		OCAP,
		OCOMPLEX,
		OIMAG,
		OLEN,
		OMAKE,
		OMAKESLICE,
		OMAKECHAN,
		OMAKEMAP,
		ONEW,
		OREAL,
		OLITERAL: // conversion or unsafe.Alignof, Offsetof, Sizeof
		if n.Left.Orig != nil && n.Left.Orig.Op == OCONV {
			break
		}
		Yyerror("%s discards result of %v", what, Nconv(n.Left, 0))
		return
	}

	// type is broken or missing, most likely a method call on a broken type
	// we will warn about the broken type elsewhere. no need to emit a potentially confusing error
	if n.Left.Type == nil || n.Left.Type.Broke != 0 {
		return
	}

	if n.Diag == 0 {
		// The syntax made sure it was a call, so this must be
		// a conversion.
		n.Diag = 1

		Yyerror("%s requires function call, not conversion", what)
	}
}

func implicitstar(nn **Node) {
	// insert implicit * if needed for fixed array
	n := *nn

	t := n.Type
	if t == nil || Isptr[t.Etype] == 0 {
		return
	}
	t = t.Type
	if t == nil {
		return
	}
	if !Isfixedarray(t) {
		return
	}
	n = Nod(OIND, n, nil)
	n.Implicit = 1
	typecheck(&n, Erv)
	*nn = n
}

func onearg(n *Node, f string, args ...interface{}) int {
	if n.Left != nil {
		return 0
	}
	if n.List == nil {
		p := fmt.Sprintf(f, args...)
		Yyerror("missing argument to %s: %v", p, Nconv(n, 0))
		return -1
	}

	if n.List.Next != nil {
		p := fmt.Sprintf(f, args...)
		Yyerror("too many arguments to %s: %v", p, Nconv(n, 0))
		n.Left = n.List.N
		n.List = nil
		return -1
	}

	n.Left = n.List.N
	n.List = nil
	return 0
}

func twoarg(n *Node) int {
	if n.Left != nil {
		return 0
	}
	if n.List == nil {
		Yyerror("missing argument to %v - %v", Oconv(int(n.Op), 0), Nconv(n, 0))
		return -1
	}

	n.Left = n.List.N
	if n.List.Next == nil {
		Yyerror("missing argument to %v - %v", Oconv(int(n.Op), 0), Nconv(n, 0))
		n.List = nil
		return -1
	}

	if n.List.Next.Next != nil {
		Yyerror("too many arguments to %v - %v", Oconv(int(n.Op), 0), Nconv(n, 0))
		n.List = nil
		return -1
	}

	n.Right = n.List.Next.N
	n.List = nil
	return 0
}

func lookdot1(errnode *Node, s *Sym, t *Type, f *Type, dostrcmp int) *Type {
	r := (*Type)(nil)
	for ; f != nil; f = f.Down {
		if dostrcmp != 0 && f.Sym.Name == s.Name {
			return f
		}
		if f.Sym != s {
			continue
		}
		if r != nil {
			if errnode != nil {
				Yyerror("ambiguous selector %v", Nconv(errnode, 0))
			} else if Isptr[t.Etype] != 0 {
				Yyerror("ambiguous selector (%v).%v", Tconv(t, 0), Sconv(s, 0))
			} else {
				Yyerror("ambiguous selector %v.%v", Tconv(t, 0), Sconv(s, 0))
			}
			break
		}

		r = f
	}

	return r
}

func looktypedot(n *Node, t *Type, dostrcmp int) bool {
	s := n.Right.Sym

	if t.Etype == TINTER {
		f1 := lookdot1(n, s, t, t.Type, dostrcmp)
		if f1 == nil {
			return false
		}

		n.Right = methodname(n.Right, t)
		n.Xoffset = f1.Width
		n.Type = f1.Type
		n.Op = ODOTINTER
		return true
	}

	// Find the base type: methtype will fail if t
	// is not of the form T or *T.
	f2 := methtype(t, 0)

	if f2 == nil {
		return false
	}

	expandmeth(f2)
	f2 = lookdot1(n, s, f2, f2.Xmethod, dostrcmp)
	if f2 == nil {
		return false
	}

	// disallow T.m if m requires *T receiver
	if Isptr[getthisx(f2.Type).Type.Type.Etype] != 0 && Isptr[t.Etype] == 0 && f2.Embedded != 2 && !isifacemethod(f2.Type) {
		Yyerror("invalid method expression %v (needs pointer receiver: (*%v).%v)", Nconv(n, 0), Tconv(t, 0), Sconv(f2.Sym, obj.FmtShort))
		return false
	}

	n.Right = methodname(n.Right, t)
	n.Xoffset = f2.Width
	n.Type = f2.Type
	n.Op = ODOTMETH
	return true
}

func derefall(t *Type) *Type {
	for t != nil && int(t.Etype) == Tptr {
		t = t.Type
	}
	return t
}

func lookdot(n *Node, t *Type, dostrcmp int) bool {
	s := n.Right.Sym

	dowidth(t)
	f1 := (*Type)(nil)
	if t.Etype == TSTRUCT || t.Etype == TINTER {
		f1 = lookdot1(n, s, t, t.Type, dostrcmp)
	}

	f2 := (*Type)(nil)
	if n.Left.Type == t || n.Left.Type.Sym == nil {
		f2 = methtype(t, 0)
		if f2 != nil {
			// Use f2->method, not f2->xmethod: adddot has
			// already inserted all the necessary embedded dots.
			f2 = lookdot1(n, s, f2, f2.Method, dostrcmp)
		}
	}

	if f1 != nil {
		if f2 != nil {
			Yyerror("%v is both field and method", Sconv(n.Right.Sym, 0))
		}
		if f1.Width == BADWIDTH {
			Fatal("lookdot badwidth %v %p", Tconv(f1, 0), f1)
		}
		n.Xoffset = f1.Width
		n.Type = f1.Type
		n.Paramfld = f1
		if t.Etype == TINTER {
			if Isptr[n.Left.Type.Etype] != 0 {
				n.Left = Nod(OIND, n.Left, nil) // implicitstar
				n.Left.Implicit = 1
				typecheck(&n.Left, Erv)
			}

			n.Op = ODOTINTER
		}

		return true
	}

	if f2 != nil {
		tt := n.Left.Type
		dowidth(tt)
		rcvr := getthisx(f2.Type).Type.Type
		if !Eqtype(rcvr, tt) {
			if int(rcvr.Etype) == Tptr && Eqtype(rcvr.Type, tt) {
				checklvalue(n.Left, "call pointer method on")
				n.Left = Nod(OADDR, n.Left, nil)
				n.Left.Implicit = 1
				typecheck(&n.Left, Etype|Erv)
			} else if int(tt.Etype) == Tptr && int(rcvr.Etype) != Tptr && Eqtype(tt.Type, rcvr) {
				n.Left = Nod(OIND, n.Left, nil)
				n.Left.Implicit = 1
				typecheck(&n.Left, Etype|Erv)
			} else if int(tt.Etype) == Tptr && int(tt.Type.Etype) == Tptr && Eqtype(derefall(tt), derefall(rcvr)) {
				Yyerror("calling method %v with receiver %v requires explicit dereference", Nconv(n.Right, 0), Nconv(n.Left, obj.FmtLong))
				for int(tt.Etype) == Tptr {
					// Stop one level early for method with pointer receiver.
					if int(rcvr.Etype) == Tptr && int(tt.Type.Etype) != Tptr {
						break
					}
					n.Left = Nod(OIND, n.Left, nil)
					n.Left.Implicit = 1
					typecheck(&n.Left, Etype|Erv)
					tt = tt.Type
				}
			} else {
				Fatal("method mismatch: %v for %v", Tconv(rcvr, 0), Tconv(tt, 0))
			}
		}

		ll := n.Left
		for ll.Left != nil {
			ll = ll.Left
		}
		if ll.Implicit != 0 {
			if Isptr[ll.Type.Etype] != 0 && ll.Type.Sym != nil && ll.Type.Sym.Def != nil && ll.Type.Sym.Def.Op == OTYPE {
				// It is invalid to automatically dereference a named pointer type when selecting a method.
				// Make n->left == ll to clarify error message.
				n.Left = ll
				return false
			}
		}

		n.Right = methodname(n.Right, n.Left.Type)
		n.Xoffset = f2.Width
		n.Type = f2.Type

		//		print("lookdot found [%p] %T\n", f2->type, f2->type);
		n.Op = ODOTMETH

		return true
	}

	return false
}

func nokeys(l *NodeList) bool {
	for ; l != nil; l = l.Next {
		if l.N.Op == OKEY {
			return false
		}
	}
	return true
}

func hasddd(t *Type) bool {
	for tl := t.Type; tl != nil; tl = tl.Down {
		if tl.Isddd != 0 {
			return true
		}
	}

	return false
}

func downcount(t *Type) int {
	n := 0
	for tl := t.Type; tl != nil; tl = tl.Down {
		n++
	}

	return n
}

/*
 * typecheck assignment: type list = expression list
 */
func typecheckaste(op int, call *Node, isddd int, tstruct *Type, nl *NodeList, desc string) {
	var t *Type
	var n *Node
	var n1 int
	var n2 int

	lno := int(lineno)

	if tstruct.Broke != 0 {
		goto out
	}

	n = nil
	if nl != nil && nl.Next == nil {
		n = nl.N
		if n.Type != nil {
			if n.Type.Etype == TSTRUCT && n.Type.Funarg != 0 {
				if !hasddd(tstruct) {
					n1 := downcount(tstruct)
					n2 := downcount(n.Type)
					if n2 > n1 {
						goto toomany
					}
					if n2 < n1 {
						goto notenough
					}
				}

				tn := n.Type.Type
				var why string
				for tl := tstruct.Type; tl != nil; tl = tl.Down {
					if tl.Isddd != 0 {
						for ; tn != nil; tn = tn.Down {
							if assignop(tn.Type, tl.Type.Type, &why) == 0 {
								if call != nil {
									Yyerror("cannot use %v as type %v in argument to %v%s", Tconv(tn.Type, 0), Tconv(tl.Type.Type, 0), Nconv(call, 0), why)
								} else {
									Yyerror("cannot use %v as type %v in %s%s", Tconv(tn.Type, 0), Tconv(tl.Type.Type, 0), desc, why)
								}
							}
						}

						goto out
					}

					if tn == nil {
						goto notenough
					}
					if assignop(tn.Type, tl.Type, &why) == 0 {
						if call != nil {
							Yyerror("cannot use %v as type %v in argument to %v%s", Tconv(tn.Type, 0), Tconv(tl.Type, 0), Nconv(call, 0), why)
						} else {
							Yyerror("cannot use %v as type %v in %s%s", Tconv(tn.Type, 0), Tconv(tl.Type, 0), desc, why)
						}
					}

					tn = tn.Down
				}

				if tn != nil {
					goto toomany
				}
				goto out
			}
		}
	}

	n1 = downcount(tstruct)
	n2 = count(nl)
	if !hasddd(tstruct) {
		if n2 > n1 {
			goto toomany
		}
		if n2 < n1 {
			goto notenough
		}
	} else {
		if isddd == 0 {
			if n2 < n1-1 {
				goto notenough
			}
		} else {
			if n2 > n1 {
				goto toomany
			}
			if n2 < n1 {
				goto notenough
			}
		}
	}

	for tl := tstruct.Type; tl != nil; tl = tl.Down {
		t = tl.Type
		if tl.Isddd != 0 {
			if isddd != 0 {
				if nl == nil {
					goto notenough
				}
				if nl.Next != nil {
					goto toomany
				}
				n = nl.N
				setlineno(n)
				if n.Type != nil {
					nl.N = assignconv(n, t, desc)
				}
				goto out
			}

			for ; nl != nil; nl = nl.Next {
				n = nl.N
				setlineno(nl.N)
				if n.Type != nil {
					nl.N = assignconv(n, t.Type, desc)
				}
			}

			goto out
		}

		if nl == nil {
			goto notenough
		}
		n = nl.N
		setlineno(n)
		if n.Type != nil {
			nl.N = assignconv(n, t, desc)
		}
		nl = nl.Next
	}

	if nl != nil {
		goto toomany
	}
	if isddd != 0 {
		if call != nil {
			Yyerror("invalid use of ... in call to %v", Nconv(call, 0))
		} else {
			Yyerror("invalid use of ... in %v", Oconv(int(op), 0))
		}
	}

out:
	lineno = int32(lno)
	return

notenough:
	if n == nil || n.Diag == 0 {
		if call != nil {
			Yyerror("not enough arguments in call to %v", Nconv(call, 0))
		} else {
			Yyerror("not enough arguments to %v", Oconv(int(op), 0))
		}
		if n != nil {
			n.Diag = 1
		}
	}

	goto out

toomany:
	if call != nil {
		Yyerror("too many arguments in call to %v", Nconv(call, 0))
	} else {
		Yyerror("too many arguments to %v", Oconv(int(op), 0))
	}
	goto out
}

/*
 * type check composite
 */
func fielddup(n *Node, hash []*Node) {
	if n.Op != ONAME {
		Fatal("fielddup: not ONAME")
	}
	s := n.Sym.Name
	h := uint(stringhash(s) % uint32(len(hash)))
	for a := hash[h]; a != nil; a = a.Ntest {
		if a.Sym.Name == s {
			Yyerror("duplicate field name in struct literal: %s", s)
			return
		}
	}

	n.Ntest = hash[h]
	hash[h] = n
}

func keydup(n *Node, hash []*Node) {
	orign := n
	if n.Op == OCONVIFACE {
		n = n.Left
	}
	evconst(n)
	if n.Op != OLITERAL {
		return // we dont check variables
	}

	var b uint32
	switch n.Val.Ctype {
	default: // unknown, bool, nil
		b = 23

	case CTINT,
		CTRUNE:
		b = uint32(Mpgetfix(n.Val.U.Xval))

	case CTFLT:
		d := mpgetflt(n.Val.U.Fval)
		x := math.Float64bits(d)
		for i := 0; i < 8; i++ {
			b = b*PRIME1 + uint32(x&0xFF)
			x >>= 8
		}

	case CTSTR:
		b = 0
		s := n.Val.U.Sval.S
		for i := len(n.Val.U.Sval.S); i > 0; i-- {
			b = b*PRIME1 + uint32(s[0])
			s = s[1:]
		}
	}

	h := uint(b % uint32(len(hash)))
	cmp := Node{}
	for a := hash[h]; a != nil; a = a.Ntest {
		cmp.Op = OEQ
		cmp.Left = n
		b = 0
		if a.Op == OCONVIFACE && orign.Op == OCONVIFACE {
			if Eqtype(a.Left.Type, n.Type) {
				cmp.Right = a.Left
				evconst(&cmp)
				b = uint32(cmp.Val.U.Bval)
			}
		} else if Eqtype(a.Type, n.Type) {
			cmp.Right = a
			evconst(&cmp)
			b = uint32(cmp.Val.U.Bval)
		}

		if b != 0 {
			Yyerror("duplicate key %v in map literal", Nconv(n, 0))
			return
		}
	}

	orign.Ntest = hash[h]
	hash[h] = orign
}

func indexdup(n *Node, hash []*Node) {
	if n.Op != OLITERAL {
		Fatal("indexdup: not OLITERAL")
	}

	b := uint32(Mpgetfix(n.Val.U.Xval))
	h := uint(b % uint32(len(hash)))
	var c uint32
	for a := hash[h]; a != nil; a = a.Ntest {
		c = uint32(Mpgetfix(a.Val.U.Xval))
		if b == c {
			Yyerror("duplicate index in array literal: %d", b)
			return
		}
	}

	n.Ntest = hash[h]
	hash[h] = n
}

func prime(h uint32, sr uint32) bool {
	for n := uint32(3); n <= sr; n += 2 {
		if h%n == 0 {
			return false
		}
	}
	return true
}

func inithash(n *Node, autohash []*Node) []*Node {
	// count the number of entries
	h := uint32(0)

	for ll := n.List; ll != nil; ll = ll.Next {
		h++
	}

	// if the auto hash table is
	// large enough use it.
	if h <= uint32(len(autohash)) {
		for i := range autohash {
			autohash[i] = nil
		}
		return autohash
	}

	// make hash size odd and 12% larger than entries
	h += h / 8

	h |= 1

	// calculate sqrt of h
	sr := h / 2

	for i := 0; i < 5; i++ {
		sr = (sr + h/sr) / 2
	}

	// check for primeality
	for !prime(h, sr) {
		h += 2
	}

	// build and return a throw-away hash table
	return make([]*Node, h)
}

func iscomptype(t *Type) bool {
	switch t.Etype {
	case TARRAY,
		TSTRUCT,
		TMAP:
		return true

	case TPTR32,
		TPTR64:
		switch t.Type.Etype {
		case TARRAY,
			TSTRUCT,
			TMAP:
			return true
		}
	}

	return false
}

func pushtype(n *Node, t *Type) {
	if n == nil || n.Op != OCOMPLIT || !iscomptype(t) {
		return
	}

	if n.Right == nil {
		n.Right = typenod(t)
		n.Implicit = 1       // don't print
		n.Right.Implicit = 1 // * is okay
	} else if Debug['s'] != 0 {
		typecheck(&n.Right, Etype)
		if n.Right.Type != nil && Eqtype(n.Right.Type, t) {
			fmt.Printf("%v: redundant type: %v\n", n.Line(), Tconv(t, 0))
		}
	}
}

func typecheckcomplit(np **Node) {
	var nerr int
	var l *Node
	var norig *Node
	var r *Node
	var t *Type

	n := *np
	lno := lineno

	if n.Right == nil {
		if n.List != nil {
			setlineno(n.List.N)
		}
		Yyerror("missing type in composite literal")
		goto error
	}

	// Save original node (including n->right)
	norig = Nod(int(n.Op), nil, nil)

	*norig = *n

	setlineno(n.Right)
	l = typecheck(&n.Right, Etype|Ecomplit) /* sic */
	t = l.Type
	if t == nil {
		goto error
	}
	nerr = nerrors
	n.Type = t

	if Isptr[t.Etype] != 0 {
		// For better or worse, we don't allow pointers as the composite literal type,
		// except when using the &T syntax, which sets implicit on the OIND.
		if n.Right.Implicit == 0 {
			Yyerror("invalid pointer type %v for composite literal (use &%v instead)", Tconv(t, 0), Tconv(t.Type, 0))
			goto error
		}

		// Also, the underlying type must be a struct, map, slice, or array.
		if !iscomptype(t) {
			Yyerror("invalid pointer type %v for composite literal", Tconv(t, 0))
			goto error
		}

		t = t.Type
	}

	switch t.Etype {
	default:
		Yyerror("invalid type for composite literal: %v", Tconv(t, 0))
		n.Type = nil

	case TARRAY:
		var autohash [101]*Node
		hash := inithash(n, autohash[:])

		length := int64(0)
		i := 0
		var l *Node
		for ll := n.List; ll != nil; ll = ll.Next {
			l = ll.N
			setlineno(l)
			if l.Op != OKEY {
				l = Nod(OKEY, Nodintconst(int64(i)), l)
				l.Left.Type = Types[TINT]
				l.Left.Typecheck = 1
				ll.N = l
			}

			typecheck(&l.Left, Erv)
			evconst(l.Left)
			i = nonnegconst(l.Left)
			if i < 0 && l.Left.Diag == 0 {
				Yyerror("array index must be non-negative integer constant")
				l.Left.Diag = 1
				i = -(1 << 30) // stay negative for a while
			}

			if i >= 0 {
				indexdup(l.Left, hash)
			}
			i++
			if int64(i) > length {
				length = int64(i)
				if t.Bound >= 0 && length > t.Bound {
					setlineno(l)
					Yyerror("array index %d out of bounds [0:%d]", length-1, t.Bound)
					t.Bound = -1 // no more errors
				}
			}

			r = l.Right
			pushtype(r, t.Type)
			typecheck(&r, Erv)
			defaultlit(&r, t.Type)
			l.Right = assignconv(r, t.Type, "array element")
		}

		if t.Bound == -100 {
			t.Bound = length
		}
		if t.Bound < 0 {
			n.Right = Nodintconst(length)
		}
		n.Op = OARRAYLIT

	case TMAP:
		var autohash [101]*Node
		hash := inithash(n, autohash[:])

		var l *Node
		for ll := n.List; ll != nil; ll = ll.Next {
			l = ll.N
			setlineno(l)
			if l.Op != OKEY {
				typecheck(&ll.N, Erv)
				Yyerror("missing key in map literal")
				continue
			}

			typecheck(&l.Left, Erv)
			defaultlit(&l.Left, t.Down)
			l.Left = assignconv(l.Left, t.Down, "map key")
			if l.Left.Op != OCONV {
				keydup(l.Left, hash)
			}

			r = l.Right
			pushtype(r, t.Type)
			typecheck(&r, Erv)
			defaultlit(&r, t.Type)
			l.Right = assignconv(r, t.Type, "map value")
		}

		n.Op = OMAPLIT

	case TSTRUCT:
		bad := 0
		if n.List != nil && nokeys(n.List) {
			// simple list of variables
			f := t.Type

			var s *Sym
			for ll := n.List; ll != nil; ll = ll.Next {
				setlineno(ll.N)
				typecheck(&ll.N, Erv)
				if f == nil {
					tmp12 := bad
					bad++
					if tmp12 == 0 {
						Yyerror("too many values in struct initializer")
					}
					continue
				}

				s = f.Sym
				if s != nil && !exportname(s.Name) && s.Pkg != localpkg {
					Yyerror("implicit assignment of unexported field '%s' in %v literal", s.Name, Tconv(t, 0))
				}

				// No pushtype allowed here.  Must name fields for that.
				ll.N = assignconv(ll.N, f.Type, "field value")

				ll.N = Nod(OKEY, newname(f.Sym), ll.N)
				ll.N.Left.Type = f
				ll.N.Left.Typecheck = 1
				f = f.Down
			}

			if f != nil {
				Yyerror("too few values in struct initializer")
			}
		} else {
			var autohash [101]*Node
			hash := inithash(n, autohash[:])

			// keyed list
			var s *Sym
			var f *Type
			var l *Node
			var s1 *Sym
			for ll := n.List; ll != nil; ll = ll.Next {
				l = ll.N
				setlineno(l)
				if l.Op != OKEY {
					tmp13 := bad
					bad++
					if tmp13 == 0 {
						Yyerror("mixture of field:value and value initializers")
					}
					typecheck(&ll.N, Erv)
					continue
				}

				s = l.Left.Sym
				if s == nil {
					Yyerror("invalid field name %v in struct initializer", Nconv(l.Left, 0))
					typecheck(&l.Right, Erv)
					continue
				}

				// Sym might have resolved to name in other top-level
				// package, because of import dot.  Redirect to correct sym
				// before we do the lookup.
				if s.Pkg != localpkg && exportname(s.Name) {
					s1 = Lookup(s.Name)
					if s1.Origpkg == s.Pkg {
						s = s1
					}
				}

				f = lookdot1(nil, s, t, t.Type, 0)
				if f == nil {
					Yyerror("unknown %v field '%v' in struct literal", Tconv(t, 0), Sconv(s, 0))
					continue
				}

				l.Left = newname(s)
				l.Left.Typecheck = 1
				l.Left.Type = f
				s = f.Sym
				fielddup(newname(s), hash)
				r = l.Right

				// No pushtype allowed here.  Tried and rejected.
				typecheck(&r, Erv)

				l.Right = assignconv(r, f.Type, "field value")
			}
		}

		n.Op = OSTRUCTLIT
	}

	if nerr != nerrors {
		goto error
	}

	n.Orig = norig
	if Isptr[n.Type.Etype] != 0 {
		n = Nod(OPTRLIT, n, nil)
		n.Typecheck = 1
		n.Type = n.Left.Type
		n.Left.Type = t
		n.Left.Typecheck = 1
	}

	n.Orig = norig
	*np = n
	lineno = lno
	return

error:
	n.Type = nil
	*np = n
	lineno = lno
}

/*
 * lvalue etc
 */
func islvalue(n *Node) bool {
	switch n.Op {
	case OINDEX:
		if Isfixedarray(n.Left.Type) {
			return islvalue(n.Left)
		}
		if n.Left.Type != nil && n.Left.Type.Etype == TSTRING {
			return false
		}
		fallthrough

		// fall through
	case OIND,
		ODOTPTR,
		OCLOSUREVAR,
		OPARAM:
		return true

	case ODOT:
		return islvalue(n.Left)

	case ONAME:
		if n.Class == PFUNC {
			return false
		}
		return true
	}

	return false
}

func checklvalue(n *Node, verb string) {
	if !islvalue(n) {
		Yyerror("cannot %s %v", verb, Nconv(n, 0))
	}
}

func checkassign(stmt *Node, n *Node) {
	// Variables declared in ORANGE are assigned on every iteration.
	if n.Defn != stmt || stmt.Op == ORANGE {
		r := outervalue(n)
		var l *Node
		for l = n; l != r; l = l.Left {
			l.Assigned = 1
			if l.Closure != nil {
				l.Closure.Assigned = 1
			}
		}

		l.Assigned = 1
		if l.Closure != nil {
			l.Closure.Assigned = 1
		}
	}

	if islvalue(n) {
		return
	}
	if n.Op == OINDEXMAP {
		n.Etype = 1
		return
	}

	// have already complained about n being undefined
	if n.Op == ONONAME {
		return
	}

	Yyerror("cannot assign to %v", Nconv(n, 0))
}

func checkassignlist(stmt *Node, l *NodeList) {
	for ; l != nil; l = l.Next {
		checkassign(stmt, l.N)
	}
}

// Check whether l and r are the same side effect-free expression,
// so that it is safe to reuse one instead of computing both.
func samesafeexpr(l *Node, r *Node) bool {
	if l.Op != r.Op || !Eqtype(l.Type, r.Type) {
		return false
	}

	switch l.Op {
	case ONAME,
		OCLOSUREVAR:
		return l == r

	case ODOT,
		ODOTPTR:
		return l.Right != nil && r.Right != nil && l.Right.Sym == r.Right.Sym && samesafeexpr(l.Left, r.Left)

	case OIND:
		return samesafeexpr(l.Left, r.Left)

	case OINDEX:
		return samesafeexpr(l.Left, r.Left) && samesafeexpr(l.Right, r.Right)
	}

	return false
}

/*
 * type check assignment.
 * if this assignment is the definition of a var on the left side,
 * fill in the var's type.
 */
func typecheckas(n *Node) {
	// delicate little dance.
	// the definition of n may refer to this assignment
	// as its definition, in which case it will call typecheckas.
	// in that case, do not call typecheck back, or it will cycle.
	// if the variable has a type (ntype) then typechecking
	// will not look at defn, so it is okay (and desirable,
	// so that the conversion below happens).
	n.Left = resolve(n.Left)

	if n.Left.Defn != n || n.Left.Ntype != nil {
		typecheck(&n.Left, Erv|Easgn)
	}

	typecheck(&n.Right, Erv)
	checkassign(n, n.Left)
	if n.Right != nil && n.Right.Type != nil {
		if n.Left.Type != nil {
			n.Right = assignconv(n.Right, n.Left.Type, "assignment")
		}
	}

	if n.Left.Defn == n && n.Left.Ntype == nil {
		defaultlit(&n.Right, nil)
		n.Left.Type = n.Right.Type
	}

	// second half of dance.
	// now that right is done, typecheck the left
	// just to get it over with.  see dance above.
	n.Typecheck = 1

	if n.Left.Typecheck == 0 {
		typecheck(&n.Left, Erv|Easgn)
	}

	// Recognize slices being updated in place, for better code generation later.
	// Don't rewrite if using race detector, to avoid needing to teach race detector
	// about this optimization.
	if n.Left != nil && n.Left.Op != OINDEXMAP && n.Right != nil && flag_race == 0 {
		switch n.Right.Op {
		// For x = x[0:y], x can be updated in place, without touching pointer.
		// TODO(rsc): Reenable once it is actually updated in place without touching the pointer.
		case OSLICE,
			OSLICE3,
			OSLICESTR:
			if false && samesafeexpr(n.Left, n.Right.Left) && (n.Right.Right.Left == nil || iszero(n.Right.Right.Left)) {
				n.Right.Reslice = 1
			}

			// For x = append(x, ...), x can be updated in place when there is capacity,
		// without touching the pointer; otherwise the emitted code to growslice
		// can take care of updating the pointer, and only in that case.
		// TODO(rsc): Reenable once the emitted code does update the pointer.
		case OAPPEND:
			if false && n.Right.List != nil && samesafeexpr(n.Left, n.Right.List.N) {
				n.Right.Reslice = 1
			}
		}
	}
}

func checkassignto(src *Type, dst *Node) {
	var why string

	if assignop(src, dst.Type, &why) == 0 {
		Yyerror("cannot assign %v to %v in multiple assignment%s", Tconv(src, 0), Nconv(dst, obj.FmtLong), why)
		return
	}
}

func typecheckas2(n *Node) {
	var ll *NodeList
	var lr *NodeList

	for ll = n.List; ll != nil; ll = ll.Next {
		// delicate little dance.
		ll.N = resolve(ll.N)

		if ll.N.Defn != n || ll.N.Ntype != nil {
			typecheck(&ll.N, Erv|Easgn)
		}
	}

	cl := count(n.List)
	cr := count(n.Rlist)
	if cl > 1 && cr == 1 {
		typecheck(&n.Rlist.N, Erv|Efnstruct)
	} else {
		typechecklist(n.Rlist, Erv)
	}
	checkassignlist(n, n.List)

	var l *Node
	var r *Node
	if cl == cr {
		// easy
		ll = n.List
		lr = n.Rlist
		for ; ll != nil; (func() { ll = ll.Next; lr = lr.Next })() {
			if ll.N.Type != nil && lr.N.Type != nil {
				lr.N = assignconv(lr.N, ll.N.Type, "assignment")
			}
			if ll.N.Defn == n && ll.N.Ntype == nil {
				defaultlit(&lr.N, nil)
				ll.N.Type = lr.N.Type
			}
		}

		goto out
	}

	l = n.List.N
	r = n.Rlist.N

	// x,y,z = f()
	if cr == 1 {
		if r.Type == nil {
			goto out
		}
		switch r.Op {
		case OCALLMETH,
			OCALLINTER,
			OCALLFUNC:
			if r.Type.Etype != TSTRUCT || r.Type.Funarg == 0 {
				break
			}
			cr = structcount(r.Type)
			if cr != cl {
				goto mismatch
			}
			n.Op = OAS2FUNC
			var s Iter
			t := Structfirst(&s, &r.Type)
			for ll = n.List; ll != nil; ll = ll.Next {
				if t.Type != nil && ll.N.Type != nil {
					checkassignto(t.Type, ll.N)
				}
				if ll.N.Defn == n && ll.N.Ntype == nil {
					ll.N.Type = t.Type
				}
				t = structnext(&s)
			}

			goto out
		}
	}

	// x, ok = y
	if cl == 2 && cr == 1 {
		if r.Type == nil {
			goto out
		}
		switch r.Op {
		case OINDEXMAP,
			ORECV,
			ODOTTYPE:
			switch r.Op {
			case OINDEXMAP:
				n.Op = OAS2MAPR

			case ORECV:
				n.Op = OAS2RECV

			case ODOTTYPE:
				n.Op = OAS2DOTTYPE
				r.Op = ODOTTYPE2
			}

			if l.Type != nil {
				checkassignto(r.Type, l)
			}
			if l.Defn == n {
				l.Type = r.Type
			}
			l := n.List.Next.N
			if l.Type != nil && l.Type.Etype != TBOOL {
				checkassignto(Types[TBOOL], l)
			}
			if l.Defn == n && l.Ntype == nil {
				l.Type = Types[TBOOL]
			}
			goto out
		}
	}

mismatch:
	Yyerror("assignment count mismatch: %d = %d", cl, cr)

	// second half of dance
out:
	n.Typecheck = 1

	for ll = n.List; ll != nil; ll = ll.Next {
		if ll.N.Typecheck == 0 {
			typecheck(&ll.N, Erv|Easgn)
		}
	}
}

/*
 * type check function definition
 */
func typecheckfunc(n *Node) {
	typecheck(&n.Nname, Erv|Easgn)
	t := n.Nname.Type
	if t == nil {
		return
	}
	n.Type = t
	t.Nname = n.Nname
	rcvr := getthisx(t).Type
	if rcvr != nil && n.Shortname != nil && !isblank(n.Shortname) {
		addmethod(n.Shortname.Sym, t, true, n.Nname.Nointerface)
	}

	for l := n.Dcl; l != nil; l = l.Next {
		if l.N.Op == ONAME && (l.N.Class == PPARAM || l.N.Class == PPARAMOUT) {
			l.N.Decldepth = 1
		}
	}
}

func stringtoarraylit(np **Node) {
	n := *np
	if n.Left.Op != OLITERAL || n.Left.Val.Ctype != CTSTR {
		Fatal("stringtoarraylit %N", n)
	}

	s := n.Left.Val.U.Sval.S
	var l *NodeList
	if n.Type.Type.Etype == TUINT8 {
		// []byte
		for i := 0; i < len(s); i++ {
			l = list(l, Nod(OKEY, Nodintconst(int64(i)), Nodintconst(int64(s[0]))))
		}
	} else {
		// []rune
		i := 0
		for _, r := range s {
			l = list(l, Nod(OKEY, Nodintconst(int64(i)), Nodintconst(int64(r))))
			i++
		}
	}

	nn := Nod(OCOMPLIT, nil, typenod(n.Type))
	nn.List = l
	typecheck(&nn, Erv)
	*np = nn
}

var ntypecheckdeftype int

var methodqueue *NodeList

func domethod(n *Node) {
	nt := n.Type.Nname
	typecheck(&nt, Etype)
	if nt.Type == nil {
		// type check failed; leave empty func
		n.Type.Etype = TFUNC

		n.Type.Nod = nil
		return
	}

	// If we have
	//	type I interface {
	//		M(_ int)
	//	}
	// then even though I.M looks like it doesn't care about the
	// value of its argument, a specific implementation of I may
	// care.  The _ would suppress the assignment to that argument
	// while generating a call, so remove it.
	for t := getinargx(nt.Type).Type; t != nil; t = t.Down {
		if t.Sym != nil && t.Sym.Name == "_" {
			t.Sym = nil
		}
	}

	*n.Type = *nt.Type
	n.Type.Nod = nil
	checkwidth(n.Type)
}

var mapqueue *NodeList

func copytype(n *Node, t *Type) {
	if t.Etype == TFORW {
		// This type isn't computed yet; when it is, update n.
		t.Copyto = list(t.Copyto, n)

		return
	}

	maplineno := int(n.Type.Maplineno)
	embedlineno := int(n.Type.Embedlineno)

	l := n.Type.Copyto
	*n.Type = *t

	t = n.Type
	t.Sym = n.Sym
	t.Local = n.Local
	t.Vargen = n.Vargen
	t.Siggen = 0
	t.Method = nil
	t.Xmethod = nil
	t.Nod = nil
	t.Printed = 0
	t.Deferwidth = 0
	t.Copyto = nil

	// Update nodes waiting on this type.
	for ; l != nil; l = l.Next {
		copytype(l.N, t)
	}

	// Double-check use of type as embedded type.
	lno := int(lineno)

	if embedlineno != 0 {
		lineno = int32(embedlineno)
		if Isptr[t.Etype] != 0 {
			Yyerror("embedded type cannot be a pointer")
		}
	}

	lineno = int32(lno)

	// Queue check for map until all the types are done settling.
	if maplineno != 0 {
		t.Maplineno = int32(maplineno)
		mapqueue = list(mapqueue, n)
	}
}

func typecheckdeftype(n *Node) {
	ntypecheckdeftype++
	lno := int(lineno)
	setlineno(n)
	n.Type.Sym = n.Sym
	n.Typecheck = 1
	typecheck(&n.Ntype, Etype)
	t := n.Ntype.Type
	if t == nil {
		n.Diag = 1
		n.Type = nil
		goto ret
	}

	if n.Type == nil {
		n.Diag = 1
		goto ret
	}

	// copy new type and clear fields
	// that don't come along.
	// anything zeroed here must be zeroed in
	// typedcl2 too.
	copytype(n, t)

ret:
	lineno = int32(lno)

	// if there are no type definitions going on, it's safe to
	// try to resolve the method types for the interfaces
	// we just read.
	if ntypecheckdeftype == 1 {
		var l *NodeList
		for {
			l = methodqueue
			if l == nil {
				break
			}
			methodqueue = nil
			for ; l != nil; l = l.Next {
				domethod(l.N)
			}
		}

		for l := mapqueue; l != nil; l = l.Next {
			lineno = l.N.Type.Maplineno
			maptype(l.N.Type, Types[TBOOL])
		}

		lineno = int32(lno)
	}

	ntypecheckdeftype--
}

func queuemethod(n *Node) {
	if ntypecheckdeftype == 0 {
		domethod(n)
		return
	}

	methodqueue = list(methodqueue, n)
}

func typecheckdef(n *Node) *Node {
	lno := int(lineno)
	setlineno(n)

	if n.Op == ONONAME {
		if n.Diag == 0 {
			n.Diag = 1
			if n.Lineno != 0 {
				lineno = n.Lineno
			}

			// Note: adderrorname looks for this string and
			// adds context about the outer expression
			Yyerror("undefined: %v", Sconv(n.Sym, 0))
		}

		return n
	}

	if n.Walkdef == 1 {
		return n
	}

	l := new(NodeList)
	l.N = n
	l.Next = typecheckdefstack
	typecheckdefstack = l

	if n.Walkdef == 2 {
		Flusherrors()
		fmt.Printf("typecheckdef loop:")
		for l := typecheckdefstack; l != nil; l = l.Next {
			fmt.Printf(" %v", Sconv(l.N.Sym, 0))
		}
		fmt.Printf("\n")
		Fatal("typecheckdef loop")
	}

	n.Walkdef = 2

	if n.Type != nil || n.Sym == nil { // builtin or no name
		goto ret
	}

	switch n.Op {
	default:
		Fatal("typecheckdef %v", Oconv(int(n.Op), 0))

		// not really syms
	case OGOTO,
		OLABEL:
		break

	case OLITERAL:
		if n.Ntype != nil {
			typecheck(&n.Ntype, Etype)
			n.Type = n.Ntype.Type
			n.Ntype = nil
			if n.Type == nil {
				n.Diag = 1
				goto ret
			}
		}

		e := n.Defn
		n.Defn = nil
		if e == nil {
			lineno = n.Lineno
			Dump("typecheckdef nil defn", n)
			Yyerror("xxx")
		}

		typecheck(&e, Erv|Eiota)
		if Isconst(e, CTNIL) {
			Yyerror("const initializer cannot be nil")
			goto ret
		}

		if e.Type != nil && e.Op != OLITERAL || !isgoconst(e) {
			if e.Diag == 0 {
				Yyerror("const initializer %v is not a constant", Nconv(e, 0))
				e.Diag = 1
			}

			goto ret
		}

		t := n.Type
		if t != nil {
			if okforconst[t.Etype] == 0 {
				Yyerror("invalid constant type %v", Tconv(t, 0))
				goto ret
			}

			if !isideal(e.Type) && !Eqtype(t, e.Type) {
				Yyerror("cannot use %v as type %v in const initializer", Nconv(e, obj.FmtLong), Tconv(t, 0))
				goto ret
			}

			Convlit(&e, t)
		}

		n.Val = e.Val
		n.Type = e.Type

	case ONAME:
		if n.Ntype != nil {
			typecheck(&n.Ntype, Etype)
			n.Type = n.Ntype.Type

			if n.Type == nil {
				n.Diag = 1
				goto ret
			}
		}

		if n.Type != nil {
			break
		}
		if n.Defn == nil {
			if n.Etype != 0 { // like OPRINTN
				break
			}
			if nsavederrors+nerrors > 0 {
				// Can have undefined variables in x := foo
				// that make x have an n->ndefn == nil.
				// If there are other errors anyway, don't
				// bother adding to the noise.
				break
			}

			Fatal("var without type, init: %v", Sconv(n.Sym, 0))
		}

		if n.Defn.Op == ONAME {
			typecheck(&n.Defn, Erv)
			n.Type = n.Defn.Type
			break
		}

		typecheck(&n.Defn, Etop) // fills in n->type

	case OTYPE:
		if Curfn != nil {
			defercheckwidth()
		}
		n.Walkdef = 1
		n.Type = typ(TFORW)
		n.Type.Sym = n.Sym
		nerrors0 := nerrors
		typecheckdeftype(n)
		if n.Type.Etype == TFORW && nerrors > nerrors0 {
			// Something went wrong during type-checking,
			// but it was reported. Silence future errors.
			n.Type.Broke = 1
		}

		if Curfn != nil {
			resumecheckwidth()
		}

		// nothing to see here
	case OPACK:
		break
	}

ret:
	if n.Op != OLITERAL && n.Type != nil && isideal(n.Type) {
		Fatal("got %v for %v", Tconv(n.Type, 0), Nconv(n, 0))
	}
	if typecheckdefstack.N != n {
		Fatal("typecheckdefstack mismatch")
	}
	l = typecheckdefstack
	typecheckdefstack = l.Next

	lineno = int32(lno)
	n.Walkdef = 1
	return n
}

func checkmake(t *Type, arg string, n *Node) int {
	if n.Op == OLITERAL {
		switch n.Val.Ctype {
		case CTINT,
			CTRUNE,
			CTFLT,
			CTCPLX:
			n.Val = toint(n.Val)
			if mpcmpfixc(n.Val.U.Xval, 0) < 0 {
				Yyerror("negative %s argument in make(%v)", arg, Tconv(t, 0))
				return -1
			}

			if Mpcmpfixfix(n.Val.U.Xval, Maxintval[TINT]) > 0 {
				Yyerror("%s argument too large in make(%v)", arg, Tconv(t, 0))
				return -1
			}

			// Delay defaultlit until after we've checked range, to avoid
			// a redundant "constant NNN overflows int" error.
			defaultlit(&n, Types[TINT])

			return 0

		default:
			break
		}
	}

	if Isint[n.Type.Etype] == 0 && n.Type.Etype != TIDEAL {
		Yyerror("non-integer %s argument in make(%v) - %v", arg, Tconv(t, 0), Tconv(n.Type, 0))
		return -1
	}

	// Defaultlit still necessary for non-constant: n might be 1<<k.
	defaultlit(&n, Types[TINT])

	return 0
}

func markbreak(n *Node, implicit *Node) {
	if n == nil {
		return
	}

	switch n.Op {
	case OBREAK:
		if n.Left == nil {
			if implicit != nil {
				implicit.Hasbreak = 1
			}
		} else {
			lab := n.Left.Sym.Label
			if lab != nil {
				lab.Def.Hasbreak = 1
			}
		}

	case OFOR,
		OSWITCH,
		OTYPESW,
		OSELECT,
		ORANGE:
		implicit = n
		fallthrough

		// fall through
	default:
		markbreak(n.Left, implicit)

		markbreak(n.Right, implicit)
		markbreak(n.Ntest, implicit)
		markbreak(n.Nincr, implicit)
		markbreaklist(n.Ninit, implicit)
		markbreaklist(n.Nbody, implicit)
		markbreaklist(n.Nelse, implicit)
		markbreaklist(n.List, implicit)
		markbreaklist(n.Rlist, implicit)
	}
}

func markbreaklist(l *NodeList, implicit *Node) {
	var n *Node
	var lab *Label

	for ; l != nil; l = l.Next {
		n = l.N
		if n.Op == OLABEL && l.Next != nil && n.Defn == l.Next.N {
			switch n.Defn.Op {
			case OFOR,
				OSWITCH,
				OTYPESW,
				OSELECT,
				ORANGE:
				lab = new(Label)
				lab.Def = n.Defn
				n.Left.Sym.Label = lab
				markbreak(n.Defn, n.Defn)
				n.Left.Sym.Label = nil
				l = l.Next
				continue
			}
		}

		markbreak(n, implicit)
	}
}

func isterminating(l *NodeList, top int) bool {
	if l == nil {
		return false
	}
	if top != 0 {
		for l.Next != nil && l.N.Op != OLABEL {
			l = l.Next
		}
		markbreaklist(l, nil)
	}

	for l.Next != nil {
		l = l.Next
	}
	n := l.N

	if n == nil {
		return false
	}

	switch n.Op {
	// NOTE: OLABEL is treated as a separate statement,
	// not a separate prefix, so skipping to the last statement
	// in the block handles the labeled statement case by
	// skipping over the label. No case OLABEL here.

	case OBLOCK:
		return isterminating(n.List, 0)

	case OGOTO,
		ORETURN,
		ORETJMP,
		OPANIC,
		OXFALL:
		return true

	case OFOR:
		if n.Ntest != nil {
			return false
		}
		if n.Hasbreak != 0 {
			return false
		}
		return true

	case OIF:
		return isterminating(n.Nbody, 0) && isterminating(n.Nelse, 0)

	case OSWITCH,
		OTYPESW,
		OSELECT:
		if n.Hasbreak != 0 {
			return false
		}
		def := 0
		for l = n.List; l != nil; l = l.Next {
			if !isterminating(l.N.Nbody, 0) {
				return false
			}
			if l.N.List == nil { // default
				def = 1
			}
		}

		if n.Op != OSELECT && def == 0 {
			return false
		}
		return true
	}

	return false
}

func checkreturn(fn *Node) {
	if fn.Type.Outtuple != 0 && fn.Nbody != nil {
		if !isterminating(fn.Nbody, 1) {
			yyerrorl(int(fn.Endlineno), "missing return at end of function")
		}
	}
}
