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
7package types
8
9import (
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// reports whether 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//
20func (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, 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				if t.len >= 0 {
162					val = constant.MakeInt64(t.len)
163				} else {
164					val = constant.MakeUnknown()
165				}
166			}
167
168		case *Slice, *Chan:
169			mode = value
170
171		case *Map:
172			if id == _Len {
173				mode = value
174			}
175		}
176
177		if mode == invalid && typ != Typ[Invalid] {
178			check.invalidArg(x.pos(), "%s for %s", x, bin.name)
179			return
180		}
181
182		x.mode = mode
183		x.typ = Typ[Int]
184		x.val = val
185		if check.Types != nil && mode != constant_ {
186			check.recordBuiltinType(call.Fun, makeSig(x.typ, typ))
187		}
188
189	case _Close:
190		// close(c)
191		c, _ := x.typ.Underlying().(*Chan)
192		if c == nil {
193			check.invalidArg(x.pos(), "%s is not a channel", x)
194			return
195		}
196		if c.dir == RecvOnly {
197			check.invalidArg(x.pos(), "%s must not be a receive-only channel", x)
198			return
199		}
200
201		x.mode = novalue
202		if check.Types != nil {
203			check.recordBuiltinType(call.Fun, makeSig(nil, c))
204		}
205
206	case _Complex:
207		// complex(x, y floatT) complexT
208		var y operand
209		arg(&y, 1)
210		if y.mode == invalid {
211			return
212		}
213
214		// convert or check untyped arguments
215		d := 0
216		if isUntyped(x.typ) {
217			d |= 1
218		}
219		if isUntyped(y.typ) {
220			d |= 2
221		}
222		switch d {
223		case 0:
224			// x and y are typed => nothing to do
225		case 1:
226			// only x is untyped => convert to type of y
227			check.convertUntyped(x, y.typ)
228		case 2:
229			// only y is untyped => convert to type of x
230			check.convertUntyped(&y, x.typ)
231		case 3:
232			// x and y are untyped =>
233			// 1) if both are constants, convert them to untyped
234			//    floating-point numbers if possible,
235			// 2) if one of them is not constant (possible because
236			//    it contains a shift that is yet untyped), convert
237			//    both of them to float64 since they must have the
238			//    same type to succeed (this will result in an error
239			//    because shifts of floats are not permitted)
240			if x.mode == constant_ && y.mode == constant_ {
241				toFloat := func(x *operand) {
242					if isNumeric(x.typ) && constant.Sign(constant.Imag(x.val)) == 0 {
243						x.typ = Typ[UntypedFloat]
244					}
245				}
246				toFloat(x)
247				toFloat(&y)
248			} else {
249				check.convertUntyped(x, Typ[Float64])
250				check.convertUntyped(&y, Typ[Float64])
251				// x and y should be invalid now, but be conservative
252				// and check below
253			}
254		}
255		if x.mode == invalid || y.mode == invalid {
256			return
257		}
258
259		// both argument types must be identical
260		if !check.identical(x.typ, y.typ) {
261			check.invalidArg(x.pos(), "mismatched types %s and %s", x.typ, y.typ)
262			return
263		}
264
265		// the argument types must be of floating-point type
266		if !isFloat(x.typ) {
267			check.invalidArg(x.pos(), "arguments have type %s, expected floating-point", x.typ)
268			return
269		}
270
271		// if both arguments are constants, the result is a constant
272		if x.mode == constant_ && y.mode == constant_ {
273			x.val = constant.BinaryOp(constant.ToFloat(x.val), token.ADD, constant.MakeImag(constant.ToFloat(y.val)))
274		} else {
275			x.mode = value
276		}
277
278		// determine result type
279		var res BasicKind
280		switch x.typ.Underlying().(*Basic).kind {
281		case Float32:
282			res = Complex64
283		case Float64:
284			res = Complex128
285		case UntypedFloat:
286			res = UntypedComplex
287		default:
288			unreachable()
289		}
290		resTyp := Typ[res]
291
292		if check.Types != nil && x.mode != constant_ {
293			check.recordBuiltinType(call.Fun, makeSig(resTyp, x.typ, x.typ))
294		}
295
296		x.typ = resTyp
297
298	case _Copy:
299		// copy(x, y []T) int
300		var dst Type
301		if t, _ := x.typ.Underlying().(*Slice); t != nil {
302			dst = t.elem
303		}
304
305		var y operand
306		arg(&y, 1)
307		if y.mode == invalid {
308			return
309		}
310		var src Type
311		switch t := y.typ.Underlying().(type) {
312		case *Basic:
313			if isString(y.typ) {
314				src = universeByte
315			}
316		case *Slice:
317			src = t.elem
318		}
319
320		if dst == nil || src == nil {
321			check.invalidArg(x.pos(), "copy expects slice arguments; found %s and %s", x, &y)
322			return
323		}
324
325		if !check.identical(dst, src) {
326			check.invalidArg(x.pos(), "arguments to copy %s and %s have different element types %s and %s", x, &y, dst, src)
327			return
328		}
329
330		if check.Types != nil {
331			check.recordBuiltinType(call.Fun, makeSig(Typ[Int], x.typ, y.typ))
332		}
333		x.mode = value
334		x.typ = Typ[Int]
335
336	case _Delete:
337		// delete(m, k)
338		m, _ := x.typ.Underlying().(*Map)
339		if m == nil {
340			check.invalidArg(x.pos(), "%s is not a map", x)
341			return
342		}
343		arg(x, 1) // k
344		if x.mode == invalid {
345			return
346		}
347
348		if !x.assignableTo(check, m.key, nil) {
349			check.invalidArg(x.pos(), "%s is not assignable to %s", x, m.key)
350			return
351		}
352
353		x.mode = novalue
354		if check.Types != nil {
355			check.recordBuiltinType(call.Fun, makeSig(nil, m, m.key))
356		}
357
358	case _Imag, _Real:
359		// imag(complexT) floatT
360		// real(complexT) floatT
361
362		// convert or check untyped argument
363		if isUntyped(x.typ) {
364			if x.mode == constant_ {
365				// an untyped constant number can always be considered
366				// as a complex constant
367				if isNumeric(x.typ) {
368					x.typ = Typ[UntypedComplex]
369				}
370			} else {
371				// an untyped non-constant argument may appear if
372				// it contains a (yet untyped non-constant) shift
373				// expression: convert it to complex128 which will
374				// result in an error (shift of complex value)
375				check.convertUntyped(x, Typ[Complex128])
376				// x should be invalid now, but be conservative and check
377				if x.mode == invalid {
378					return
379				}
380			}
381		}
382
383		// the argument must be of complex type
384		if !isComplex(x.typ) {
385			check.invalidArg(x.pos(), "argument has type %s, expected complex type", x.typ)
386			return
387		}
388
389		// if the argument is a constant, the result is a constant
390		if x.mode == constant_ {
391			if id == _Real {
392				x.val = constant.Real(x.val)
393			} else {
394				x.val = constant.Imag(x.val)
395			}
396		} else {
397			x.mode = value
398		}
399
400		// determine result type
401		var res BasicKind
402		switch x.typ.Underlying().(*Basic).kind {
403		case Complex64:
404			res = Float32
405		case Complex128:
406			res = Float64
407		case UntypedComplex:
408			res = UntypedFloat
409		default:
410			unreachable()
411		}
412		resTyp := Typ[res]
413
414		if check.Types != nil && x.mode != constant_ {
415			check.recordBuiltinType(call.Fun, makeSig(resTyp, x.typ))
416		}
417
418		x.typ = resTyp
419
420	case _Make:
421		// make(T, n)
422		// make(T, n, m)
423		// (no argument evaluated yet)
424		arg0 := call.Args[0]
425		T := check.typ(arg0)
426		if T == Typ[Invalid] {
427			return
428		}
429
430		var min int // minimum number of arguments
431		switch T.Underlying().(type) {
432		case *Slice:
433			min = 2
434		case *Map, *Chan:
435			min = 1
436		default:
437			check.invalidArg(arg0.Pos(), "cannot make %s; type must be slice, map, or channel", arg0)
438			return
439		}
440		if nargs < min || min+1 < nargs {
441			check.errorf(call.Pos(), "%v expects %d or %d arguments; found %d", call, min, min+1, nargs)
442			return
443		}
444		var sizes []int64 // constant integer arguments, if any
445		for _, arg := range call.Args[1:] {
446			if s, ok := check.index(arg, -1); ok && s >= 0 {
447				sizes = append(sizes, s)
448			}
449		}
450		if len(sizes) == 2 && sizes[0] > sizes[1] {
451			check.invalidArg(call.Args[1].Pos(), "length and capacity swapped")
452			// safe to continue
453		}
454		x.mode = value
455		x.typ = T
456		if check.Types != nil {
457			params := [...]Type{T, Typ[Int], Typ[Int]}
458			check.recordBuiltinType(call.Fun, makeSig(x.typ, params[:1+len(sizes)]...))
459		}
460
461	case _New:
462		// new(T)
463		// (no argument evaluated yet)
464		T := check.typ(call.Args[0])
465		if T == Typ[Invalid] {
466			return
467		}
468
469		x.mode = value
470		x.typ = &Pointer{base: T}
471		if check.Types != nil {
472			check.recordBuiltinType(call.Fun, makeSig(x.typ, T))
473		}
474
475	case _Panic:
476		// panic(x)
477		// record panic call if inside a function with result parameters
478		// (for use in Checker.isTerminating)
479		if check.sig != nil && check.sig.results.Len() > 0 {
480			// function has result parameters
481			p := check.isPanic
482			if p == nil {
483				// allocate lazily
484				p = make(map[*ast.CallExpr]bool)
485				check.isPanic = p
486			}
487			p[call] = true
488		}
489
490		check.assignment(x, &emptyInterface, "argument to panic")
491		if x.mode == invalid {
492			return
493		}
494
495		x.mode = novalue
496		if check.Types != nil {
497			check.recordBuiltinType(call.Fun, makeSig(nil, &emptyInterface))
498		}
499
500	case _Print, _Println:
501		// print(x, y, ...)
502		// println(x, y, ...)
503		var params []Type
504		if nargs > 0 {
505			params = make([]Type, nargs)
506			for i := 0; i < nargs; i++ {
507				if i > 0 {
508					arg(x, i) // first argument already evaluated
509				}
510				check.assignment(x, nil, "argument to "+predeclaredFuncs[id].name)
511				if x.mode == invalid {
512					// TODO(gri) "use" all arguments?
513					return
514				}
515				params[i] = x.typ
516			}
517		}
518
519		x.mode = novalue
520		if check.Types != nil {
521			check.recordBuiltinType(call.Fun, makeSig(nil, params...))
522		}
523
524	case _Recover:
525		// recover() interface{}
526		x.mode = value
527		x.typ = &emptyInterface
528		if check.Types != nil {
529			check.recordBuiltinType(call.Fun, makeSig(x.typ))
530		}
531
532	case _Alignof:
533		// unsafe.Alignof(x T) uintptr
534		check.assignment(x, nil, "argument to unsafe.Alignof")
535		if x.mode == invalid {
536			return
537		}
538
539		x.mode = constant_
540		x.val = constant.MakeInt64(check.conf.alignof(x.typ))
541		x.typ = Typ[Uintptr]
542		// result is constant - no need to record signature
543
544	case _Offsetof:
545		// unsafe.Offsetof(x T) uintptr, where x must be a selector
546		// (no argument evaluated yet)
547		arg0 := call.Args[0]
548		selx, _ := unparen(arg0).(*ast.SelectorExpr)
549		if selx == nil {
550			check.invalidArg(arg0.Pos(), "%s is not a selector expression", arg0)
551			check.use(arg0)
552			return
553		}
554
555		check.expr(x, selx.X)
556		if x.mode == invalid {
557			return
558		}
559
560		base := derefStructPtr(x.typ)
561		sel := selx.Sel.Name
562		obj, index, indirect := check.lookupFieldOrMethod(base, false, check.pkg, sel)
563		switch obj.(type) {
564		case nil:
565			check.invalidArg(x.pos(), "%s has no single field %s", base, sel)
566			return
567		case *Func:
568			// TODO(gri) Using derefStructPtr may result in methods being found
569			// that don't actually exist. An error either way, but the error
570			// message is confusing. See: https://play.golang.org/p/al75v23kUy ,
571			// but go/types reports: "invalid argument: x.m is a method value".
572			check.invalidArg(arg0.Pos(), "%s is a method value", arg0)
573			return
574		}
575		if indirect {
576			check.invalidArg(x.pos(), "field %s is embedded via a pointer in %s", sel, base)
577			return
578		}
579
580		// TODO(gri) Should we pass x.typ instead of base (and indirect report if derefStructPtr indirected)?
581		check.recordSelection(selx, FieldVal, base, obj, index, false)
582
583		offs := check.conf.offsetof(base, index)
584		x.mode = constant_
585		x.val = constant.MakeInt64(offs)
586		x.typ = Typ[Uintptr]
587		// result is constant - no need to record signature
588
589	case _Sizeof:
590		// unsafe.Sizeof(x T) uintptr
591		check.assignment(x, nil, "argument to unsafe.Sizeof")
592		if x.mode == invalid {
593			return
594		}
595
596		x.mode = constant_
597		x.val = constant.MakeInt64(check.conf.sizeof(x.typ))
598		x.typ = Typ[Uintptr]
599		// result is constant - no need to record signature
600
601	case _Assert:
602		// assert(pred) causes a typechecker error if pred is false.
603		// The result of assert is the value of pred if there is no error.
604		// Note: assert is only available in self-test mode.
605		if x.mode != constant_ || !isBoolean(x.typ) {
606			check.invalidArg(x.pos(), "%s is not a boolean constant", x)
607			return
608		}
609		if x.val.Kind() != constant.Bool {
610			check.errorf(x.pos(), "internal error: value of %s should be a boolean constant", x)
611			return
612		}
613		if !constant.BoolVal(x.val) {
614			check.errorf(call.Pos(), "%v failed", call)
615			// compile-time assertion failure - safe to continue
616		}
617		// result is constant - no need to record signature
618
619	case _Trace:
620		// trace(x, y, z, ...) dumps the positions, expressions, and
621		// values of its arguments. The result of trace is the value
622		// of the first argument.
623		// Note: trace is only available in self-test mode.
624		// (no argument evaluated yet)
625		if nargs == 0 {
626			check.dump("%v: trace() without arguments", call.Pos())
627			x.mode = novalue
628			break
629		}
630		var t operand
631		x1 := x
632		for _, arg := range call.Args {
633			check.rawExpr(x1, arg, nil) // permit trace for types, e.g.: new(trace(T))
634			check.dump("%v: %s", x1.pos(), x1)
635			x1 = &t // use incoming x only for first argument
636		}
637		// trace is only available in test mode - no need to record signature
638
639	default:
640		unreachable()
641	}
642
643	return true
644}
645
646// makeSig makes a signature for the given argument and result types.
647// Default types are used for untyped arguments, and res may be nil.
648func makeSig(res Type, args ...Type) *Signature {
649	list := make([]*Var, len(args))
650	for i, param := range args {
651		list[i] = NewVar(token.NoPos, nil, "", Default(param))
652	}
653	params := NewTuple(list...)
654	var result *Tuple
655	if res != nil {
656		assert(!isUntyped(res))
657		result = NewTuple(NewVar(token.NoPos, nil, "", res))
658	}
659	return &Signature{params: params, results: result}
660}
661
662// implicitArrayDeref returns A if typ is of the form *A and A is an array;
663// otherwise it returns typ.
664//
665func implicitArrayDeref(typ Type) Type {
666	if p, ok := typ.(*Pointer); ok {
667		if a, ok := p.base.Underlying().(*Array); ok {
668			return a
669		}
670	}
671	return typ
672}
673
674// unparen returns e with any enclosing parentheses stripped.
675func unparen(e ast.Expr) ast.Expr {
676	for {
677		p, ok := e.(*ast.ParenExpr)
678		if !ok {
679			return e
680		}
681		e = p.X
682	}
683}
684