Black Lives Matter. Support the Equal Justice Initiative.

Source file src/cmd/compile/internal/typecheck/expr.go

Documentation: cmd/compile/internal/typecheck

     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 typecheck
     6  
     7  import (
     8  	"fmt"
     9  	"go/constant"
    10  	"go/token"
    11  	"strings"
    12  
    13  	"cmd/compile/internal/base"
    14  	"cmd/compile/internal/ir"
    15  	"cmd/compile/internal/types"
    16  )
    17  
    18  // tcAddr typechecks an OADDR node.
    19  func tcAddr(n *ir.AddrExpr) ir.Node {
    20  	n.X = Expr(n.X)
    21  	if n.X.Type() == nil {
    22  		n.SetType(nil)
    23  		return n
    24  	}
    25  
    26  	switch n.X.Op() {
    27  	case ir.OARRAYLIT, ir.OMAPLIT, ir.OSLICELIT, ir.OSTRUCTLIT:
    28  		n.SetOp(ir.OPTRLIT)
    29  
    30  	default:
    31  		checklvalue(n.X, "take the address of")
    32  		r := ir.OuterValue(n.X)
    33  		if r.Op() == ir.ONAME {
    34  			r := r.(*ir.Name)
    35  			if ir.Orig(r) != r {
    36  				base.Fatalf("found non-orig name node %v", r) // TODO(mdempsky): What does this mean?
    37  			}
    38  		}
    39  		n.X = DefaultLit(n.X, nil)
    40  		if n.X.Type() == nil {
    41  			n.SetType(nil)
    42  			return n
    43  		}
    44  	}
    45  
    46  	n.SetType(types.NewPtr(n.X.Type()))
    47  	return n
    48  }
    49  
    50  func tcShift(n, l, r ir.Node) (ir.Node, ir.Node, *types.Type) {
    51  	if l.Type() == nil || r.Type() == nil {
    52  		return l, r, nil
    53  	}
    54  
    55  	r = DefaultLit(r, types.Types[types.TUINT])
    56  	t := r.Type()
    57  	if !t.IsInteger() {
    58  		base.Errorf("invalid operation: %v (shift count type %v, must be integer)", n, r.Type())
    59  		return l, r, nil
    60  	}
    61  	if t.IsSigned() && !types.AllowsGoVersion(curpkg(), 1, 13) {
    62  		base.ErrorfVers("go1.13", "invalid operation: %v (signed shift count type %v)", n, r.Type())
    63  		return l, r, nil
    64  	}
    65  	t = l.Type()
    66  	if t != nil && t.Kind() != types.TIDEAL && !t.IsInteger() {
    67  		base.Errorf("invalid operation: %v (shift of type %v)", n, t)
    68  		return l, r, nil
    69  	}
    70  
    71  	// no DefaultLit for left
    72  	// the outer context gives the type
    73  	t = l.Type()
    74  	if (l.Type() == types.UntypedFloat || l.Type() == types.UntypedComplex) && r.Op() == ir.OLITERAL {
    75  		t = types.UntypedInt
    76  	}
    77  	return l, r, t
    78  }
    79  
    80  func IsCmp(op ir.Op) bool {
    81  	return iscmp[op]
    82  }
    83  
    84  // tcArith typechecks operands of a binary arithmetic expression.
    85  // The result of tcArith MUST be assigned back to original operands,
    86  // t is the type of the expression, and should be set by the caller. e.g:
    87  //     n.X, n.Y, t = tcArith(n, op, n.X, n.Y)
    88  //     n.SetType(t)
    89  func tcArith(n ir.Node, op ir.Op, l, r ir.Node) (ir.Node, ir.Node, *types.Type) {
    90  	l, r = defaultlit2(l, r, false)
    91  	if l.Type() == nil || r.Type() == nil {
    92  		return l, r, nil
    93  	}
    94  	t := l.Type()
    95  	if t.Kind() == types.TIDEAL {
    96  		t = r.Type()
    97  	}
    98  	aop := ir.OXXX
    99  	if iscmp[n.Op()] && t.Kind() != types.TIDEAL && !types.Identical(l.Type(), r.Type()) {
   100  		// comparison is okay as long as one side is
   101  		// assignable to the other.  convert so they have
   102  		// the same type.
   103  		//
   104  		// the only conversion that isn't a no-op is concrete == interface.
   105  		// in that case, check comparability of the concrete type.
   106  		// The conversion allocates, so only do it if the concrete type is huge.
   107  		converted := false
   108  		if r.Type().Kind() != types.TBLANK {
   109  			aop, _ = Assignop(l.Type(), r.Type())
   110  			if aop != ir.OXXX {
   111  				if r.Type().IsInterface() && !l.Type().IsInterface() && !types.IsComparable(l.Type()) {
   112  					base.Errorf("invalid operation: %v (operator %v not defined on %s)", n, op, typekind(l.Type()))
   113  					return l, r, nil
   114  				}
   115  
   116  				types.CalcSize(l.Type())
   117  				if r.Type().IsInterface() == l.Type().IsInterface() || l.Type().Width >= 1<<16 {
   118  					l = ir.NewConvExpr(base.Pos, aop, r.Type(), l)
   119  					l.SetTypecheck(1)
   120  				}
   121  
   122  				t = r.Type()
   123  				converted = true
   124  			}
   125  		}
   126  
   127  		if !converted && l.Type().Kind() != types.TBLANK {
   128  			aop, _ = Assignop(r.Type(), l.Type())
   129  			if aop != ir.OXXX {
   130  				if l.Type().IsInterface() && !r.Type().IsInterface() && !types.IsComparable(r.Type()) {
   131  					base.Errorf("invalid operation: %v (operator %v not defined on %s)", n, op, typekind(r.Type()))
   132  					return l, r, nil
   133  				}
   134  
   135  				types.CalcSize(r.Type())
   136  				if r.Type().IsInterface() == l.Type().IsInterface() || r.Type().Width >= 1<<16 {
   137  					r = ir.NewConvExpr(base.Pos, aop, l.Type(), r)
   138  					r.SetTypecheck(1)
   139  				}
   140  
   141  				t = l.Type()
   142  			}
   143  		}
   144  	}
   145  
   146  	if t.Kind() != types.TIDEAL && !types.Identical(l.Type(), r.Type()) {
   147  		l, r = defaultlit2(l, r, true)
   148  		if l.Type() == nil || r.Type() == nil {
   149  			return l, r, nil
   150  		}
   151  		if l.Type().IsInterface() == r.Type().IsInterface() || aop == 0 {
   152  			base.Errorf("invalid operation: %v (mismatched types %v and %v)", n, l.Type(), r.Type())
   153  			return l, r, nil
   154  		}
   155  	}
   156  
   157  	if t.Kind() == types.TIDEAL {
   158  		t = mixUntyped(l.Type(), r.Type())
   159  	}
   160  	if dt := defaultType(t); !okfor[op][dt.Kind()] {
   161  		base.Errorf("invalid operation: %v (operator %v not defined on %s)", n, op, typekind(t))
   162  		return l, r, nil
   163  	}
   164  
   165  	// okfor allows any array == array, map == map, func == func.
   166  	// restrict to slice/map/func == nil and nil == slice/map/func.
   167  	if l.Type().IsArray() && !types.IsComparable(l.Type()) {
   168  		base.Errorf("invalid operation: %v (%v cannot be compared)", n, l.Type())
   169  		return l, r, nil
   170  	}
   171  
   172  	if l.Type().IsSlice() && !ir.IsNil(l) && !ir.IsNil(r) {
   173  		base.Errorf("invalid operation: %v (slice can only be compared to nil)", n)
   174  		return l, r, nil
   175  	}
   176  
   177  	if l.Type().IsMap() && !ir.IsNil(l) && !ir.IsNil(r) {
   178  		base.Errorf("invalid operation: %v (map can only be compared to nil)", n)
   179  		return l, r, nil
   180  	}
   181  
   182  	if l.Type().Kind() == types.TFUNC && !ir.IsNil(l) && !ir.IsNil(r) {
   183  		base.Errorf("invalid operation: %v (func can only be compared to nil)", n)
   184  		return l, r, nil
   185  	}
   186  
   187  	if l.Type().IsStruct() {
   188  		if f := types.IncomparableField(l.Type()); f != nil {
   189  			base.Errorf("invalid operation: %v (struct containing %v cannot be compared)", n, f.Type)
   190  			return l, r, nil
   191  		}
   192  	}
   193  
   194  	if (op == ir.ODIV || op == ir.OMOD) && ir.IsConst(r, constant.Int) {
   195  		if constant.Sign(r.Val()) == 0 {
   196  			base.Errorf("division by zero")
   197  			return l, r, nil
   198  		}
   199  	}
   200  
   201  	return l, r, t
   202  }
   203  
   204  // The result of tcCompLit MUST be assigned back to n, e.g.
   205  // 	n.Left = tcCompLit(n.Left)
   206  func tcCompLit(n *ir.CompLitExpr) (res ir.Node) {
   207  	if base.EnableTrace && base.Flag.LowerT {
   208  		defer tracePrint("tcCompLit", n)(&res)
   209  	}
   210  
   211  	lno := base.Pos
   212  	defer func() {
   213  		base.Pos = lno
   214  	}()
   215  
   216  	if n.Ntype == nil {
   217  		base.ErrorfAt(n.Pos(), "missing type in composite literal")
   218  		n.SetType(nil)
   219  		return n
   220  	}
   221  
   222  	// Save original node (including n.Right)
   223  	n.SetOrig(ir.Copy(n))
   224  
   225  	ir.SetPos(n.Ntype)
   226  
   227  	// Need to handle [...]T arrays specially.
   228  	if array, ok := n.Ntype.(*ir.ArrayType); ok && array.Elem != nil && array.Len == nil {
   229  		array.Elem = typecheckNtype(array.Elem)
   230  		elemType := array.Elem.Type()
   231  		if elemType == nil {
   232  			n.SetType(nil)
   233  			return n
   234  		}
   235  		length := typecheckarraylit(elemType, -1, n.List, "array literal")
   236  		n.SetOp(ir.OARRAYLIT)
   237  		n.SetType(types.NewArray(elemType, length))
   238  		n.Ntype = nil
   239  		return n
   240  	}
   241  
   242  	n.Ntype = typecheckNtype(n.Ntype)
   243  	t := n.Ntype.Type()
   244  	if t == nil {
   245  		n.SetType(nil)
   246  		return n
   247  	}
   248  	n.SetType(t)
   249  
   250  	switch t.Kind() {
   251  	default:
   252  		base.Errorf("invalid composite literal type %v", t)
   253  		n.SetType(nil)
   254  
   255  	case types.TARRAY:
   256  		typecheckarraylit(t.Elem(), t.NumElem(), n.List, "array literal")
   257  		n.SetOp(ir.OARRAYLIT)
   258  		n.Ntype = nil
   259  
   260  	case types.TSLICE:
   261  		length := typecheckarraylit(t.Elem(), -1, n.List, "slice literal")
   262  		n.SetOp(ir.OSLICELIT)
   263  		n.Ntype = nil
   264  		n.Len = length
   265  
   266  	case types.TMAP:
   267  		var cs constSet
   268  		for i3, l := range n.List {
   269  			ir.SetPos(l)
   270  			if l.Op() != ir.OKEY {
   271  				n.List[i3] = Expr(l)
   272  				base.Errorf("missing key in map literal")
   273  				continue
   274  			}
   275  			l := l.(*ir.KeyExpr)
   276  
   277  			r := l.Key
   278  			r = pushtype(r, t.Key())
   279  			r = Expr(r)
   280  			l.Key = AssignConv(r, t.Key(), "map key")
   281  			cs.add(base.Pos, l.Key, "key", "map literal")
   282  
   283  			r = l.Value
   284  			r = pushtype(r, t.Elem())
   285  			r = Expr(r)
   286  			l.Value = AssignConv(r, t.Elem(), "map value")
   287  		}
   288  
   289  		n.SetOp(ir.OMAPLIT)
   290  		n.Ntype = nil
   291  
   292  	case types.TSTRUCT:
   293  		// Need valid field offsets for Xoffset below.
   294  		types.CalcSize(t)
   295  
   296  		errored := false
   297  		if len(n.List) != 0 && nokeys(n.List) {
   298  			// simple list of variables
   299  			ls := n.List
   300  			for i, n1 := range ls {
   301  				ir.SetPos(n1)
   302  				n1 = Expr(n1)
   303  				ls[i] = n1
   304  				if i >= t.NumFields() {
   305  					if !errored {
   306  						base.Errorf("too many values in %v", n)
   307  						errored = true
   308  					}
   309  					continue
   310  				}
   311  
   312  				f := t.Field(i)
   313  				s := f.Sym
   314  				if s != nil && !types.IsExported(s.Name) && s.Pkg != types.LocalPkg {
   315  					base.Errorf("implicit assignment of unexported field '%s' in %v literal", s.Name, t)
   316  				}
   317  				// No pushtype allowed here. Must name fields for that.
   318  				n1 = AssignConv(n1, f.Type, "field value")
   319  				sk := ir.NewStructKeyExpr(base.Pos, f.Sym, n1)
   320  				sk.Offset = f.Offset
   321  				ls[i] = sk
   322  			}
   323  			if len(ls) < t.NumFields() {
   324  				base.Errorf("too few values in %v", n)
   325  			}
   326  		} else {
   327  			hash := make(map[string]bool)
   328  
   329  			// keyed list
   330  			ls := n.List
   331  			for i, l := range ls {
   332  				ir.SetPos(l)
   333  
   334  				if l.Op() == ir.OKEY {
   335  					kv := l.(*ir.KeyExpr)
   336  					key := kv.Key
   337  
   338  					// Sym might have resolved to name in other top-level
   339  					// package, because of import dot. Redirect to correct sym
   340  					// before we do the lookup.
   341  					s := key.Sym()
   342  					if id, ok := key.(*ir.Ident); ok && DotImportRefs[id] != nil {
   343  						s = Lookup(s.Name)
   344  					}
   345  
   346  					// An OXDOT uses the Sym field to hold
   347  					// the field to the right of the dot,
   348  					// so s will be non-nil, but an OXDOT
   349  					// is never a valid struct literal key.
   350  					if s == nil || s.Pkg != types.LocalPkg || key.Op() == ir.OXDOT || s.IsBlank() {
   351  						base.Errorf("invalid field name %v in struct initializer", key)
   352  						continue
   353  					}
   354  
   355  					l = ir.NewStructKeyExpr(l.Pos(), s, kv.Value)
   356  					ls[i] = l
   357  				}
   358  
   359  				if l.Op() != ir.OSTRUCTKEY {
   360  					if !errored {
   361  						base.Errorf("mixture of field:value and value initializers")
   362  						errored = true
   363  					}
   364  					ls[i] = Expr(ls[i])
   365  					continue
   366  				}
   367  				l := l.(*ir.StructKeyExpr)
   368  
   369  				f := Lookdot1(nil, l.Field, t, t.Fields(), 0)
   370  				if f == nil {
   371  					if ci := Lookdot1(nil, l.Field, t, t.Fields(), 2); ci != nil { // Case-insensitive lookup.
   372  						if visible(ci.Sym) {
   373  							base.Errorf("unknown field '%v' in struct literal of type %v (but does have %v)", l.Field, t, ci.Sym)
   374  						} else if nonexported(l.Field) && l.Field.Name == ci.Sym.Name { // Ensure exactness before the suggestion.
   375  							base.Errorf("cannot refer to unexported field '%v' in struct literal of type %v", l.Field, t)
   376  						} else {
   377  							base.Errorf("unknown field '%v' in struct literal of type %v", l.Field, t)
   378  						}
   379  						continue
   380  					}
   381  					var f *types.Field
   382  					p, _ := dotpath(l.Field, t, &f, true)
   383  					if p == nil || f.IsMethod() {
   384  						base.Errorf("unknown field '%v' in struct literal of type %v", l.Field, t)
   385  						continue
   386  					}
   387  					// dotpath returns the parent embedded types in reverse order.
   388  					var ep []string
   389  					for ei := len(p) - 1; ei >= 0; ei-- {
   390  						ep = append(ep, p[ei].field.Sym.Name)
   391  					}
   392  					ep = append(ep, l.Field.Name)
   393  					base.Errorf("cannot use promoted field %v in struct literal of type %v", strings.Join(ep, "."), t)
   394  					continue
   395  				}
   396  				fielddup(f.Sym.Name, hash)
   397  				l.Offset = f.Offset
   398  
   399  				// No pushtype allowed here. Tried and rejected.
   400  				l.Value = Expr(l.Value)
   401  				l.Value = AssignConv(l.Value, f.Type, "field value")
   402  			}
   403  		}
   404  
   405  		n.SetOp(ir.OSTRUCTLIT)
   406  		n.Ntype = nil
   407  	}
   408  
   409  	return n
   410  }
   411  
   412  // tcConv typechecks an OCONV node.
   413  func tcConv(n *ir.ConvExpr) ir.Node {
   414  	types.CheckSize(n.Type()) // ensure width is calculated for backend
   415  	n.X = Expr(n.X)
   416  	n.X = convlit1(n.X, n.Type(), true, nil)
   417  	t := n.X.Type()
   418  	if t == nil || n.Type() == nil {
   419  		n.SetType(nil)
   420  		return n
   421  	}
   422  	op, why := Convertop(n.X.Op() == ir.OLITERAL, t, n.Type())
   423  	if op == ir.OXXX {
   424  		if !n.Diag() && !n.Type().Broke() && !n.X.Diag() {
   425  			base.Errorf("cannot convert %L to type %v%s", n.X, n.Type(), why)
   426  			n.SetDiag(true)
   427  		}
   428  		n.SetOp(ir.OCONV)
   429  		n.SetType(nil)
   430  		return n
   431  	}
   432  
   433  	n.SetOp(op)
   434  	switch n.Op() {
   435  	case ir.OCONVNOP:
   436  		if t.Kind() == n.Type().Kind() {
   437  			switch t.Kind() {
   438  			case types.TFLOAT32, types.TFLOAT64, types.TCOMPLEX64, types.TCOMPLEX128:
   439  				// Floating point casts imply rounding and
   440  				// so the conversion must be kept.
   441  				n.SetOp(ir.OCONV)
   442  			}
   443  		}
   444  
   445  	// do not convert to []byte literal. See CL 125796.
   446  	// generated code and compiler memory footprint is better without it.
   447  	case ir.OSTR2BYTES:
   448  		// ok
   449  
   450  	case ir.OSTR2RUNES:
   451  		if n.X.Op() == ir.OLITERAL {
   452  			return stringtoruneslit(n)
   453  		}
   454  	}
   455  	return n
   456  }
   457  
   458  // tcDot typechecks an OXDOT or ODOT node.
   459  func tcDot(n *ir.SelectorExpr, top int) ir.Node {
   460  	if n.Op() == ir.OXDOT {
   461  		n = AddImplicitDots(n)
   462  		n.SetOp(ir.ODOT)
   463  		if n.X == nil {
   464  			n.SetType(nil)
   465  			return n
   466  		}
   467  	}
   468  
   469  	n.X = typecheck(n.X, ctxExpr|ctxType)
   470  	n.X = DefaultLit(n.X, nil)
   471  
   472  	t := n.X.Type()
   473  	if t == nil {
   474  		base.UpdateErrorDot(ir.Line(n), fmt.Sprint(n.X), fmt.Sprint(n))
   475  		n.SetType(nil)
   476  		return n
   477  	}
   478  
   479  	if n.X.Op() == ir.OTYPE {
   480  		return typecheckMethodExpr(n)
   481  	}
   482  
   483  	if t.IsPtr() && !t.Elem().IsInterface() {
   484  		t = t.Elem()
   485  		if t == nil {
   486  			n.SetType(nil)
   487  			return n
   488  		}
   489  		n.SetOp(ir.ODOTPTR)
   490  		types.CheckSize(t)
   491  	}
   492  
   493  	if n.Sel.IsBlank() {
   494  		base.Errorf("cannot refer to blank field or method")
   495  		n.SetType(nil)
   496  		return n
   497  	}
   498  
   499  	if Lookdot(n, t, 0) == nil {
   500  		// Legitimate field or method lookup failed, try to explain the error
   501  		switch {
   502  		case t.IsEmptyInterface():
   503  			base.Errorf("%v undefined (type %v is interface with no methods)", n, n.X.Type())
   504  
   505  		case t.IsPtr() && t.Elem().IsInterface():
   506  			// Pointer to interface is almost always a mistake.
   507  			base.Errorf("%v undefined (type %v is pointer to interface, not interface)", n, n.X.Type())
   508  
   509  		case Lookdot(n, t, 1) != nil:
   510  			// Field or method matches by name, but it is not exported.
   511  			base.Errorf("%v undefined (cannot refer to unexported field or method %v)", n, n.Sel)
   512  
   513  		default:
   514  			if mt := Lookdot(n, t, 2); mt != nil && visible(mt.Sym) { // Case-insensitive lookup.
   515  				base.Errorf("%v undefined (type %v has no field or method %v, but does have %v)", n, n.X.Type(), n.Sel, mt.Sym)
   516  			} else {
   517  				base.Errorf("%v undefined (type %v has no field or method %v)", n, n.X.Type(), n.Sel)
   518  			}
   519  		}
   520  		n.SetType(nil)
   521  		return n
   522  	}
   523  
   524  	if (n.Op() == ir.ODOTINTER || n.Op() == ir.ODOTMETH) && top&ctxCallee == 0 {
   525  		n.SetOp(ir.OCALLPART)
   526  		n.SetType(MethodValueWrapper(n).Type())
   527  	}
   528  	return n
   529  }
   530  
   531  // tcDotType typechecks an ODOTTYPE node.
   532  func tcDotType(n *ir.TypeAssertExpr) ir.Node {
   533  	n.X = Expr(n.X)
   534  	n.X = DefaultLit(n.X, nil)
   535  	l := n.X
   536  	t := l.Type()
   537  	if t == nil {
   538  		n.SetType(nil)
   539  		return n
   540  	}
   541  	if !t.IsInterface() {
   542  		base.Errorf("invalid type assertion: %v (non-interface type %v on left)", n, t)
   543  		n.SetType(nil)
   544  		return n
   545  	}
   546  
   547  	if n.Ntype != nil {
   548  		n.Ntype = typecheckNtype(n.Ntype)
   549  		n.SetType(n.Ntype.Type())
   550  		n.Ntype = nil
   551  		if n.Type() == nil {
   552  			return n
   553  		}
   554  	}
   555  
   556  	if n.Type() != nil && !n.Type().IsInterface() {
   557  		var missing, have *types.Field
   558  		var ptr int
   559  		if !implements(n.Type(), t, &missing, &have, &ptr) {
   560  			if have != nil && have.Sym == missing.Sym {
   561  				base.Errorf("impossible type assertion:\n\t%v does not implement %v (wrong type for %v method)\n"+
   562  					"\t\thave %v%S\n\t\twant %v%S", n.Type(), t, missing.Sym, have.Sym, have.Type, missing.Sym, missing.Type)
   563  			} else if ptr != 0 {
   564  				base.Errorf("impossible type assertion:\n\t%v does not implement %v (%v method has pointer receiver)", n.Type(), t, missing.Sym)
   565  			} else if have != nil {
   566  				base.Errorf("impossible type assertion:\n\t%v does not implement %v (missing %v method)\n"+
   567  					"\t\thave %v%S\n\t\twant %v%S", n.Type(), t, missing.Sym, have.Sym, have.Type, missing.Sym, missing.Type)
   568  			} else {
   569  				base.Errorf("impossible type assertion:\n\t%v does not implement %v (missing %v method)", n.Type(), t, missing.Sym)
   570  			}
   571  			n.SetType(nil)
   572  			return n
   573  		}
   574  	}
   575  	return n
   576  }
   577  
   578  // tcITab typechecks an OITAB node.
   579  func tcITab(n *ir.UnaryExpr) ir.Node {
   580  	n.X = Expr(n.X)
   581  	t := n.X.Type()
   582  	if t == nil {
   583  		n.SetType(nil)
   584  		return n
   585  	}
   586  	if !t.IsInterface() {
   587  		base.Fatalf("OITAB of %v", t)
   588  	}
   589  	n.SetType(types.NewPtr(types.Types[types.TUINTPTR]))
   590  	return n
   591  }
   592  
   593  // tcIndex typechecks an OINDEX node.
   594  func tcIndex(n *ir.IndexExpr) ir.Node {
   595  	n.X = Expr(n.X)
   596  	n.X = DefaultLit(n.X, nil)
   597  	n.X = implicitstar(n.X)
   598  	l := n.X
   599  	n.Index = Expr(n.Index)
   600  	r := n.Index
   601  	t := l.Type()
   602  	if t == nil || r.Type() == nil {
   603  		n.SetType(nil)
   604  		return n
   605  	}
   606  	switch t.Kind() {
   607  	default:
   608  		base.Errorf("invalid operation: %v (type %v does not support indexing)", n, t)
   609  		n.SetType(nil)
   610  		return n
   611  
   612  	case types.TSTRING, types.TARRAY, types.TSLICE:
   613  		n.Index = indexlit(n.Index)
   614  		if t.IsString() {
   615  			n.SetType(types.ByteType)
   616  		} else {
   617  			n.SetType(t.Elem())
   618  		}
   619  		why := "string"
   620  		if t.IsArray() {
   621  			why = "array"
   622  		} else if t.IsSlice() {
   623  			why = "slice"
   624  		}
   625  
   626  		if n.Index.Type() != nil && !n.Index.Type().IsInteger() {
   627  			base.Errorf("non-integer %s index %v", why, n.Index)
   628  			return n
   629  		}
   630  
   631  		if !n.Bounded() && ir.IsConst(n.Index, constant.Int) {
   632  			x := n.Index.Val()
   633  			if constant.Sign(x) < 0 {
   634  				base.Errorf("invalid %s index %v (index must be non-negative)", why, n.Index)
   635  			} else if t.IsArray() && constant.Compare(x, token.GEQ, constant.MakeInt64(t.NumElem())) {
   636  				base.Errorf("invalid array index %v (out of bounds for %d-element array)", n.Index, t.NumElem())
   637  			} else if ir.IsConst(n.X, constant.String) && constant.Compare(x, token.GEQ, constant.MakeInt64(int64(len(ir.StringVal(n.X))))) {
   638  				base.Errorf("invalid string index %v (out of bounds for %d-byte string)", n.Index, len(ir.StringVal(n.X)))
   639  			} else if ir.ConstOverflow(x, types.Types[types.TINT]) {
   640  				base.Errorf("invalid %s index %v (index too large)", why, n.Index)
   641  			}
   642  		}
   643  
   644  	case types.TMAP:
   645  		n.Index = AssignConv(n.Index, t.Key(), "map index")
   646  		n.SetType(t.Elem())
   647  		n.SetOp(ir.OINDEXMAP)
   648  		n.Assigned = false
   649  	}
   650  	return n
   651  }
   652  
   653  // tcLenCap typechecks an OLEN or OCAP node.
   654  func tcLenCap(n *ir.UnaryExpr) ir.Node {
   655  	n.X = Expr(n.X)
   656  	n.X = DefaultLit(n.X, nil)
   657  	n.X = implicitstar(n.X)
   658  	l := n.X
   659  	t := l.Type()
   660  	if t == nil {
   661  		n.SetType(nil)
   662  		return n
   663  	}
   664  
   665  	var ok bool
   666  	if n.Op() == ir.OLEN {
   667  		ok = okforlen[t.Kind()]
   668  	} else {
   669  		ok = okforcap[t.Kind()]
   670  	}
   671  	if !ok {
   672  		base.Errorf("invalid argument %L for %v", l, n.Op())
   673  		n.SetType(nil)
   674  		return n
   675  	}
   676  
   677  	n.SetType(types.Types[types.TINT])
   678  	return n
   679  }
   680  
   681  // tcRecv typechecks an ORECV node.
   682  func tcRecv(n *ir.UnaryExpr) ir.Node {
   683  	n.X = Expr(n.X)
   684  	n.X = DefaultLit(n.X, nil)
   685  	l := n.X
   686  	t := l.Type()
   687  	if t == nil {
   688  		n.SetType(nil)
   689  		return n
   690  	}
   691  	if !t.IsChan() {
   692  		base.Errorf("invalid operation: %v (receive from non-chan type %v)", n, t)
   693  		n.SetType(nil)
   694  		return n
   695  	}
   696  
   697  	if !t.ChanDir().CanRecv() {
   698  		base.Errorf("invalid operation: %v (receive from send-only type %v)", n, t)
   699  		n.SetType(nil)
   700  		return n
   701  	}
   702  
   703  	n.SetType(t.Elem())
   704  	return n
   705  }
   706  
   707  // tcSPtr typechecks an OSPTR node.
   708  func tcSPtr(n *ir.UnaryExpr) ir.Node {
   709  	n.X = Expr(n.X)
   710  	t := n.X.Type()
   711  	if t == nil {
   712  		n.SetType(nil)
   713  		return n
   714  	}
   715  	if !t.IsSlice() && !t.IsString() {
   716  		base.Fatalf("OSPTR of %v", t)
   717  	}
   718  	if t.IsString() {
   719  		n.SetType(types.NewPtr(types.Types[types.TUINT8]))
   720  	} else {
   721  		n.SetType(types.NewPtr(t.Elem()))
   722  	}
   723  	return n
   724  }
   725  
   726  // tcSlice typechecks an OSLICE or OSLICE3 node.
   727  func tcSlice(n *ir.SliceExpr) ir.Node {
   728  	n.X = DefaultLit(Expr(n.X), nil)
   729  	n.Low = indexlit(Expr(n.Low))
   730  	n.High = indexlit(Expr(n.High))
   731  	n.Max = indexlit(Expr(n.Max))
   732  	hasmax := n.Op().IsSlice3()
   733  	l := n.X
   734  	if l.Type() == nil {
   735  		n.SetType(nil)
   736  		return n
   737  	}
   738  	if l.Type().IsArray() {
   739  		if !ir.IsAddressable(n.X) {
   740  			base.Errorf("invalid operation %v (slice of unaddressable value)", n)
   741  			n.SetType(nil)
   742  			return n
   743  		}
   744  
   745  		addr := NodAddr(n.X)
   746  		addr.SetImplicit(true)
   747  		n.X = Expr(addr)
   748  		l = n.X
   749  	}
   750  	t := l.Type()
   751  	var tp *types.Type
   752  	if t.IsString() {
   753  		if hasmax {
   754  			base.Errorf("invalid operation %v (3-index slice of string)", n)
   755  			n.SetType(nil)
   756  			return n
   757  		}
   758  		n.SetType(t)
   759  		n.SetOp(ir.OSLICESTR)
   760  	} else if t.IsPtr() && t.Elem().IsArray() {
   761  		tp = t.Elem()
   762  		n.SetType(types.NewSlice(tp.Elem()))
   763  		types.CalcSize(n.Type())
   764  		if hasmax {
   765  			n.SetOp(ir.OSLICE3ARR)
   766  		} else {
   767  			n.SetOp(ir.OSLICEARR)
   768  		}
   769  	} else if t.IsSlice() {
   770  		n.SetType(t)
   771  	} else {
   772  		base.Errorf("cannot slice %v (type %v)", l, t)
   773  		n.SetType(nil)
   774  		return n
   775  	}
   776  
   777  	if n.Low != nil && !checksliceindex(l, n.Low, tp) {
   778  		n.SetType(nil)
   779  		return n
   780  	}
   781  	if n.High != nil && !checksliceindex(l, n.High, tp) {
   782  		n.SetType(nil)
   783  		return n
   784  	}
   785  	if n.Max != nil && !checksliceindex(l, n.Max, tp) {
   786  		n.SetType(nil)
   787  		return n
   788  	}
   789  	if !checksliceconst(n.Low, n.High) || !checksliceconst(n.Low, n.Max) || !checksliceconst(n.High, n.Max) {
   790  		n.SetType(nil)
   791  		return n
   792  	}
   793  	return n
   794  }
   795  
   796  // tcSliceHeader typechecks an OSLICEHEADER node.
   797  func tcSliceHeader(n *ir.SliceHeaderExpr) ir.Node {
   798  	// Errors here are Fatalf instead of Errorf because only the compiler
   799  	// can construct an OSLICEHEADER node.
   800  	// Components used in OSLICEHEADER that are supplied by parsed source code
   801  	// have already been typechecked in e.g. OMAKESLICE earlier.
   802  	t := n.Type()
   803  	if t == nil {
   804  		base.Fatalf("no type specified for OSLICEHEADER")
   805  	}
   806  
   807  	if !t.IsSlice() {
   808  		base.Fatalf("invalid type %v for OSLICEHEADER", n.Type())
   809  	}
   810  
   811  	if n.Ptr == nil || n.Ptr.Type() == nil || !n.Ptr.Type().IsUnsafePtr() {
   812  		base.Fatalf("need unsafe.Pointer for OSLICEHEADER")
   813  	}
   814  
   815  	n.Ptr = Expr(n.Ptr)
   816  	n.Len = DefaultLit(Expr(n.Len), types.Types[types.TINT])
   817  	n.Cap = DefaultLit(Expr(n.Cap), types.Types[types.TINT])
   818  
   819  	if ir.IsConst(n.Len, constant.Int) && ir.Int64Val(n.Len) < 0 {
   820  		base.Fatalf("len for OSLICEHEADER must be non-negative")
   821  	}
   822  
   823  	if ir.IsConst(n.Cap, constant.Int) && ir.Int64Val(n.Cap) < 0 {
   824  		base.Fatalf("cap for OSLICEHEADER must be non-negative")
   825  	}
   826  
   827  	if ir.IsConst(n.Len, constant.Int) && ir.IsConst(n.Cap, constant.Int) && constant.Compare(n.Len.Val(), token.GTR, n.Cap.Val()) {
   828  		base.Fatalf("len larger than cap for OSLICEHEADER")
   829  	}
   830  
   831  	return n
   832  }
   833  
   834  // tcStar typechecks an ODEREF node, which may be an expression or a type.
   835  func tcStar(n *ir.StarExpr, top int) ir.Node {
   836  	n.X = typecheck(n.X, ctxExpr|ctxType)
   837  	l := n.X
   838  	t := l.Type()
   839  	if t == nil {
   840  		n.SetType(nil)
   841  		return n
   842  	}
   843  	if l.Op() == ir.OTYPE {
   844  		n.SetOTYPE(types.NewPtr(l.Type()))
   845  		// Ensure l.Type gets CalcSize'd for the backend. Issue 20174.
   846  		types.CheckSize(l.Type())
   847  		return n
   848  	}
   849  
   850  	if !t.IsPtr() {
   851  		if top&(ctxExpr|ctxStmt) != 0 {
   852  			base.Errorf("invalid indirect of %L", n.X)
   853  			n.SetType(nil)
   854  			return n
   855  		}
   856  		base.Errorf("%v is not a type", l)
   857  		return n
   858  	}
   859  
   860  	n.SetType(t.Elem())
   861  	return n
   862  }
   863  
   864  // tcUnaryArith typechecks a unary arithmetic expression.
   865  func tcUnaryArith(n *ir.UnaryExpr) ir.Node {
   866  	n.X = Expr(n.X)
   867  	l := n.X
   868  	t := l.Type()
   869  	if t == nil {
   870  		n.SetType(nil)
   871  		return n
   872  	}
   873  	if !okfor[n.Op()][defaultType(t).Kind()] {
   874  		base.Errorf("invalid operation: %v (operator %v not defined on %s)", n, n.Op(), typekind(t))
   875  		n.SetType(nil)
   876  		return n
   877  	}
   878  
   879  	n.SetType(t)
   880  	return n
   881  }
   882  

View as plain text