* tree-ssa-reassoc.c (reassociate_bb): Clarify code slighly.
[official-gcc.git] / libgo / go / go / types / builtins.go
blob596a989a2dfa2cbe957b96e1f0010318c592dc79
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.
5 // This file implements typechecking of builtin function calls.
7 package types
9 import (
10 "go/ast"
11 "go/constant"
12 "go/token"
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.
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
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
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
51 // evaluate first argument, if present
52 if nargs > 0 {
53 arg(x, 0)
54 if x.mode == invalid {
55 return
58 case _Make, _New, _Offsetof, _Trace:
59 // arguments require special handling
62 // check argument count
64 msg := ""
65 if nargs < bin.nargs {
66 msg = "not enough"
67 } else if !bin.variadic && nargs > bin.nargs {
68 msg = "too many"
70 if msg != "" {
71 check.invalidOp(call.Rparen, "%s arguments for %s (expected %d, found %d)", msg, call, bin.nargs, nargs)
72 return
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
92 // remember arguments that have been evaluated already
93 alist := []operand{*x}
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
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)
109 x.mode = value
110 x.typ = S
111 break
113 alist = append(alist, *x)
114 // fallthrough
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
126 arg(x, i)
127 }, nargs)
128 // ok to continue even if check.arguments reported errors
130 x.mode = value
131 x.typ = S
132 if check.Types != nil {
133 check.recordBuiltinType(call.Fun, sig)
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
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)
164 case *Slice, *Chan:
165 mode = value
167 case *Map:
168 if id == _Len {
169 mode = value
173 if mode == invalid {
174 check.invalidArg(x.pos(), "%s for %s", x, bin.name)
175 return
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))
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
192 if c.dir == RecvOnly {
193 check.invalidArg(x.pos(), "%s must not be a receive-only channel", x)
194 return
197 x.mode = novalue
198 if check.Types != nil {
199 check.recordBuiltinType(call.Fun, makeSig(nil, c))
202 case _Complex:
203 // complex(x, y floatT) complexT
204 var y operand
205 arg(&y, 1)
206 if y.mode == invalid {
207 return
210 // convert or check untyped arguments
211 d := 0
212 if isUntyped(x.typ) {
213 d |= 1
215 if isUntyped(y.typ) {
216 d |= 2
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]
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
251 if x.mode == invalid || y.mode == invalid {
252 return
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
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
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
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()
286 resTyp := Typ[res]
288 if check.Types != nil && x.mode != constant_ {
289 check.recordBuiltinType(call.Fun, makeSig(resTyp, x.typ, x.typ))
292 x.typ = resTyp
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
301 var y operand
302 arg(&y, 1)
303 if y.mode == invalid {
304 return
306 var src Type
307 switch t := y.typ.Underlying().(type) {
308 case *Basic:
309 if isString(y.typ) {
310 src = universeByte
312 case *Slice:
313 src = t.elem
316 if dst == nil || src == nil {
317 check.invalidArg(x.pos(), "copy expects slice arguments; found %s and %s", x, &y)
318 return
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
326 if check.Types != nil {
327 check.recordBuiltinType(call.Fun, makeSig(Typ[Int], x.typ, y.typ))
329 x.mode = value
330 x.typ = Typ[Int]
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
339 arg(x, 1) // k
340 if x.mode == invalid {
341 return
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
349 x.mode = novalue
350 if check.Types != nil {
351 check.recordBuiltinType(call.Fun, makeSig(nil, m, m.key))
354 case _Imag, _Real:
355 // imag(complexT) floatT
356 // real(complexT) floatT
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]
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
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
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)
392 } else {
393 x.mode = value
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()
408 resTyp := Typ[res]
410 if check.Types != nil && x.mode != constant_ {
411 check.recordBuiltinType(call.Fun, makeSig(resTyp, x.typ))
414 x.typ = resTyp
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
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
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
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)
446 if len(sizes) == 2 && sizes[0] > sizes[1] {
447 check.invalidArg(call.Args[1].Pos(), "length and capacity swapped")
448 // safe to continue
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)]...))
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
465 x.mode = value
466 x.typ = &Pointer{base: T}
467 if check.Types != nil {
468 check.recordBuiltinType(call.Fun, makeSig(x.typ, T))
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
479 x.mode = novalue
480 if check.Types != nil {
481 check.recordBuiltinType(call.Fun, makeSig(nil, T))
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
494 check.assignment(x, nil, "argument to "+predeclaredFuncs[id].name)
495 if x.mode == invalid {
496 // TODO(gri) "use" all arguments?
497 return
499 params[i] = x.typ
503 x.mode = novalue
504 if check.Types != nil {
505 check.recordBuiltinType(call.Fun, makeSig(nil, params...))
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))
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
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
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
539 check.expr(x, selx.X)
540 if x.mode == invalid {
541 return
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
559 if indirect {
560 check.invalidArg(x.pos(), "field %s is embedded via a pointer in %s", sel, base)
561 return
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)
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
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
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
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
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
597 if !constant.BoolVal(x.val) {
598 check.errorf(call.Pos(), "%v failed", call)
599 // compile-time assertion failure - safe to continue
601 // result is constant - no need to record signature
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
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
621 // trace is only available in test mode - no need to record signature
623 default:
624 unreachable()
627 return true
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.
632 func 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))
637 params := NewTuple(list...)
638 var result *Tuple
639 if res != nil {
640 assert(!isUntyped(res))
641 result = NewTuple(NewVar(token.NoPos, nil, "", res))
643 return &Signature{params: params, results: result}
646 // implicitArrayDeref returns A if typ is of the form *A and A is an array;
647 // otherwise it returns typ.
649 func implicitArrayDeref(typ Type) Type {
650 if p, ok := typ.(*Pointer); ok {
651 if a, ok := p.base.Underlying().(*Array); ok {
652 return a
655 return typ
658 // unparen returns e with any enclosing parentheses stripped.
659 func unparen(e ast.Expr) ast.Expr {
660 for {
661 p, ok := e.(*ast.ParenExpr)
662 if !ok {
663 return e
665 e = p.X