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