Home | History | Annotate | Download | only in types
      1 // Copyright 2012 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 // This file implements typechecking of builtin function calls.
      6 
      7 package types
      8 
      9 import (
     10 	"go/ast"
     11 	"go/constant"
     12 	"go/token"
     13 )
     14 
     15 // builtin type-checks a call to the built-in specified by id and
     16 // returns true if the call is valid, with *x holding the result;
     17 // but x.expr is not set. If the call is invalid, the result is
     18 // false, and *x is undefined.
     19 //
     20 func (check *Checker) builtin(x *operand, call *ast.CallExpr, id builtinId) (_ bool) {
     21 	// append is the only built-in that permits the use of ... for the last argument
     22 	bin := predeclaredFuncs[id]
     23 	if call.Ellipsis.IsValid() && id != _Append {
     24 		check.invalidOp(call.Ellipsis, "invalid use of ... with built-in %s", bin.name)
     25 		check.use(call.Args...)
     26 		return
     27 	}
     28 
     29 	// For len(x) and cap(x) we need to know if x contains any function calls or
     30 	// receive operations. Save/restore current setting and set hasCallOrRecv to
     31 	// false for the evaluation of x so that we can check it afterwards.
     32 	// Note: We must do this _before_ calling unpack because unpack evaluates the
     33 	//       first argument before we even call arg(x, 0)!
     34 	if id == _Len || id == _Cap {
     35 		defer func(b bool) {
     36 			check.hasCallOrRecv = b
     37 		}(check.hasCallOrRecv)
     38 		check.hasCallOrRecv = false
     39 	}
     40 
     41 	// determine actual arguments
     42 	var arg getter
     43 	nargs := len(call.Args)
     44 	switch id {
     45 	default:
     46 		// make argument getter
     47 		arg, nargs, _ = unpack(func(x *operand, i int) { check.multiExpr(x, call.Args[i]) }, nargs, false)
     48 		if arg == nil {
     49 			return
     50 		}
     51 		// evaluate first argument, if present
     52 		if nargs > 0 {
     53 			arg(x, 0)
     54 			if x.mode == invalid {
     55 				return
     56 			}
     57 		}
     58 	case _Make, _New, _Offsetof, _Trace:
     59 		// arguments require special handling
     60 	}
     61 
     62 	// check argument count
     63 	{
     64 		msg := ""
     65 		if nargs < bin.nargs {
     66 			msg = "not enough"
     67 		} else if !bin.variadic && nargs > bin.nargs {
     68 			msg = "too many"
     69 		}
     70 		if msg != "" {
     71 			check.invalidOp(call.Rparen, "%s arguments for %s (expected %d, found %d)", msg, call, bin.nargs, nargs)
     72 			return
     73 		}
     74 	}
     75 
     76 	switch id {
     77 	case _Append:
     78 		// append(s S, x ...T) S, where T is the element type of S
     79 		// spec: "The variadic function append appends zero or more values x to s of type
     80 		// S, which must be a slice type, and returns the resulting slice, also of type S.
     81 		// The values x are passed to a parameter of type ...T where T is the element type
     82 		// of S and the respective parameter passing rules apply."
     83 		S := x.typ
     84 		var T Type
     85 		if s, _ := S.Underlying().(*Slice); s != nil {
     86 			T = s.elem
     87 		} else {
     88 			check.invalidArg(x.pos(), "%s is not a slice", x)
     89 			return
     90 		}
     91 
     92 		// remember arguments that have been evaluated already
     93 		alist := []operand{*x}
     94 
     95 		// spec: "As a special case, append also accepts a first argument assignable
     96 		// to type []byte with a second argument of string type followed by ... .
     97 		// This form appends the bytes of the string.
     98 		if nargs == 2 && call.Ellipsis.IsValid() && x.assignableTo(check.conf, NewSlice(universeByte), nil) {
     99 			arg(x, 1)
    100 			if x.mode == invalid {
    101 				return
    102 			}
    103 			if isString(x.typ) {
    104 				if check.Types != nil {
    105 					sig := makeSig(S, S, x.typ)
    106 					sig.variadic = true
    107 					check.recordBuiltinType(call.Fun, sig)
    108 				}
    109 				x.mode = value
    110 				x.typ = S
    111 				break
    112 			}
    113 			alist = append(alist, *x)
    114 			// fallthrough
    115 		}
    116 
    117 		// check general case by creating custom signature
    118 		sig := makeSig(S, S, NewSlice(T)) // []T required for variadic signature
    119 		sig.variadic = true
    120 		check.arguments(x, call, sig, func(x *operand, i int) {
    121 			// only evaluate arguments that have not been evaluated before
    122 			if i < len(alist) {
    123 				*x = alist[i]
    124 				return
    125 			}
    126 			arg(x, i)
    127 		}, nargs)
    128 		// ok to continue even if check.arguments reported errors
    129 
    130 		x.mode = value
    131 		x.typ = S
    132 		if check.Types != nil {
    133 			check.recordBuiltinType(call.Fun, sig)
    134 		}
    135 
    136 	case _Cap, _Len:
    137 		// cap(x)
    138 		// len(x)
    139 		mode := invalid
    140 		var typ Type
    141 		var val constant.Value
    142 		switch typ = implicitArrayDeref(x.typ.Underlying()); t := typ.(type) {
    143 		case *Basic:
    144 			if isString(t) && id == _Len {
    145 				if x.mode == constant_ {
    146 					mode = constant_
    147 					val = constant.MakeInt64(int64(len(constant.StringVal(x.val))))
    148 				} else {
    149 					mode = value
    150 				}
    151 			}
    152 
    153 		case *Array:
    154 			mode = value
    155 			// spec: "The expressions len(s) and cap(s) are constants
    156 			// if the type of s is an array or pointer to an array and
    157 			// the expression s does not contain channel receives or
    158 			// function calls; in this case s is not evaluated."
    159 			if !check.hasCallOrRecv {
    160 				mode = constant_
    161 				val = constant.MakeInt64(t.len)
    162 			}
    163 
    164 		case *Slice, *Chan:
    165 			mode = value
    166 
    167 		case *Map:
    168 			if id == _Len {
    169 				mode = value
    170 			}
    171 		}
    172 
    173 		if mode == invalid {
    174 			check.invalidArg(x.pos(), "%s for %s", x, bin.name)
    175 			return
    176 		}
    177 
    178 		x.mode = mode
    179 		x.typ = Typ[Int]
    180 		x.val = val
    181 		if check.Types != nil && mode != constant_ {
    182 			check.recordBuiltinType(call.Fun, makeSig(x.typ, typ))
    183 		}
    184 
    185 	case _Close:
    186 		// close(c)
    187 		c, _ := x.typ.Underlying().(*Chan)
    188 		if c == nil {
    189 			check.invalidArg(x.pos(), "%s is not a channel", x)
    190 			return
    191 		}
    192 		if c.dir == RecvOnly {
    193 			check.invalidArg(x.pos(), "%s must not be a receive-only channel", x)
    194 			return
    195 		}
    196 
    197 		x.mode = novalue
    198 		if check.Types != nil {
    199 			check.recordBuiltinType(call.Fun, makeSig(nil, c))
    200 		}
    201 
    202 	case _Complex:
    203 		// complex(x, y floatT) complexT
    204 		var y operand
    205 		arg(&y, 1)
    206 		if y.mode == invalid {
    207 			return
    208 		}
    209 
    210 		// convert or check untyped arguments
    211 		d := 0
    212 		if isUntyped(x.typ) {
    213 			d |= 1
    214 		}
    215 		if isUntyped(y.typ) {
    216 			d |= 2
    217 		}
    218 		switch d {
    219 		case 0:
    220 			// x and y are typed => nothing to do
    221 		case 1:
    222 			// only x is untyped => convert to type of y
    223 			check.convertUntyped(x, y.typ)
    224 		case 2:
    225 			// only y is untyped => convert to type of x
    226 			check.convertUntyped(&y, x.typ)
    227 		case 3:
    228 			// x and y are untyped =>
    229 			// 1) if both are constants, convert them to untyped
    230 			//    floating-point numbers if possible,
    231 			// 2) if one of them is not constant (possible because
    232 			//    it contains a shift that is yet untyped), convert
    233 			//    both of them to float64 since they must have the
    234 			//    same type to succeed (this will result in an error
    235 			//    because shifts of floats are not permitted)
    236 			if x.mode == constant_ && y.mode == constant_ {
    237 				toFloat := func(x *operand) {
    238 					if isNumeric(x.typ) && constant.Sign(constant.Imag(x.val)) == 0 {
    239 						x.typ = Typ[UntypedFloat]
    240 					}
    241 				}
    242 				toFloat(x)
    243 				toFloat(&y)
    244 			} else {
    245 				check.convertUntyped(x, Typ[Float64])
    246 				check.convertUntyped(&y, Typ[Float64])
    247 				// x and y should be invalid now, but be conservative
    248 				// and check below
    249 			}
    250 		}
    251 		if x.mode == invalid || y.mode == invalid {
    252 			return
    253 		}
    254 
    255 		// both argument types must be identical
    256 		if !Identical(x.typ, y.typ) {
    257 			check.invalidArg(x.pos(), "mismatched types %s and %s", x.typ, y.typ)
    258 			return
    259 		}
    260 
    261 		// the argument types must be of floating-point type
    262 		if !isFloat(x.typ) {
    263 			check.invalidArg(x.pos(), "arguments have type %s, expected floating-point", x.typ)
    264 			return
    265 		}
    266 
    267 		// if both arguments are constants, the result is a constant
    268 		if x.mode == constant_ && y.mode == constant_ {
    269 			x.val = constant.BinaryOp(constant.ToFloat(x.val), token.ADD, constant.MakeImag(constant.ToFloat(y.val)))
    270 		} else {
    271 			x.mode = value
    272 		}
    273 
    274 		// determine result type
    275 		var res BasicKind
    276 		switch x.typ.Underlying().(*Basic).kind {
    277 		case Float32:
    278 			res = Complex64
    279 		case Float64:
    280 			res = Complex128
    281 		case UntypedFloat:
    282 			res = UntypedComplex
    283 		default:
    284 			unreachable()
    285 		}
    286 		resTyp := Typ[res]
    287 
    288 		if check.Types != nil && x.mode != constant_ {
    289 			check.recordBuiltinType(call.Fun, makeSig(resTyp, x.typ, x.typ))
    290 		}
    291 
    292 		x.typ = resTyp
    293 
    294 	case _Copy:
    295 		// copy(x, y []T) int
    296 		var dst Type
    297 		if t, _ := x.typ.Underlying().(*Slice); t != nil {
    298 			dst = t.elem
    299 		}
    300 
    301 		var y operand
    302 		arg(&y, 1)
    303 		if y.mode == invalid {
    304 			return
    305 		}
    306 		var src Type
    307 		switch t := y.typ.Underlying().(type) {
    308 		case *Basic:
    309 			if isString(y.typ) {
    310 				src = universeByte
    311 			}
    312 		case *Slice:
    313 			src = t.elem
    314 		}
    315 
    316 		if dst == nil || src == nil {
    317 			check.invalidArg(x.pos(), "copy expects slice arguments; found %s and %s", x, &y)
    318 			return
    319 		}
    320 
    321 		if !Identical(dst, src) {
    322 			check.invalidArg(x.pos(), "arguments to copy %s and %s have different element types %s and %s", x, &y, dst, src)
    323 			return
    324 		}
    325 
    326 		if check.Types != nil {
    327 			check.recordBuiltinType(call.Fun, makeSig(Typ[Int], x.typ, y.typ))
    328 		}
    329 		x.mode = value
    330 		x.typ = Typ[Int]
    331 
    332 	case _Delete:
    333 		// delete(m, k)
    334 		m, _ := x.typ.Underlying().(*Map)
    335 		if m == nil {
    336 			check.invalidArg(x.pos(), "%s is not a map", x)
    337 			return
    338 		}
    339 		arg(x, 1) // k
    340 		if x.mode == invalid {
    341 			return
    342 		}
    343 
    344 		if !x.assignableTo(check.conf, m.key, nil) {
    345 			check.invalidArg(x.pos(), "%s is not assignable to %s", x, m.key)
    346 			return
    347 		}
    348 
    349 		x.mode = novalue
    350 		if check.Types != nil {
    351 			check.recordBuiltinType(call.Fun, makeSig(nil, m, m.key))
    352 		}
    353 
    354 	case _Imag, _Real:
    355 		// imag(complexT) floatT
    356 		// real(complexT) floatT
    357 
    358 		// convert or check untyped argument
    359 		if isUntyped(x.typ) {
    360 			if x.mode == constant_ {
    361 				// an untyped constant number can alway be considered
    362 				// as a complex constant
    363 				if isNumeric(x.typ) {
    364 					x.typ = Typ[UntypedComplex]
    365 				}
    366 			} else {
    367 				// an untyped non-constant argument may appear if
    368 				// it contains a (yet untyped non-constant) shift
    369 				// expression: convert it to complex128 which will
    370 				// result in an error (shift of complex value)
    371 				check.convertUntyped(x, Typ[Complex128])
    372 				// x should be invalid now, but be conservative and check
    373 				if x.mode == invalid {
    374 					return
    375 				}
    376 			}
    377 		}
    378 
    379 		// the argument must be of complex type
    380 		if !isComplex(x.typ) {
    381 			check.invalidArg(x.pos(), "argument has type %s, expected complex type", x.typ)
    382 			return
    383 		}
    384 
    385 		// if the argument is a constant, the result is a constant
    386 		if x.mode == constant_ {
    387 			if id == _Real {
    388 				x.val = constant.Real(x.val)
    389 			} else {
    390 				x.val = constant.Imag(x.val)
    391 			}
    392 		} else {
    393 			x.mode = value
    394 		}
    395 
    396 		// determine result type
    397 		var res BasicKind
    398 		switch x.typ.Underlying().(*Basic).kind {
    399 		case Complex64:
    400 			res = Float32
    401 		case Complex128:
    402 			res = Float64
    403 		case UntypedComplex:
    404 			res = UntypedFloat
    405 		default:
    406 			unreachable()
    407 		}
    408 		resTyp := Typ[res]
    409 
    410 		if check.Types != nil && x.mode != constant_ {
    411 			check.recordBuiltinType(call.Fun, makeSig(resTyp, x.typ))
    412 		}
    413 
    414 		x.typ = resTyp
    415 
    416 	case _Make:
    417 		// make(T, n)
    418 		// make(T, n, m)
    419 		// (no argument evaluated yet)
    420 		arg0 := call.Args[0]
    421 		T := check.typ(arg0)
    422 		if T == Typ[Invalid] {
    423 			return
    424 		}
    425 
    426 		var min int // minimum number of arguments
    427 		switch T.Underlying().(type) {
    428 		case *Slice:
    429 			min = 2
    430 		case *Map, *Chan:
    431 			min = 1
    432 		default:
    433 			check.invalidArg(arg0.Pos(), "cannot make %s; type must be slice, map, or channel", arg0)
    434 			return
    435 		}
    436 		if nargs < min || min+1 < nargs {
    437 			check.errorf(call.Pos(), "%v expects %d or %d arguments; found %d", call, min, min+1, nargs)
    438 			return
    439 		}
    440 		var sizes []int64 // constant integer arguments, if any
    441 		for _, arg := range call.Args[1:] {
    442 			if s, ok := check.index(arg, -1); ok && s >= 0 {
    443 				sizes = append(sizes, s)
    444 			}
    445 		}
    446 		if len(sizes) == 2 && sizes[0] > sizes[1] {
    447 			check.invalidArg(call.Args[1].Pos(), "length and capacity swapped")
    448 			// safe to continue
    449 		}
    450 		x.mode = value
    451 		x.typ = T
    452 		if check.Types != nil {
    453 			params := [...]Type{T, Typ[Int], Typ[Int]}
    454 			check.recordBuiltinType(call.Fun, makeSig(x.typ, params[:1+len(sizes)]...))
    455 		}
    456 
    457 	case _New:
    458 		// new(T)
    459 		// (no argument evaluated yet)
    460 		T := check.typ(call.Args[0])
    461 		if T == Typ[Invalid] {
    462 			return
    463 		}
    464 
    465 		x.mode = value
    466 		x.typ = &Pointer{base: T}
    467 		if check.Types != nil {
    468 			check.recordBuiltinType(call.Fun, makeSig(x.typ, T))
    469 		}
    470 
    471 	case _Panic:
    472 		// panic(x)
    473 		check.assignment(x, &emptyInterface, "argument to panic")
    474 		if x.mode == invalid {
    475 			return
    476 		}
    477 
    478 		x.mode = novalue
    479 		if check.Types != nil {
    480 			check.recordBuiltinType(call.Fun, makeSig(nil, &emptyInterface))
    481 		}
    482 
    483 	case _Print, _Println:
    484 		// print(x, y, ...)
    485 		// println(x, y, ...)
    486 		var params []Type
    487 		if nargs > 0 {
    488 			params = make([]Type, nargs)
    489 			for i := 0; i < nargs; i++ {
    490 				if i > 0 {
    491 					arg(x, i) // first argument already evaluated
    492 				}
    493 				check.assignment(x, nil, "argument to "+predeclaredFuncs[id].name)
    494 				if x.mode == invalid {
    495 					// TODO(gri) "use" all arguments?
    496 					return
    497 				}
    498 				params[i] = x.typ
    499 			}
    500 		}
    501 
    502 		x.mode = novalue
    503 		if check.Types != nil {
    504 			check.recordBuiltinType(call.Fun, makeSig(nil, params...))
    505 		}
    506 
    507 	case _Recover:
    508 		// recover() interface{}
    509 		x.mode = value
    510 		x.typ = &emptyInterface
    511 		if check.Types != nil {
    512 			check.recordBuiltinType(call.Fun, makeSig(x.typ))
    513 		}
    514 
    515 	case _Alignof:
    516 		// unsafe.Alignof(x T) uintptr
    517 		check.assignment(x, nil, "argument to unsafe.Alignof")
    518 		if x.mode == invalid {
    519 			return
    520 		}
    521 
    522 		x.mode = constant_
    523 		x.val = constant.MakeInt64(check.conf.alignof(x.typ))
    524 		x.typ = Typ[Uintptr]
    525 		// result is constant - no need to record signature
    526 
    527 	case _Offsetof:
    528 		// unsafe.Offsetof(x T) uintptr, where x must be a selector
    529 		// (no argument evaluated yet)
    530 		arg0 := call.Args[0]
    531 		selx, _ := unparen(arg0).(*ast.SelectorExpr)
    532 		if selx == nil {
    533 			check.invalidArg(arg0.Pos(), "%s is not a selector expression", arg0)
    534 			check.use(arg0)
    535 			return
    536 		}
    537 
    538 		check.expr(x, selx.X)
    539 		if x.mode == invalid {
    540 			return
    541 		}
    542 
    543 		base := derefStructPtr(x.typ)
    544 		sel := selx.Sel.Name
    545 		obj, index, indirect := LookupFieldOrMethod(base, false, check.pkg, sel)
    546 		switch obj.(type) {
    547 		case nil:
    548 			check.invalidArg(x.pos(), "%s has no single field %s", base, sel)
    549 			return
    550 		case *Func:
    551 			// TODO(gri) Using derefStructPtr may result in methods being found
    552 			// that don't actually exist. An error either way, but the error
    553 			// message is confusing. See: https://play.golang.org/p/al75v23kUy ,
    554 			// but go/types reports: "invalid argument: x.m is a method value".
    555 			check.invalidArg(arg0.Pos(), "%s is a method value", arg0)
    556 			return
    557 		}
    558 		if indirect {
    559 			check.invalidArg(x.pos(), "field %s is embedded via a pointer in %s", sel, base)
    560 			return
    561 		}
    562 
    563 		// TODO(gri) Should we pass x.typ instead of base (and indirect report if derefStructPtr indirected)?
    564 		check.recordSelection(selx, FieldVal, base, obj, index, false)
    565 
    566 		offs := check.conf.offsetof(base, index)
    567 		x.mode = constant_
    568 		x.val = constant.MakeInt64(offs)
    569 		x.typ = Typ[Uintptr]
    570 		// result is constant - no need to record signature
    571 
    572 	case _Sizeof:
    573 		// unsafe.Sizeof(x T) uintptr
    574 		check.assignment(x, nil, "argument to unsafe.Sizeof")
    575 		if x.mode == invalid {
    576 			return
    577 		}
    578 
    579 		x.mode = constant_
    580 		x.val = constant.MakeInt64(check.conf.sizeof(x.typ))
    581 		x.typ = Typ[Uintptr]
    582 		// result is constant - no need to record signature
    583 
    584 	case _Assert:
    585 		// assert(pred) causes a typechecker error if pred is false.
    586 		// The result of assert is the value of pred if there is no error.
    587 		// Note: assert is only available in self-test mode.
    588 		if x.mode != constant_ || !isBoolean(x.typ) {
    589 			check.invalidArg(x.pos(), "%s is not a boolean constant", x)
    590 			return
    591 		}
    592 		if x.val.Kind() != constant.Bool {
    593 			check.errorf(x.pos(), "internal error: value of %s should be a boolean constant", x)
    594 			return
    595 		}
    596 		if !constant.BoolVal(x.val) {
    597 			check.errorf(call.Pos(), "%v failed", call)
    598 			// compile-time assertion failure - safe to continue
    599 		}
    600 		// result is constant - no need to record signature
    601 
    602 	case _Trace:
    603 		// trace(x, y, z, ...) dumps the positions, expressions, and
    604 		// values of its arguments. The result of trace is the value
    605 		// of the first argument.
    606 		// Note: trace is only available in self-test mode.
    607 		// (no argument evaluated yet)
    608 		if nargs == 0 {
    609 			check.dump("%s: trace() without arguments", call.Pos())
    610 			x.mode = novalue
    611 			break
    612 		}
    613 		var t operand
    614 		x1 := x
    615 		for _, arg := range call.Args {
    616 			check.rawExpr(x1, arg, nil) // permit trace for types, e.g.: new(trace(T))
    617 			check.dump("%s: %s", x1.pos(), x1)
    618 			x1 = &t // use incoming x only for first argument
    619 		}
    620 		// trace is only available in test mode - no need to record signature
    621 
    622 	default:
    623 		unreachable()
    624 	}
    625 
    626 	return true
    627 }
    628 
    629 // makeSig makes a signature for the given argument and result types.
    630 // Default types are used for untyped arguments, and res may be nil.
    631 func makeSig(res Type, args ...Type) *Signature {
    632 	list := make([]*Var, len(args))
    633 	for i, param := range args {
    634 		list[i] = NewVar(token.NoPos, nil, "", Default(param))
    635 	}
    636 	params := NewTuple(list...)
    637 	var result *Tuple
    638 	if res != nil {
    639 		assert(!isUntyped(res))
    640 		result = NewTuple(NewVar(token.NoPos, nil, "", res))
    641 	}
    642 	return &Signature{params: params, results: result}
    643 }
    644 
    645 // implicitArrayDeref returns A if typ is of the form *A and A is an array;
    646 // otherwise it returns typ.
    647 //
    648 func implicitArrayDeref(typ Type) Type {
    649 	if p, ok := typ.(*Pointer); ok {
    650 		if a, ok := p.base.Underlying().(*Array); ok {
    651 			return a
    652 		}
    653 	}
    654 	return typ
    655 }
    656 
    657 // unparen returns e with any enclosing parentheses stripped.
    658 func unparen(e ast.Expr) ast.Expr {
    659 	for {
    660 		p, ok := e.(*ast.ParenExpr)
    661 		if !ok {
    662 			return e
    663 		}
    664 		e = p.X
    665 	}
    666 }
    667