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