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