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