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// 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//
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.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		T := new(Interface)
474		check.assignment(x, T, "argument to panic")
475		if x.mode == invalid {
476			return
477		}
478
479		x.mode = novalue
480		if check.Types != nil {
481			check.recordBuiltinType(call.Fun, makeSig(nil, T))
482		}
483
484	case _Print, _Println:
485		// print(x, y, ...)
486		// println(x, y, ...)
487		var params []Type
488		if nargs > 0 {
489			params = make([]Type, nargs)
490			for i := 0; i < nargs; i++ {
491				if i > 0 {
492					arg(x, i) // first argument already evaluated
493				}
494				check.assignment(x, nil, "argument to "+predeclaredFuncs[id].name)
495				if x.mode == invalid {
496					// TODO(gri) "use" all arguments?
497					return
498				}
499				params[i] = x.typ
500			}
501		}
502
503		x.mode = novalue
504		if check.Types != nil {
505			check.recordBuiltinType(call.Fun, makeSig(nil, params...))
506		}
507
508	case _Recover:
509		// recover() interface{}
510		x.mode = value
511		x.typ = new(Interface)
512		if check.Types != nil {
513			check.recordBuiltinType(call.Fun, makeSig(x.typ))
514		}
515
516	case _Alignof:
517		// unsafe.Alignof(x T) uintptr
518		check.assignment(x, nil, "argument to unsafe.Alignof")
519		if x.mode == invalid {
520			return
521		}
522
523		x.mode = constant_
524		x.val = constant.MakeInt64(check.conf.alignof(x.typ))
525		x.typ = Typ[Uintptr]
526		// result is constant - no need to record signature
527
528	case _Offsetof:
529		// unsafe.Offsetof(x T) uintptr, where x must be a selector
530		// (no argument evaluated yet)
531		arg0 := call.Args[0]
532		selx, _ := unparen(arg0).(*ast.SelectorExpr)
533		if selx == nil {
534			check.invalidArg(arg0.Pos(), "%s is not a selector expression", arg0)
535			check.use(arg0)
536			return
537		}
538
539		check.expr(x, selx.X)
540		if x.mode == invalid {
541			return
542		}
543
544		base := derefStructPtr(x.typ)
545		sel := selx.Sel.Name
546		obj, index, indirect := LookupFieldOrMethod(base, false, check.pkg, sel)
547		switch obj.(type) {
548		case nil:
549			check.invalidArg(x.pos(), "%s has no single field %s", base, sel)
550			return
551		case *Func:
552			// TODO(gri) Using derefStructPtr may result in methods being found
553			// that don't actually exist. An error either way, but the error
554			// message is confusing. See: https://play.golang.org/p/al75v23kUy ,
555			// but go/types reports: "invalid argument: x.m is a method value".
556			check.invalidArg(arg0.Pos(), "%s is a method value", arg0)
557			return
558		}
559		if indirect {
560			check.invalidArg(x.pos(), "field %s is embedded via a pointer in %s", sel, base)
561			return
562		}
563
564		// TODO(gri) Should we pass x.typ instead of base (and indirect report if derefStructPtr indirected)?
565		check.recordSelection(selx, FieldVal, base, obj, index, false)
566
567		offs := check.conf.offsetof(base, index)
568		x.mode = constant_
569		x.val = constant.MakeInt64(offs)
570		x.typ = Typ[Uintptr]
571		// result is constant - no need to record signature
572
573	case _Sizeof:
574		// unsafe.Sizeof(x T) uintptr
575		check.assignment(x, nil, "argument to unsafe.Sizeof")
576		if x.mode == invalid {
577			return
578		}
579
580		x.mode = constant_
581		x.val = constant.MakeInt64(check.conf.sizeof(x.typ))
582		x.typ = Typ[Uintptr]
583		// result is constant - no need to record signature
584
585	case _Assert:
586		// assert(pred) causes a typechecker error if pred is false.
587		// The result of assert is the value of pred if there is no error.
588		// Note: assert is only available in self-test mode.
589		if x.mode != constant_ || !isBoolean(x.typ) {
590			check.invalidArg(x.pos(), "%s is not a boolean constant", x)
591			return
592		}
593		if x.val.Kind() != constant.Bool {
594			check.errorf(x.pos(), "internal error: value of %s should be a boolean constant", x)
595			return
596		}
597		if !constant.BoolVal(x.val) {
598			check.errorf(call.Pos(), "%v failed", call)
599			// compile-time assertion failure - safe to continue
600		}
601		// result is constant - no need to record signature
602
603	case _Trace:
604		// trace(x, y, z, ...) dumps the positions, expressions, and
605		// values of its arguments. The result of trace is the value
606		// of the first argument.
607		// Note: trace is only available in self-test mode.
608		// (no argument evaluated yet)
609		if nargs == 0 {
610			check.dump("%s: trace() without arguments", call.Pos())
611			x.mode = novalue
612			break
613		}
614		var t operand
615		x1 := x
616		for _, arg := range call.Args {
617			check.rawExpr(x1, arg, nil) // permit trace for types, e.g.: new(trace(T))
618			check.dump("%s: %s", x1.pos(), x1)
619			x1 = &t // use incoming x only for first argument
620		}
621		// trace is only available in test mode - no need to record signature
622
623	default:
624		unreachable()
625	}
626
627	return true
628}
629
630// makeSig makes a signature for the given argument and result types.
631// Default types are used for untyped arguments, and res may be nil.
632func makeSig(res Type, args ...Type) *Signature {
633	list := make([]*Var, len(args))
634	for i, param := range args {
635		list[i] = NewVar(token.NoPos, nil, "", Default(param))
636	}
637	params := NewTuple(list...)
638	var result *Tuple
639	if res != nil {
640		assert(!isUntyped(res))
641		result = NewTuple(NewVar(token.NoPos, nil, "", res))
642	}
643	return &Signature{params: params, results: result}
644}
645
646// implicitArrayDeref returns A if typ is of the form *A and A is an array;
647// otherwise it returns typ.
648//
649func implicitArrayDeref(typ Type) Type {
650	if p, ok := typ.(*Pointer); ok {
651		if a, ok := p.base.Underlying().(*Array); ok {
652			return a
653		}
654	}
655	return typ
656}
657
658// unparen returns e with any enclosing parentheses stripped.
659func unparen(e ast.Expr) ast.Expr {
660	for {
661		p, ok := e.(*ast.ParenExpr)
662		if !ok {
663			return e
664		}
665		e = p.X
666	}
667}
668