github.com/megatontech/mynoteforgo@v0.0.0-20200507084910-5d0c6ea6e890/源码/cmd/compile/internal/gc/subr.go (about) 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 5 package gc 6 7 import ( 8 "cmd/compile/internal/types" 9 "cmd/internal/objabi" 10 "cmd/internal/src" 11 "crypto/md5" 12 "encoding/binary" 13 "fmt" 14 "os" 15 "runtime/debug" 16 "sort" 17 "strconv" 18 "strings" 19 "sync" 20 "unicode" 21 "unicode/utf8" 22 ) 23 24 type Error struct { 25 pos src.XPos 26 msg string 27 } 28 29 var errors []Error 30 31 // largeStack is info about a function whose stack frame is too large (rare). 32 type largeStack struct { 33 locals int64 34 args int64 35 callee int64 36 pos src.XPos 37 } 38 39 var ( 40 largeStackFramesMu sync.Mutex // protects largeStackFrames 41 largeStackFrames []largeStack 42 ) 43 44 func errorexit() { 45 flusherrors() 46 if outfile != "" { 47 os.Remove(outfile) 48 } 49 os.Exit(2) 50 } 51 52 func adderrorname(n *Node) { 53 if n.Op != ODOT { 54 return 55 } 56 old := fmt.Sprintf("%v: undefined: %v\n", n.Line(), n.Left) 57 if len(errors) > 0 && errors[len(errors)-1].pos.Line() == n.Pos.Line() && errors[len(errors)-1].msg == old { 58 errors[len(errors)-1].msg = fmt.Sprintf("%v: undefined: %v in %v\n", n.Line(), n.Left, n) 59 } 60 } 61 62 func adderr(pos src.XPos, format string, args ...interface{}) { 63 errors = append(errors, Error{ 64 pos: pos, 65 msg: fmt.Sprintf("%v: %s\n", linestr(pos), fmt.Sprintf(format, args...)), 66 }) 67 } 68 69 // byPos sorts errors by source position. 70 type byPos []Error 71 72 func (x byPos) Len() int { return len(x) } 73 func (x byPos) Less(i, j int) bool { return x[i].pos.Before(x[j].pos) } 74 func (x byPos) Swap(i, j int) { x[i], x[j] = x[j], x[i] } 75 76 // flusherrors sorts errors seen so far by line number, prints them to stdout, 77 // and empties the errors array. 78 func flusherrors() { 79 Ctxt.Bso.Flush() 80 if len(errors) == 0 { 81 return 82 } 83 sort.Stable(byPos(errors)) 84 for i, err := range errors { 85 if i == 0 || err.msg != errors[i-1].msg { 86 fmt.Printf("%s", err.msg) 87 } 88 } 89 errors = errors[:0] 90 } 91 92 func hcrash() { 93 if Debug['h'] != 0 { 94 flusherrors() 95 if outfile != "" { 96 os.Remove(outfile) 97 } 98 var x *int 99 *x = 0 100 } 101 } 102 103 func linestr(pos src.XPos) string { 104 return Ctxt.OutermostPos(pos).Format(Debug['C'] == 0, Debug['L'] == 1) 105 } 106 107 // lasterror keeps track of the most recently issued error. 108 // It is used to avoid multiple error messages on the same 109 // line. 110 var lasterror struct { 111 syntax src.XPos // source position of last syntax error 112 other src.XPos // source position of last non-syntax error 113 msg string // error message of last non-syntax error 114 } 115 116 // sameline reports whether two positions a, b are on the same line. 117 func sameline(a, b src.XPos) bool { 118 p := Ctxt.PosTable.Pos(a) 119 q := Ctxt.PosTable.Pos(b) 120 return p.Base() == q.Base() && p.Line() == q.Line() 121 } 122 123 func yyerrorl(pos src.XPos, format string, args ...interface{}) { 124 msg := fmt.Sprintf(format, args...) 125 126 if strings.HasPrefix(msg, "syntax error") { 127 nsyntaxerrors++ 128 // only one syntax error per line, no matter what error 129 if sameline(lasterror.syntax, pos) { 130 return 131 } 132 lasterror.syntax = pos 133 } else { 134 // only one of multiple equal non-syntax errors per line 135 // (flusherrors shows only one of them, so we filter them 136 // here as best as we can (they may not appear in order) 137 // so that we don't count them here and exit early, and 138 // then have nothing to show for.) 139 if sameline(lasterror.other, pos) && lasterror.msg == msg { 140 return 141 } 142 lasterror.other = pos 143 lasterror.msg = msg 144 } 145 146 adderr(pos, "%s", msg) 147 148 hcrash() 149 nerrors++ 150 if nsavederrors+nerrors >= 10 && Debug['e'] == 0 { 151 flusherrors() 152 fmt.Printf("%v: too many errors\n", linestr(pos)) 153 errorexit() 154 } 155 } 156 157 func yyerror(format string, args ...interface{}) { 158 yyerrorl(lineno, format, args...) 159 } 160 161 func Warn(fmt_ string, args ...interface{}) { 162 adderr(lineno, fmt_, args...) 163 164 hcrash() 165 } 166 167 func Warnl(line src.XPos, fmt_ string, args ...interface{}) { 168 adderr(line, fmt_, args...) 169 if Debug['m'] != 0 { 170 flusherrors() 171 } 172 } 173 174 func Fatalf(fmt_ string, args ...interface{}) { 175 flusherrors() 176 177 if Debug_panic != 0 || nsavederrors+nerrors == 0 { 178 fmt.Printf("%v: internal compiler error: ", linestr(lineno)) 179 fmt.Printf(fmt_, args...) 180 fmt.Printf("\n") 181 182 // If this is a released compiler version, ask for a bug report. 183 if strings.HasPrefix(objabi.Version, "go") { 184 fmt.Printf("\n") 185 fmt.Printf("Please file a bug report including a short program that triggers the error.\n") 186 fmt.Printf("https://golang.org/issue/new\n") 187 } else { 188 // Not a release; dump a stack trace, too. 189 fmt.Println() 190 os.Stdout.Write(debug.Stack()) 191 fmt.Println() 192 } 193 } 194 195 hcrash() 196 errorexit() 197 } 198 199 func setlineno(n *Node) src.XPos { 200 lno := lineno 201 if n != nil { 202 switch n.Op { 203 case ONAME, OPACK: 204 break 205 206 case OLITERAL, OTYPE: 207 if n.Sym != nil { 208 break 209 } 210 fallthrough 211 212 default: 213 lineno = n.Pos 214 if !lineno.IsKnown() { 215 if Debug['K'] != 0 { 216 Warn("setlineno: unknown position (line 0)") 217 } 218 lineno = lno 219 } 220 } 221 } 222 223 return lno 224 } 225 226 func lookup(name string) *types.Sym { 227 return localpkg.Lookup(name) 228 } 229 230 // lookupN looks up the symbol starting with prefix and ending with 231 // the decimal n. If prefix is too long, lookupN panics. 232 func lookupN(prefix string, n int) *types.Sym { 233 var buf [20]byte // plenty long enough for all current users 234 copy(buf[:], prefix) 235 b := strconv.AppendInt(buf[:len(prefix)], int64(n), 10) 236 return localpkg.LookupBytes(b) 237 } 238 239 // autolabel generates a new Name node for use with 240 // an automatically generated label. 241 // prefix is a short mnemonic (e.g. ".s" for switch) 242 // to help with debugging. 243 // It should begin with "." to avoid conflicts with 244 // user labels. 245 func autolabel(prefix string) *types.Sym { 246 if prefix[0] != '.' { 247 Fatalf("autolabel prefix must start with '.', have %q", prefix) 248 } 249 fn := Curfn 250 if Curfn == nil { 251 Fatalf("autolabel outside function") 252 } 253 n := fn.Func.Label 254 fn.Func.Label++ 255 return lookupN(prefix, int(n)) 256 } 257 258 func restrictlookup(name string, pkg *types.Pkg) *types.Sym { 259 if !types.IsExported(name) && pkg != localpkg { 260 yyerror("cannot refer to unexported name %s.%s", pkg.Name, name) 261 } 262 return pkg.Lookup(name) 263 } 264 265 // find all the exported symbols in package opkg 266 // and make them available in the current package 267 func importdot(opkg *types.Pkg, pack *Node) { 268 n := 0 269 for _, s := range opkg.Syms { 270 if s.Def == nil { 271 continue 272 } 273 if !types.IsExported(s.Name) || strings.ContainsRune(s.Name, 0xb7) { // 0xb7 = center dot 274 continue 275 } 276 s1 := lookup(s.Name) 277 if s1.Def != nil { 278 pkgerror := fmt.Sprintf("during import %q", opkg.Path) 279 redeclare(lineno, s1, pkgerror) 280 continue 281 } 282 283 s1.Def = s.Def 284 s1.Block = s.Block 285 if asNode(s1.Def).Name == nil { 286 Dump("s1def", asNode(s1.Def)) 287 Fatalf("missing Name") 288 } 289 asNode(s1.Def).Name.Pack = pack 290 s1.Origpkg = opkg 291 n++ 292 } 293 294 if n == 0 { 295 // can't possibly be used - there were no symbols 296 yyerrorl(pack.Pos, "imported and not used: %q", opkg.Path) 297 } 298 } 299 300 func nod(op Op, nleft, nright *Node) *Node { 301 return nodl(lineno, op, nleft, nright) 302 } 303 304 func nodl(pos src.XPos, op Op, nleft, nright *Node) *Node { 305 var n *Node 306 switch op { 307 case OCLOSURE, ODCLFUNC: 308 var x struct { 309 Node 310 Func 311 } 312 n = &x.Node 313 n.Func = &x.Func 314 case ONAME: 315 Fatalf("use newname instead") 316 case OLABEL, OPACK: 317 var x struct { 318 Node 319 Name 320 } 321 n = &x.Node 322 n.Name = &x.Name 323 default: 324 n = new(Node) 325 } 326 n.Op = op 327 n.Left = nleft 328 n.Right = nright 329 n.Pos = pos 330 n.Xoffset = BADWIDTH 331 n.Orig = n 332 return n 333 } 334 335 // newname returns a new ONAME Node associated with symbol s. 336 func newname(s *types.Sym) *Node { 337 n := newnamel(lineno, s) 338 n.Name.Curfn = Curfn 339 return n 340 } 341 342 // newname returns a new ONAME Node associated with symbol s at position pos. 343 // The caller is responsible for setting n.Name.Curfn. 344 func newnamel(pos src.XPos, s *types.Sym) *Node { 345 if s == nil { 346 Fatalf("newnamel nil") 347 } 348 349 var x struct { 350 Node 351 Name 352 Param 353 } 354 n := &x.Node 355 n.Name = &x.Name 356 n.Name.Param = &x.Param 357 358 n.Op = ONAME 359 n.Pos = pos 360 n.Orig = n 361 362 n.Sym = s 363 n.SetAddable(true) 364 return n 365 } 366 367 // nodSym makes a Node with Op op and with the Left field set to left 368 // and the Sym field set to sym. This is for ODOT and friends. 369 func nodSym(op Op, left *Node, sym *types.Sym) *Node { 370 n := nod(op, left, nil) 371 n.Sym = sym 372 return n 373 } 374 375 // rawcopy returns a shallow copy of n. 376 // Note: copy or sepcopy (rather than rawcopy) is usually the 377 // correct choice (see comment with Node.copy, below). 378 func (n *Node) rawcopy() *Node { 379 copy := *n 380 return © 381 } 382 383 // sepcopy returns a separate shallow copy of n, with the copy's 384 // Orig pointing to itself. 385 func (n *Node) sepcopy() *Node { 386 copy := *n 387 copy.Orig = © 388 return © 389 } 390 391 // copy returns shallow copy of n and adjusts the copy's Orig if 392 // necessary: In general, if n.Orig points to itself, the copy's 393 // Orig should point to itself as well. Otherwise, if n is modified, 394 // the copy's Orig node appears modified, too, and then doesn't 395 // represent the original node anymore. 396 // (This caused the wrong complit Op to be used when printing error 397 // messages; see issues #26855, #27765). 398 func (n *Node) copy() *Node { 399 copy := *n 400 if n.Orig == n { 401 copy.Orig = © 402 } 403 return © 404 } 405 406 // methcmp sorts methods by symbol. 407 type methcmp []*types.Field 408 409 func (x methcmp) Len() int { return len(x) } 410 func (x methcmp) Swap(i, j int) { x[i], x[j] = x[j], x[i] } 411 func (x methcmp) Less(i, j int) bool { return x[i].Sym.Less(x[j].Sym) } 412 413 func nodintconst(v int64) *Node { 414 u := new(Mpint) 415 u.SetInt64(v) 416 return nodlit(Val{u}) 417 } 418 419 func nodfltconst(v *Mpflt) *Node { 420 u := newMpflt() 421 u.Set(v) 422 return nodlit(Val{u}) 423 } 424 425 func nodnil() *Node { 426 return nodlit(Val{new(NilVal)}) 427 } 428 429 func nodbool(b bool) *Node { 430 return nodlit(Val{b}) 431 } 432 433 func nodstr(s string) *Node { 434 return nodlit(Val{s}) 435 } 436 437 // treecopy recursively copies n, with the exception of 438 // ONAME, OLITERAL, OTYPE, and non-iota ONONAME leaves. 439 // Copies of iota ONONAME nodes are assigned the current 440 // value of iota_. If pos.IsKnown(), it sets the source 441 // position of newly allocated nodes to pos. 442 func treecopy(n *Node, pos src.XPos) *Node { 443 if n == nil { 444 return nil 445 } 446 447 switch n.Op { 448 default: 449 m := n.sepcopy() 450 m.Left = treecopy(n.Left, pos) 451 m.Right = treecopy(n.Right, pos) 452 m.List.Set(listtreecopy(n.List.Slice(), pos)) 453 if pos.IsKnown() { 454 m.Pos = pos 455 } 456 if m.Name != nil && n.Op != ODCLFIELD { 457 Dump("treecopy", n) 458 Fatalf("treecopy Name") 459 } 460 return m 461 462 case OPACK: 463 // OPACK nodes are never valid in const value declarations, 464 // but allow them like any other declared symbol to avoid 465 // crashing (golang.org/issue/11361). 466 fallthrough 467 468 case ONAME, ONONAME, OLITERAL, OTYPE: 469 return n 470 471 } 472 } 473 474 // isNil reports whether n represents the universal untyped zero value "nil". 475 func (n *Node) isNil() bool { 476 // Check n.Orig because constant propagation may produce typed nil constants, 477 // which don't exist in the Go spec. 478 return Isconst(n.Orig, CTNIL) 479 } 480 481 func isptrto(t *types.Type, et types.EType) bool { 482 if t == nil { 483 return false 484 } 485 if !t.IsPtr() { 486 return false 487 } 488 t = t.Elem() 489 if t == nil { 490 return false 491 } 492 if t.Etype != et { 493 return false 494 } 495 return true 496 } 497 498 func (n *Node) isBlank() bool { 499 if n == nil { 500 return false 501 } 502 return n.Sym.IsBlank() 503 } 504 505 // methtype returns the underlying type, if any, 506 // that owns methods with receiver parameter t. 507 // The result is either a named type or an anonymous struct. 508 func methtype(t *types.Type) *types.Type { 509 if t == nil { 510 return nil 511 } 512 513 // Strip away pointer if it's there. 514 if t.IsPtr() { 515 if t.Sym != nil { 516 return nil 517 } 518 t = t.Elem() 519 if t == nil { 520 return nil 521 } 522 } 523 524 // Must be a named type or anonymous struct. 525 if t.Sym == nil && !t.IsStruct() { 526 return nil 527 } 528 529 // Check types. 530 if issimple[t.Etype] { 531 return t 532 } 533 switch t.Etype { 534 case TARRAY, TCHAN, TFUNC, TMAP, TSLICE, TSTRING, TSTRUCT: 535 return t 536 } 537 return nil 538 } 539 540 // Are t1 and t2 equal struct types when field names are ignored? 541 // For deciding whether the result struct from g can be copied 542 // directly when compiling f(g()). 543 func eqtypenoname(t1 *types.Type, t2 *types.Type) bool { 544 if t1 == nil || t2 == nil || !t1.IsStruct() || !t2.IsStruct() { 545 return false 546 } 547 548 if t1.NumFields() != t2.NumFields() { 549 return false 550 } 551 for i, f1 := range t1.FieldSlice() { 552 f2 := t2.Field(i) 553 if !types.Identical(f1.Type, f2.Type) { 554 return false 555 } 556 } 557 return true 558 } 559 560 // Is type src assignment compatible to type dst? 561 // If so, return op code to use in conversion. 562 // If not, return 0. 563 func assignop(src *types.Type, dst *types.Type, why *string) Op { 564 if why != nil { 565 *why = "" 566 } 567 568 if src == dst { 569 return OCONVNOP 570 } 571 if src == nil || dst == nil || src.Etype == TFORW || dst.Etype == TFORW || src.Orig == nil || dst.Orig == nil { 572 return 0 573 } 574 575 // 1. src type is identical to dst. 576 if types.Identical(src, dst) { 577 return OCONVNOP 578 } 579 580 // 2. src and dst have identical underlying types 581 // and either src or dst is not a named type or 582 // both are empty interface types. 583 // For assignable but different non-empty interface types, 584 // we want to recompute the itab. Recomputing the itab ensures 585 // that itabs are unique (thus an interface with a compile-time 586 // type I has an itab with interface type I). 587 if types.Identical(src.Orig, dst.Orig) { 588 if src.IsEmptyInterface() { 589 // Conversion between two empty interfaces 590 // requires no code. 591 return OCONVNOP 592 } 593 if (src.Sym == nil || dst.Sym == nil) && !src.IsInterface() { 594 // Conversion between two types, at least one unnamed, 595 // needs no conversion. The exception is nonempty interfaces 596 // which need to have their itab updated. 597 return OCONVNOP 598 } 599 } 600 601 // 3. dst is an interface type and src implements dst. 602 if dst.IsInterface() && src.Etype != TNIL { 603 var missing, have *types.Field 604 var ptr int 605 if implements(src, dst, &missing, &have, &ptr) { 606 return OCONVIFACE 607 } 608 609 // we'll have complained about this method anyway, suppress spurious messages. 610 if have != nil && have.Sym == missing.Sym && (have.Type.Broke() || missing.Type.Broke()) { 611 return OCONVIFACE 612 } 613 614 if why != nil { 615 if isptrto(src, TINTER) { 616 *why = fmt.Sprintf(":\n\t%v is pointer to interface, not interface", src) 617 } else if have != nil && have.Sym == missing.Sym && have.Nointerface() { 618 *why = fmt.Sprintf(":\n\t%v does not implement %v (%v method is marked 'nointerface')", src, dst, missing.Sym) 619 } else if have != nil && have.Sym == missing.Sym { 620 *why = fmt.Sprintf(":\n\t%v does not implement %v (wrong type for %v method)\n"+ 621 "\t\thave %v%0S\n\t\twant %v%0S", src, dst, missing.Sym, have.Sym, have.Type, missing.Sym, missing.Type) 622 } else if ptr != 0 { 623 *why = fmt.Sprintf(":\n\t%v does not implement %v (%v method has pointer receiver)", src, dst, missing.Sym) 624 } else if have != nil { 625 *why = fmt.Sprintf(":\n\t%v does not implement %v (missing %v method)\n"+ 626 "\t\thave %v%0S\n\t\twant %v%0S", src, dst, missing.Sym, have.Sym, have.Type, missing.Sym, missing.Type) 627 } else { 628 *why = fmt.Sprintf(":\n\t%v does not implement %v (missing %v method)", src, dst, missing.Sym) 629 } 630 } 631 632 return 0 633 } 634 635 if isptrto(dst, TINTER) { 636 if why != nil { 637 *why = fmt.Sprintf(":\n\t%v is pointer to interface, not interface", dst) 638 } 639 return 0 640 } 641 642 if src.IsInterface() && dst.Etype != TBLANK { 643 var missing, have *types.Field 644 var ptr int 645 if why != nil && implements(dst, src, &missing, &have, &ptr) { 646 *why = ": need type assertion" 647 } 648 return 0 649 } 650 651 // 4. src is a bidirectional channel value, dst is a channel type, 652 // src and dst have identical element types, and 653 // either src or dst is not a named type. 654 if src.IsChan() && src.ChanDir() == types.Cboth && dst.IsChan() { 655 if types.Identical(src.Elem(), dst.Elem()) && (src.Sym == nil || dst.Sym == nil) { 656 return OCONVNOP 657 } 658 } 659 660 // 5. src is the predeclared identifier nil and dst is a nillable type. 661 if src.Etype == TNIL { 662 switch dst.Etype { 663 case TPTR, 664 TFUNC, 665 TMAP, 666 TCHAN, 667 TINTER, 668 TSLICE: 669 return OCONVNOP 670 } 671 } 672 673 // 6. rule about untyped constants - already converted by defaultlit. 674 675 // 7. Any typed value can be assigned to the blank identifier. 676 if dst.Etype == TBLANK { 677 return OCONVNOP 678 } 679 680 return 0 681 } 682 683 // Can we convert a value of type src to a value of type dst? 684 // If so, return op code to use in conversion (maybe OCONVNOP). 685 // If not, return 0. 686 func convertop(src *types.Type, dst *types.Type, why *string) Op { 687 if why != nil { 688 *why = "" 689 } 690 691 if src == dst { 692 return OCONVNOP 693 } 694 if src == nil || dst == nil { 695 return 0 696 } 697 698 // Conversions from regular to go:notinheap are not allowed 699 // (unless it's unsafe.Pointer). These are runtime-specific 700 // rules. 701 // (a) Disallow (*T) to (*U) where T is go:notinheap but U isn't. 702 if src.IsPtr() && dst.IsPtr() && dst.Elem().NotInHeap() && !src.Elem().NotInHeap() { 703 if why != nil { 704 *why = fmt.Sprintf(":\n\t%v is go:notinheap, but %v is not", dst.Elem(), src.Elem()) 705 } 706 return 0 707 } 708 // (b) Disallow string to []T where T is go:notinheap. 709 if src.IsString() && dst.IsSlice() && dst.Elem().NotInHeap() && (dst.Elem().Etype == types.Bytetype.Etype || dst.Elem().Etype == types.Runetype.Etype) { 710 if why != nil { 711 *why = fmt.Sprintf(":\n\t%v is go:notinheap", dst.Elem()) 712 } 713 return 0 714 } 715 716 // 1. src can be assigned to dst. 717 op := assignop(src, dst, why) 718 if op != 0 { 719 return op 720 } 721 722 // The rules for interfaces are no different in conversions 723 // than assignments. If interfaces are involved, stop now 724 // with the good message from assignop. 725 // Otherwise clear the error. 726 if src.IsInterface() || dst.IsInterface() { 727 return 0 728 } 729 if why != nil { 730 *why = "" 731 } 732 733 // 2. Ignoring struct tags, src and dst have identical underlying types. 734 if types.IdenticalIgnoreTags(src.Orig, dst.Orig) { 735 return OCONVNOP 736 } 737 738 // 3. src and dst are unnamed pointer types and, ignoring struct tags, 739 // their base types have identical underlying types. 740 if src.IsPtr() && dst.IsPtr() && src.Sym == nil && dst.Sym == nil { 741 if types.IdenticalIgnoreTags(src.Elem().Orig, dst.Elem().Orig) { 742 return OCONVNOP 743 } 744 } 745 746 // 4. src and dst are both integer or floating point types. 747 if (src.IsInteger() || src.IsFloat()) && (dst.IsInteger() || dst.IsFloat()) { 748 if simtype[src.Etype] == simtype[dst.Etype] { 749 return OCONVNOP 750 } 751 return OCONV 752 } 753 754 // 5. src and dst are both complex types. 755 if src.IsComplex() && dst.IsComplex() { 756 if simtype[src.Etype] == simtype[dst.Etype] { 757 return OCONVNOP 758 } 759 return OCONV 760 } 761 762 // 6. src is an integer or has type []byte or []rune 763 // and dst is a string type. 764 if src.IsInteger() && dst.IsString() { 765 return ORUNESTR 766 } 767 768 if src.IsSlice() && dst.IsString() { 769 if src.Elem().Etype == types.Bytetype.Etype { 770 return OBYTES2STR 771 } 772 if src.Elem().Etype == types.Runetype.Etype { 773 return ORUNES2STR 774 } 775 } 776 777 // 7. src is a string and dst is []byte or []rune. 778 // String to slice. 779 if src.IsString() && dst.IsSlice() { 780 if dst.Elem().Etype == types.Bytetype.Etype { 781 return OSTR2BYTES 782 } 783 if dst.Elem().Etype == types.Runetype.Etype { 784 return OSTR2RUNES 785 } 786 } 787 788 // 8. src is a pointer or uintptr and dst is unsafe.Pointer. 789 if (src.IsPtr() || src.Etype == TUINTPTR) && dst.Etype == TUNSAFEPTR { 790 return OCONVNOP 791 } 792 793 // 9. src is unsafe.Pointer and dst is a pointer or uintptr. 794 if src.Etype == TUNSAFEPTR && (dst.IsPtr() || dst.Etype == TUINTPTR) { 795 return OCONVNOP 796 } 797 798 // src is map and dst is a pointer to corresponding hmap. 799 // This rule is needed for the implementation detail that 800 // go gc maps are implemented as a pointer to a hmap struct. 801 if src.Etype == TMAP && dst.IsPtr() && 802 src.MapType().Hmap == dst.Elem() { 803 return OCONVNOP 804 } 805 806 return 0 807 } 808 809 func assignconv(n *Node, t *types.Type, context string) *Node { 810 return assignconvfn(n, t, func() string { return context }) 811 } 812 813 // Convert node n for assignment to type t. 814 func assignconvfn(n *Node, t *types.Type, context func() string) *Node { 815 if n == nil || n.Type == nil || n.Type.Broke() { 816 return n 817 } 818 819 if t.Etype == TBLANK && n.Type.Etype == TNIL { 820 yyerror("use of untyped nil") 821 } 822 823 old := n 824 od := old.Diag() 825 old.SetDiag(true) // silence errors about n; we'll issue one below 826 n = defaultlit(n, t) 827 old.SetDiag(od) 828 if t.Etype == TBLANK { 829 return n 830 } 831 832 // Convert ideal bool from comparison to plain bool 833 // if the next step is non-bool (like interface{}). 834 if n.Type == types.Idealbool && !t.IsBoolean() { 835 if n.Op == ONAME || n.Op == OLITERAL { 836 r := nod(OCONVNOP, n, nil) 837 r.Type = types.Types[TBOOL] 838 r.SetTypecheck(1) 839 r.SetImplicit(true) 840 n = r 841 } 842 } 843 844 if types.Identical(n.Type, t) { 845 return n 846 } 847 848 var why string 849 op := assignop(n.Type, t, &why) 850 if op == 0 { 851 if !old.Diag() { 852 yyerror("cannot use %L as type %v in %s%s", n, t, context(), why) 853 } 854 op = OCONV 855 } 856 857 r := nod(op, n, nil) 858 r.Type = t 859 r.SetTypecheck(1) 860 r.SetImplicit(true) 861 r.Orig = n.Orig 862 return r 863 } 864 865 // IsMethod reports whether n is a method. 866 // n must be a function or a method. 867 func (n *Node) IsMethod() bool { 868 return n.Type.Recv() != nil 869 } 870 871 // SliceBounds returns n's slice bounds: low, high, and max in expr[low:high:max]. 872 // n must be a slice expression. max is nil if n is a simple slice expression. 873 func (n *Node) SliceBounds() (low, high, max *Node) { 874 if n.List.Len() == 0 { 875 return nil, nil, nil 876 } 877 878 switch n.Op { 879 case OSLICE, OSLICEARR, OSLICESTR: 880 s := n.List.Slice() 881 return s[0], s[1], nil 882 case OSLICE3, OSLICE3ARR: 883 s := n.List.Slice() 884 return s[0], s[1], s[2] 885 } 886 Fatalf("SliceBounds op %v: %v", n.Op, n) 887 return nil, nil, nil 888 } 889 890 // SetSliceBounds sets n's slice bounds, where n is a slice expression. 891 // n must be a slice expression. If max is non-nil, n must be a full slice expression. 892 func (n *Node) SetSliceBounds(low, high, max *Node) { 893 switch n.Op { 894 case OSLICE, OSLICEARR, OSLICESTR: 895 if max != nil { 896 Fatalf("SetSliceBounds %v given three bounds", n.Op) 897 } 898 s := n.List.Slice() 899 if s == nil { 900 if low == nil && high == nil { 901 return 902 } 903 n.List.Set2(low, high) 904 return 905 } 906 s[0] = low 907 s[1] = high 908 return 909 case OSLICE3, OSLICE3ARR: 910 s := n.List.Slice() 911 if s == nil { 912 if low == nil && high == nil && max == nil { 913 return 914 } 915 n.List.Set3(low, high, max) 916 return 917 } 918 s[0] = low 919 s[1] = high 920 s[2] = max 921 return 922 } 923 Fatalf("SetSliceBounds op %v: %v", n.Op, n) 924 } 925 926 // IsSlice3 reports whether o is a slice3 op (OSLICE3, OSLICE3ARR). 927 // o must be a slicing op. 928 func (o Op) IsSlice3() bool { 929 switch o { 930 case OSLICE, OSLICEARR, OSLICESTR: 931 return false 932 case OSLICE3, OSLICE3ARR: 933 return true 934 } 935 Fatalf("IsSlice3 op %v", o) 936 return false 937 } 938 939 // labeledControl returns the control flow Node (for, switch, select) 940 // associated with the label n, if any. 941 func (n *Node) labeledControl() *Node { 942 if n.Op != OLABEL { 943 Fatalf("labeledControl %v", n.Op) 944 } 945 ctl := n.Name.Defn 946 if ctl == nil { 947 return nil 948 } 949 switch ctl.Op { 950 case OFOR, OFORUNTIL, OSWITCH, OSELECT: 951 return ctl 952 } 953 return nil 954 } 955 956 func syslook(name string) *Node { 957 s := Runtimepkg.Lookup(name) 958 if s == nil || s.Def == nil { 959 Fatalf("syslook: can't find runtime.%s", name) 960 } 961 return asNode(s.Def) 962 } 963 964 // typehash computes a hash value for type t to use in type switch statements. 965 func typehash(t *types.Type) uint32 { 966 p := t.LongString() 967 968 // Using MD5 is overkill, but reduces accidental collisions. 969 h := md5.Sum([]byte(p)) 970 return binary.LittleEndian.Uint32(h[:4]) 971 } 972 973 // updateHasCall checks whether expression n contains any function 974 // calls and sets the n.HasCall flag if so. 975 func updateHasCall(n *Node) { 976 if n == nil { 977 return 978 } 979 n.SetHasCall(calcHasCall(n)) 980 } 981 982 func calcHasCall(n *Node) bool { 983 if n.Ninit.Len() != 0 { 984 // TODO(mdempsky): This seems overly conservative. 985 return true 986 } 987 988 switch n.Op { 989 case OLITERAL, ONAME, OTYPE: 990 if n.HasCall() { 991 Fatalf("OLITERAL/ONAME/OTYPE should never have calls: %+v", n) 992 } 993 return false 994 case OCALL, OCALLFUNC, OCALLMETH, OCALLINTER: 995 return true 996 case OANDAND, OOROR: 997 // hard with instrumented code 998 if instrumenting { 999 return true 1000 } 1001 case OINDEX, OSLICE, OSLICEARR, OSLICE3, OSLICE3ARR, OSLICESTR, 1002 ODEREF, ODOTPTR, ODOTTYPE, ODIV, OMOD: 1003 // These ops might panic, make sure they are done 1004 // before we start marshaling args for a call. See issue 16760. 1005 return true 1006 1007 // When using soft-float, these ops might be rewritten to function calls 1008 // so we ensure they are evaluated first. 1009 case OADD, OSUB, ONEG, OMUL: 1010 if thearch.SoftFloat && (isFloat[n.Type.Etype] || isComplex[n.Type.Etype]) { 1011 return true 1012 } 1013 case OLT, OEQ, ONE, OLE, OGE, OGT: 1014 if thearch.SoftFloat && (isFloat[n.Left.Type.Etype] || isComplex[n.Left.Type.Etype]) { 1015 return true 1016 } 1017 case OCONV: 1018 if thearch.SoftFloat && ((isFloat[n.Type.Etype] || isComplex[n.Type.Etype]) || (isFloat[n.Left.Type.Etype] || isComplex[n.Left.Type.Etype])) { 1019 return true 1020 } 1021 } 1022 1023 if n.Left != nil && n.Left.HasCall() { 1024 return true 1025 } 1026 if n.Right != nil && n.Right.HasCall() { 1027 return true 1028 } 1029 return false 1030 } 1031 1032 func badtype(op Op, tl *types.Type, tr *types.Type) { 1033 fmt_ := "" 1034 if tl != nil { 1035 fmt_ += fmt.Sprintf("\n\t%v", tl) 1036 } 1037 if tr != nil { 1038 fmt_ += fmt.Sprintf("\n\t%v", tr) 1039 } 1040 1041 // common mistake: *struct and *interface. 1042 if tl != nil && tr != nil && tl.IsPtr() && tr.IsPtr() { 1043 if tl.Elem().IsStruct() && tr.Elem().IsInterface() { 1044 fmt_ += "\n\t(*struct vs *interface)" 1045 } else if tl.Elem().IsInterface() && tr.Elem().IsStruct() { 1046 fmt_ += "\n\t(*interface vs *struct)" 1047 } 1048 } 1049 1050 s := fmt_ 1051 yyerror("illegal types for operand: %v%s", op, s) 1052 } 1053 1054 // brcom returns !(op). 1055 // For example, brcom(==) is !=. 1056 func brcom(op Op) Op { 1057 switch op { 1058 case OEQ: 1059 return ONE 1060 case ONE: 1061 return OEQ 1062 case OLT: 1063 return OGE 1064 case OGT: 1065 return OLE 1066 case OLE: 1067 return OGT 1068 case OGE: 1069 return OLT 1070 } 1071 Fatalf("brcom: no com for %v\n", op) 1072 return op 1073 } 1074 1075 // brrev returns reverse(op). 1076 // For example, Brrev(<) is >. 1077 func brrev(op Op) Op { 1078 switch op { 1079 case OEQ: 1080 return OEQ 1081 case ONE: 1082 return ONE 1083 case OLT: 1084 return OGT 1085 case OGT: 1086 return OLT 1087 case OLE: 1088 return OGE 1089 case OGE: 1090 return OLE 1091 } 1092 Fatalf("brrev: no rev for %v\n", op) 1093 return op 1094 } 1095 1096 // return side effect-free n, appending side effects to init. 1097 // result is assignable if n is. 1098 func safeexpr(n *Node, init *Nodes) *Node { 1099 if n == nil { 1100 return nil 1101 } 1102 1103 if n.Ninit.Len() != 0 { 1104 walkstmtlist(n.Ninit.Slice()) 1105 init.AppendNodes(&n.Ninit) 1106 } 1107 1108 switch n.Op { 1109 case ONAME, OLITERAL: 1110 return n 1111 1112 case ODOT, OLEN, OCAP: 1113 l := safeexpr(n.Left, init) 1114 if l == n.Left { 1115 return n 1116 } 1117 r := n.copy() 1118 r.Left = l 1119 r = typecheck(r, ctxExpr) 1120 r = walkexpr(r, init) 1121 return r 1122 1123 case ODOTPTR, ODEREF: 1124 l := safeexpr(n.Left, init) 1125 if l == n.Left { 1126 return n 1127 } 1128 a := n.copy() 1129 a.Left = l 1130 a = walkexpr(a, init) 1131 return a 1132 1133 case OINDEX, OINDEXMAP: 1134 l := safeexpr(n.Left, init) 1135 r := safeexpr(n.Right, init) 1136 if l == n.Left && r == n.Right { 1137 return n 1138 } 1139 a := n.copy() 1140 a.Left = l 1141 a.Right = r 1142 a = walkexpr(a, init) 1143 return a 1144 1145 case OSTRUCTLIT, OARRAYLIT, OSLICELIT: 1146 if isStaticCompositeLiteral(n) { 1147 return n 1148 } 1149 } 1150 1151 // make a copy; must not be used as an lvalue 1152 if islvalue(n) { 1153 Fatalf("missing lvalue case in safeexpr: %v", n) 1154 } 1155 return cheapexpr(n, init) 1156 } 1157 1158 func copyexpr(n *Node, t *types.Type, init *Nodes) *Node { 1159 l := temp(t) 1160 a := nod(OAS, l, n) 1161 a = typecheck(a, ctxStmt) 1162 a = walkexpr(a, init) 1163 init.Append(a) 1164 return l 1165 } 1166 1167 // return side-effect free and cheap n, appending side effects to init. 1168 // result may not be assignable. 1169 func cheapexpr(n *Node, init *Nodes) *Node { 1170 switch n.Op { 1171 case ONAME, OLITERAL: 1172 return n 1173 } 1174 1175 return copyexpr(n, n.Type, init) 1176 } 1177 1178 // Code to resolve elided DOTs in embedded types. 1179 1180 // A Dlist stores a pointer to a TFIELD Type embedded within 1181 // a TSTRUCT or TINTER Type. 1182 type Dlist struct { 1183 field *types.Field 1184 } 1185 1186 // dotlist is used by adddot1 to record the path of embedded fields 1187 // used to access a target field or method. 1188 // Must be non-nil so that dotpath returns a non-nil slice even if d is zero. 1189 var dotlist = make([]Dlist, 10) 1190 1191 // lookdot0 returns the number of fields or methods named s associated 1192 // with Type t. If exactly one exists, it will be returned in *save 1193 // (if save is not nil). 1194 func lookdot0(s *types.Sym, t *types.Type, save **types.Field, ignorecase bool) int { 1195 u := t 1196 if u.IsPtr() { 1197 u = u.Elem() 1198 } 1199 1200 c := 0 1201 if u.IsStruct() || u.IsInterface() { 1202 for _, f := range u.Fields().Slice() { 1203 if f.Sym == s || (ignorecase && f.Type.Etype == TFUNC && f.Type.Recv() != nil && strings.EqualFold(f.Sym.Name, s.Name)) { 1204 if save != nil { 1205 *save = f 1206 } 1207 c++ 1208 } 1209 } 1210 } 1211 1212 u = methtype(t) 1213 if u != nil { 1214 for _, f := range u.Methods().Slice() { 1215 if f.Embedded == 0 && (f.Sym == s || (ignorecase && strings.EqualFold(f.Sym.Name, s.Name))) { 1216 if save != nil { 1217 *save = f 1218 } 1219 c++ 1220 } 1221 } 1222 } 1223 1224 return c 1225 } 1226 1227 // adddot1 returns the number of fields or methods named s at depth d in Type t. 1228 // If exactly one exists, it will be returned in *save (if save is not nil), 1229 // and dotlist will contain the path of embedded fields traversed to find it, 1230 // in reverse order. If none exist, more will indicate whether t contains any 1231 // embedded fields at depth d, so callers can decide whether to retry at 1232 // a greater depth. 1233 func adddot1(s *types.Sym, t *types.Type, d int, save **types.Field, ignorecase bool) (c int, more bool) { 1234 if t.Recur() { 1235 return 1236 } 1237 t.SetRecur(true) 1238 defer t.SetRecur(false) 1239 1240 var u *types.Type 1241 d-- 1242 if d < 0 { 1243 // We've reached our target depth. If t has any fields/methods 1244 // named s, then we're done. Otherwise, we still need to check 1245 // below for embedded fields. 1246 c = lookdot0(s, t, save, ignorecase) 1247 if c != 0 { 1248 return c, false 1249 } 1250 } 1251 1252 u = t 1253 if u.IsPtr() { 1254 u = u.Elem() 1255 } 1256 if !u.IsStruct() && !u.IsInterface() { 1257 return c, false 1258 } 1259 1260 for _, f := range u.Fields().Slice() { 1261 if f.Embedded == 0 || f.Sym == nil { 1262 continue 1263 } 1264 if d < 0 { 1265 // Found an embedded field at target depth. 1266 return c, true 1267 } 1268 a, more1 := adddot1(s, f.Type, d, save, ignorecase) 1269 if a != 0 && c == 0 { 1270 dotlist[d].field = f 1271 } 1272 c += a 1273 if more1 { 1274 more = true 1275 } 1276 } 1277 1278 return c, more 1279 } 1280 1281 // dotpath computes the unique shortest explicit selector path to fully qualify 1282 // a selection expression x.f, where x is of type t and f is the symbol s. 1283 // If no such path exists, dotpath returns nil. 1284 // If there are multiple shortest paths to the same depth, ambig is true. 1285 func dotpath(s *types.Sym, t *types.Type, save **types.Field, ignorecase bool) (path []Dlist, ambig bool) { 1286 // The embedding of types within structs imposes a tree structure onto 1287 // types: structs parent the types they embed, and types parent their 1288 // fields or methods. Our goal here is to find the shortest path to 1289 // a field or method named s in the subtree rooted at t. To accomplish 1290 // that, we iteratively perform depth-first searches of increasing depth 1291 // until we either find the named field/method or exhaust the tree. 1292 for d := 0; ; d++ { 1293 if d > len(dotlist) { 1294 dotlist = append(dotlist, Dlist{}) 1295 } 1296 if c, more := adddot1(s, t, d, save, ignorecase); c == 1 { 1297 return dotlist[:d], false 1298 } else if c > 1 { 1299 return nil, true 1300 } else if !more { 1301 return nil, false 1302 } 1303 } 1304 } 1305 1306 // in T.field 1307 // find missing fields that 1308 // will give shortest unique addressing. 1309 // modify the tree with missing type names. 1310 func adddot(n *Node) *Node { 1311 n.Left = typecheck(n.Left, Etype|ctxExpr) 1312 if n.Left.Diag() { 1313 n.SetDiag(true) 1314 } 1315 t := n.Left.Type 1316 if t == nil { 1317 return n 1318 } 1319 1320 if n.Left.Op == OTYPE { 1321 return n 1322 } 1323 1324 s := n.Sym 1325 if s == nil { 1326 return n 1327 } 1328 1329 switch path, ambig := dotpath(s, t, nil, false); { 1330 case path != nil: 1331 // rebuild elided dots 1332 for c := len(path) - 1; c >= 0; c-- { 1333 n.Left = nodSym(ODOT, n.Left, path[c].field.Sym) 1334 n.Left.SetImplicit(true) 1335 } 1336 case ambig: 1337 yyerror("ambiguous selector %v", n) 1338 n.Left = nil 1339 } 1340 1341 return n 1342 } 1343 1344 // Code to help generate trampoline functions for methods on embedded 1345 // types. These are approx the same as the corresponding adddot 1346 // routines except that they expect to be called with unique tasks and 1347 // they return the actual methods. 1348 1349 type Symlink struct { 1350 field *types.Field 1351 } 1352 1353 var slist []Symlink 1354 1355 func expand0(t *types.Type) { 1356 u := t 1357 if u.IsPtr() { 1358 u = u.Elem() 1359 } 1360 1361 if u.IsInterface() { 1362 for _, f := range u.Fields().Slice() { 1363 if f.Sym.Uniq() { 1364 continue 1365 } 1366 f.Sym.SetUniq(true) 1367 slist = append(slist, Symlink{field: f}) 1368 } 1369 1370 return 1371 } 1372 1373 u = methtype(t) 1374 if u != nil { 1375 for _, f := range u.Methods().Slice() { 1376 if f.Sym.Uniq() { 1377 continue 1378 } 1379 f.Sym.SetUniq(true) 1380 slist = append(slist, Symlink{field: f}) 1381 } 1382 } 1383 } 1384 1385 func expand1(t *types.Type, top bool) { 1386 if t.Recur() { 1387 return 1388 } 1389 t.SetRecur(true) 1390 1391 if !top { 1392 expand0(t) 1393 } 1394 1395 u := t 1396 if u.IsPtr() { 1397 u = u.Elem() 1398 } 1399 1400 if u.IsStruct() || u.IsInterface() { 1401 for _, f := range u.Fields().Slice() { 1402 if f.Embedded == 0 { 1403 continue 1404 } 1405 if f.Sym == nil { 1406 continue 1407 } 1408 expand1(f.Type, false) 1409 } 1410 } 1411 1412 t.SetRecur(false) 1413 } 1414 1415 func expandmeth(t *types.Type) { 1416 if t == nil || t.AllMethods().Len() != 0 { 1417 return 1418 } 1419 1420 // mark top-level method symbols 1421 // so that expand1 doesn't consider them. 1422 for _, f := range t.Methods().Slice() { 1423 f.Sym.SetUniq(true) 1424 } 1425 1426 // generate all reachable methods 1427 slist = slist[:0] 1428 expand1(t, true) 1429 1430 // check each method to be uniquely reachable 1431 var ms []*types.Field 1432 for i, sl := range slist { 1433 slist[i].field = nil 1434 sl.field.Sym.SetUniq(false) 1435 1436 var f *types.Field 1437 path, _ := dotpath(sl.field.Sym, t, &f, false) 1438 if path == nil { 1439 continue 1440 } 1441 1442 // dotpath may have dug out arbitrary fields, we only want methods. 1443 if f.Type.Etype != TFUNC || f.Type.Recv() == nil { 1444 continue 1445 } 1446 1447 // add it to the base type method list 1448 f = f.Copy() 1449 f.Embedded = 1 // needs a trampoline 1450 for _, d := range path { 1451 if d.field.Type.IsPtr() { 1452 f.Embedded = 2 1453 break 1454 } 1455 } 1456 ms = append(ms, f) 1457 } 1458 1459 for _, f := range t.Methods().Slice() { 1460 f.Sym.SetUniq(false) 1461 } 1462 1463 ms = append(ms, t.Methods().Slice()...) 1464 sort.Sort(methcmp(ms)) 1465 t.AllMethods().Set(ms) 1466 } 1467 1468 // Given funarg struct list, return list of ODCLFIELD Node fn args. 1469 func structargs(tl *types.Type, mustname bool) []*Node { 1470 var args []*Node 1471 gen := 0 1472 for _, t := range tl.Fields().Slice() { 1473 s := t.Sym 1474 if mustname && (s == nil || s.Name == "_") { 1475 // invent a name so that we can refer to it in the trampoline 1476 s = lookupN(".anon", gen) 1477 gen++ 1478 } 1479 a := symfield(s, t.Type) 1480 a.Pos = t.Pos 1481 a.SetIsDDD(t.IsDDD()) 1482 args = append(args, a) 1483 } 1484 1485 return args 1486 } 1487 1488 // Generate a wrapper function to convert from 1489 // a receiver of type T to a receiver of type U. 1490 // That is, 1491 // 1492 // func (t T) M() { 1493 // ... 1494 // } 1495 // 1496 // already exists; this function generates 1497 // 1498 // func (u U) M() { 1499 // u.M() 1500 // } 1501 // 1502 // where the types T and U are such that u.M() is valid 1503 // and calls the T.M method. 1504 // The resulting function is for use in method tables. 1505 // 1506 // rcvr - U 1507 // method - M func (t T)(), a TFIELD type struct 1508 // newnam - the eventual mangled name of this function 1509 func genwrapper(rcvr *types.Type, method *types.Field, newnam *types.Sym) { 1510 if false && Debug['r'] != 0 { 1511 fmt.Printf("genwrapper rcvrtype=%v method=%v newnam=%v\n", rcvr, method, newnam) 1512 } 1513 1514 // Only generate (*T).M wrappers for T.M in T's own package. 1515 if rcvr.IsPtr() && rcvr.Elem() == method.Type.Recv().Type && 1516 rcvr.Elem().Sym != nil && rcvr.Elem().Sym.Pkg != localpkg { 1517 return 1518 } 1519 1520 // Only generate I.M wrappers for I in I's own package 1521 // but keep doing it for error.Error (was issue #29304). 1522 if rcvr.IsInterface() && rcvr.Sym != nil && rcvr.Sym.Pkg != localpkg && rcvr != types.Errortype { 1523 return 1524 } 1525 1526 lineno = autogeneratedPos 1527 dclcontext = PEXTERN 1528 1529 tfn := nod(OTFUNC, nil, nil) 1530 tfn.Left = namedfield(".this", rcvr) 1531 tfn.List.Set(structargs(method.Type.Params(), true)) 1532 tfn.Rlist.Set(structargs(method.Type.Results(), false)) 1533 1534 disableExport(newnam) 1535 fn := dclfunc(newnam, tfn) 1536 fn.Func.SetDupok(true) 1537 1538 nthis := asNode(tfn.Type.Recv().Nname) 1539 1540 methodrcvr := method.Type.Recv().Type 1541 1542 // generate nil pointer check for better error 1543 if rcvr.IsPtr() && rcvr.Elem() == methodrcvr { 1544 // generating wrapper from *T to T. 1545 n := nod(OIF, nil, nil) 1546 n.Left = nod(OEQ, nthis, nodnil()) 1547 call := nod(OCALL, syslook("panicwrap"), nil) 1548 n.Nbody.Set1(call) 1549 fn.Nbody.Append(n) 1550 } 1551 1552 dot := adddot(nodSym(OXDOT, nthis, method.Sym)) 1553 1554 // generate call 1555 // It's not possible to use a tail call when dynamic linking on ppc64le. The 1556 // bad scenario is when a local call is made to the wrapper: the wrapper will 1557 // call the implementation, which might be in a different module and so set 1558 // the TOC to the appropriate value for that module. But if it returns 1559 // directly to the wrapper's caller, nothing will reset it to the correct 1560 // value for that function. 1561 if !instrumenting && rcvr.IsPtr() && methodrcvr.IsPtr() && method.Embedded != 0 && !isifacemethod(method.Type) && !(thearch.LinkArch.Name == "ppc64le" && Ctxt.Flag_dynlink) { 1562 // generate tail call: adjust pointer receiver and jump to embedded method. 1563 dot = dot.Left // skip final .M 1564 // TODO(mdempsky): Remove dependency on dotlist. 1565 if !dotlist[0].field.Type.IsPtr() { 1566 dot = nod(OADDR, dot, nil) 1567 } 1568 as := nod(OAS, nthis, convnop(dot, rcvr)) 1569 fn.Nbody.Append(as) 1570 fn.Nbody.Append(nodSym(ORETJMP, nil, methodSym(methodrcvr, method.Sym))) 1571 } else { 1572 fn.Func.SetWrapper(true) // ignore frame for panic+recover matching 1573 call := nod(OCALL, dot, nil) 1574 call.List.Set(paramNnames(tfn.Type)) 1575 call.SetIsDDD(tfn.Type.IsVariadic()) 1576 if method.Type.NumResults() > 0 { 1577 n := nod(ORETURN, nil, nil) 1578 n.List.Set1(call) 1579 call = n 1580 } 1581 fn.Nbody.Append(call) 1582 } 1583 1584 if false && Debug['r'] != 0 { 1585 dumplist("genwrapper body", fn.Nbody) 1586 } 1587 1588 funcbody() 1589 if debug_dclstack != 0 { 1590 testdclstack() 1591 } 1592 1593 fn = typecheck(fn, ctxStmt) 1594 1595 Curfn = fn 1596 typecheckslice(fn.Nbody.Slice(), ctxStmt) 1597 1598 // Inline calls within (*T).M wrappers. This is safe because we only 1599 // generate those wrappers within the same compilation unit as (T).M. 1600 // TODO(mdempsky): Investigate why we can't enable this more generally. 1601 if rcvr.IsPtr() && rcvr.Elem() == method.Type.Recv().Type && rcvr.Elem().Sym != nil { 1602 inlcalls(fn) 1603 } 1604 escAnalyze([]*Node{fn}, false) 1605 1606 Curfn = nil 1607 funccompile(fn) 1608 } 1609 1610 func paramNnames(ft *types.Type) []*Node { 1611 args := make([]*Node, ft.NumParams()) 1612 for i, f := range ft.Params().FieldSlice() { 1613 args[i] = asNode(f.Nname) 1614 } 1615 return args 1616 } 1617 1618 func hashmem(t *types.Type) *Node { 1619 sym := Runtimepkg.Lookup("memhash") 1620 1621 n := newname(sym) 1622 n.SetClass(PFUNC) 1623 n.Sym.SetFunc(true) 1624 n.Type = functype(nil, []*Node{ 1625 anonfield(types.NewPtr(t)), 1626 anonfield(types.Types[TUINTPTR]), 1627 anonfield(types.Types[TUINTPTR]), 1628 }, []*Node{ 1629 anonfield(types.Types[TUINTPTR]), 1630 }) 1631 return n 1632 } 1633 1634 func ifacelookdot(s *types.Sym, t *types.Type, ignorecase bool) (m *types.Field, followptr bool) { 1635 if t == nil { 1636 return nil, false 1637 } 1638 1639 path, ambig := dotpath(s, t, &m, ignorecase) 1640 if path == nil { 1641 if ambig { 1642 yyerror("%v.%v is ambiguous", t, s) 1643 } 1644 return nil, false 1645 } 1646 1647 for _, d := range path { 1648 if d.field.Type.IsPtr() { 1649 followptr = true 1650 break 1651 } 1652 } 1653 1654 if m.Type.Etype != TFUNC || m.Type.Recv() == nil { 1655 yyerror("%v.%v is a field, not a method", t, s) 1656 return nil, followptr 1657 } 1658 1659 return m, followptr 1660 } 1661 1662 func implements(t, iface *types.Type, m, samename **types.Field, ptr *int) bool { 1663 t0 := t 1664 if t == nil { 1665 return false 1666 } 1667 1668 if t.IsInterface() { 1669 i := 0 1670 tms := t.Fields().Slice() 1671 for _, im := range iface.Fields().Slice() { 1672 for i < len(tms) && tms[i].Sym != im.Sym { 1673 i++ 1674 } 1675 if i == len(tms) { 1676 *m = im 1677 *samename = nil 1678 *ptr = 0 1679 return false 1680 } 1681 tm := tms[i] 1682 if !types.Identical(tm.Type, im.Type) { 1683 *m = im 1684 *samename = tm 1685 *ptr = 0 1686 return false 1687 } 1688 } 1689 1690 return true 1691 } 1692 1693 t = methtype(t) 1694 var tms []*types.Field 1695 if t != nil { 1696 expandmeth(t) 1697 tms = t.AllMethods().Slice() 1698 } 1699 i := 0 1700 for _, im := range iface.Fields().Slice() { 1701 if im.Broke() { 1702 continue 1703 } 1704 for i < len(tms) && tms[i].Sym != im.Sym { 1705 i++ 1706 } 1707 if i == len(tms) { 1708 *m = im 1709 *samename, _ = ifacelookdot(im.Sym, t, true) 1710 *ptr = 0 1711 return false 1712 } 1713 tm := tms[i] 1714 if tm.Nointerface() || !types.Identical(tm.Type, im.Type) { 1715 *m = im 1716 *samename = tm 1717 *ptr = 0 1718 return false 1719 } 1720 followptr := tm.Embedded == 2 1721 1722 // if pointer receiver in method, 1723 // the method does not exist for value types. 1724 rcvr := tm.Type.Recv().Type 1725 if rcvr.IsPtr() && !t0.IsPtr() && !followptr && !isifacemethod(tm.Type) { 1726 if false && Debug['r'] != 0 { 1727 yyerror("interface pointer mismatch") 1728 } 1729 1730 *m = im 1731 *samename = nil 1732 *ptr = 1 1733 return false 1734 } 1735 } 1736 1737 // We're going to emit an OCONVIFACE. 1738 // Call itabname so that (t, iface) 1739 // gets added to itabs early, which allows 1740 // us to de-virtualize calls through this 1741 // type/interface pair later. See peekitabs in reflect.go 1742 if isdirectiface(t0) && !iface.IsEmptyInterface() { 1743 itabname(t0, iface) 1744 } 1745 return true 1746 } 1747 1748 func listtreecopy(l []*Node, pos src.XPos) []*Node { 1749 var out []*Node 1750 for _, n := range l { 1751 out = append(out, treecopy(n, pos)) 1752 } 1753 return out 1754 } 1755 1756 func liststmt(l []*Node) *Node { 1757 n := nod(OBLOCK, nil, nil) 1758 n.List.Set(l) 1759 if len(l) != 0 { 1760 n.Pos = l[0].Pos 1761 } 1762 return n 1763 } 1764 1765 func (l Nodes) asblock() *Node { 1766 n := nod(OBLOCK, nil, nil) 1767 n.List = l 1768 if l.Len() != 0 { 1769 n.Pos = l.First().Pos 1770 } 1771 return n 1772 } 1773 1774 func ngotype(n *Node) *types.Sym { 1775 if n.Type != nil { 1776 return typenamesym(n.Type) 1777 } 1778 return nil 1779 } 1780 1781 // The result of addinit MUST be assigned back to n, e.g. 1782 // n.Left = addinit(n.Left, init) 1783 func addinit(n *Node, init []*Node) *Node { 1784 if len(init) == 0 { 1785 return n 1786 } 1787 if n.mayBeShared() { 1788 // Introduce OCONVNOP to hold init list. 1789 n = nod(OCONVNOP, n, nil) 1790 n.Type = n.Left.Type 1791 n.SetTypecheck(1) 1792 } 1793 1794 n.Ninit.Prepend(init...) 1795 n.SetHasCall(true) 1796 return n 1797 } 1798 1799 // The linker uses the magic symbol prefixes "go." and "type." 1800 // Avoid potential confusion between import paths and symbols 1801 // by rejecting these reserved imports for now. Also, people 1802 // "can do weird things in GOPATH and we'd prefer they didn't 1803 // do _that_ weird thing" (per rsc). See also #4257. 1804 var reservedimports = []string{ 1805 "go", 1806 "type", 1807 } 1808 1809 func isbadimport(path string, allowSpace bool) bool { 1810 if strings.Contains(path, "\x00") { 1811 yyerror("import path contains NUL") 1812 return true 1813 } 1814 1815 for _, ri := range reservedimports { 1816 if path == ri { 1817 yyerror("import path %q is reserved and cannot be used", path) 1818 return true 1819 } 1820 } 1821 1822 for _, r := range path { 1823 if r == utf8.RuneError { 1824 yyerror("import path contains invalid UTF-8 sequence: %q", path) 1825 return true 1826 } 1827 1828 if r < 0x20 || r == 0x7f { 1829 yyerror("import path contains control character: %q", path) 1830 return true 1831 } 1832 1833 if r == '\\' { 1834 yyerror("import path contains backslash; use slash: %q", path) 1835 return true 1836 } 1837 1838 if !allowSpace && unicode.IsSpace(r) { 1839 yyerror("import path contains space character: %q", path) 1840 return true 1841 } 1842 1843 if strings.ContainsRune("!\"#$%&'()*,:;<=>?[]^`{|}", r) { 1844 yyerror("import path contains invalid character '%c': %q", r, path) 1845 return true 1846 } 1847 } 1848 1849 return false 1850 } 1851 1852 func checknil(x *Node, init *Nodes) { 1853 x = walkexpr(x, nil) // caller has not done this yet 1854 if x.Type.IsInterface() { 1855 x = nod(OITAB, x, nil) 1856 x = typecheck(x, ctxExpr) 1857 } 1858 1859 n := nod(OCHECKNIL, x, nil) 1860 n.SetTypecheck(1) 1861 init.Append(n) 1862 } 1863 1864 // Can this type be stored directly in an interface word? 1865 // Yes, if the representation is a single pointer. 1866 func isdirectiface(t *types.Type) bool { 1867 if t.Broke() { 1868 return false 1869 } 1870 1871 switch t.Etype { 1872 case TPTR, 1873 TCHAN, 1874 TMAP, 1875 TFUNC, 1876 TUNSAFEPTR: 1877 return true 1878 1879 case TARRAY: 1880 // Array of 1 direct iface type can be direct. 1881 return t.NumElem() == 1 && isdirectiface(t.Elem()) 1882 1883 case TSTRUCT: 1884 // Struct with 1 field of direct iface type can be direct. 1885 return t.NumFields() == 1 && isdirectiface(t.Field(0).Type) 1886 } 1887 1888 return false 1889 } 1890 1891 // itabType loads the _type field from a runtime.itab struct. 1892 func itabType(itab *Node) *Node { 1893 typ := nodSym(ODOTPTR, itab, nil) 1894 typ.Type = types.NewPtr(types.Types[TUINT8]) 1895 typ.SetTypecheck(1) 1896 typ.Xoffset = int64(Widthptr) // offset of _type in runtime.itab 1897 typ.SetBounded(true) // guaranteed not to fault 1898 return typ 1899 } 1900 1901 // ifaceData loads the data field from an interface. 1902 // The concrete type must be known to have type t. 1903 // It follows the pointer if !isdirectiface(t). 1904 func ifaceData(n *Node, t *types.Type) *Node { 1905 ptr := nodSym(OIDATA, n, nil) 1906 if isdirectiface(t) { 1907 ptr.Type = t 1908 ptr.SetTypecheck(1) 1909 return ptr 1910 } 1911 ptr.Type = types.NewPtr(t) 1912 ptr.SetBounded(true) 1913 ptr.SetTypecheck(1) 1914 ind := nod(ODEREF, ptr, nil) 1915 ind.Type = t 1916 ind.SetTypecheck(1) 1917 return ind 1918 }