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

View as plain text