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