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

View as plain text