...

Source file src/go/types/builtins.go

     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	// 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	//
    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, 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 !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 !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 alway 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 := 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.
   648	func 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	//
   665	func 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.
   675	func 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	

View as plain text