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

View as plain text