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