...

Source file src/pkg/cmd/compile/internal/gc/typecheck.go

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

View as plain text