1// Copyright 2009 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 5package typecheck 6 7import ( 8 "fmt" 9 "go/constant" 10 "go/token" 11 "strings" 12 13 "cmd/compile/internal/base" 14 "cmd/compile/internal/ir" 15 "cmd/compile/internal/types" 16 "cmd/internal/src" 17) 18 19func AssignExpr(n ir.Node) ir.Node { return typecheck(n, ctxExpr|ctxAssign) } 20func Expr(n ir.Node) ir.Node { return typecheck(n, ctxExpr) } 21func Stmt(n ir.Node) ir.Node { return typecheck(n, ctxStmt) } 22 23func Exprs(exprs []ir.Node) { typecheckslice(exprs, ctxExpr) } 24func Stmts(stmts []ir.Node) { typecheckslice(stmts, ctxStmt) } 25 26func Call(pos src.XPos, callee ir.Node, args []ir.Node, dots bool) ir.Node { 27 call := ir.NewCallExpr(pos, ir.OCALL, callee, args) 28 call.IsDDD = dots 29 return typecheck(call, ctxStmt|ctxExpr) 30} 31 32func Callee(n ir.Node) ir.Node { 33 return typecheck(n, ctxExpr|ctxCallee) 34} 35 36var traceIndent []byte 37 38func tracePrint(title string, n ir.Node) func(np *ir.Node) { 39 indent := traceIndent 40 41 // guard against nil 42 var pos, op string 43 var tc uint8 44 if n != nil { 45 pos = base.FmtPos(n.Pos()) 46 op = n.Op().String() 47 tc = n.Typecheck() 48 } 49 50 types.SkipSizeForTracing = true 51 defer func() { types.SkipSizeForTracing = false }() 52 fmt.Printf("%s: %s%s %p %s %v tc=%d\n", pos, indent, title, n, op, n, tc) 53 traceIndent = append(traceIndent, ". "...) 54 55 return func(np *ir.Node) { 56 traceIndent = traceIndent[:len(traceIndent)-2] 57 58 // if we have a result, use that 59 if np != nil { 60 n = *np 61 } 62 63 // guard against nil 64 // use outer pos, op so we don't get empty pos/op if n == nil (nicer output) 65 var tc uint8 66 var typ *types.Type 67 if n != nil { 68 pos = base.FmtPos(n.Pos()) 69 op = n.Op().String() 70 tc = n.Typecheck() 71 typ = n.Type() 72 } 73 74 types.SkipSizeForTracing = true 75 defer func() { types.SkipSizeForTracing = false }() 76 fmt.Printf("%s: %s=> %p %s %v tc=%d type=%L\n", pos, indent, n, op, n, tc, typ) 77 } 78} 79 80const ( 81 ctxStmt = 1 << iota // evaluated at statement level 82 ctxExpr // evaluated in value context 83 ctxType // evaluated in type context 84 ctxCallee // call-only expressions are ok 85 ctxMultiOK // multivalue function returns are ok 86 ctxAssign // assigning to expression 87) 88 89// type checks the whole tree of an expression. 90// calculates expression types. 91// evaluates compile time constants. 92// marks variables that escape the local frame. 93// rewrites n.Op to be more specific in some cases. 94 95func typecheckslice(l []ir.Node, top int) { 96 for i := range l { 97 l[i] = typecheck(l[i], top) 98 } 99} 100 101var _typekind = []string{ 102 types.TINT: "int", 103 types.TUINT: "uint", 104 types.TINT8: "int8", 105 types.TUINT8: "uint8", 106 types.TINT16: "int16", 107 types.TUINT16: "uint16", 108 types.TINT32: "int32", 109 types.TUINT32: "uint32", 110 types.TINT64: "int64", 111 types.TUINT64: "uint64", 112 types.TUINTPTR: "uintptr", 113 types.TCOMPLEX64: "complex64", 114 types.TCOMPLEX128: "complex128", 115 types.TFLOAT32: "float32", 116 types.TFLOAT64: "float64", 117 types.TBOOL: "bool", 118 types.TSTRING: "string", 119 types.TPTR: "pointer", 120 types.TUNSAFEPTR: "unsafe.Pointer", 121 types.TSTRUCT: "struct", 122 types.TINTER: "interface", 123 types.TCHAN: "chan", 124 types.TMAP: "map", 125 types.TARRAY: "array", 126 types.TSLICE: "slice", 127 types.TFUNC: "func", 128 types.TNIL: "nil", 129 types.TIDEAL: "untyped number", 130} 131 132func typekind(t *types.Type) string { 133 if t.IsUntyped() { 134 return fmt.Sprintf("%v", t) 135 } 136 et := t.Kind() 137 if int(et) < len(_typekind) { 138 s := _typekind[et] 139 if s != "" { 140 return s 141 } 142 } 143 return fmt.Sprintf("etype=%d", et) 144} 145 146// typecheck type checks node n. 147// The result of typecheck MUST be assigned back to n, e.g. 148// 149// n.Left = typecheck(n.Left, top) 150func typecheck(n ir.Node, top int) (res ir.Node) { 151 if n == nil { 152 return nil 153 } 154 155 // only trace if there's work to do 156 if base.EnableTrace && base.Flag.LowerT { 157 defer tracePrint("typecheck", n)(&res) 158 } 159 160 lno := ir.SetPos(n) 161 defer func() { base.Pos = lno }() 162 163 // Skip typecheck if already done. 164 // But re-typecheck ONAME/OTYPE/OLITERAL/OPACK node in case context has changed. 165 if n.Typecheck() == 1 || n.Typecheck() == 3 { 166 switch n.Op() { 167 case ir.ONAME: 168 break 169 170 default: 171 return n 172 } 173 } 174 175 if n.Typecheck() == 2 { 176 base.FatalfAt(n.Pos(), "typechecking loop") 177 } 178 179 n.SetTypecheck(2) 180 n = typecheck1(n, top) 181 n.SetTypecheck(1) 182 183 t := n.Type() 184 if t != nil && !t.IsFuncArgStruct() && n.Op() != ir.OTYPE { 185 switch t.Kind() { 186 case types.TFUNC, // might have TANY; wait until it's called 187 types.TANY, types.TFORW, types.TIDEAL, types.TNIL, types.TBLANK: 188 break 189 190 default: 191 types.CheckSize(t) 192 } 193 } 194 195 return n 196} 197 198// indexlit implements typechecking of untyped values as 199// array/slice indexes. It is almost equivalent to DefaultLit 200// but also accepts untyped numeric values representable as 201// value of type int (see also checkmake for comparison). 202// The result of indexlit MUST be assigned back to n, e.g. 203// 204// n.Left = indexlit(n.Left) 205func indexlit(n ir.Node) ir.Node { 206 if n != nil && n.Type() != nil && n.Type().Kind() == types.TIDEAL { 207 return DefaultLit(n, types.Types[types.TINT]) 208 } 209 return n 210} 211 212// typecheck1 should ONLY be called from typecheck. 213func typecheck1(n ir.Node, top int) ir.Node { 214 // Skip over parens. 215 for n.Op() == ir.OPAREN { 216 n = n.(*ir.ParenExpr).X 217 } 218 219 switch n.Op() { 220 default: 221 ir.Dump("typecheck", n) 222 base.Fatalf("typecheck %v", n.Op()) 223 panic("unreachable") 224 225 case ir.ONAME: 226 n := n.(*ir.Name) 227 if n.BuiltinOp != 0 { 228 if top&ctxCallee == 0 { 229 base.Errorf("use of builtin %v not in function call", n.Sym()) 230 n.SetType(nil) 231 return n 232 } 233 return n 234 } 235 if top&ctxAssign == 0 { 236 // not a write to the variable 237 if ir.IsBlank(n) { 238 base.Errorf("cannot use _ as value") 239 n.SetType(nil) 240 return n 241 } 242 n.SetUsed(true) 243 } 244 return n 245 246 // type or expr 247 case ir.ODEREF: 248 n := n.(*ir.StarExpr) 249 return tcStar(n, top) 250 251 // x op= y 252 case ir.OASOP: 253 n := n.(*ir.AssignOpStmt) 254 n.X, n.Y = Expr(n.X), Expr(n.Y) 255 checkassign(n.X) 256 if n.IncDec && !okforarith[n.X.Type().Kind()] { 257 base.Errorf("invalid operation: %v (non-numeric type %v)", n, n.X.Type()) 258 return n 259 } 260 switch n.AsOp { 261 case ir.OLSH, ir.ORSH: 262 n.X, n.Y, _ = tcShift(n, n.X, n.Y) 263 case ir.OADD, ir.OAND, ir.OANDNOT, ir.ODIV, ir.OMOD, ir.OMUL, ir.OOR, ir.OSUB, ir.OXOR: 264 n.X, n.Y, _ = tcArith(n, n.AsOp, n.X, n.Y) 265 default: 266 base.Fatalf("invalid assign op: %v", n.AsOp) 267 } 268 return n 269 270 // logical operators 271 case ir.OANDAND, ir.OOROR: 272 n := n.(*ir.LogicalExpr) 273 n.X, n.Y = Expr(n.X), Expr(n.Y) 274 if n.X.Type() == nil || n.Y.Type() == nil { 275 n.SetType(nil) 276 return n 277 } 278 // For "x == x && len(s)", it's better to report that "len(s)" (type int) 279 // can't be used with "&&" than to report that "x == x" (type untyped bool) 280 // can't be converted to int (see issue #41500). 281 if !n.X.Type().IsBoolean() { 282 base.Errorf("invalid operation: %v (operator %v not defined on %s)", n, n.Op(), typekind(n.X.Type())) 283 n.SetType(nil) 284 return n 285 } 286 if !n.Y.Type().IsBoolean() { 287 base.Errorf("invalid operation: %v (operator %v not defined on %s)", n, n.Op(), typekind(n.Y.Type())) 288 n.SetType(nil) 289 return n 290 } 291 l, r, t := tcArith(n, n.Op(), n.X, n.Y) 292 n.X, n.Y = l, r 293 n.SetType(t) 294 return n 295 296 // shift operators 297 case ir.OLSH, ir.ORSH: 298 n := n.(*ir.BinaryExpr) 299 n.X, n.Y = Expr(n.X), Expr(n.Y) 300 l, r, t := tcShift(n, n.X, n.Y) 301 n.X, n.Y = l, r 302 n.SetType(t) 303 return n 304 305 // comparison operators 306 case ir.OEQ, ir.OGE, ir.OGT, ir.OLE, ir.OLT, ir.ONE: 307 n := n.(*ir.BinaryExpr) 308 n.X, n.Y = Expr(n.X), Expr(n.Y) 309 l, r, t := tcArith(n, n.Op(), n.X, n.Y) 310 if t != nil { 311 n.X, n.Y = l, r 312 n.SetType(types.UntypedBool) 313 n.X, n.Y = defaultlit2(l, r, true) 314 } 315 return n 316 317 // binary operators 318 case ir.OADD, ir.OAND, ir.OANDNOT, ir.ODIV, ir.OMOD, ir.OMUL, ir.OOR, ir.OSUB, ir.OXOR: 319 n := n.(*ir.BinaryExpr) 320 n.X, n.Y = Expr(n.X), Expr(n.Y) 321 l, r, t := tcArith(n, n.Op(), n.X, n.Y) 322 if t != nil && t.Kind() == types.TSTRING && n.Op() == ir.OADD { 323 // create or update OADDSTR node with list of strings in x + y + z + (w + v) + ... 324 var add *ir.AddStringExpr 325 if l.Op() == ir.OADDSTR { 326 add = l.(*ir.AddStringExpr) 327 add.SetPos(n.Pos()) 328 } else { 329 add = ir.NewAddStringExpr(n.Pos(), []ir.Node{l}) 330 } 331 if r.Op() == ir.OADDSTR { 332 r := r.(*ir.AddStringExpr) 333 add.List.Append(r.List.Take()...) 334 } else { 335 add.List.Append(r) 336 } 337 add.SetType(t) 338 return add 339 } 340 n.X, n.Y = l, r 341 n.SetType(t) 342 return n 343 344 case ir.OBITNOT, ir.ONEG, ir.ONOT, ir.OPLUS: 345 n := n.(*ir.UnaryExpr) 346 return tcUnaryArith(n) 347 348 // exprs 349 case ir.OCOMPLIT: 350 return tcCompLit(n.(*ir.CompLitExpr)) 351 352 case ir.OXDOT, ir.ODOT: 353 n := n.(*ir.SelectorExpr) 354 return tcDot(n, top) 355 356 case ir.ODOTTYPE: 357 n := n.(*ir.TypeAssertExpr) 358 return tcDotType(n) 359 360 case ir.OINDEX: 361 n := n.(*ir.IndexExpr) 362 return tcIndex(n) 363 364 case ir.ORECV: 365 n := n.(*ir.UnaryExpr) 366 return tcRecv(n) 367 368 case ir.OSEND: 369 n := n.(*ir.SendStmt) 370 return tcSend(n) 371 372 case ir.OSLICEHEADER: 373 n := n.(*ir.SliceHeaderExpr) 374 return tcSliceHeader(n) 375 376 case ir.OSTRINGHEADER: 377 n := n.(*ir.StringHeaderExpr) 378 return tcStringHeader(n) 379 380 case ir.OMAKESLICECOPY: 381 n := n.(*ir.MakeExpr) 382 return tcMakeSliceCopy(n) 383 384 case ir.OSLICE, ir.OSLICE3: 385 n := n.(*ir.SliceExpr) 386 return tcSlice(n) 387 388 // call and call like 389 case ir.OCALL: 390 n := n.(*ir.CallExpr) 391 return tcCall(n, top) 392 393 case ir.OCAP, ir.OLEN: 394 n := n.(*ir.UnaryExpr) 395 return tcLenCap(n) 396 397 case ir.OMIN, ir.OMAX: 398 n := n.(*ir.CallExpr) 399 return tcMinMax(n) 400 401 case ir.OREAL, ir.OIMAG: 402 n := n.(*ir.UnaryExpr) 403 return tcRealImag(n) 404 405 case ir.OCOMPLEX: 406 n := n.(*ir.BinaryExpr) 407 return tcComplex(n) 408 409 case ir.OCLEAR: 410 n := n.(*ir.UnaryExpr) 411 return tcClear(n) 412 413 case ir.OCLOSE: 414 n := n.(*ir.UnaryExpr) 415 return tcClose(n) 416 417 case ir.ODELETE: 418 n := n.(*ir.CallExpr) 419 return tcDelete(n) 420 421 case ir.OAPPEND: 422 n := n.(*ir.CallExpr) 423 return tcAppend(n) 424 425 case ir.OCOPY: 426 n := n.(*ir.BinaryExpr) 427 return tcCopy(n) 428 429 case ir.OCONV: 430 n := n.(*ir.ConvExpr) 431 return tcConv(n) 432 433 case ir.OMAKE: 434 n := n.(*ir.CallExpr) 435 return tcMake(n) 436 437 case ir.ONEW: 438 n := n.(*ir.UnaryExpr) 439 return tcNew(n) 440 441 case ir.OPRINT, ir.OPRINTLN: 442 n := n.(*ir.CallExpr) 443 return tcPrint(n) 444 445 case ir.OPANIC: 446 n := n.(*ir.UnaryExpr) 447 return tcPanic(n) 448 449 case ir.ORECOVER: 450 n := n.(*ir.CallExpr) 451 return tcRecover(n) 452 453 case ir.OUNSAFEADD: 454 n := n.(*ir.BinaryExpr) 455 return tcUnsafeAdd(n) 456 457 case ir.OUNSAFESLICE: 458 n := n.(*ir.BinaryExpr) 459 return tcUnsafeSlice(n) 460 461 case ir.OUNSAFESLICEDATA: 462 n := n.(*ir.UnaryExpr) 463 return tcUnsafeData(n) 464 465 case ir.OUNSAFESTRING: 466 n := n.(*ir.BinaryExpr) 467 return tcUnsafeString(n) 468 469 case ir.OUNSAFESTRINGDATA: 470 n := n.(*ir.UnaryExpr) 471 return tcUnsafeData(n) 472 473 case ir.OITAB: 474 n := n.(*ir.UnaryExpr) 475 return tcITab(n) 476 477 case ir.OIDATA: 478 // Whoever creates the OIDATA node must know a priori the concrete type at that moment, 479 // usually by just having checked the OITAB. 480 n := n.(*ir.UnaryExpr) 481 base.Fatalf("cannot typecheck interface data %v", n) 482 panic("unreachable") 483 484 case ir.OSPTR: 485 n := n.(*ir.UnaryExpr) 486 return tcSPtr(n) 487 488 case ir.OCFUNC: 489 n := n.(*ir.UnaryExpr) 490 n.X = Expr(n.X) 491 n.SetType(types.Types[types.TUINTPTR]) 492 return n 493 494 case ir.OGETCALLERPC, ir.OGETCALLERSP: 495 n := n.(*ir.CallExpr) 496 if len(n.Args) != 0 { 497 base.FatalfAt(n.Pos(), "unexpected arguments: %v", n) 498 } 499 n.SetType(types.Types[types.TUINTPTR]) 500 return n 501 502 case ir.OCONVNOP: 503 n := n.(*ir.ConvExpr) 504 n.X = Expr(n.X) 505 return n 506 507 // statements 508 case ir.OAS: 509 n := n.(*ir.AssignStmt) 510 tcAssign(n) 511 512 // Code that creates temps does not bother to set defn, so do it here. 513 if n.X.Op() == ir.ONAME && ir.IsAutoTmp(n.X) { 514 n.X.Name().Defn = n 515 } 516 return n 517 518 case ir.OAS2: 519 tcAssignList(n.(*ir.AssignListStmt)) 520 return n 521 522 case ir.OBREAK, 523 ir.OCONTINUE, 524 ir.ODCL, 525 ir.OGOTO, 526 ir.OFALL: 527 return n 528 529 case ir.OBLOCK: 530 n := n.(*ir.BlockStmt) 531 Stmts(n.List) 532 return n 533 534 case ir.OLABEL: 535 if n.Sym().IsBlank() { 536 // Empty identifier is valid but useless. 537 // Eliminate now to simplify life later. 538 // See issues 7538, 11589, 11593. 539 n = ir.NewBlockStmt(n.Pos(), nil) 540 } 541 return n 542 543 case ir.ODEFER, ir.OGO: 544 n := n.(*ir.GoDeferStmt) 545 n.Call = typecheck(n.Call, ctxStmt|ctxExpr) 546 tcGoDefer(n) 547 return n 548 549 case ir.OFOR: 550 n := n.(*ir.ForStmt) 551 return tcFor(n) 552 553 case ir.OIF: 554 n := n.(*ir.IfStmt) 555 return tcIf(n) 556 557 case ir.ORETURN: 558 n := n.(*ir.ReturnStmt) 559 return tcReturn(n) 560 561 case ir.OTAILCALL: 562 n := n.(*ir.TailCallStmt) 563 n.Call = typecheck(n.Call, ctxStmt|ctxExpr).(*ir.CallExpr) 564 return n 565 566 case ir.OCHECKNIL: 567 n := n.(*ir.UnaryExpr) 568 return tcCheckNil(n) 569 570 case ir.OSELECT: 571 tcSelect(n.(*ir.SelectStmt)) 572 return n 573 574 case ir.OSWITCH: 575 tcSwitch(n.(*ir.SwitchStmt)) 576 return n 577 578 case ir.ORANGE: 579 tcRange(n.(*ir.RangeStmt)) 580 return n 581 582 case ir.OTYPESW: 583 n := n.(*ir.TypeSwitchGuard) 584 base.Fatalf("use of .(type) outside type switch") 585 return n 586 587 case ir.ODCLFUNC: 588 tcFunc(n.(*ir.Func)) 589 return n 590 } 591 592 // No return n here! 593 // Individual cases can type-assert n, introducing a new one. 594 // Each must execute its own return n. 595} 596 597func typecheckargs(n ir.InitNode) { 598 var list []ir.Node 599 switch n := n.(type) { 600 default: 601 base.Fatalf("typecheckargs %+v", n.Op()) 602 case *ir.CallExpr: 603 list = n.Args 604 if n.IsDDD { 605 Exprs(list) 606 return 607 } 608 case *ir.ReturnStmt: 609 list = n.Results 610 } 611 if len(list) != 1 { 612 Exprs(list) 613 return 614 } 615 616 typecheckslice(list, ctxExpr|ctxMultiOK) 617 t := list[0].Type() 618 if t == nil || !t.IsFuncArgStruct() { 619 return 620 } 621 622 // Rewrite f(g()) into t1, t2, ... = g(); f(t1, t2, ...). 623 RewriteMultiValueCall(n, list[0]) 624} 625 626// RewriteNonNameCall replaces non-Name call expressions with temps, 627// rewriting f()(...) to t0 := f(); t0(...). 628func RewriteNonNameCall(n *ir.CallExpr) { 629 np := &n.Fun 630 if dot, ok := (*np).(*ir.SelectorExpr); ok && (dot.Op() == ir.ODOTMETH || dot.Op() == ir.ODOTINTER || dot.Op() == ir.OMETHVALUE) { 631 np = &dot.X // peel away method selector 632 } 633 634 // Check for side effects in the callee expression. 635 // We explicitly special case new(T) though, because it doesn't have 636 // observable side effects, and keeping it in place allows better escape analysis. 637 if !ir.Any(*np, func(n ir.Node) bool { return n.Op() != ir.ONEW && callOrChan(n) }) { 638 return 639 } 640 641 tmp := TempAt(base.Pos, ir.CurFunc, (*np).Type()) 642 as := ir.NewAssignStmt(base.Pos, tmp, *np) 643 as.PtrInit().Append(Stmt(ir.NewDecl(n.Pos(), ir.ODCL, tmp))) 644 *np = tmp 645 646 n.PtrInit().Append(Stmt(as)) 647} 648 649// RewriteMultiValueCall rewrites multi-valued f() to use temporaries, 650// so the backend wouldn't need to worry about tuple-valued expressions. 651func RewriteMultiValueCall(n ir.InitNode, call ir.Node) { 652 as := ir.NewAssignListStmt(base.Pos, ir.OAS2, nil, []ir.Node{call}) 653 results := call.Type().Fields() 654 list := make([]ir.Node, len(results)) 655 for i, result := range results { 656 tmp := TempAt(base.Pos, ir.CurFunc, result.Type) 657 as.PtrInit().Append(ir.NewDecl(base.Pos, ir.ODCL, tmp)) 658 as.Lhs.Append(tmp) 659 list[i] = tmp 660 } 661 662 n.PtrInit().Append(Stmt(as)) 663 664 switch n := n.(type) { 665 default: 666 base.Fatalf("RewriteMultiValueCall %+v", n.Op()) 667 case *ir.CallExpr: 668 n.Args = list 669 case *ir.ReturnStmt: 670 n.Results = list 671 case *ir.AssignListStmt: 672 if n.Op() != ir.OAS2FUNC { 673 base.Fatalf("RewriteMultiValueCall: invalid op %v", n.Op()) 674 } 675 as.SetOp(ir.OAS2FUNC) 676 n.SetOp(ir.OAS2) 677 n.Rhs = make([]ir.Node, len(list)) 678 for i, tmp := range list { 679 n.Rhs[i] = AssignConv(tmp, n.Lhs[i].Type(), "assignment") 680 } 681 } 682} 683 684func checksliceindex(l ir.Node, r ir.Node, tp *types.Type) bool { 685 t := r.Type() 686 if t == nil { 687 return false 688 } 689 if !t.IsInteger() { 690 base.Errorf("invalid slice index %v (type %v)", r, t) 691 return false 692 } 693 694 if r.Op() == ir.OLITERAL { 695 x := r.Val() 696 if constant.Sign(x) < 0 { 697 base.Errorf("invalid slice index %v (index must be non-negative)", r) 698 return false 699 } else if tp != nil && tp.NumElem() >= 0 && constant.Compare(x, token.GTR, constant.MakeInt64(tp.NumElem())) { 700 base.Errorf("invalid slice index %v (out of bounds for %d-element array)", r, tp.NumElem()) 701 return false 702 } else if ir.IsConst(l, constant.String) && constant.Compare(x, token.GTR, constant.MakeInt64(int64(len(ir.StringVal(l))))) { 703 base.Errorf("invalid slice index %v (out of bounds for %d-byte string)", r, len(ir.StringVal(l))) 704 return false 705 } else if ir.ConstOverflow(x, types.Types[types.TINT]) { 706 base.Errorf("invalid slice index %v (index too large)", r) 707 return false 708 } 709 } 710 711 return true 712} 713 714func checksliceconst(lo ir.Node, hi ir.Node) bool { 715 if lo != nil && hi != nil && lo.Op() == ir.OLITERAL && hi.Op() == ir.OLITERAL && constant.Compare(lo.Val(), token.GTR, hi.Val()) { 716 base.Errorf("invalid slice index: %v > %v", lo, hi) 717 return false 718 } 719 720 return true 721} 722 723// The result of implicitstar MUST be assigned back to n, e.g. 724// 725// n.Left = implicitstar(n.Left) 726func implicitstar(n ir.Node) ir.Node { 727 // insert implicit * if needed for fixed array 728 t := n.Type() 729 if t == nil || !t.IsPtr() { 730 return n 731 } 732 t = t.Elem() 733 if t == nil { 734 return n 735 } 736 if !t.IsArray() { 737 return n 738 } 739 star := ir.NewStarExpr(base.Pos, n) 740 star.SetImplicit(true) 741 return Expr(star) 742} 743 744func needOneArg(n *ir.CallExpr, f string, args ...interface{}) (ir.Node, bool) { 745 if len(n.Args) == 0 { 746 p := fmt.Sprintf(f, args...) 747 base.Errorf("missing argument to %s: %v", p, n) 748 return nil, false 749 } 750 751 if len(n.Args) > 1 { 752 p := fmt.Sprintf(f, args...) 753 base.Errorf("too many arguments to %s: %v", p, n) 754 return n.Args[0], false 755 } 756 757 return n.Args[0], true 758} 759 760func needTwoArgs(n *ir.CallExpr) (ir.Node, ir.Node, bool) { 761 if len(n.Args) != 2 { 762 if len(n.Args) < 2 { 763 base.Errorf("not enough arguments in call to %v", n) 764 } else { 765 base.Errorf("too many arguments in call to %v", n) 766 } 767 return nil, nil, false 768 } 769 return n.Args[0], n.Args[1], true 770} 771 772// Lookdot1 looks up the specified method s in the list fs of methods, returning 773// the matching field or nil. If dostrcmp is 0, it matches the symbols. If 774// dostrcmp is 1, it matches by name exactly. If dostrcmp is 2, it matches names 775// with case folding. 776func Lookdot1(errnode ir.Node, s *types.Sym, t *types.Type, fs []*types.Field, dostrcmp int) *types.Field { 777 var r *types.Field 778 for _, f := range fs { 779 if dostrcmp != 0 && f.Sym.Name == s.Name { 780 return f 781 } 782 if dostrcmp == 2 && strings.EqualFold(f.Sym.Name, s.Name) { 783 return f 784 } 785 if f.Sym != s { 786 continue 787 } 788 if r != nil { 789 if errnode != nil { 790 base.Errorf("ambiguous selector %v", errnode) 791 } else if t.IsPtr() { 792 base.Errorf("ambiguous selector (%v).%v", t, s) 793 } else { 794 base.Errorf("ambiguous selector %v.%v", t, s) 795 } 796 break 797 } 798 799 r = f 800 } 801 802 return r 803} 804 805// NewMethodExpr returns an OMETHEXPR node representing method 806// expression "recv.sym". 807func NewMethodExpr(pos src.XPos, recv *types.Type, sym *types.Sym) *ir.SelectorExpr { 808 // Compute the method set for recv. 809 var ms []*types.Field 810 if recv.IsInterface() { 811 ms = recv.AllMethods() 812 } else { 813 mt := types.ReceiverBaseType(recv) 814 if mt == nil { 815 base.FatalfAt(pos, "type %v has no receiver base type", recv) 816 } 817 CalcMethods(mt) 818 ms = mt.AllMethods() 819 } 820 821 m := Lookdot1(nil, sym, recv, ms, 0) 822 if m == nil { 823 base.FatalfAt(pos, "type %v has no method %v", recv, sym) 824 } 825 826 if !types.IsMethodApplicable(recv, m) { 827 base.FatalfAt(pos, "invalid method expression %v.%v (needs pointer receiver)", recv, sym) 828 } 829 830 n := ir.NewSelectorExpr(pos, ir.OMETHEXPR, ir.TypeNode(recv), sym) 831 n.Selection = m 832 n.SetType(NewMethodType(m.Type, recv)) 833 n.SetTypecheck(1) 834 return n 835} 836 837func derefall(t *types.Type) *types.Type { 838 for t != nil && t.IsPtr() { 839 t = t.Elem() 840 } 841 return t 842} 843 844// Lookdot looks up field or method n.Sel in the type t and returns the matching 845// field. It transforms the op of node n to ODOTINTER or ODOTMETH, if appropriate. 846// It also may add a StarExpr node to n.X as needed for access to non-pointer 847// methods. If dostrcmp is 0, it matches the field/method with the exact symbol 848// as n.Sel (appropriate for exported fields). If dostrcmp is 1, it matches by name 849// exactly. If dostrcmp is 2, it matches names with case folding. 850func Lookdot(n *ir.SelectorExpr, t *types.Type, dostrcmp int) *types.Field { 851 s := n.Sel 852 853 types.CalcSize(t) 854 var f1 *types.Field 855 if t.IsStruct() { 856 f1 = Lookdot1(n, s, t, t.Fields(), dostrcmp) 857 } else if t.IsInterface() { 858 f1 = Lookdot1(n, s, t, t.AllMethods(), dostrcmp) 859 } 860 861 var f2 *types.Field 862 if n.X.Type() == t || n.X.Type().Sym() == nil { 863 mt := types.ReceiverBaseType(t) 864 if mt != nil { 865 f2 = Lookdot1(n, s, mt, mt.Methods(), dostrcmp) 866 } 867 } 868 869 if f1 != nil { 870 if dostrcmp > 1 { 871 // Already in the process of diagnosing an error. 872 return f1 873 } 874 if f2 != nil { 875 base.Errorf("%v is both field and method", n.Sel) 876 } 877 if f1.Offset == types.BADWIDTH { 878 base.Fatalf("Lookdot badwidth t=%v, f1=%v@%p", t, f1, f1) 879 } 880 n.Selection = f1 881 n.SetType(f1.Type) 882 if t.IsInterface() { 883 if n.X.Type().IsPtr() { 884 star := ir.NewStarExpr(base.Pos, n.X) 885 star.SetImplicit(true) 886 n.X = Expr(star) 887 } 888 889 n.SetOp(ir.ODOTINTER) 890 } 891 return f1 892 } 893 894 if f2 != nil { 895 if dostrcmp > 1 { 896 // Already in the process of diagnosing an error. 897 return f2 898 } 899 orig := n.X 900 tt := n.X.Type() 901 types.CalcSize(tt) 902 rcvr := f2.Type.Recv().Type 903 if !types.Identical(rcvr, tt) { 904 if rcvr.IsPtr() && types.Identical(rcvr.Elem(), tt) { 905 checklvalue(n.X, "call pointer method on") 906 addr := NodAddr(n.X) 907 addr.SetImplicit(true) 908 n.X = typecheck(addr, ctxType|ctxExpr) 909 } else if tt.IsPtr() && (!rcvr.IsPtr() || rcvr.IsPtr() && rcvr.Elem().NotInHeap()) && types.Identical(tt.Elem(), rcvr) { 910 star := ir.NewStarExpr(base.Pos, n.X) 911 star.SetImplicit(true) 912 n.X = typecheck(star, ctxType|ctxExpr) 913 } else if tt.IsPtr() && tt.Elem().IsPtr() && types.Identical(derefall(tt), derefall(rcvr)) { 914 base.Errorf("calling method %v with receiver %L requires explicit dereference", n.Sel, n.X) 915 for tt.IsPtr() { 916 // Stop one level early for method with pointer receiver. 917 if rcvr.IsPtr() && !tt.Elem().IsPtr() { 918 break 919 } 920 star := ir.NewStarExpr(base.Pos, n.X) 921 star.SetImplicit(true) 922 n.X = typecheck(star, ctxType|ctxExpr) 923 tt = tt.Elem() 924 } 925 } else { 926 base.Fatalf("method mismatch: %v for %v", rcvr, tt) 927 } 928 } 929 930 // Check that we haven't implicitly dereferenced any defined pointer types. 931 for x := n.X; ; { 932 var inner ir.Node 933 implicit := false 934 switch x := x.(type) { 935 case *ir.AddrExpr: 936 inner, implicit = x.X, x.Implicit() 937 case *ir.SelectorExpr: 938 inner, implicit = x.X, x.Implicit() 939 case *ir.StarExpr: 940 inner, implicit = x.X, x.Implicit() 941 } 942 if !implicit { 943 break 944 } 945 if inner.Type().Sym() != nil && (x.Op() == ir.ODEREF || x.Op() == ir.ODOTPTR) { 946 // Found an implicit dereference of a defined pointer type. 947 // Restore n.X for better error message. 948 n.X = orig 949 return nil 950 } 951 x = inner 952 } 953 954 n.Selection = f2 955 n.SetType(f2.Type) 956 n.SetOp(ir.ODOTMETH) 957 958 return f2 959 } 960 961 return nil 962} 963 964func nokeys(l ir.Nodes) bool { 965 for _, n := range l { 966 if n.Op() == ir.OKEY || n.Op() == ir.OSTRUCTKEY { 967 return false 968 } 969 } 970 return true 971} 972 973func hasddd(params []*types.Field) bool { 974 // TODO(mdempsky): Simply check the last param. 975 for _, tl := range params { 976 if tl.IsDDD() { 977 return true 978 } 979 } 980 981 return false 982} 983 984// typecheck assignment: type list = expression list 985func typecheckaste(op ir.Op, call ir.Node, isddd bool, params []*types.Field, nl ir.Nodes, desc func() string) { 986 var t *types.Type 987 var i int 988 989 lno := base.Pos 990 defer func() { base.Pos = lno }() 991 992 var n ir.Node 993 if len(nl) == 1 { 994 n = nl[0] 995 } 996 997 n1 := len(params) 998 n2 := len(nl) 999 if !hasddd(params) { 1000 if isddd { 1001 goto invalidddd 1002 } 1003 if n2 > n1 { 1004 goto toomany 1005 } 1006 if n2 < n1 { 1007 goto notenough 1008 } 1009 } else { 1010 if !isddd { 1011 if n2 < n1-1 { 1012 goto notenough 1013 } 1014 } else { 1015 if n2 > n1 { 1016 goto toomany 1017 } 1018 if n2 < n1 { 1019 goto notenough 1020 } 1021 } 1022 } 1023 1024 i = 0 1025 for _, tl := range params { 1026 t = tl.Type 1027 if tl.IsDDD() { 1028 if isddd { 1029 if i >= len(nl) { 1030 goto notenough 1031 } 1032 if len(nl)-i > 1 { 1033 goto toomany 1034 } 1035 n = nl[i] 1036 ir.SetPos(n) 1037 if n.Type() != nil { 1038 nl[i] = assignconvfn(n, t, desc) 1039 } 1040 return 1041 } 1042 1043 // TODO(mdempsky): Make into ... call with implicit slice. 1044 for ; i < len(nl); i++ { 1045 n = nl[i] 1046 ir.SetPos(n) 1047 if n.Type() != nil { 1048 nl[i] = assignconvfn(n, t.Elem(), desc) 1049 } 1050 } 1051 return 1052 } 1053 1054 if i >= len(nl) { 1055 goto notenough 1056 } 1057 n = nl[i] 1058 ir.SetPos(n) 1059 if n.Type() != nil { 1060 nl[i] = assignconvfn(n, t, desc) 1061 } 1062 i++ 1063 } 1064 1065 if i < len(nl) { 1066 goto toomany 1067 } 1068 1069invalidddd: 1070 if isddd { 1071 if call != nil { 1072 base.Errorf("invalid use of ... in call to %v", call) 1073 } else { 1074 base.Errorf("invalid use of ... in %v", op) 1075 } 1076 } 1077 return 1078 1079notenough: 1080 if n == nil || n.Type() != nil { 1081 base.Fatalf("not enough arguments to %v", op) 1082 } 1083 return 1084 1085toomany: 1086 base.Fatalf("too many arguments to %v", op) 1087} 1088 1089// type check composite. 1090func fielddup(name string, hash map[string]bool) { 1091 if hash[name] { 1092 base.Errorf("duplicate field name in struct literal: %s", name) 1093 return 1094 } 1095 hash[name] = true 1096} 1097 1098// typecheckarraylit type-checks a sequence of slice/array literal elements. 1099func typecheckarraylit(elemType *types.Type, bound int64, elts []ir.Node, ctx string) int64 { 1100 // If there are key/value pairs, create a map to keep seen 1101 // keys so we can check for duplicate indices. 1102 var indices map[int64]bool 1103 for _, elt := range elts { 1104 if elt.Op() == ir.OKEY { 1105 indices = make(map[int64]bool) 1106 break 1107 } 1108 } 1109 1110 var key, length int64 1111 for i, elt := range elts { 1112 ir.SetPos(elt) 1113 r := elts[i] 1114 var kv *ir.KeyExpr 1115 if elt.Op() == ir.OKEY { 1116 elt := elt.(*ir.KeyExpr) 1117 elt.Key = Expr(elt.Key) 1118 key = IndexConst(elt.Key) 1119 if key < 0 { 1120 base.Fatalf("invalid index: %v", elt.Key) 1121 } 1122 kv = elt 1123 r = elt.Value 1124 } 1125 1126 r = Expr(r) 1127 r = AssignConv(r, elemType, ctx) 1128 if kv != nil { 1129 kv.Value = r 1130 } else { 1131 elts[i] = r 1132 } 1133 1134 if key >= 0 { 1135 if indices != nil { 1136 if indices[key] { 1137 base.Errorf("duplicate index in %s: %d", ctx, key) 1138 } else { 1139 indices[key] = true 1140 } 1141 } 1142 1143 if bound >= 0 && key >= bound { 1144 base.Errorf("array index %d out of bounds [0:%d]", key, bound) 1145 bound = -1 1146 } 1147 } 1148 1149 key++ 1150 if key > length { 1151 length = key 1152 } 1153 } 1154 1155 return length 1156} 1157 1158// visible reports whether sym is exported or locally defined. 1159func visible(sym *types.Sym) bool { 1160 return sym != nil && (types.IsExported(sym.Name) || sym.Pkg == types.LocalPkg) 1161} 1162 1163// nonexported reports whether sym is an unexported field. 1164func nonexported(sym *types.Sym) bool { 1165 return sym != nil && !types.IsExported(sym.Name) 1166} 1167 1168func checklvalue(n ir.Node, verb string) { 1169 if !ir.IsAddressable(n) { 1170 base.Errorf("cannot %s %v", verb, n) 1171 } 1172} 1173 1174func checkassign(n ir.Node) { 1175 // have already complained about n being invalid 1176 if n.Type() == nil { 1177 if base.Errors() == 0 { 1178 base.Fatalf("expected an error about %v", n) 1179 } 1180 return 1181 } 1182 1183 if ir.IsAddressable(n) { 1184 return 1185 } 1186 if n.Op() == ir.OINDEXMAP { 1187 n := n.(*ir.IndexExpr) 1188 n.Assigned = true 1189 return 1190 } 1191 1192 defer n.SetType(nil) 1193 1194 switch { 1195 case n.Op() == ir.ODOT && n.(*ir.SelectorExpr).X.Op() == ir.OINDEXMAP: 1196 base.Errorf("cannot assign to struct field %v in map", n) 1197 case (n.Op() == ir.OINDEX && n.(*ir.IndexExpr).X.Type().IsString()) || n.Op() == ir.OSLICESTR: 1198 base.Errorf("cannot assign to %v (strings are immutable)", n) 1199 case n.Op() == ir.OLITERAL && n.Sym() != nil && ir.IsConstNode(n): 1200 base.Errorf("cannot assign to %v (declared const)", n) 1201 default: 1202 base.Errorf("cannot assign to %v", n) 1203 } 1204} 1205 1206func checkassignto(src *types.Type, dst ir.Node) { 1207 // TODO(mdempsky): Handle all untyped types correctly. 1208 if src == types.UntypedBool && dst.Type().IsBoolean() { 1209 return 1210 } 1211 1212 if op, why := assignOp(src, dst.Type()); op == ir.OXXX { 1213 base.Errorf("cannot assign %v to %L in multiple assignment%s", src, dst, why) 1214 return 1215 } 1216} 1217 1218// The result of stringtoruneslit MUST be assigned back to n, e.g. 1219// 1220// n.Left = stringtoruneslit(n.Left) 1221func stringtoruneslit(n *ir.ConvExpr) ir.Node { 1222 if n.X.Op() != ir.OLITERAL || n.X.Val().Kind() != constant.String { 1223 base.Fatalf("stringtoarraylit %v", n) 1224 } 1225 1226 var l []ir.Node 1227 i := 0 1228 for _, r := range ir.StringVal(n.X) { 1229 l = append(l, ir.NewKeyExpr(base.Pos, ir.NewInt(base.Pos, int64(i)), ir.NewInt(base.Pos, int64(r)))) 1230 i++ 1231 } 1232 1233 return Expr(ir.NewCompLitExpr(base.Pos, ir.OCOMPLIT, n.Type(), l)) 1234} 1235 1236func checkmake(t *types.Type, arg string, np *ir.Node) bool { 1237 n := *np 1238 if !n.Type().IsInteger() && n.Type().Kind() != types.TIDEAL { 1239 base.Errorf("non-integer %s argument in make(%v) - %v", arg, t, n.Type()) 1240 return false 1241 } 1242 1243 // Do range checks for constants before DefaultLit 1244 // to avoid redundant "constant NNN overflows int" errors. 1245 if n.Op() == ir.OLITERAL { 1246 v := toint(n.Val()) 1247 if constant.Sign(v) < 0 { 1248 base.Errorf("negative %s argument in make(%v)", arg, t) 1249 return false 1250 } 1251 if ir.ConstOverflow(v, types.Types[types.TINT]) { 1252 base.Errorf("%s argument too large in make(%v)", arg, t) 1253 return false 1254 } 1255 } 1256 1257 // DefaultLit is necessary for non-constants too: n might be 1.1<<k. 1258 // TODO(gri) The length argument requirements for (array/slice) make 1259 // are the same as for index expressions. Factor the code better; 1260 // for instance, indexlit might be called here and incorporate some 1261 // of the bounds checks done for make. 1262 n = DefaultLit(n, types.Types[types.TINT]) 1263 *np = n 1264 1265 return true 1266} 1267 1268// checkunsafesliceorstring is like checkmake but for unsafe.{Slice,String}. 1269func checkunsafesliceorstring(op ir.Op, np *ir.Node) bool { 1270 n := *np 1271 if !n.Type().IsInteger() && n.Type().Kind() != types.TIDEAL { 1272 base.Errorf("non-integer len argument in %v - %v", op, n.Type()) 1273 return false 1274 } 1275 1276 // Do range checks for constants before DefaultLit 1277 // to avoid redundant "constant NNN overflows int" errors. 1278 if n.Op() == ir.OLITERAL { 1279 v := toint(n.Val()) 1280 if constant.Sign(v) < 0 { 1281 base.Errorf("negative len argument in %v", op) 1282 return false 1283 } 1284 if ir.ConstOverflow(v, types.Types[types.TINT]) { 1285 base.Errorf("len argument too large in %v", op) 1286 return false 1287 } 1288 } 1289 1290 // DefaultLit is necessary for non-constants too: n might be 1.1<<k. 1291 n = DefaultLit(n, types.Types[types.TINT]) 1292 *np = n 1293 1294 return true 1295} 1296 1297func Conv(n ir.Node, t *types.Type) ir.Node { 1298 if types.IdenticalStrict(n.Type(), t) { 1299 return n 1300 } 1301 n = ir.NewConvExpr(base.Pos, ir.OCONV, nil, n) 1302 n.SetType(t) 1303 n = Expr(n) 1304 return n 1305} 1306 1307// ConvNop converts node n to type t using the OCONVNOP op 1308// and typechecks the result with ctxExpr. 1309func ConvNop(n ir.Node, t *types.Type) ir.Node { 1310 if types.IdenticalStrict(n.Type(), t) { 1311 return n 1312 } 1313 n = ir.NewConvExpr(base.Pos, ir.OCONVNOP, nil, n) 1314 n.SetType(t) 1315 n = Expr(n) 1316 return n 1317} 1318