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