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