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