// 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))
			}
		}

		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")
		}
	}
}
