github.com/riscv/riscv-go@v0.0.0-20200123204226-124ebd6fcc8e/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/internal/obj" 10 "cmd/internal/src" 11 "crypto/md5" 12 "encoding/binary" 13 "fmt" 14 "os" 15 "runtime/debug" 16 "sort" 17 "strconv" 18 "strings" 19 "unicode" 20 "unicode/utf8" 21 ) 22 23 type Error struct { 24 pos src.XPos 25 msg string 26 } 27 28 var errors []Error 29 30 func errorexit() { 31 flusherrors() 32 if outfile != "" { 33 os.Remove(outfile) 34 } 35 os.Exit(2) 36 } 37 38 func adderrorname(n *Node) { 39 if n.Op != ODOT { 40 return 41 } 42 old := fmt.Sprintf("%v: undefined: %v\n", n.Line(), n.Left) 43 if len(errors) > 0 && errors[len(errors)-1].pos.Line() == n.Pos.Line() && errors[len(errors)-1].msg == old { 44 errors[len(errors)-1].msg = fmt.Sprintf("%v: undefined: %v in %v\n", n.Line(), n.Left, n) 45 } 46 } 47 48 func adderr(pos src.XPos, format string, args ...interface{}) { 49 errors = append(errors, Error{ 50 pos: pos, 51 msg: fmt.Sprintf("%v: %s\n", linestr(pos), fmt.Sprintf(format, args...)), 52 }) 53 } 54 55 // byPos sorts errors by source position. 56 type byPos []Error 57 58 func (x byPos) Len() int { return len(x) } 59 func (x byPos) Less(i, j int) bool { return x[i].pos.Before(x[j].pos) } 60 func (x byPos) Swap(i, j int) { x[i], x[j] = x[j], x[i] } 61 62 // flusherrors sorts errors seen so far by line number, prints them to stdout, 63 // and empties the errors array. 64 func flusherrors() { 65 Ctxt.Bso.Flush() 66 if len(errors) == 0 { 67 return 68 } 69 sort.Stable(byPos(errors)) 70 for i := 0; i < len(errors); i++ { 71 if i == 0 || errors[i].msg != errors[i-1].msg { 72 fmt.Printf("%s", errors[i].msg) 73 } 74 } 75 errors = errors[:0] 76 } 77 78 func hcrash() { 79 if Debug['h'] != 0 { 80 flusherrors() 81 if outfile != "" { 82 os.Remove(outfile) 83 } 84 var x *int 85 *x = 0 86 } 87 } 88 89 func linestr(pos src.XPos) string { 90 return Ctxt.PosTable.Pos(pos).String() 91 } 92 93 // lasterror keeps track of the most recently issued error. 94 // It is used to avoid multiple error messages on the same 95 // line. 96 var lasterror struct { 97 syntax src.XPos // source position of last syntax error 98 other src.XPos // source position of last non-syntax error 99 msg string // error message of last non-syntax error 100 } 101 102 // sameline reports whether two positions a, b are on the same line. 103 func sameline(a, b src.XPos) bool { 104 p := Ctxt.PosTable.Pos(a) 105 q := Ctxt.PosTable.Pos(b) 106 return p.Base() == q.Base() && p.Line() == q.Line() 107 } 108 109 func yyerrorl(pos src.XPos, format string, args ...interface{}) { 110 msg := fmt.Sprintf(format, args...) 111 112 if strings.HasPrefix(msg, "syntax error") { 113 nsyntaxerrors++ 114 // only one syntax error per line, no matter what error 115 if sameline(lasterror.syntax, pos) { 116 return 117 } 118 lasterror.syntax = pos 119 } else { 120 // only one of multiple equal non-syntax errors per line 121 // (flusherrors shows only one of them, so we filter them 122 // here as best as we can (they may not appear in order) 123 // so that we don't count them here and exit early, and 124 // then have nothing to show for.) 125 if sameline(lasterror.other, pos) && lasterror.msg == msg { 126 return 127 } 128 lasterror.other = pos 129 lasterror.msg = msg 130 } 131 132 adderr(pos, "%s", msg) 133 134 hcrash() 135 nerrors++ 136 if nsavederrors+nerrors >= 10 && Debug['e'] == 0 { 137 flusherrors() 138 fmt.Printf("%v: too many errors\n", linestr(pos)) 139 errorexit() 140 } 141 } 142 143 func yyerror(format string, args ...interface{}) { 144 yyerrorl(lineno, format, args...) 145 } 146 147 func Warn(fmt_ string, args ...interface{}) { 148 adderr(lineno, fmt_, args...) 149 150 hcrash() 151 } 152 153 func Warnl(line src.XPos, fmt_ string, args ...interface{}) { 154 adderr(line, fmt_, args...) 155 if Debug['m'] != 0 { 156 flusherrors() 157 } 158 } 159 160 func Fatalf(fmt_ string, args ...interface{}) { 161 flusherrors() 162 163 fmt.Printf("%v: internal compiler error: ", linestr(lineno)) 164 fmt.Printf(fmt_, args...) 165 fmt.Printf("\n") 166 167 // If this is a released compiler version, ask for a bug report. 168 if strings.HasPrefix(obj.Version, "release") { 169 fmt.Printf("\n") 170 fmt.Printf("Please file a bug report including a short program that triggers the error.\n") 171 fmt.Printf("https://golang.org/issue/new\n") 172 } else { 173 // Not a release; dump a stack trace, too. 174 fmt.Println() 175 os.Stdout.Write(debug.Stack()) 176 fmt.Println() 177 } 178 179 hcrash() 180 errorexit() 181 } 182 183 func setlineno(n *Node) src.XPos { 184 lno := lineno 185 if n != nil { 186 switch n.Op { 187 case ONAME, OPACK: 188 break 189 190 case OLITERAL, OTYPE: 191 if n.Sym != nil { 192 break 193 } 194 fallthrough 195 196 default: 197 lineno = n.Pos 198 if !lineno.IsKnown() { 199 if Debug['K'] != 0 { 200 Warn("setlineno: unknown position (line 0)") 201 } 202 lineno = lno 203 } 204 } 205 } 206 207 return lno 208 } 209 210 func lookup(name string) *Sym { 211 return localpkg.Lookup(name) 212 } 213 214 func lookupf(format string, a ...interface{}) *Sym { 215 return lookup(fmt.Sprintf(format, a...)) 216 } 217 218 func lookupBytes(name []byte) *Sym { 219 return localpkg.LookupBytes(name) 220 } 221 222 // lookupN looks up the symbol starting with prefix and ending with 223 // the decimal n. If prefix is too long, lookupN panics. 224 func lookupN(prefix string, n int) *Sym { 225 var buf [20]byte // plenty long enough for all current users 226 copy(buf[:], prefix) 227 b := strconv.AppendInt(buf[:len(prefix)], int64(n), 10) 228 return lookupBytes(b) 229 } 230 231 // autolabel generates a new Name node for use with 232 // an automatically generated label. 233 // prefix is a short mnemonic (e.g. ".s" for switch) 234 // to help with debugging. 235 // It should begin with "." to avoid conflicts with 236 // user labels. 237 func autolabel(prefix string) *Node { 238 if prefix[0] != '.' { 239 Fatalf("autolabel prefix must start with '.', have %q", prefix) 240 } 241 fn := Curfn 242 if Curfn == nil { 243 Fatalf("autolabel outside function") 244 } 245 n := fn.Func.Label 246 fn.Func.Label++ 247 return newname(lookupN(prefix, int(n))) 248 } 249 250 var initSyms []*Sym 251 252 var nopkg = &Pkg{ 253 Syms: make(map[string]*Sym), 254 } 255 256 func (pkg *Pkg) Lookup(name string) *Sym { 257 if pkg == nil { 258 pkg = nopkg 259 } 260 if s := pkg.Syms[name]; s != nil { 261 return s 262 } 263 264 s := &Sym{ 265 Name: name, 266 Pkg: pkg, 267 } 268 if name == "init" { 269 initSyms = append(initSyms, s) 270 } 271 pkg.Syms[name] = s 272 return s 273 } 274 275 func (pkg *Pkg) LookupBytes(name []byte) *Sym { 276 if pkg == nil { 277 pkg = nopkg 278 } 279 if s := pkg.Syms[string(name)]; s != nil { 280 return s 281 } 282 str := internString(name) 283 return pkg.Lookup(str) 284 } 285 286 func Pkglookup(name string, pkg *Pkg) *Sym { 287 return pkg.Lookup(name) 288 } 289 290 func restrictlookup(name string, pkg *Pkg) *Sym { 291 if !exportname(name) && pkg != localpkg { 292 yyerror("cannot refer to unexported name %s.%s", pkg.Name, name) 293 } 294 return Pkglookup(name, pkg) 295 } 296 297 // find all the exported symbols in package opkg 298 // and make them available in the current package 299 func importdot(opkg *Pkg, pack *Node) { 300 var s1 *Sym 301 var pkgerror string 302 303 n := 0 304 for _, s := range opkg.Syms { 305 if s.Def == nil { 306 continue 307 } 308 if !exportname(s.Name) || strings.ContainsRune(s.Name, 0xb7) { // 0xb7 = center dot 309 continue 310 } 311 s1 = lookup(s.Name) 312 if s1.Def != nil { 313 pkgerror = fmt.Sprintf("during import %q", opkg.Path) 314 redeclare(s1, pkgerror) 315 continue 316 } 317 318 s1.Def = s.Def 319 s1.Block = s.Block 320 if s1.Def.Name == nil { 321 Dump("s1def", s1.Def) 322 Fatalf("missing Name") 323 } 324 s1.Def.Name.Pack = pack 325 s1.Origpkg = opkg 326 n++ 327 } 328 329 if n == 0 { 330 // can't possibly be used - there were no symbols 331 yyerrorl(pack.Pos, "imported and not used: %q", opkg.Path) 332 } 333 } 334 335 func nod(op Op, nleft *Node, nright *Node) *Node { 336 var n *Node 337 switch op { 338 case OCLOSURE, ODCLFUNC: 339 var x struct { 340 Node 341 Func 342 } 343 n = &x.Node 344 n.Func = &x.Func 345 n.Func.IsHiddenClosure = Curfn != nil 346 case ONAME: 347 var x struct { 348 Node 349 Name 350 Param 351 } 352 n = &x.Node 353 n.Name = &x.Name 354 n.Name.Param = &x.Param 355 case OLABEL, OPACK: 356 var x struct { 357 Node 358 Name 359 } 360 n = &x.Node 361 n.Name = &x.Name 362 default: 363 n = new(Node) 364 } 365 n.Op = op 366 n.Left = nleft 367 n.Right = nright 368 n.Pos = lineno 369 n.Xoffset = BADWIDTH 370 n.Orig = n 371 if n.Name != nil { 372 n.Name.Curfn = Curfn 373 } 374 return n 375 } 376 377 // nodSym makes a Node with Op op and with the Left field set to left 378 // and the Sym field set to sym. This is for ODOT and friends. 379 func nodSym(op Op, left *Node, sym *Sym) *Node { 380 n := nod(op, left, nil) 381 n.Sym = sym 382 return n 383 } 384 385 func saveorignode(n *Node) { 386 if n.Orig != nil { 387 return 388 } 389 norig := nod(n.Op, nil, nil) 390 *norig = *n 391 n.Orig = norig 392 } 393 394 // methcmp sorts by symbol, then by package path for unexported symbols. 395 type methcmp []*Field 396 397 func (x methcmp) Len() int { return len(x) } 398 func (x methcmp) Swap(i, j int) { x[i], x[j] = x[j], x[i] } 399 func (x methcmp) Less(i, j int) bool { 400 a := x[i] 401 b := x[j] 402 if a.Sym == nil && b.Sym == nil { 403 return false 404 } 405 if a.Sym == nil { 406 return true 407 } 408 if b.Sym == nil { 409 return false 410 } 411 if a.Sym.Name != b.Sym.Name { 412 return a.Sym.Name < b.Sym.Name 413 } 414 if !exportname(a.Sym.Name) { 415 if a.Sym.Pkg.Path != b.Sym.Pkg.Path { 416 return a.Sym.Pkg.Path < b.Sym.Pkg.Path 417 } 418 } 419 420 return false 421 } 422 423 func nodintconst(v int64) *Node { 424 c := nod(OLITERAL, nil, nil) 425 c.Addable = true 426 c.SetVal(Val{new(Mpint)}) 427 c.Val().U.(*Mpint).SetInt64(v) 428 c.Type = Types[TIDEAL] 429 ullmancalc(c) 430 return c 431 } 432 433 func nodfltconst(v *Mpflt) *Node { 434 c := nod(OLITERAL, nil, nil) 435 c.Addable = true 436 c.SetVal(Val{newMpflt()}) 437 c.Val().U.(*Mpflt).Set(v) 438 c.Type = Types[TIDEAL] 439 ullmancalc(c) 440 return c 441 } 442 443 func Nodconst(n *Node, t *Type, v int64) { 444 *n = Node{} 445 n.Op = OLITERAL 446 n.Addable = true 447 ullmancalc(n) 448 n.SetVal(Val{new(Mpint)}) 449 n.Val().U.(*Mpint).SetInt64(v) 450 n.Type = t 451 452 if t.IsFloat() { 453 Fatalf("nodconst: bad type %v", t) 454 } 455 } 456 457 func nodnil() *Node { 458 c := nodintconst(0) 459 c.SetVal(Val{new(NilVal)}) 460 c.Type = Types[TNIL] 461 return c 462 } 463 464 func nodbool(b bool) *Node { 465 c := nodintconst(0) 466 c.SetVal(Val{b}) 467 c.Type = idealbool 468 return c 469 } 470 471 // treecopy recursively copies n, with the exception of 472 // ONAME, OLITERAL, OTYPE, and non-iota ONONAME leaves. 473 // Copies of iota ONONAME nodes are assigned the current 474 // value of iota_. If pos.IsKnown(), it sets the source 475 // position of newly allocated nodes to pos. 476 func treecopy(n *Node, pos src.XPos) *Node { 477 if n == nil { 478 return nil 479 } 480 481 switch n.Op { 482 default: 483 m := *n 484 m.Orig = &m 485 m.Left = treecopy(n.Left, pos) 486 m.Right = treecopy(n.Right, pos) 487 m.List.Set(listtreecopy(n.List.Slice(), pos)) 488 if pos.IsKnown() { 489 m.Pos = pos 490 } 491 if m.Name != nil && n.Op != ODCLFIELD { 492 Dump("treecopy", n) 493 Fatalf("treecopy Name") 494 } 495 return &m 496 497 case OPACK: 498 // OPACK nodes are never valid in const value declarations, 499 // but allow them like any other declared symbol to avoid 500 // crashing (golang.org/issue/11361). 501 fallthrough 502 503 case ONAME, ONONAME, OLITERAL, OTYPE: 504 return n 505 506 } 507 } 508 509 // isnil reports whether n represents the universal untyped zero value "nil". 510 func isnil(n *Node) bool { 511 // Check n.Orig because constant propagation may produce typed nil constants, 512 // which don't exist in the Go spec. 513 return Isconst(n.Orig, CTNIL) 514 } 515 516 func isptrto(t *Type, et EType) bool { 517 if t == nil { 518 return false 519 } 520 if !t.IsPtr() { 521 return false 522 } 523 t = t.Elem() 524 if t == nil { 525 return false 526 } 527 if t.Etype != et { 528 return false 529 } 530 return true 531 } 532 533 func isblank(n *Node) bool { 534 if n == nil { 535 return false 536 } 537 return isblanksym(n.Sym) 538 } 539 540 func isblanksym(s *Sym) bool { 541 return s != nil && s.Name == "_" 542 } 543 544 // methtype returns the underlying type, if any, 545 // that owns methods with receiver parameter t. 546 // The result is either a named type or an anonymous struct. 547 func methtype(t *Type) *Type { 548 if t == nil { 549 return nil 550 } 551 552 // Strip away pointer if it's there. 553 if t.IsPtr() { 554 if t.Sym != nil { 555 return nil 556 } 557 t = t.Elem() 558 if t == nil { 559 return nil 560 } 561 } 562 563 // Must be a named type or anonymous struct. 564 if t.Sym == nil && !t.IsStruct() { 565 return nil 566 } 567 568 // Check types. 569 if issimple[t.Etype] { 570 return t 571 } 572 switch t.Etype { 573 case TARRAY, TCHAN, TFUNC, TMAP, TSLICE, TSTRING, TSTRUCT: 574 return t 575 } 576 return nil 577 } 578 579 func cplxsubtype(et EType) EType { 580 switch et { 581 case TCOMPLEX64: 582 return TFLOAT32 583 584 case TCOMPLEX128: 585 return TFLOAT64 586 } 587 588 Fatalf("cplxsubtype: %v\n", et) 589 return 0 590 } 591 592 // eqtype reports whether t1 and t2 are identical, following the spec rules. 593 // 594 // Any cyclic type must go through a named type, and if one is 595 // named, it is only identical to the other if they are the same 596 // pointer (t1 == t2), so there's no chance of chasing cycles 597 // ad infinitum, so no need for a depth counter. 598 func eqtype(t1, t2 *Type) bool { 599 return eqtype1(t1, t2, true, nil) 600 } 601 602 // eqtypeIgnoreTags is like eqtype but it ignores struct tags for struct identity. 603 func eqtypeIgnoreTags(t1, t2 *Type) bool { 604 return eqtype1(t1, t2, false, nil) 605 } 606 607 type typePair struct { 608 t1 *Type 609 t2 *Type 610 } 611 612 func eqtype1(t1, t2 *Type, cmpTags bool, assumedEqual map[typePair]struct{}) bool { 613 if t1 == t2 { 614 return true 615 } 616 if t1 == nil || t2 == nil || t1.Etype != t2.Etype || t1.Broke || t2.Broke { 617 return false 618 } 619 if t1.Sym != nil || t2.Sym != nil { 620 // Special case: we keep byte/uint8 and rune/int32 621 // separate for error messages. Treat them as equal. 622 switch t1.Etype { 623 case TUINT8: 624 return (t1 == Types[TUINT8] || t1 == bytetype) && (t2 == Types[TUINT8] || t2 == bytetype) 625 case TINT32: 626 return (t1 == Types[TINT32] || t1 == runetype) && (t2 == Types[TINT32] || t2 == runetype) 627 default: 628 return false 629 } 630 } 631 632 if assumedEqual == nil { 633 assumedEqual = make(map[typePair]struct{}) 634 } else if _, ok := assumedEqual[typePair{t1, t2}]; ok { 635 return true 636 } 637 assumedEqual[typePair{t1, t2}] = struct{}{} 638 639 switch t1.Etype { 640 case TINTER, TSTRUCT: 641 t1, i1 := iterFields(t1) 642 t2, i2 := iterFields(t2) 643 for ; t1 != nil && t2 != nil; t1, t2 = i1.Next(), i2.Next() { 644 if t1.Sym != t2.Sym || t1.Embedded != t2.Embedded || !eqtype1(t1.Type, t2.Type, cmpTags, assumedEqual) || cmpTags && t1.Note != t2.Note { 645 return false 646 } 647 } 648 649 if t1 == nil && t2 == nil { 650 return true 651 } 652 return false 653 654 case TFUNC: 655 // Check parameters and result parameters for type equality. 656 // We intentionally ignore receiver parameters for type 657 // equality, because they're never relevant. 658 for _, f := range paramsResults { 659 // Loop over fields in structs, ignoring argument names. 660 ta, ia := iterFields(f(t1)) 661 tb, ib := iterFields(f(t2)) 662 for ; ta != nil && tb != nil; ta, tb = ia.Next(), ib.Next() { 663 if ta.Isddd != tb.Isddd || !eqtype1(ta.Type, tb.Type, cmpTags, assumedEqual) { 664 return false 665 } 666 } 667 if ta != nil || tb != nil { 668 return false 669 } 670 } 671 return true 672 673 case TARRAY: 674 if t1.NumElem() != t2.NumElem() { 675 return false 676 } 677 678 case TCHAN: 679 if t1.ChanDir() != t2.ChanDir() { 680 return false 681 } 682 683 case TMAP: 684 if !eqtype1(t1.Key(), t2.Key(), cmpTags, assumedEqual) { 685 return false 686 } 687 return eqtype1(t1.Val(), t2.Val(), cmpTags, assumedEqual) 688 } 689 690 return eqtype1(t1.Elem(), t2.Elem(), cmpTags, assumedEqual) 691 } 692 693 // Are t1 and t2 equal struct types when field names are ignored? 694 // For deciding whether the result struct from g can be copied 695 // directly when compiling f(g()). 696 func eqtypenoname(t1 *Type, t2 *Type) bool { 697 if t1 == nil || t2 == nil || !t1.IsStruct() || !t2.IsStruct() { 698 return false 699 } 700 701 f1, i1 := iterFields(t1) 702 f2, i2 := iterFields(t2) 703 for { 704 if !eqtype(f1.Type, f2.Type) { 705 return false 706 } 707 if f1 == nil { 708 return true 709 } 710 f1 = i1.Next() 711 f2 = i2.Next() 712 } 713 } 714 715 // Is type src assignment compatible to type dst? 716 // If so, return op code to use in conversion. 717 // If not, return 0. 718 func assignop(src *Type, dst *Type, why *string) Op { 719 if why != nil { 720 *why = "" 721 } 722 723 // TODO(rsc,lvd): This behaves poorly in the presence of inlining. 724 // https://golang.org/issue/2795 725 if safemode && importpkg == nil && src != nil && src.Etype == TUNSAFEPTR { 726 yyerror("cannot use unsafe.Pointer") 727 errorexit() 728 } 729 730 if src == dst { 731 return OCONVNOP 732 } 733 if src == nil || dst == nil || src.Etype == TFORW || dst.Etype == TFORW || src.Orig == nil || dst.Orig == nil { 734 return 0 735 } 736 737 // 1. src type is identical to dst. 738 if eqtype(src, dst) { 739 return OCONVNOP 740 } 741 742 // 2. src and dst have identical underlying types 743 // and either src or dst is not a named type or 744 // both are empty interface types. 745 // For assignable but different non-empty interface types, 746 // we want to recompute the itab. 747 if eqtype(src.Orig, dst.Orig) && (src.Sym == nil || dst.Sym == nil || src.IsEmptyInterface()) { 748 return OCONVNOP 749 } 750 751 // 3. dst is an interface type and src implements dst. 752 if dst.IsInterface() && src.Etype != TNIL { 753 var missing, have *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 *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() == 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 *Type, dst *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 == bytetype.Etype { 913 return OARRAYBYTESTR 914 } 915 if src.Elem().Etype == 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 == bytetype.Etype { 924 return OSTRARRAYBYTE 925 } 926 if dst.Elem().Etype == 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 *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 *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.Diag = true // silence errors about n; we'll issue one below 961 n = defaultlit(n, t) 962 old.Diag = 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 == idealbool && !t.IsBoolean() { 970 if n.Op == ONAME || n.Op == OLITERAL { 971 r := nod(OCONVNOP, n, nil) 972 r.Type = Types[TBOOL] 973 r.Typecheck = 1 974 r.Implicit = 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.Implicit = 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.Set([]*Node{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.Set([]*Node{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 func syslook(name string) *Node { 1073 s := Pkglookup(name, Runtimepkg) 1074 if s == nil || s.Def == nil { 1075 Fatalf("syslook: can't find runtime.%s", name) 1076 } 1077 return s.Def 1078 } 1079 1080 // typehash computes a hash value for type t to use in type switch 1081 // statements. 1082 func typehash(t *Type) uint32 { 1083 // t.tconv(FmtLeft | FmtUnsigned) already contains all the necessary logic 1084 // to generate a representation that completely describes the type, so using 1085 // it here avoids duplicating that code. 1086 // See the comments in exprSwitch.checkDupCases. 1087 p := t.tconv(FmtLeft | FmtUnsigned) 1088 1089 // Using MD5 is overkill, but reduces accidental collisions. 1090 h := md5.Sum([]byte(p)) 1091 return binary.LittleEndian.Uint32(h[:4]) 1092 } 1093 1094 // ptrto returns the Type *t. 1095 // The returned struct must not be modified. 1096 func ptrto(t *Type) *Type { 1097 if Tptr == 0 { 1098 Fatalf("ptrto: no tptr") 1099 } 1100 if t == nil { 1101 Fatalf("ptrto: nil ptr") 1102 } 1103 return typPtr(t) 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 // calculate sethi/ullman number 1137 // roughly how many registers needed to 1138 // compile a node. used to compile the 1139 // hardest side first to minimize registers. 1140 func ullmancalc(n *Node) { 1141 if n == nil { 1142 return 1143 } 1144 1145 var ul int 1146 var ur int 1147 if n.Ninit.Len() != 0 { 1148 ul = UINF 1149 goto out 1150 } 1151 1152 switch n.Op { 1153 case OLITERAL, ONAME: 1154 ul = 1 1155 if n.Class == PAUTOHEAP { 1156 ul++ 1157 } 1158 goto out 1159 1160 case OCALL, OCALLFUNC, OCALLMETH, OCALLINTER, OASWB: 1161 ul = UINF 1162 goto out 1163 1164 // hard with instrumented code 1165 case OANDAND, OOROR: 1166 if instrumenting { 1167 ul = UINF 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 ul = UINF 1175 goto out 1176 } 1177 1178 ul = 1 1179 if n.Left != nil { 1180 ul = int(n.Left.Ullman) 1181 } 1182 ur = 1 1183 if n.Right != nil { 1184 ur = int(n.Right.Ullman) 1185 } 1186 if ul == ur { 1187 ul += 1 1188 } 1189 if ur > ul { 1190 ul = ur 1191 } 1192 1193 out: 1194 if ul > 200 { 1195 ul = 200 // clamp to uchar with room to grow 1196 } 1197 n.Ullman = uint8(ul) 1198 } 1199 1200 func badtype(op Op, tl *Type, tr *Type) { 1201 fmt_ := "" 1202 if tl != nil { 1203 fmt_ += fmt.Sprintf("\n\t%v", tl) 1204 } 1205 if tr != nil { 1206 fmt_ += fmt.Sprintf("\n\t%v", tr) 1207 } 1208 1209 // common mistake: *struct and *interface. 1210 if tl != nil && tr != nil && tl.IsPtr() && tr.IsPtr() { 1211 if tl.Elem().IsStruct() && tr.Elem().IsInterface() { 1212 fmt_ += "\n\t(*struct vs *interface)" 1213 } else if tl.Elem().IsInterface() && tr.Elem().IsStruct() { 1214 fmt_ += "\n\t(*interface vs *struct)" 1215 } 1216 } 1217 1218 s := fmt_ 1219 yyerror("illegal types for operand: %v%s", op, s) 1220 } 1221 1222 // brcom returns !(op). 1223 // For example, brcom(==) is !=. 1224 func brcom(op Op) Op { 1225 switch op { 1226 case OEQ: 1227 return ONE 1228 case ONE: 1229 return OEQ 1230 case OLT: 1231 return OGE 1232 case OGT: 1233 return OLE 1234 case OLE: 1235 return OGT 1236 case OGE: 1237 return OLT 1238 } 1239 Fatalf("brcom: no com for %v\n", op) 1240 return op 1241 } 1242 1243 // brrev returns reverse(op). 1244 // For example, Brrev(<) is >. 1245 func brrev(op Op) Op { 1246 switch op { 1247 case OEQ: 1248 return OEQ 1249 case ONE: 1250 return ONE 1251 case OLT: 1252 return OGT 1253 case OGT: 1254 return OLT 1255 case OLE: 1256 return OGE 1257 case OGE: 1258 return OLE 1259 } 1260 Fatalf("brrev: no rev for %v\n", op) 1261 return op 1262 } 1263 1264 // return side effect-free n, appending side effects to init. 1265 // result is assignable if n is. 1266 func safeexpr(n *Node, init *Nodes) *Node { 1267 if n == nil { 1268 return nil 1269 } 1270 1271 if n.Ninit.Len() != 0 { 1272 walkstmtlist(n.Ninit.Slice()) 1273 init.AppendNodes(&n.Ninit) 1274 } 1275 1276 switch n.Op { 1277 case ONAME, OLITERAL: 1278 return n 1279 1280 case ODOT, OLEN, OCAP: 1281 l := safeexpr(n.Left, init) 1282 if l == n.Left { 1283 return n 1284 } 1285 r := nod(OXXX, nil, nil) 1286 *r = *n 1287 r.Left = l 1288 r = typecheck(r, Erv) 1289 r = walkexpr(r, init) 1290 return r 1291 1292 case ODOTPTR, OIND: 1293 l := safeexpr(n.Left, init) 1294 if l == n.Left { 1295 return n 1296 } 1297 a := nod(OXXX, nil, nil) 1298 *a = *n 1299 a.Left = l 1300 a = walkexpr(a, init) 1301 return a 1302 1303 case OINDEX, OINDEXMAP: 1304 l := safeexpr(n.Left, init) 1305 r := safeexpr(n.Right, init) 1306 if l == n.Left && r == n.Right { 1307 return n 1308 } 1309 a := nod(OXXX, nil, nil) 1310 *a = *n 1311 a.Left = l 1312 a.Right = r 1313 a = walkexpr(a, init) 1314 return a 1315 1316 case OSTRUCTLIT, OARRAYLIT, OSLICELIT: 1317 if isStaticCompositeLiteral(n) { 1318 return n 1319 } 1320 } 1321 1322 // make a copy; must not be used as an lvalue 1323 if islvalue(n) { 1324 Fatalf("missing lvalue case in safeexpr: %v", n) 1325 } 1326 return cheapexpr(n, init) 1327 } 1328 1329 func copyexpr(n *Node, t *Type, init *Nodes) *Node { 1330 l := temp(t) 1331 a := nod(OAS, l, n) 1332 a = typecheck(a, Etop) 1333 a = walkexpr(a, init) 1334 init.Append(a) 1335 return l 1336 } 1337 1338 // return side-effect free and cheap n, appending side effects to init. 1339 // result may not be assignable. 1340 func cheapexpr(n *Node, init *Nodes) *Node { 1341 switch n.Op { 1342 case ONAME, OLITERAL: 1343 return n 1344 } 1345 1346 return copyexpr(n, n.Type, init) 1347 } 1348 1349 // Code to resolve elided DOTs in embedded types. 1350 1351 // A Dlist stores a pointer to a TFIELD Type embedded within 1352 // a TSTRUCT or TINTER Type. 1353 type Dlist struct { 1354 field *Field 1355 } 1356 1357 // dotlist is used by adddot1 to record the path of embedded fields 1358 // used to access a target field or method. 1359 // Must be non-nil so that dotpath returns a non-nil slice even if d is zero. 1360 var dotlist = make([]Dlist, 10) 1361 1362 // lookdot0 returns the number of fields or methods named s associated 1363 // with Type t. If exactly one exists, it will be returned in *save 1364 // (if save is not nil). 1365 func lookdot0(s *Sym, t *Type, save **Field, ignorecase bool) int { 1366 u := t 1367 if u.IsPtr() { 1368 u = u.Elem() 1369 } 1370 1371 c := 0 1372 if u.IsStruct() || u.IsInterface() { 1373 for _, f := range u.Fields().Slice() { 1374 if f.Sym == s || (ignorecase && f.Type.Etype == TFUNC && f.Type.Recv() != nil && strings.EqualFold(f.Sym.Name, s.Name)) { 1375 if save != nil { 1376 *save = f 1377 } 1378 c++ 1379 } 1380 } 1381 } 1382 1383 u = methtype(t) 1384 if u != nil { 1385 for _, f := range u.Methods().Slice() { 1386 if f.Embedded == 0 && (f.Sym == s || (ignorecase && strings.EqualFold(f.Sym.Name, s.Name))) { 1387 if save != nil { 1388 *save = f 1389 } 1390 c++ 1391 } 1392 } 1393 } 1394 1395 return c 1396 } 1397 1398 // adddot1 returns the number of fields or methods named s at depth d in Type t. 1399 // If exactly one exists, it will be returned in *save (if save is not nil), 1400 // and dotlist will contain the path of embedded fields traversed to find it, 1401 // in reverse order. If none exist, more will indicate whether t contains any 1402 // embedded fields at depth d, so callers can decide whether to retry at 1403 // a greater depth. 1404 func adddot1(s *Sym, t *Type, d int, save **Field, ignorecase bool) (c int, more bool) { 1405 if t.Trecur != 0 { 1406 return 1407 } 1408 t.Trecur = 1 1409 1410 var u *Type 1411 d-- 1412 if d < 0 { 1413 // We've reached our target depth. If t has any fields/methods 1414 // named s, then we're done. Otherwise, we still need to check 1415 // below for embedded fields. 1416 c = lookdot0(s, t, save, ignorecase) 1417 if c != 0 { 1418 goto out 1419 } 1420 } 1421 1422 u = t 1423 if u.IsPtr() { 1424 u = u.Elem() 1425 } 1426 if !u.IsStruct() && !u.IsInterface() { 1427 goto out 1428 } 1429 1430 for _, f := range u.Fields().Slice() { 1431 if f.Embedded == 0 || f.Sym == nil { 1432 continue 1433 } 1434 if d < 0 { 1435 // Found an embedded field at target depth. 1436 more = true 1437 goto out 1438 } 1439 a, more1 := adddot1(s, f.Type, d, save, ignorecase) 1440 if a != 0 && c == 0 { 1441 dotlist[d].field = f 1442 } 1443 c += a 1444 if more1 { 1445 more = true 1446 } 1447 } 1448 1449 out: 1450 t.Trecur = 0 1451 return c, more 1452 } 1453 1454 // dotpath computes the unique shortest explicit selector path to fully qualify 1455 // a selection expression x.f, where x is of type t and f is the symbol s. 1456 // If no such path exists, dotpath returns nil. 1457 // If there are multiple shortest paths to the same depth, ambig is true. 1458 func dotpath(s *Sym, t *Type, save **Field, ignorecase bool) (path []Dlist, ambig bool) { 1459 // The embedding of types within structs imposes a tree structure onto 1460 // types: structs parent the types they embed, and types parent their 1461 // fields or methods. Our goal here is to find the shortest path to 1462 // a field or method named s in the subtree rooted at t. To accomplish 1463 // that, we iteratively perform depth-first searches of increasing depth 1464 // until we either find the named field/method or exhaust the tree. 1465 for d := 0; ; d++ { 1466 if d > len(dotlist) { 1467 dotlist = append(dotlist, Dlist{}) 1468 } 1469 if c, more := adddot1(s, t, d, save, ignorecase); c == 1 { 1470 return dotlist[:d], false 1471 } else if c > 1 { 1472 return nil, true 1473 } else if !more { 1474 return nil, false 1475 } 1476 } 1477 } 1478 1479 // in T.field 1480 // find missing fields that 1481 // will give shortest unique addressing. 1482 // modify the tree with missing type names. 1483 func adddot(n *Node) *Node { 1484 n.Left = typecheck(n.Left, Etype|Erv) 1485 if n.Left.Diag { 1486 n.Diag = true 1487 } 1488 t := n.Left.Type 1489 if t == nil { 1490 return n 1491 } 1492 1493 if n.Left.Op == OTYPE { 1494 return n 1495 } 1496 1497 s := n.Sym 1498 if s == nil { 1499 return n 1500 } 1501 1502 switch path, ambig := dotpath(s, t, nil, false); { 1503 case path != nil: 1504 // rebuild elided dots 1505 for c := len(path) - 1; c >= 0; c-- { 1506 n.Left = nodSym(ODOT, n.Left, path[c].field.Sym) 1507 n.Left.Implicit = true 1508 } 1509 case ambig: 1510 yyerror("ambiguous selector %v", n) 1511 n.Left = nil 1512 } 1513 1514 return n 1515 } 1516 1517 // code to help generate trampoline 1518 // functions for methods on embedded 1519 // subtypes. 1520 // these are approx the same as 1521 // the corresponding adddot routines 1522 // except that they expect to be called 1523 // with unique tasks and they return 1524 // the actual methods. 1525 type Symlink struct { 1526 field *Field 1527 followptr bool 1528 } 1529 1530 var slist []Symlink 1531 1532 func expand0(t *Type, followptr bool) { 1533 u := t 1534 if u.IsPtr() { 1535 followptr = true 1536 u = u.Elem() 1537 } 1538 1539 if u.IsInterface() { 1540 for _, f := range u.Fields().Slice() { 1541 if f.Sym.Flags&SymUniq != 0 { 1542 continue 1543 } 1544 f.Sym.Flags |= SymUniq 1545 slist = append(slist, Symlink{field: f, followptr: followptr}) 1546 } 1547 1548 return 1549 } 1550 1551 u = methtype(t) 1552 if u != nil { 1553 for _, f := range u.Methods().Slice() { 1554 if f.Sym.Flags&SymUniq != 0 { 1555 continue 1556 } 1557 f.Sym.Flags |= SymUniq 1558 slist = append(slist, Symlink{field: f, followptr: followptr}) 1559 } 1560 } 1561 } 1562 1563 func expand1(t *Type, top, followptr bool) { 1564 if t.Trecur != 0 { 1565 return 1566 } 1567 t.Trecur = 1 1568 1569 if !top { 1570 expand0(t, followptr) 1571 } 1572 1573 u := t 1574 if u.IsPtr() { 1575 followptr = true 1576 u = u.Elem() 1577 } 1578 1579 if !u.IsStruct() && !u.IsInterface() { 1580 goto out 1581 } 1582 1583 for _, f := range u.Fields().Slice() { 1584 if f.Embedded == 0 { 1585 continue 1586 } 1587 if f.Sym == nil { 1588 continue 1589 } 1590 expand1(f.Type, false, followptr) 1591 } 1592 1593 out: 1594 t.Trecur = 0 1595 } 1596 1597 func expandmeth(t *Type) { 1598 if t == nil || t.AllMethods().Len() != 0 { 1599 return 1600 } 1601 1602 // mark top-level method symbols 1603 // so that expand1 doesn't consider them. 1604 for _, f := range t.Methods().Slice() { 1605 f.Sym.Flags |= SymUniq 1606 } 1607 1608 // generate all reachable methods 1609 slist = slist[:0] 1610 expand1(t, true, false) 1611 1612 // check each method to be uniquely reachable 1613 var ms []*Field 1614 for i, sl := range slist { 1615 slist[i].field = nil 1616 sl.field.Sym.Flags &^= SymUniq 1617 1618 var f *Field 1619 if path, _ := dotpath(sl.field.Sym, t, &f, false); path == nil { 1620 continue 1621 } 1622 1623 // dotpath may have dug out arbitrary fields, we only want methods. 1624 if f.Type.Etype != TFUNC || f.Type.Recv() == nil { 1625 continue 1626 } 1627 1628 // add it to the base type method list 1629 f = f.Copy() 1630 f.Embedded = 1 // needs a trampoline 1631 if sl.followptr { 1632 f.Embedded = 2 1633 } 1634 ms = append(ms, f) 1635 } 1636 1637 for _, f := range t.Methods().Slice() { 1638 f.Sym.Flags &^= SymUniq 1639 } 1640 1641 ms = append(ms, t.Methods().Slice()...) 1642 t.AllMethods().Set(ms) 1643 } 1644 1645 // Given funarg struct list, return list of ODCLFIELD Node fn args. 1646 func structargs(tl *Type, mustname bool) []*Node { 1647 var args []*Node 1648 gen := 0 1649 for _, t := range tl.Fields().Slice() { 1650 var n *Node 1651 if mustname && (t.Sym == nil || t.Sym.Name == "_") { 1652 // invent a name so that we can refer to it in the trampoline 1653 buf := fmt.Sprintf(".anon%d", gen) 1654 gen++ 1655 n = newname(lookup(buf)) 1656 } else if t.Sym != nil { 1657 n = newname(t.Sym) 1658 } 1659 a := nod(ODCLFIELD, n, typenod(t.Type)) 1660 a.Isddd = t.Isddd 1661 if n != nil { 1662 n.Isddd = t.Isddd 1663 } 1664 args = append(args, a) 1665 } 1666 1667 return args 1668 } 1669 1670 // Generate a wrapper function to convert from 1671 // a receiver of type T to a receiver of type U. 1672 // That is, 1673 // 1674 // func (t T) M() { 1675 // ... 1676 // } 1677 // 1678 // already exists; this function generates 1679 // 1680 // func (u U) M() { 1681 // u.M() 1682 // } 1683 // 1684 // where the types T and U are such that u.M() is valid 1685 // and calls the T.M method. 1686 // The resulting function is for use in method tables. 1687 // 1688 // rcvr - U 1689 // method - M func (t T)(), a TFIELD type struct 1690 // newnam - the eventual mangled name of this function 1691 1692 func genwrapper(rcvr *Type, method *Field, newnam *Sym, iface int) { 1693 if false && Debug['r'] != 0 { 1694 fmt.Printf("genwrapper rcvrtype=%v method=%v newnam=%v\n", rcvr, method, newnam) 1695 } 1696 1697 lineno = MakePos(src.NewFileBase("<autogenerated>", "<autogenerated>"), 1, 0) 1698 1699 dclcontext = PEXTERN 1700 markdcl() 1701 1702 this := nod(ODCLFIELD, newname(lookup(".this")), typenod(rcvr)) 1703 this.Left.Name.Param.Ntype = this.Right 1704 in := structargs(method.Type.Params(), true) 1705 out := structargs(method.Type.Results(), false) 1706 1707 t := nod(OTFUNC, nil, nil) 1708 l := []*Node{this} 1709 if iface != 0 && rcvr.Width < Types[Tptr].Width { 1710 // Building method for interface table and receiver 1711 // is smaller than the single pointer-sized word 1712 // that the interface call will pass in. 1713 // Add a dummy padding argument after the 1714 // receiver to make up the difference. 1715 tpad := typArray(Types[TUINT8], Types[Tptr].Width-rcvr.Width) 1716 pad := nod(ODCLFIELD, newname(lookup(".pad")), typenod(tpad)) 1717 l = append(l, pad) 1718 } 1719 1720 t.List.Set(append(l, in...)) 1721 t.Rlist.Set(out) 1722 1723 fn := nod(ODCLFUNC, nil, nil) 1724 fn.Func.Nname = newname(newnam) 1725 fn.Func.Nname.Name.Defn = fn 1726 fn.Func.Nname.Name.Param.Ntype = t 1727 declare(fn.Func.Nname, PFUNC) 1728 funchdr(fn) 1729 1730 // arg list 1731 var args []*Node 1732 1733 isddd := false 1734 for _, n := range in { 1735 args = append(args, n.Left) 1736 isddd = n.Left.Isddd 1737 } 1738 1739 methodrcvr := method.Type.Recv().Type 1740 1741 // generate nil pointer check for better error 1742 if rcvr.IsPtr() && rcvr.Elem() == methodrcvr { 1743 // generating wrapper from *T to T. 1744 n := nod(OIF, nil, nil) 1745 1746 n.Left = nod(OEQ, this.Left, nodnil()) 1747 1748 // these strings are already in the reflect tables, 1749 // so no space cost to use them here. 1750 var l []*Node 1751 1752 var v Val 1753 v.U = rcvr.Elem().Sym.Pkg.Name // package name 1754 l = append(l, nodlit(v)) 1755 v.U = rcvr.Elem().Sym.Name // type name 1756 l = append(l, nodlit(v)) 1757 v.U = method.Sym.Name 1758 l = append(l, nodlit(v)) // method name 1759 call := nod(OCALL, syslook("panicwrap"), nil) 1760 call.List.Set(l) 1761 n.Nbody.Set1(call) 1762 fn.Nbody.Append(n) 1763 } 1764 1765 dot := adddot(nodSym(OXDOT, this.Left, method.Sym)) 1766 1767 // generate call 1768 // It's not possible to use a tail call when dynamic linking on ppc64le. The 1769 // bad scenario is when a local call is made to the wrapper: the wrapper will 1770 // call the implementation, which might be in a different module and so set 1771 // the TOC to the appropriate value for that module. But if it returns 1772 // directly to the wrapper's caller, nothing will reset it to the correct 1773 // value for that function. 1774 if !instrumenting && rcvr.IsPtr() && methodrcvr.IsPtr() && method.Embedded != 0 && !isifacemethod(method.Type) && !(Thearch.LinkArch.Name == "ppc64le" && Ctxt.Flag_dynlink) { 1775 // generate tail call: adjust pointer receiver and jump to embedded method. 1776 dot = dot.Left // skip final .M 1777 // TODO(mdempsky): Remove dependency on dotlist. 1778 if !dotlist[0].field.Type.IsPtr() { 1779 dot = nod(OADDR, dot, nil) 1780 } 1781 as := nod(OAS, this.Left, nod(OCONVNOP, dot, nil)) 1782 as.Right.Type = rcvr 1783 fn.Nbody.Append(as) 1784 n := nod(ORETJMP, nil, nil) 1785 n.Left = newname(methodsym(method.Sym, methodrcvr, 0)) 1786 fn.Nbody.Append(n) 1787 // When tail-calling, we can't use a frame pointer. 1788 fn.Func.NoFramePointer = true 1789 } else { 1790 fn.Func.Wrapper = true // ignore frame for panic+recover matching 1791 call := nod(OCALL, dot, nil) 1792 call.List.Set(args) 1793 call.Isddd = isddd 1794 if method.Type.Results().NumFields() > 0 { 1795 n := nod(ORETURN, nil, nil) 1796 n.List.Set1(call) 1797 call = n 1798 } 1799 1800 fn.Nbody.Append(call) 1801 } 1802 1803 if false && Debug['r'] != 0 { 1804 dumplist("genwrapper body", fn.Nbody) 1805 } 1806 1807 funcbody(fn) 1808 Curfn = fn 1809 popdcl() 1810 if debug_dclstack != 0 { 1811 testdclstack() 1812 } 1813 1814 // wrappers where T is anonymous (struct or interface) can be duplicated. 1815 if rcvr.IsStruct() || rcvr.IsInterface() || rcvr.IsPtr() && rcvr.Elem().IsStruct() { 1816 fn.Func.Dupok = true 1817 } 1818 fn = typecheck(fn, Etop) 1819 typecheckslice(fn.Nbody.Slice(), Etop) 1820 1821 inlcalls(fn) 1822 escAnalyze([]*Node{fn}, false) 1823 1824 Curfn = nil 1825 funccompile(fn) 1826 } 1827 1828 func hashmem(t *Type) *Node { 1829 sym := Pkglookup("memhash", Runtimepkg) 1830 1831 n := newname(sym) 1832 n.Class = PFUNC 1833 tfn := nod(OTFUNC, nil, nil) 1834 tfn.List.Append(nod(ODCLFIELD, nil, typenod(ptrto(t)))) 1835 tfn.List.Append(nod(ODCLFIELD, nil, typenod(Types[TUINTPTR]))) 1836 tfn.List.Append(nod(ODCLFIELD, nil, typenod(Types[TUINTPTR]))) 1837 tfn.Rlist.Append(nod(ODCLFIELD, nil, typenod(Types[TUINTPTR]))) 1838 tfn = typecheck(tfn, Etype) 1839 n.Type = tfn.Type 1840 return n 1841 } 1842 1843 func ifacelookdot(s *Sym, t *Type, followptr *bool, ignorecase bool) *Field { 1844 *followptr = false 1845 1846 if t == nil { 1847 return nil 1848 } 1849 1850 var m *Field 1851 path, ambig := dotpath(s, t, &m, ignorecase) 1852 if path == nil { 1853 if ambig { 1854 yyerror("%v.%v is ambiguous", t, s) 1855 } 1856 return nil 1857 } 1858 1859 for _, d := range path { 1860 if d.field.Type.IsPtr() { 1861 *followptr = true 1862 break 1863 } 1864 } 1865 1866 if m.Type.Etype != TFUNC || m.Type.Recv() == nil { 1867 yyerror("%v.%v is a field, not a method", t, s) 1868 return nil 1869 } 1870 1871 return m 1872 } 1873 1874 func implements(t, iface *Type, m, samename **Field, ptr *int) bool { 1875 t0 := t 1876 if t == nil { 1877 return false 1878 } 1879 1880 // if this is too slow, 1881 // could sort these first 1882 // and then do one loop. 1883 1884 if t.IsInterface() { 1885 for _, im := range iface.Fields().Slice() { 1886 for _, tm := range t.Fields().Slice() { 1887 if tm.Sym == im.Sym { 1888 if eqtype(tm.Type, im.Type) { 1889 goto found 1890 } 1891 *m = im 1892 *samename = tm 1893 *ptr = 0 1894 return false 1895 } 1896 } 1897 1898 *m = im 1899 *samename = nil 1900 *ptr = 0 1901 return false 1902 found: 1903 } 1904 1905 return true 1906 } 1907 1908 t = methtype(t) 1909 if t != nil { 1910 expandmeth(t) 1911 } 1912 for _, im := range iface.Fields().Slice() { 1913 if im.Broke { 1914 continue 1915 } 1916 var followptr bool 1917 tm := ifacelookdot(im.Sym, t, &followptr, false) 1918 if tm == nil || tm.Nointerface || !eqtype(tm.Type, im.Type) { 1919 if tm == nil { 1920 tm = ifacelookdot(im.Sym, t, &followptr, true) 1921 } 1922 *m = im 1923 *samename = tm 1924 *ptr = 0 1925 return false 1926 } 1927 1928 // if pointer receiver in method, 1929 // the method does not exist for value types. 1930 rcvr := tm.Type.Recv().Type 1931 1932 if rcvr.IsPtr() && !t0.IsPtr() && !followptr && !isifacemethod(tm.Type) { 1933 if false && Debug['r'] != 0 { 1934 yyerror("interface pointer mismatch") 1935 } 1936 1937 *m = im 1938 *samename = nil 1939 *ptr = 1 1940 return false 1941 } 1942 } 1943 1944 return true 1945 } 1946 1947 // even simpler simtype; get rid of ptr, bool. 1948 // assuming that the front end has rejected 1949 // all the invalid conversions (like ptr -> bool) 1950 func Simsimtype(t *Type) EType { 1951 if t == nil { 1952 return 0 1953 } 1954 1955 et := simtype[t.Etype] 1956 switch et { 1957 case TPTR32: 1958 et = TUINT32 1959 1960 case TPTR64: 1961 et = TUINT64 1962 1963 case TBOOL: 1964 et = TUINT8 1965 } 1966 1967 return et 1968 } 1969 1970 func listtreecopy(l []*Node, pos src.XPos) []*Node { 1971 var out []*Node 1972 for _, n := range l { 1973 out = append(out, treecopy(n, pos)) 1974 } 1975 return out 1976 } 1977 1978 func liststmt(l []*Node) *Node { 1979 n := nod(OBLOCK, nil, nil) 1980 n.List.Set(l) 1981 if len(l) != 0 { 1982 n.Pos = l[0].Pos 1983 } 1984 return n 1985 } 1986 1987 // return power of 2 of the constant 1988 // operand. -1 if it is not a power of 2. 1989 // 1000+ if it is a -(power of 2) 1990 func powtwo(n *Node) int { 1991 if n == nil || n.Op != OLITERAL || n.Type == nil { 1992 return -1 1993 } 1994 if !n.Type.IsInteger() { 1995 return -1 1996 } 1997 1998 v := uint64(n.Int64()) 1999 b := uint64(1) 2000 for i := 0; i < 64; i++ { 2001 if b == v { 2002 return i 2003 } 2004 b = b << 1 2005 } 2006 2007 if !n.Type.IsSigned() { 2008 return -1 2009 } 2010 2011 v = -v 2012 b = 1 2013 for i := 0; i < 64; i++ { 2014 if b == v { 2015 return i + 1000 2016 } 2017 b = b << 1 2018 } 2019 2020 return -1 2021 } 2022 2023 func ngotype(n *Node) *Sym { 2024 if n.Type != nil { 2025 return typenamesym(n.Type) 2026 } 2027 return nil 2028 } 2029 2030 // Convert raw string to the prefix that will be used in the symbol 2031 // table. All control characters, space, '%' and '"', as well as 2032 // non-7-bit clean bytes turn into %xx. The period needs escaping 2033 // only in the last segment of the path, and it makes for happier 2034 // users if we escape that as little as possible. 2035 // 2036 // If you edit this, edit ../../debug/goobj/read.go:/importPathToPrefix too. 2037 func pathtoprefix(s string) string { 2038 slash := strings.LastIndex(s, "/") 2039 for i := 0; i < len(s); i++ { 2040 c := s[i] 2041 if c <= ' ' || i >= slash && c == '.' || c == '%' || c == '"' || c >= 0x7F { 2042 var buf bytes.Buffer 2043 for i := 0; i < len(s); i++ { 2044 c := s[i] 2045 if c <= ' ' || i >= slash && c == '.' || c == '%' || c == '"' || c >= 0x7F { 2046 fmt.Fprintf(&buf, "%%%02x", c) 2047 continue 2048 } 2049 buf.WriteByte(c) 2050 } 2051 return buf.String() 2052 } 2053 } 2054 return s 2055 } 2056 2057 var pkgMap = make(map[string]*Pkg) 2058 var pkgs []*Pkg 2059 2060 func mkpkg(path string) *Pkg { 2061 if p := pkgMap[path]; p != nil { 2062 return p 2063 } 2064 2065 p := new(Pkg) 2066 p.Path = path 2067 p.Prefix = pathtoprefix(path) 2068 p.Syms = make(map[string]*Sym) 2069 pkgMap[path] = p 2070 pkgs = append(pkgs, p) 2071 return p 2072 } 2073 2074 // The result of addinit MUST be assigned back to n, e.g. 2075 // n.Left = addinit(n.Left, init) 2076 func addinit(n *Node, init []*Node) *Node { 2077 if len(init) == 0 { 2078 return n 2079 } 2080 2081 switch n.Op { 2082 // There may be multiple refs to this node; 2083 // introduce OCONVNOP to hold init list. 2084 case ONAME, OLITERAL: 2085 n = nod(OCONVNOP, n, nil) 2086 n.Type = n.Left.Type 2087 n.Typecheck = 1 2088 } 2089 2090 n.Ninit.Prepend(init...) 2091 n.Ullman = UINF 2092 return n 2093 } 2094 2095 var reservedimports = []string{ 2096 "go", 2097 "type", 2098 } 2099 2100 func isbadimport(path string) bool { 2101 if strings.Contains(path, "\x00") { 2102 yyerror("import path contains NUL") 2103 return true 2104 } 2105 2106 for _, ri := range reservedimports { 2107 if path == ri { 2108 yyerror("import path %q is reserved and cannot be used", path) 2109 return true 2110 } 2111 } 2112 2113 for _, r := range path { 2114 if r == utf8.RuneError { 2115 yyerror("import path contains invalid UTF-8 sequence: %q", path) 2116 return true 2117 } 2118 2119 if r < 0x20 || r == 0x7f { 2120 yyerror("import path contains control character: %q", path) 2121 return true 2122 } 2123 2124 if r == '\\' { 2125 yyerror("import path contains backslash; use slash: %q", path) 2126 return true 2127 } 2128 2129 if unicode.IsSpace(r) { 2130 yyerror("import path contains space character: %q", path) 2131 return true 2132 } 2133 2134 if strings.ContainsRune("!\"#$%&'()*,:;<=>?[]^`{|}", r) { 2135 yyerror("import path contains invalid character '%c': %q", r, path) 2136 return true 2137 } 2138 } 2139 2140 return false 2141 } 2142 2143 func checknil(x *Node, init *Nodes) { 2144 x = walkexpr(x, nil) // caller has not done this yet 2145 if x.Type.IsInterface() { 2146 x = nod(OITAB, x, nil) 2147 x = typecheck(x, Erv) 2148 } 2149 2150 n := nod(OCHECKNIL, x, nil) 2151 n.Typecheck = 1 2152 init.Append(n) 2153 } 2154 2155 // Can this type be stored directly in an interface word? 2156 // Yes, if the representation is a single pointer. 2157 func isdirectiface(t *Type) bool { 2158 switch t.Etype { 2159 case TPTR32, 2160 TPTR64, 2161 TCHAN, 2162 TMAP, 2163 TFUNC, 2164 TUNSAFEPTR: 2165 return true 2166 2167 case TARRAY: 2168 // Array of 1 direct iface type can be direct. 2169 return t.NumElem() == 1 && isdirectiface(t.Elem()) 2170 2171 case TSTRUCT: 2172 // Struct with 1 field of direct iface type can be direct. 2173 return t.NumFields() == 1 && isdirectiface(t.Field(0).Type) 2174 } 2175 2176 return false 2177 } 2178 2179 // itabType loads the _type field from a runtime.itab struct. 2180 func itabType(itab *Node) *Node { 2181 typ := nodSym(ODOTPTR, itab, nil) 2182 typ.Type = ptrto(Types[TUINT8]) 2183 typ.Typecheck = 1 2184 typ.Xoffset = int64(Widthptr) // offset of _type in runtime.itab 2185 typ.Bounded = true // guaranteed not to fault 2186 return typ 2187 } 2188 2189 // ifaceData loads the data field from an interface. 2190 // The concrete type must be known to have type t. 2191 // It follows the pointer if !isdirectiface(t). 2192 func ifaceData(n *Node, t *Type) *Node { 2193 ptr := nodSym(OIDATA, n, nil) 2194 if isdirectiface(t) { 2195 ptr.Type = t 2196 ptr.Typecheck = 1 2197 return ptr 2198 } 2199 ptr.Type = ptrto(t) 2200 ptr.Bounded = true 2201 ptr.Typecheck = 1 2202 ind := nod(OIND, ptr, nil) 2203 ind.Type = t 2204 ind.Typecheck = 1 2205 return ind 2206 } 2207 2208 // iet returns 'T' if t is a concrete type, 2209 // 'I' if t is an interface type, and 'E' if t is an empty interface type. 2210 // It is used to build calls to the conv* and assert* runtime routines. 2211 func (t *Type) iet() byte { 2212 if t.IsEmptyInterface() { 2213 return 'E' 2214 } 2215 if t.IsInterface() { 2216 return 'I' 2217 } 2218 return 'T' 2219 }