github.com/FenixAra/go@v0.0.0-20170127160404-96ea0918e670/src/cmd/compile/internal/gc/const.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 "strings" 8 9 // Ctype describes the constant kind of an "ideal" (untyped) constant. 10 type Ctype int8 11 12 const ( 13 CTxxx Ctype = iota 14 15 CTINT 16 CTRUNE 17 CTFLT 18 CTCPLX 19 CTSTR 20 CTBOOL 21 CTNIL 22 ) 23 24 type Val struct { 25 // U contains one of: 26 // bool bool when n.ValCtype() == CTBOOL 27 // *Mpint int when n.ValCtype() == CTINT, rune when n.ValCtype() == CTRUNE 28 // *Mpflt float when n.ValCtype() == CTFLT 29 // *Mpcplx pair of floats when n.ValCtype() == CTCPLX 30 // string string when n.ValCtype() == CTSTR 31 // *Nilval when n.ValCtype() == CTNIL 32 U interface{} 33 } 34 35 func (v Val) Ctype() Ctype { 36 switch x := v.U.(type) { 37 default: 38 Fatalf("unexpected Ctype for %T", v.U) 39 panic("not reached") 40 case nil: 41 return 0 42 case *NilVal: 43 return CTNIL 44 case bool: 45 return CTBOOL 46 case *Mpint: 47 if x.Rune { 48 return CTRUNE 49 } 50 return CTINT 51 case *Mpflt: 52 return CTFLT 53 case *Mpcplx: 54 return CTCPLX 55 case string: 56 return CTSTR 57 } 58 } 59 60 func eqval(a, b Val) bool { 61 if a.Ctype() != b.Ctype() { 62 return false 63 } 64 switch x := a.U.(type) { 65 default: 66 Fatalf("unexpected Ctype for %T", a.U) 67 panic("not reached") 68 case *NilVal: 69 return true 70 case bool: 71 y := b.U.(bool) 72 return x == y 73 case *Mpint: 74 y := b.U.(*Mpint) 75 return x.Cmp(y) == 0 76 case *Mpflt: 77 y := b.U.(*Mpflt) 78 return x.Cmp(y) == 0 79 case *Mpcplx: 80 y := b.U.(*Mpcplx) 81 return x.Real.Cmp(&y.Real) == 0 && x.Imag.Cmp(&y.Imag) == 0 82 case string: 83 y := b.U.(string) 84 return x == y 85 } 86 } 87 88 // Interface returns the constant value stored in v as an interface{}. 89 // It returns int64s for ints and runes, float64s for floats, 90 // complex128s for complex values, and nil for constant nils. 91 func (v Val) Interface() interface{} { 92 switch x := v.U.(type) { 93 default: 94 Fatalf("unexpected Interface for %T", v.U) 95 panic("not reached") 96 case *NilVal: 97 return nil 98 case bool, string: 99 return x 100 case *Mpint: 101 return x.Int64() 102 case *Mpflt: 103 return x.Float64() 104 case *Mpcplx: 105 return complex(x.Real.Float64(), x.Imag.Float64()) 106 } 107 } 108 109 type NilVal struct{} 110 111 // Int64 returns n as an int64. 112 // n must be an integer or rune constant. 113 func (n *Node) Int64() int64 { 114 if !Isconst(n, CTINT) { 115 Fatalf("Int(%v)", n) 116 } 117 return n.Val().U.(*Mpint).Int64() 118 } 119 120 // truncate float literal fv to 32-bit or 64-bit precision 121 // according to type; return truncated value. 122 func truncfltlit(oldv *Mpflt, t *Type) *Mpflt { 123 if t == nil { 124 return oldv 125 } 126 127 var v Val 128 v.U = oldv 129 overflow(v, t) 130 131 fv := newMpflt() 132 fv.Set(oldv) 133 134 // convert large precision literal floating 135 // into limited precision (float64 or float32) 136 switch t.Etype { 137 case TFLOAT64: 138 d := fv.Float64() 139 fv.SetFloat64(d) 140 141 case TFLOAT32: 142 d := fv.Float32() 143 fv.SetFloat64(d) 144 } 145 146 return fv 147 } 148 149 // canReuseNode indicates whether it is known to be safe 150 // to reuse a Node. 151 type canReuseNode bool 152 153 const ( 154 noReuse canReuseNode = false // not necessarily safe to reuse 155 reuseOK canReuseNode = true // safe to reuse 156 ) 157 158 // convert n, if literal, to type t. 159 // implicit conversion. 160 // The result of convlit MUST be assigned back to n, e.g. 161 // n.Left = convlit(n.Left, t) 162 func convlit(n *Node, t *Type) *Node { 163 return convlit1(n, t, false, noReuse) 164 } 165 166 // convlit1 converts n, if literal, to type t. 167 // It returns a new node if necessary. 168 // The result of convlit1 MUST be assigned back to n, e.g. 169 // n.Left = convlit1(n.Left, t, explicit, reuse) 170 func convlit1(n *Node, t *Type, explicit bool, reuse canReuseNode) *Node { 171 if n == nil || t == nil || n.Type == nil || t.IsUntyped() || n.Type == t { 172 return n 173 } 174 if !explicit && !n.Type.IsUntyped() { 175 return n 176 } 177 178 if n.Op == OLITERAL && !reuse { 179 // Can't always set n.Type directly on OLITERAL nodes. 180 // See discussion on CL 20813. 181 nn := *n 182 n = &nn 183 reuse = true 184 } 185 186 switch n.Op { 187 default: 188 if n.Type == idealbool { 189 if t.IsBoolean() { 190 n.Type = t 191 } else { 192 n.Type = Types[TBOOL] 193 } 194 } 195 196 if n.Type.Etype == TIDEAL { 197 n.Left = convlit(n.Left, t) 198 n.Right = convlit(n.Right, t) 199 n.Type = t 200 } 201 202 return n 203 204 // target is invalid type for a constant? leave alone. 205 case OLITERAL: 206 if !okforconst[t.Etype] && n.Type.Etype != TNIL { 207 return defaultlitreuse(n, nil, reuse) 208 } 209 210 case OLSH, ORSH: 211 n.Left = convlit1(n.Left, t, explicit && n.Left.Type.IsUntyped(), noReuse) 212 t = n.Left.Type 213 if t != nil && t.Etype == TIDEAL && n.Val().Ctype() != CTINT { 214 n.SetVal(toint(n.Val())) 215 } 216 if t != nil && !t.IsInteger() { 217 yyerror("invalid operation: %v (shift of type %v)", n, t) 218 t = nil 219 } 220 221 n.Type = t 222 return n 223 224 case OCOMPLEX: 225 if n.Type.Etype == TIDEAL { 226 switch t.Etype { 227 default: 228 // If trying to convert to non-complex type, 229 // leave as complex128 and let typechecker complain. 230 t = Types[TCOMPLEX128] 231 fallthrough 232 case TCOMPLEX128: 233 n.Type = t 234 n.Left = convlit(n.Left, Types[TFLOAT64]) 235 n.Right = convlit(n.Right, Types[TFLOAT64]) 236 237 case TCOMPLEX64: 238 n.Type = t 239 n.Left = convlit(n.Left, Types[TFLOAT32]) 240 n.Right = convlit(n.Right, Types[TFLOAT32]) 241 } 242 } 243 244 return n 245 } 246 247 // avoided repeated calculations, errors 248 if eqtype(n.Type, t) { 249 return n 250 } 251 252 ct := consttype(n) 253 var et EType 254 if ct < 0 { 255 goto bad 256 } 257 258 et = t.Etype 259 if et == TINTER { 260 if ct == CTNIL && n.Type == Types[TNIL] { 261 n.Type = t 262 return n 263 } 264 return defaultlitreuse(n, nil, reuse) 265 } 266 267 switch ct { 268 default: 269 goto bad 270 271 case CTNIL: 272 switch et { 273 default: 274 n.Type = nil 275 goto bad 276 277 // let normal conversion code handle it 278 case TSTRING: 279 return n 280 281 case TARRAY: 282 goto bad 283 284 case TPTR32, 285 TPTR64, 286 TINTER, 287 TMAP, 288 TCHAN, 289 TFUNC, 290 TSLICE, 291 TUNSAFEPTR: 292 break 293 294 // A nil literal may be converted to uintptr 295 // if it is an unsafe.Pointer 296 case TUINTPTR: 297 if n.Type.Etype == TUNSAFEPTR { 298 n.SetVal(Val{new(Mpint)}) 299 n.Val().U.(*Mpint).SetInt64(0) 300 } else { 301 goto bad 302 } 303 } 304 305 case CTSTR, CTBOOL: 306 if et != n.Type.Etype { 307 goto bad 308 } 309 310 case CTINT, CTRUNE, CTFLT, CTCPLX: 311 if n.Type.Etype == TUNSAFEPTR && t.Etype != TUINTPTR { 312 goto bad 313 } 314 ct := n.Val().Ctype() 315 if isInt[et] { 316 switch ct { 317 default: 318 goto bad 319 320 case CTCPLX, CTFLT, CTRUNE: 321 n.SetVal(toint(n.Val())) 322 fallthrough 323 324 case CTINT: 325 overflow(n.Val(), t) 326 } 327 } else if isFloat[et] { 328 switch ct { 329 default: 330 goto bad 331 332 case CTCPLX, CTINT, CTRUNE: 333 n.SetVal(toflt(n.Val())) 334 fallthrough 335 336 case CTFLT: 337 n.SetVal(Val{truncfltlit(n.Val().U.(*Mpflt), t)}) 338 } 339 } else if isComplex[et] { 340 switch ct { 341 default: 342 goto bad 343 344 case CTFLT, CTINT, CTRUNE: 345 n.SetVal(tocplx(n.Val())) 346 fallthrough 347 348 case CTCPLX: 349 overflow(n.Val(), t) 350 } 351 } else if et == TSTRING && (ct == CTINT || ct == CTRUNE) && explicit { 352 n.SetVal(tostr(n.Val())) 353 } else { 354 goto bad 355 } 356 } 357 358 n.Type = t 359 return n 360 361 bad: 362 if !n.Diag { 363 if !t.Broke { 364 yyerror("cannot convert %v to type %v", n, t) 365 } 366 n.Diag = true 367 } 368 369 if n.Type.IsUntyped() { 370 n = defaultlitreuse(n, nil, reuse) 371 } 372 return n 373 } 374 375 func copyval(v Val) Val { 376 switch u := v.U.(type) { 377 case *Mpint: 378 i := new(Mpint) 379 i.Set(u) 380 i.Rune = u.Rune 381 v.U = i 382 383 case *Mpflt: 384 f := newMpflt() 385 f.Set(u) 386 v.U = f 387 388 case *Mpcplx: 389 c := new(Mpcplx) 390 c.Real.Set(&u.Real) 391 c.Imag.Set(&u.Imag) 392 v.U = c 393 } 394 395 return v 396 } 397 398 func tocplx(v Val) Val { 399 switch u := v.U.(type) { 400 case *Mpint: 401 c := new(Mpcplx) 402 c.Real.SetInt(u) 403 c.Imag.SetFloat64(0.0) 404 v.U = c 405 406 case *Mpflt: 407 c := new(Mpcplx) 408 c.Real.Set(u) 409 c.Imag.SetFloat64(0.0) 410 v.U = c 411 } 412 413 return v 414 } 415 416 func toflt(v Val) Val { 417 switch u := v.U.(type) { 418 case *Mpint: 419 f := newMpflt() 420 f.SetInt(u) 421 v.U = f 422 423 case *Mpcplx: 424 f := newMpflt() 425 f.Set(&u.Real) 426 if u.Imag.CmpFloat64(0) != 0 { 427 yyerror("constant %v%vi truncated to real", fconv(&u.Real, FmtSharp), fconv(&u.Imag, FmtSharp|FmtSign)) 428 } 429 v.U = f 430 } 431 432 return v 433 } 434 435 func toint(v Val) Val { 436 switch u := v.U.(type) { 437 case *Mpint: 438 if u.Rune { 439 i := new(Mpint) 440 i.Set(u) 441 v.U = i 442 } 443 444 case *Mpflt: 445 i := new(Mpint) 446 if i.SetFloat(u) < 0 { 447 msg := "constant %v truncated to integer" 448 // provide better error message if SetFloat failed because f was too large 449 if u.Val.IsInt() { 450 msg = "constant %v overflows integer" 451 } 452 yyerror(msg, fconv(u, FmtSharp)) 453 } 454 v.U = i 455 456 case *Mpcplx: 457 i := new(Mpint) 458 if i.SetFloat(&u.Real) < 0 { 459 yyerror("constant %v%vi truncated to integer", fconv(&u.Real, FmtSharp), fconv(&u.Imag, FmtSharp|FmtSign)) 460 } 461 if u.Imag.CmpFloat64(0) != 0 { 462 yyerror("constant %v%vi truncated to real", fconv(&u.Real, FmtSharp), fconv(&u.Imag, FmtSharp|FmtSign)) 463 } 464 v.U = i 465 } 466 467 return v 468 } 469 470 func doesoverflow(v Val, t *Type) bool { 471 switch u := v.U.(type) { 472 case *Mpint: 473 if !t.IsInteger() { 474 Fatalf("overflow: %v integer constant", t) 475 } 476 return u.Cmp(minintval[t.Etype]) < 0 || u.Cmp(maxintval[t.Etype]) > 0 477 478 case *Mpflt: 479 if !t.IsFloat() { 480 Fatalf("overflow: %v floating-point constant", t) 481 } 482 return u.Cmp(minfltval[t.Etype]) <= 0 || u.Cmp(maxfltval[t.Etype]) >= 0 483 484 case *Mpcplx: 485 if !t.IsComplex() { 486 Fatalf("overflow: %v complex constant", t) 487 } 488 return u.Real.Cmp(minfltval[t.Etype]) <= 0 || u.Real.Cmp(maxfltval[t.Etype]) >= 0 || 489 u.Imag.Cmp(minfltval[t.Etype]) <= 0 || u.Imag.Cmp(maxfltval[t.Etype]) >= 0 490 } 491 492 return false 493 } 494 495 func overflow(v Val, t *Type) { 496 // v has already been converted 497 // to appropriate form for t. 498 if t == nil || t.Etype == TIDEAL { 499 return 500 } 501 502 // Only uintptrs may be converted to unsafe.Pointer, which cannot overflow. 503 if t.Etype == TUNSAFEPTR { 504 return 505 } 506 507 if doesoverflow(v, t) { 508 yyerror("constant %v overflows %v", v, t) 509 } 510 } 511 512 func tostr(v Val) Val { 513 switch u := v.U.(type) { 514 case *Mpint: 515 var i int64 = 0xFFFD 516 if u.Cmp(minintval[TUINT32]) >= 0 && u.Cmp(maxintval[TUINT32]) <= 0 { 517 i = u.Int64() 518 } 519 v.U = string(i) 520 521 case *NilVal: 522 // Can happen because of string([]byte(nil)). 523 v.U = "" 524 } 525 526 return v 527 } 528 529 func consttype(n *Node) Ctype { 530 if n == nil || n.Op != OLITERAL { 531 return -1 532 } 533 return n.Val().Ctype() 534 } 535 536 func Isconst(n *Node, ct Ctype) bool { 537 t := consttype(n) 538 539 // If the caller is asking for CTINT, allow CTRUNE too. 540 // Makes life easier for back ends. 541 return t == ct || (ct == CTINT && t == CTRUNE) 542 } 543 544 func saveorig(n *Node) *Node { 545 if n == n.Orig { 546 // duplicate node for n->orig. 547 n1 := nod(OLITERAL, nil, nil) 548 549 n.Orig = n1 550 *n1 = *n 551 } 552 553 return n.Orig 554 } 555 556 // if n is constant, rewrite as OLITERAL node. 557 func evconst(n *Node) { 558 // pick off just the opcodes that can be 559 // constant evaluated. 560 switch n.Op { 561 default: 562 return 563 564 case OADD, 565 OAND, 566 OANDAND, 567 OANDNOT, 568 OARRAYBYTESTR, 569 OCOM, 570 ODIV, 571 OEQ, 572 OGE, 573 OGT, 574 OLE, 575 OLSH, 576 OLT, 577 OMINUS, 578 OMOD, 579 OMUL, 580 ONE, 581 ONOT, 582 OOR, 583 OOROR, 584 OPLUS, 585 ORSH, 586 OSUB, 587 OXOR: 588 break 589 590 case OCONV: 591 if n.Type == nil { 592 return 593 } 594 if !okforconst[n.Type.Etype] && n.Type.Etype != TNIL { 595 return 596 } 597 598 // merge adjacent constants in the argument list. 599 case OADDSTR: 600 s := n.List.Slice() 601 for i1 := 0; i1 < len(s); i1++ { 602 if Isconst(s[i1], CTSTR) && i1+1 < len(s) && Isconst(s[i1+1], CTSTR) { 603 // merge from i1 up to but not including i2 604 var strs []string 605 i2 := i1 606 for i2 < len(s) && Isconst(s[i2], CTSTR) { 607 strs = append(strs, s[i2].Val().U.(string)) 608 i2++ 609 } 610 611 nl := *s[i1] 612 nl.Orig = &nl 613 nl.SetVal(Val{strings.Join(strs, "")}) 614 s[i1] = &nl 615 s = append(s[:i1+1], s[i2:]...) 616 } 617 } 618 619 if len(s) == 1 && Isconst(s[0], CTSTR) { 620 n.Op = OLITERAL 621 n.SetVal(s[0].Val()) 622 } else { 623 n.List.Set(s) 624 } 625 626 return 627 } 628 629 nl := n.Left 630 if nl == nil || nl.Type == nil { 631 return 632 } 633 if consttype(nl) < 0 { 634 return 635 } 636 wl := nl.Type.Etype 637 if isInt[wl] || isFloat[wl] || isComplex[wl] { 638 wl = TIDEAL 639 } 640 641 // avoid constant conversions in switches below 642 const ( 643 CTINT_ = uint32(CTINT) 644 CTRUNE_ = uint32(CTRUNE) 645 CTFLT_ = uint32(CTFLT) 646 CTCPLX_ = uint32(CTCPLX) 647 CTSTR_ = uint32(CTSTR) 648 CTBOOL_ = uint32(CTBOOL) 649 CTNIL_ = uint32(CTNIL) 650 OCONV_ = uint32(OCONV) << 16 651 OARRAYBYTESTR_ = uint32(OARRAYBYTESTR) << 16 652 OPLUS_ = uint32(OPLUS) << 16 653 OMINUS_ = uint32(OMINUS) << 16 654 OCOM_ = uint32(OCOM) << 16 655 ONOT_ = uint32(ONOT) << 16 656 OLSH_ = uint32(OLSH) << 16 657 ORSH_ = uint32(ORSH) << 16 658 OADD_ = uint32(OADD) << 16 659 OSUB_ = uint32(OSUB) << 16 660 OMUL_ = uint32(OMUL) << 16 661 ODIV_ = uint32(ODIV) << 16 662 OMOD_ = uint32(OMOD) << 16 663 OOR_ = uint32(OOR) << 16 664 OAND_ = uint32(OAND) << 16 665 OANDNOT_ = uint32(OANDNOT) << 16 666 OXOR_ = uint32(OXOR) << 16 667 OEQ_ = uint32(OEQ) << 16 668 ONE_ = uint32(ONE) << 16 669 OLT_ = uint32(OLT) << 16 670 OLE_ = uint32(OLE) << 16 671 OGE_ = uint32(OGE) << 16 672 OGT_ = uint32(OGT) << 16 673 OOROR_ = uint32(OOROR) << 16 674 OANDAND_ = uint32(OANDAND) << 16 675 ) 676 677 nr := n.Right 678 var rv Val 679 var lno int32 680 var wr EType 681 var v Val 682 var norig *Node 683 var nn *Node 684 if nr == nil { 685 // copy numeric value to avoid modifying 686 // nl, in case someone still refers to it (e.g. iota). 687 v = nl.Val() 688 689 if wl == TIDEAL { 690 v = copyval(v) 691 } 692 693 switch uint32(n.Op)<<16 | uint32(v.Ctype()) { 694 default: 695 if !n.Diag { 696 yyerror("illegal constant expression %v %v", n.Op, nl.Type) 697 n.Diag = true 698 } 699 return 700 701 case OCONV_ | CTNIL_, 702 OARRAYBYTESTR_ | CTNIL_: 703 if n.Type.IsString() { 704 v = tostr(v) 705 nl.Type = n.Type 706 break 707 } 708 fallthrough 709 case OCONV_ | CTINT_, 710 OCONV_ | CTRUNE_, 711 OCONV_ | CTFLT_, 712 OCONV_ | CTSTR_, 713 OCONV_ | CTBOOL_: 714 nl = convlit1(nl, n.Type, true, false) 715 v = nl.Val() 716 717 case OPLUS_ | CTINT_, 718 OPLUS_ | CTRUNE_: 719 break 720 721 case OMINUS_ | CTINT_, 722 OMINUS_ | CTRUNE_: 723 v.U.(*Mpint).Neg() 724 725 case OCOM_ | CTINT_, 726 OCOM_ | CTRUNE_: 727 var et EType = Txxx 728 if nl.Type != nil { 729 et = nl.Type.Etype 730 } 731 732 // calculate the mask in b 733 // result will be (a ^ mask) 734 var b Mpint 735 switch et { 736 // signed guys change sign 737 default: 738 b.SetInt64(-1) 739 740 // unsigned guys invert their bits 741 case TUINT8, 742 TUINT16, 743 TUINT32, 744 TUINT64, 745 TUINT, 746 TUINTPTR: 747 b.Set(maxintval[et]) 748 } 749 750 v.U.(*Mpint).Xor(&b) 751 752 case OPLUS_ | CTFLT_: 753 break 754 755 case OMINUS_ | CTFLT_: 756 v.U.(*Mpflt).Neg() 757 758 case OPLUS_ | CTCPLX_: 759 break 760 761 case OMINUS_ | CTCPLX_: 762 v.U.(*Mpcplx).Real.Neg() 763 v.U.(*Mpcplx).Imag.Neg() 764 765 case ONOT_ | CTBOOL_: 766 if !v.U.(bool) { 767 goto settrue 768 } 769 goto setfalse 770 } 771 goto ret 772 } 773 if nr.Type == nil { 774 return 775 } 776 if consttype(nr) < 0 { 777 return 778 } 779 wr = nr.Type.Etype 780 if isInt[wr] || isFloat[wr] || isComplex[wr] { 781 wr = TIDEAL 782 } 783 784 // check for compatible general types (numeric, string, etc) 785 if wl != wr { 786 if wl == TINTER || wr == TINTER { 787 goto setfalse 788 } 789 goto illegal 790 } 791 792 // check for compatible types. 793 switch n.Op { 794 // ideal const mixes with anything but otherwise must match. 795 default: 796 if nl.Type.Etype != TIDEAL { 797 nr = defaultlit(nr, nl.Type) 798 n.Right = nr 799 } 800 801 if nr.Type.Etype != TIDEAL { 802 nl = defaultlit(nl, nr.Type) 803 n.Left = nl 804 } 805 806 if nl.Type.Etype != nr.Type.Etype { 807 goto illegal 808 } 809 810 // right must be unsigned. 811 // left can be ideal. 812 case OLSH, ORSH: 813 nr = defaultlit(nr, Types[TUINT]) 814 815 n.Right = nr 816 if nr.Type != nil && (nr.Type.IsSigned() || !nr.Type.IsInteger()) { 817 goto illegal 818 } 819 if nl.Val().Ctype() != CTRUNE { 820 nl.SetVal(toint(nl.Val())) 821 } 822 nr.SetVal(toint(nr.Val())) 823 } 824 825 // copy numeric value to avoid modifying 826 // n->left, in case someone still refers to it (e.g. iota). 827 v = nl.Val() 828 829 if wl == TIDEAL { 830 v = copyval(v) 831 } 832 833 rv = nr.Val() 834 835 // convert to common ideal 836 if v.Ctype() == CTCPLX || rv.Ctype() == CTCPLX { 837 v = tocplx(v) 838 rv = tocplx(rv) 839 } 840 841 if v.Ctype() == CTFLT || rv.Ctype() == CTFLT { 842 v = toflt(v) 843 rv = toflt(rv) 844 } 845 846 // Rune and int turns into rune. 847 if v.Ctype() == CTRUNE && rv.Ctype() == CTINT { 848 i := new(Mpint) 849 i.Set(rv.U.(*Mpint)) 850 i.Rune = true 851 rv.U = i 852 } 853 if v.Ctype() == CTINT && rv.Ctype() == CTRUNE { 854 if n.Op == OLSH || n.Op == ORSH { 855 i := new(Mpint) 856 i.Set(rv.U.(*Mpint)) 857 rv.U = i 858 } else { 859 i := new(Mpint) 860 i.Set(v.U.(*Mpint)) 861 i.Rune = true 862 v.U = i 863 } 864 } 865 866 if v.Ctype() != rv.Ctype() { 867 // Use of undefined name as constant? 868 if (v.Ctype() == 0 || rv.Ctype() == 0) && nerrors > 0 { 869 return 870 } 871 Fatalf("constant type mismatch %v(%d) %v(%d)", nl.Type, v.Ctype(), nr.Type, rv.Ctype()) 872 } 873 874 // run op 875 switch uint32(n.Op)<<16 | uint32(v.Ctype()) { 876 default: 877 goto illegal 878 879 case OADD_ | CTINT_, 880 OADD_ | CTRUNE_: 881 v.U.(*Mpint).Add(rv.U.(*Mpint)) 882 883 case OSUB_ | CTINT_, 884 OSUB_ | CTRUNE_: 885 v.U.(*Mpint).Sub(rv.U.(*Mpint)) 886 887 case OMUL_ | CTINT_, 888 OMUL_ | CTRUNE_: 889 v.U.(*Mpint).Mul(rv.U.(*Mpint)) 890 891 case ODIV_ | CTINT_, 892 ODIV_ | CTRUNE_: 893 if rv.U.(*Mpint).CmpInt64(0) == 0 { 894 yyerror("division by zero") 895 v.U.(*Mpint).SetOverflow() 896 break 897 } 898 899 v.U.(*Mpint).Quo(rv.U.(*Mpint)) 900 901 case OMOD_ | CTINT_, 902 OMOD_ | CTRUNE_: 903 if rv.U.(*Mpint).CmpInt64(0) == 0 { 904 yyerror("division by zero") 905 v.U.(*Mpint).SetOverflow() 906 break 907 } 908 909 v.U.(*Mpint).Rem(rv.U.(*Mpint)) 910 911 case OLSH_ | CTINT_, 912 OLSH_ | CTRUNE_: 913 v.U.(*Mpint).Lsh(rv.U.(*Mpint)) 914 915 case ORSH_ | CTINT_, 916 ORSH_ | CTRUNE_: 917 v.U.(*Mpint).Rsh(rv.U.(*Mpint)) 918 919 case OOR_ | CTINT_, 920 OOR_ | CTRUNE_: 921 v.U.(*Mpint).Or(rv.U.(*Mpint)) 922 923 case OAND_ | CTINT_, 924 OAND_ | CTRUNE_: 925 v.U.(*Mpint).And(rv.U.(*Mpint)) 926 927 case OANDNOT_ | CTINT_, 928 OANDNOT_ | CTRUNE_: 929 v.U.(*Mpint).AndNot(rv.U.(*Mpint)) 930 931 case OXOR_ | CTINT_, 932 OXOR_ | CTRUNE_: 933 v.U.(*Mpint).Xor(rv.U.(*Mpint)) 934 935 case OADD_ | CTFLT_: 936 v.U.(*Mpflt).Add(rv.U.(*Mpflt)) 937 938 case OSUB_ | CTFLT_: 939 v.U.(*Mpflt).Sub(rv.U.(*Mpflt)) 940 941 case OMUL_ | CTFLT_: 942 v.U.(*Mpflt).Mul(rv.U.(*Mpflt)) 943 944 case ODIV_ | CTFLT_: 945 if rv.U.(*Mpflt).CmpFloat64(0) == 0 { 946 yyerror("division by zero") 947 v.U.(*Mpflt).SetFloat64(1.0) 948 break 949 } 950 951 v.U.(*Mpflt).Quo(rv.U.(*Mpflt)) 952 953 // The default case above would print 'ideal % ideal', 954 // which is not quite an ideal error. 955 case OMOD_ | CTFLT_: 956 if !n.Diag { 957 yyerror("illegal constant expression: floating-point %% operation") 958 n.Diag = true 959 } 960 961 return 962 963 case OADD_ | CTCPLX_: 964 v.U.(*Mpcplx).Real.Add(&rv.U.(*Mpcplx).Real) 965 v.U.(*Mpcplx).Imag.Add(&rv.U.(*Mpcplx).Imag) 966 967 case OSUB_ | CTCPLX_: 968 v.U.(*Mpcplx).Real.Sub(&rv.U.(*Mpcplx).Real) 969 v.U.(*Mpcplx).Imag.Sub(&rv.U.(*Mpcplx).Imag) 970 971 case OMUL_ | CTCPLX_: 972 cmplxmpy(v.U.(*Mpcplx), rv.U.(*Mpcplx)) 973 974 case ODIV_ | CTCPLX_: 975 if rv.U.(*Mpcplx).Real.CmpFloat64(0) == 0 && rv.U.(*Mpcplx).Imag.CmpFloat64(0) == 0 { 976 yyerror("complex division by zero") 977 rv.U.(*Mpcplx).Real.SetFloat64(1.0) 978 rv.U.(*Mpcplx).Imag.SetFloat64(0.0) 979 break 980 } 981 982 cmplxdiv(v.U.(*Mpcplx), rv.U.(*Mpcplx)) 983 984 case OEQ_ | CTNIL_: 985 goto settrue 986 987 case ONE_ | CTNIL_: 988 goto setfalse 989 990 case OEQ_ | CTINT_, 991 OEQ_ | CTRUNE_: 992 if v.U.(*Mpint).Cmp(rv.U.(*Mpint)) == 0 { 993 goto settrue 994 } 995 goto setfalse 996 997 case ONE_ | CTINT_, 998 ONE_ | CTRUNE_: 999 if v.U.(*Mpint).Cmp(rv.U.(*Mpint)) != 0 { 1000 goto settrue 1001 } 1002 goto setfalse 1003 1004 case OLT_ | CTINT_, 1005 OLT_ | CTRUNE_: 1006 if v.U.(*Mpint).Cmp(rv.U.(*Mpint)) < 0 { 1007 goto settrue 1008 } 1009 goto setfalse 1010 1011 case OLE_ | CTINT_, 1012 OLE_ | CTRUNE_: 1013 if v.U.(*Mpint).Cmp(rv.U.(*Mpint)) <= 0 { 1014 goto settrue 1015 } 1016 goto setfalse 1017 1018 case OGE_ | CTINT_, 1019 OGE_ | CTRUNE_: 1020 if v.U.(*Mpint).Cmp(rv.U.(*Mpint)) >= 0 { 1021 goto settrue 1022 } 1023 goto setfalse 1024 1025 case OGT_ | CTINT_, 1026 OGT_ | CTRUNE_: 1027 if v.U.(*Mpint).Cmp(rv.U.(*Mpint)) > 0 { 1028 goto settrue 1029 } 1030 goto setfalse 1031 1032 case OEQ_ | CTFLT_: 1033 if v.U.(*Mpflt).Cmp(rv.U.(*Mpflt)) == 0 { 1034 goto settrue 1035 } 1036 goto setfalse 1037 1038 case ONE_ | CTFLT_: 1039 if v.U.(*Mpflt).Cmp(rv.U.(*Mpflt)) != 0 { 1040 goto settrue 1041 } 1042 goto setfalse 1043 1044 case OLT_ | CTFLT_: 1045 if v.U.(*Mpflt).Cmp(rv.U.(*Mpflt)) < 0 { 1046 goto settrue 1047 } 1048 goto setfalse 1049 1050 case OLE_ | CTFLT_: 1051 if v.U.(*Mpflt).Cmp(rv.U.(*Mpflt)) <= 0 { 1052 goto settrue 1053 } 1054 goto setfalse 1055 1056 case OGE_ | CTFLT_: 1057 if v.U.(*Mpflt).Cmp(rv.U.(*Mpflt)) >= 0 { 1058 goto settrue 1059 } 1060 goto setfalse 1061 1062 case OGT_ | CTFLT_: 1063 if v.U.(*Mpflt).Cmp(rv.U.(*Mpflt)) > 0 { 1064 goto settrue 1065 } 1066 goto setfalse 1067 1068 case OEQ_ | CTCPLX_: 1069 if v.U.(*Mpcplx).Real.Cmp(&rv.U.(*Mpcplx).Real) == 0 && v.U.(*Mpcplx).Imag.Cmp(&rv.U.(*Mpcplx).Imag) == 0 { 1070 goto settrue 1071 } 1072 goto setfalse 1073 1074 case ONE_ | CTCPLX_: 1075 if v.U.(*Mpcplx).Real.Cmp(&rv.U.(*Mpcplx).Real) != 0 || v.U.(*Mpcplx).Imag.Cmp(&rv.U.(*Mpcplx).Imag) != 0 { 1076 goto settrue 1077 } 1078 goto setfalse 1079 1080 case OEQ_ | CTSTR_: 1081 if strlit(nl) == strlit(nr) { 1082 goto settrue 1083 } 1084 goto setfalse 1085 1086 case ONE_ | CTSTR_: 1087 if strlit(nl) != strlit(nr) { 1088 goto settrue 1089 } 1090 goto setfalse 1091 1092 case OLT_ | CTSTR_: 1093 if strlit(nl) < strlit(nr) { 1094 goto settrue 1095 } 1096 goto setfalse 1097 1098 case OLE_ | CTSTR_: 1099 if strlit(nl) <= strlit(nr) { 1100 goto settrue 1101 } 1102 goto setfalse 1103 1104 case OGE_ | CTSTR_: 1105 if strlit(nl) >= strlit(nr) { 1106 goto settrue 1107 } 1108 goto setfalse 1109 1110 case OGT_ | CTSTR_: 1111 if strlit(nl) > strlit(nr) { 1112 goto settrue 1113 } 1114 goto setfalse 1115 1116 case OOROR_ | CTBOOL_: 1117 if v.U.(bool) || rv.U.(bool) { 1118 goto settrue 1119 } 1120 goto setfalse 1121 1122 case OANDAND_ | CTBOOL_: 1123 if v.U.(bool) && rv.U.(bool) { 1124 goto settrue 1125 } 1126 goto setfalse 1127 1128 case OEQ_ | CTBOOL_: 1129 if v.U.(bool) == rv.U.(bool) { 1130 goto settrue 1131 } 1132 goto setfalse 1133 1134 case ONE_ | CTBOOL_: 1135 if v.U.(bool) != rv.U.(bool) { 1136 goto settrue 1137 } 1138 goto setfalse 1139 } 1140 1141 goto ret 1142 1143 ret: 1144 norig = saveorig(n) 1145 *n = *nl 1146 1147 // restore value of n->orig. 1148 n.Orig = norig 1149 1150 n.SetVal(v) 1151 1152 // check range. 1153 lno = setlineno(n) 1154 overflow(v, n.Type) 1155 lineno = lno 1156 1157 // truncate precision for non-ideal float. 1158 if v.Ctype() == CTFLT && n.Type.Etype != TIDEAL { 1159 n.SetVal(Val{truncfltlit(v.U.(*Mpflt), n.Type)}) 1160 } 1161 return 1162 1163 settrue: 1164 nn = nodbool(true) 1165 nn.Orig = saveorig(n) 1166 if !iscmp[n.Op] { 1167 nn.Type = nl.Type 1168 } 1169 *n = *nn 1170 return 1171 1172 setfalse: 1173 nn = nodbool(false) 1174 nn.Orig = saveorig(n) 1175 if !iscmp[n.Op] { 1176 nn.Type = nl.Type 1177 } 1178 *n = *nn 1179 return 1180 1181 illegal: 1182 if !n.Diag { 1183 yyerror("illegal constant expression: %v %v %v", nl.Type, n.Op, nr.Type) 1184 n.Diag = true 1185 } 1186 } 1187 1188 func nodlit(v Val) *Node { 1189 n := nod(OLITERAL, nil, nil) 1190 n.SetVal(v) 1191 switch v.Ctype() { 1192 default: 1193 Fatalf("nodlit ctype %d", v.Ctype()) 1194 1195 case CTSTR: 1196 n.Type = idealstring 1197 1198 case CTBOOL: 1199 n.Type = idealbool 1200 1201 case CTINT, CTRUNE, CTFLT, CTCPLX: 1202 n.Type = Types[TIDEAL] 1203 1204 case CTNIL: 1205 n.Type = Types[TNIL] 1206 } 1207 1208 return n 1209 } 1210 1211 func nodcplxlit(r Val, i Val) *Node { 1212 r = toflt(r) 1213 i = toflt(i) 1214 1215 c := new(Mpcplx) 1216 n := nod(OLITERAL, nil, nil) 1217 n.Type = Types[TIDEAL] 1218 n.SetVal(Val{c}) 1219 1220 if r.Ctype() != CTFLT || i.Ctype() != CTFLT { 1221 Fatalf("nodcplxlit ctype %d/%d", r.Ctype(), i.Ctype()) 1222 } 1223 1224 c.Real.Set(r.U.(*Mpflt)) 1225 c.Imag.Set(i.U.(*Mpflt)) 1226 return n 1227 } 1228 1229 // idealkind returns a constant kind like consttype 1230 // but for an arbitrary "ideal" (untyped constant) expression. 1231 func idealkind(n *Node) Ctype { 1232 if n == nil || !n.Type.IsUntyped() { 1233 return CTxxx 1234 } 1235 1236 switch n.Op { 1237 default: 1238 return CTxxx 1239 1240 case OLITERAL: 1241 return n.Val().Ctype() 1242 1243 // numeric kinds. 1244 case OADD, 1245 OAND, 1246 OANDNOT, 1247 OCOM, 1248 ODIV, 1249 OMINUS, 1250 OMOD, 1251 OMUL, 1252 OSUB, 1253 OXOR, 1254 OOR, 1255 OPLUS: 1256 k1 := idealkind(n.Left) 1257 1258 k2 := idealkind(n.Right) 1259 if k1 > k2 { 1260 return k1 1261 } else { 1262 return k2 1263 } 1264 1265 case OREAL, OIMAG: 1266 return CTFLT 1267 1268 case OCOMPLEX: 1269 return CTCPLX 1270 1271 case OADDSTR: 1272 return CTSTR 1273 1274 case OANDAND, 1275 OEQ, 1276 OGE, 1277 OGT, 1278 OLE, 1279 OLT, 1280 ONE, 1281 ONOT, 1282 OOROR, 1283 OCMPSTR, 1284 OCMPIFACE: 1285 return CTBOOL 1286 1287 // shifts (beware!). 1288 case OLSH, ORSH: 1289 return idealkind(n.Left) 1290 } 1291 } 1292 1293 // The result of defaultlit MUST be assigned back to n, e.g. 1294 // n.Left = defaultlit(n.Left, t) 1295 func defaultlit(n *Node, t *Type) *Node { 1296 return defaultlitreuse(n, t, noReuse) 1297 } 1298 1299 // The result of defaultlitreuse MUST be assigned back to n, e.g. 1300 // n.Left = defaultlitreuse(n.Left, t, reuse) 1301 func defaultlitreuse(n *Node, t *Type, reuse canReuseNode) *Node { 1302 if n == nil || !n.Type.IsUntyped() { 1303 return n 1304 } 1305 1306 if n.Op == OLITERAL && !reuse { 1307 nn := *n 1308 n = &nn 1309 reuse = true 1310 } 1311 1312 lno := setlineno(n) 1313 ctype := idealkind(n) 1314 var t1 *Type 1315 switch ctype { 1316 default: 1317 if t != nil { 1318 return convlit(n, t) 1319 } 1320 1321 if n.Val().Ctype() == CTNIL { 1322 lineno = lno 1323 if !n.Diag { 1324 yyerror("use of untyped nil") 1325 n.Diag = true 1326 } 1327 1328 n.Type = nil 1329 break 1330 } 1331 1332 if n.Val().Ctype() == CTSTR { 1333 t1 := Types[TSTRING] 1334 n = convlit1(n, t1, false, reuse) 1335 break 1336 } 1337 1338 yyerror("defaultlit: unknown literal: %v", n) 1339 1340 case CTxxx: 1341 Fatalf("defaultlit: idealkind is CTxxx: %+v", n) 1342 1343 case CTBOOL: 1344 t1 := Types[TBOOL] 1345 if t != nil && t.IsBoolean() { 1346 t1 = t 1347 } 1348 n = convlit1(n, t1, false, reuse) 1349 1350 case CTINT: 1351 t1 = Types[TINT] 1352 goto num 1353 1354 case CTRUNE: 1355 t1 = runetype 1356 goto num 1357 1358 case CTFLT: 1359 t1 = Types[TFLOAT64] 1360 goto num 1361 1362 case CTCPLX: 1363 t1 = Types[TCOMPLEX128] 1364 goto num 1365 } 1366 1367 lineno = lno 1368 return n 1369 1370 num: 1371 // Note: n.Val().Ctype() can be CTxxx (not a constant) here 1372 // in the case of an untyped non-constant value, like 1<<i. 1373 v1 := n.Val() 1374 if t != nil { 1375 if t.IsInteger() { 1376 t1 = t 1377 v1 = toint(n.Val()) 1378 } else if t.IsFloat() { 1379 t1 = t 1380 v1 = toflt(n.Val()) 1381 } else if t.IsComplex() { 1382 t1 = t 1383 v1 = tocplx(n.Val()) 1384 } 1385 if n.Val().Ctype() != CTxxx { 1386 n.SetVal(v1) 1387 } 1388 } 1389 1390 if n.Val().Ctype() != CTxxx { 1391 overflow(n.Val(), t1) 1392 } 1393 n = convlit1(n, t1, false, reuse) 1394 lineno = lno 1395 return n 1396 } 1397 1398 // defaultlit on both nodes simultaneously; 1399 // if they're both ideal going in they better 1400 // get the same type going out. 1401 // force means must assign concrete (non-ideal) type. 1402 // The results of defaultlit2 MUST be assigned back to l and r, e.g. 1403 // n.Left, n.Right = defaultlit2(n.Left, n.Right, force) 1404 func defaultlit2(l *Node, r *Node, force bool) (*Node, *Node) { 1405 if l.Type == nil || r.Type == nil { 1406 return l, r 1407 } 1408 if !l.Type.IsUntyped() { 1409 r = convlit(r, l.Type) 1410 return l, r 1411 } 1412 1413 if !r.Type.IsUntyped() { 1414 l = convlit(l, r.Type) 1415 return l, r 1416 } 1417 1418 if !force { 1419 return l, r 1420 } 1421 1422 if l.Type.IsBoolean() { 1423 l = convlit(l, Types[TBOOL]) 1424 r = convlit(r, Types[TBOOL]) 1425 } 1426 1427 lkind := idealkind(l) 1428 rkind := idealkind(r) 1429 if lkind == CTCPLX || rkind == CTCPLX { 1430 l = convlit(l, Types[TCOMPLEX128]) 1431 r = convlit(r, Types[TCOMPLEX128]) 1432 return l, r 1433 } 1434 1435 if lkind == CTFLT || rkind == CTFLT { 1436 l = convlit(l, Types[TFLOAT64]) 1437 r = convlit(r, Types[TFLOAT64]) 1438 return l, r 1439 } 1440 1441 if lkind == CTRUNE || rkind == CTRUNE { 1442 l = convlit(l, runetype) 1443 r = convlit(r, runetype) 1444 return l, r 1445 } 1446 1447 l = convlit(l, Types[TINT]) 1448 r = convlit(r, Types[TINT]) 1449 1450 return l, r 1451 } 1452 1453 // strlit returns the value of a literal string Node as a string. 1454 func strlit(n *Node) string { 1455 return n.Val().U.(string) 1456 } 1457 1458 func smallintconst(n *Node) bool { 1459 if n.Op == OLITERAL && Isconst(n, CTINT) && n.Type != nil { 1460 switch simtype[n.Type.Etype] { 1461 case TINT8, 1462 TUINT8, 1463 TINT16, 1464 TUINT16, 1465 TINT32, 1466 TUINT32, 1467 TBOOL, 1468 TPTR32: 1469 return true 1470 1471 case TIDEAL, TINT64, TUINT64, TPTR64: 1472 v, ok := n.Val().U.(*Mpint) 1473 if ok && v.Cmp(minintval[TINT32]) > 0 && v.Cmp(maxintval[TINT32]) < 0 { 1474 return true 1475 } 1476 } 1477 } 1478 1479 return false 1480 } 1481 1482 // nonnegintconst checks if Node n contains a constant expression 1483 // representable as a non-negative small integer, and returns its 1484 // (integer) value if that's the case. Otherwise, it returns -1. 1485 func nonnegintconst(n *Node) int64 { 1486 if n.Op != OLITERAL { 1487 return -1 1488 } 1489 1490 // toint will leave n.Val unchanged if it's not castable to an 1491 // Mpint, so we still have to guard the conversion. 1492 v := toint(n.Val()) 1493 vi, ok := v.U.(*Mpint) 1494 if !ok || vi.Val.Sign() < 0 || vi.Cmp(maxintval[TINT32]) > 0 { 1495 return -1 1496 } 1497 1498 return vi.Int64() 1499 } 1500 1501 // complex multiply v *= rv 1502 // (a, b) * (c, d) = (a*c - b*d, b*c + a*d) 1503 func cmplxmpy(v *Mpcplx, rv *Mpcplx) { 1504 var ac Mpflt 1505 var bd Mpflt 1506 var bc Mpflt 1507 var ad Mpflt 1508 1509 ac.Set(&v.Real) 1510 ac.Mul(&rv.Real) // ac 1511 1512 bd.Set(&v.Imag) 1513 1514 bd.Mul(&rv.Imag) // bd 1515 1516 bc.Set(&v.Imag) 1517 1518 bc.Mul(&rv.Real) // bc 1519 1520 ad.Set(&v.Real) 1521 1522 ad.Mul(&rv.Imag) // ad 1523 1524 v.Real.Set(&ac) 1525 1526 v.Real.Sub(&bd) // ac-bd 1527 1528 v.Imag.Set(&bc) 1529 1530 v.Imag.Add(&ad) // bc+ad 1531 } 1532 1533 // complex divide v /= rv 1534 // (a, b) / (c, d) = ((a*c + b*d), (b*c - a*d))/(c*c + d*d) 1535 func cmplxdiv(v *Mpcplx, rv *Mpcplx) { 1536 var ac Mpflt 1537 var bd Mpflt 1538 var bc Mpflt 1539 var ad Mpflt 1540 var cc_plus_dd Mpflt 1541 1542 cc_plus_dd.Set(&rv.Real) 1543 cc_plus_dd.Mul(&rv.Real) // cc 1544 1545 ac.Set(&rv.Imag) 1546 1547 ac.Mul(&rv.Imag) // dd 1548 1549 cc_plus_dd.Add(&ac) // cc+dd 1550 1551 ac.Set(&v.Real) 1552 1553 ac.Mul(&rv.Real) // ac 1554 1555 bd.Set(&v.Imag) 1556 1557 bd.Mul(&rv.Imag) // bd 1558 1559 bc.Set(&v.Imag) 1560 1561 bc.Mul(&rv.Real) // bc 1562 1563 ad.Set(&v.Real) 1564 1565 ad.Mul(&rv.Imag) // ad 1566 1567 v.Real.Set(&ac) 1568 1569 v.Real.Add(&bd) // ac+bd 1570 v.Real.Quo(&cc_plus_dd) // (ac+bd)/(cc+dd) 1571 1572 v.Imag.Set(&bc) 1573 1574 v.Imag.Sub(&ad) // bc-ad 1575 v.Imag.Quo(&cc_plus_dd) // (bc+ad)/(cc+dd) 1576 } 1577 1578 // Is n a Go language constant (as opposed to a compile-time constant)? 1579 // Expressions derived from nil, like string([]byte(nil)), while they 1580 // may be known at compile time, are not Go language constants. 1581 // Only called for expressions known to evaluated to compile-time 1582 // constants. 1583 func isgoconst(n *Node) bool { 1584 if n.Orig != nil { 1585 n = n.Orig 1586 } 1587 1588 switch n.Op { 1589 case OADD, 1590 OADDSTR, 1591 OAND, 1592 OANDAND, 1593 OANDNOT, 1594 OCOM, 1595 ODIV, 1596 OEQ, 1597 OGE, 1598 OGT, 1599 OLE, 1600 OLSH, 1601 OLT, 1602 OMINUS, 1603 OMOD, 1604 OMUL, 1605 ONE, 1606 ONOT, 1607 OOR, 1608 OOROR, 1609 OPLUS, 1610 ORSH, 1611 OSUB, 1612 OXOR, 1613 OIOTA, 1614 OCOMPLEX, 1615 OREAL, 1616 OIMAG: 1617 if isgoconst(n.Left) && (n.Right == nil || isgoconst(n.Right)) { 1618 return true 1619 } 1620 1621 case OCONV: 1622 if okforconst[n.Type.Etype] && isgoconst(n.Left) { 1623 return true 1624 } 1625 1626 case OLEN, OCAP: 1627 l := n.Left 1628 if isgoconst(l) { 1629 return true 1630 } 1631 1632 // Special case: len/cap is constant when applied to array or 1633 // pointer to array when the expression does not contain 1634 // function calls or channel receive operations. 1635 t := l.Type 1636 1637 if t != nil && t.IsPtr() { 1638 t = t.Elem() 1639 } 1640 if t != nil && t.IsArray() && !hascallchan(l) { 1641 return true 1642 } 1643 1644 case OLITERAL: 1645 if n.Val().Ctype() != CTNIL { 1646 return true 1647 } 1648 1649 case ONAME: 1650 l := n.Sym.Def 1651 if l != nil && l.Op == OLITERAL && n.Val().Ctype() != CTNIL { 1652 return true 1653 } 1654 1655 case ONONAME: 1656 if n.Sym.Def != nil && n.Sym.Def.Op == OIOTA { 1657 return true 1658 } 1659 1660 case OALIGNOF, OOFFSETOF, OSIZEOF: 1661 return true 1662 } 1663 1664 //dump("nonconst", n); 1665 return false 1666 } 1667 1668 func hascallchan(n *Node) bool { 1669 if n == nil { 1670 return false 1671 } 1672 switch n.Op { 1673 case OAPPEND, 1674 OCALL, 1675 OCALLFUNC, 1676 OCALLINTER, 1677 OCALLMETH, 1678 OCAP, 1679 OCLOSE, 1680 OCOMPLEX, 1681 OCOPY, 1682 ODELETE, 1683 OIMAG, 1684 OLEN, 1685 OMAKE, 1686 ONEW, 1687 OPANIC, 1688 OPRINT, 1689 OPRINTN, 1690 OREAL, 1691 ORECOVER, 1692 ORECV: 1693 return true 1694 } 1695 1696 if hascallchan(n.Left) || hascallchan(n.Right) { 1697 return true 1698 } 1699 for _, n1 := range n.List.Slice() { 1700 if hascallchan(n1) { 1701 return true 1702 } 1703 } 1704 for _, n2 := range n.Rlist.Slice() { 1705 if hascallchan(n2) { 1706 return true 1707 } 1708 } 1709 1710 return false 1711 }