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