github.com/megatontech/mynoteforgo@v0.0.0-20200507084910-5d0c6ea6e890/源码/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 "math/big" 10 "strings" 11 ) 12 13 // Ctype describes the constant kind of an "ideal" (untyped) constant. 14 type Ctype uint8 15 16 const ( 17 CTxxx Ctype = iota 18 19 CTINT 20 CTRUNE 21 CTFLT 22 CTCPLX 23 CTSTR 24 CTBOOL 25 CTNIL 26 ) 27 28 type Val struct { 29 // U contains one of: 30 // bool bool when n.ValCtype() == CTBOOL 31 // *Mpint int when n.ValCtype() == CTINT, rune when n.ValCtype() == CTRUNE 32 // *Mpflt float when n.ValCtype() == CTFLT 33 // *Mpcplx pair of floats when n.ValCtype() == CTCPLX 34 // string string when n.ValCtype() == CTSTR 35 // *Nilval when n.ValCtype() == CTNIL 36 U interface{} 37 } 38 39 func (v Val) Ctype() Ctype { 40 switch x := v.U.(type) { 41 default: 42 Fatalf("unexpected Ctype for %T", v.U) 43 panic("unreachable") 44 case nil: 45 return 0 46 case *NilVal: 47 return CTNIL 48 case bool: 49 return CTBOOL 50 case *Mpint: 51 if x.Rune { 52 return CTRUNE 53 } 54 return CTINT 55 case *Mpflt: 56 return CTFLT 57 case *Mpcplx: 58 return CTCPLX 59 case string: 60 return CTSTR 61 } 62 } 63 64 func eqval(a, b Val) bool { 65 if a.Ctype() != b.Ctype() { 66 return false 67 } 68 switch x := a.U.(type) { 69 default: 70 Fatalf("unexpected Ctype for %T", a.U) 71 panic("unreachable") 72 case *NilVal: 73 return true 74 case bool: 75 y := b.U.(bool) 76 return x == y 77 case *Mpint: 78 y := b.U.(*Mpint) 79 return x.Cmp(y) == 0 80 case *Mpflt: 81 y := b.U.(*Mpflt) 82 return x.Cmp(y) == 0 83 case *Mpcplx: 84 y := b.U.(*Mpcplx) 85 return x.Real.Cmp(&y.Real) == 0 && x.Imag.Cmp(&y.Imag) == 0 86 case string: 87 y := b.U.(string) 88 return x == y 89 } 90 } 91 92 // Interface returns the constant value stored in v as an interface{}. 93 // It returns int64s for ints and runes, float64s for floats, 94 // complex128s for complex values, and nil for constant nils. 95 func (v Val) Interface() interface{} { 96 switch x := v.U.(type) { 97 default: 98 Fatalf("unexpected Interface for %T", v.U) 99 panic("unreachable") 100 case *NilVal: 101 return nil 102 case bool, string: 103 return x 104 case *Mpint: 105 return x.Int64() 106 case *Mpflt: 107 return x.Float64() 108 case *Mpcplx: 109 return complex(x.Real.Float64(), x.Imag.Float64()) 110 } 111 } 112 113 type NilVal struct{} 114 115 // Int64 returns n as an int64. 116 // n must be an integer or rune constant. 117 func (n *Node) Int64() int64 { 118 if !Isconst(n, CTINT) { 119 Fatalf("Int64(%v)", n) 120 } 121 return n.Val().U.(*Mpint).Int64() 122 } 123 124 // CanInt64 reports whether it is safe to call Int64() on n. 125 func (n *Node) CanInt64() bool { 126 if !Isconst(n, CTINT) { 127 return false 128 } 129 130 // if the value inside n cannot be represented as an int64, the 131 // return value of Int64 is undefined 132 return n.Val().U.(*Mpint).CmpInt64(n.Int64()) == 0 133 } 134 135 // Bool returns n as a bool. 136 // n must be a boolean constant. 137 func (n *Node) Bool() bool { 138 if !Isconst(n, CTBOOL) { 139 Fatalf("Bool(%v)", n) 140 } 141 return n.Val().U.(bool) 142 } 143 144 // truncate float literal fv to 32-bit or 64-bit precision 145 // according to type; return truncated value. 146 func truncfltlit(oldv *Mpflt, t *types.Type) *Mpflt { 147 if t == nil { 148 return oldv 149 } 150 151 if overflow(Val{oldv}, t) { 152 // If there was overflow, simply continuing would set the 153 // value to Inf which in turn would lead to spurious follow-on 154 // errors. Avoid this by returning the existing value. 155 return oldv 156 } 157 158 fv := newMpflt() 159 160 // convert large precision literal floating 161 // into limited precision (float64 or float32) 162 switch t.Etype { 163 case types.TFLOAT32: 164 fv.SetFloat64(oldv.Float32()) 165 case types.TFLOAT64: 166 fv.SetFloat64(oldv.Float64()) 167 default: 168 Fatalf("truncfltlit: unexpected Etype %v", t.Etype) 169 } 170 171 return fv 172 } 173 174 // truncate Real and Imag parts of Mpcplx to 32-bit or 64-bit 175 // precision, according to type; return truncated value. In case of 176 // overflow, calls yyerror but does not truncate the input value. 177 func trunccmplxlit(oldv *Mpcplx, t *types.Type) *Mpcplx { 178 if t == nil { 179 return oldv 180 } 181 182 if overflow(Val{oldv}, t) { 183 // If there was overflow, simply continuing would set the 184 // value to Inf which in turn would lead to spurious follow-on 185 // errors. Avoid this by returning the existing value. 186 return oldv 187 } 188 189 cv := newMpcmplx() 190 191 switch t.Etype { 192 case types.TCOMPLEX64: 193 cv.Real.SetFloat64(oldv.Real.Float32()) 194 cv.Imag.SetFloat64(oldv.Imag.Float32()) 195 case types.TCOMPLEX128: 196 cv.Real.SetFloat64(oldv.Real.Float64()) 197 cv.Imag.SetFloat64(oldv.Imag.Float64()) 198 default: 199 Fatalf("trunccplxlit: unexpected Etype %v", t.Etype) 200 } 201 202 return cv 203 } 204 205 // canReuseNode indicates whether it is known to be safe 206 // to reuse a Node. 207 type canReuseNode bool 208 209 const ( 210 noReuse canReuseNode = false // not necessarily safe to reuse 211 reuseOK canReuseNode = true // safe to reuse 212 ) 213 214 // convert n, if literal, to type t. 215 // implicit conversion. 216 // The result of convlit MUST be assigned back to n, e.g. 217 // n.Left = convlit(n.Left, t) 218 func convlit(n *Node, t *types.Type) *Node { 219 return convlit1(n, t, false, noReuse) 220 } 221 222 // convlit1 converts n, if literal, to type t. 223 // It returns a new node if necessary. 224 // The result of convlit1 MUST be assigned back to n, e.g. 225 // n.Left = convlit1(n.Left, t, explicit, reuse) 226 func convlit1(n *Node, t *types.Type, explicit bool, reuse canReuseNode) *Node { 227 if n == nil || t == nil || n.Type == nil || t.IsUntyped() || n.Type == t { 228 return n 229 } 230 if !explicit && !n.Type.IsUntyped() { 231 return n 232 } 233 234 if n.Op == OLITERAL && !reuse { 235 // Can't always set n.Type directly on OLITERAL nodes. 236 // See discussion on CL 20813. 237 n = n.rawcopy() 238 reuse = true 239 } 240 241 switch n.Op { 242 default: 243 if n.Type == types.Idealbool { 244 if !t.IsBoolean() { 245 t = types.Types[TBOOL] 246 } 247 switch n.Op { 248 case ONOT: 249 n.Left = convlit(n.Left, t) 250 case OANDAND, OOROR: 251 n.Left = convlit(n.Left, t) 252 n.Right = convlit(n.Right, t) 253 } 254 n.Type = t 255 } 256 257 if n.Type.IsUntyped() { 258 if t.IsInterface() { 259 n.Left, n.Right = defaultlit2(n.Left, n.Right, true) 260 n.Type = n.Left.Type // same as n.Right.Type per defaultlit2 261 } else { 262 n.Left = convlit(n.Left, t) 263 n.Right = convlit(n.Right, t) 264 n.Type = t 265 } 266 } 267 268 return n 269 270 // target is invalid type for a constant? leave alone. 271 case OLITERAL: 272 if !okforconst[t.Etype] && n.Type.Etype != TNIL { 273 return defaultlitreuse(n, nil, reuse) 274 } 275 276 case OLSH, ORSH: 277 n.Left = convlit1(n.Left, t, explicit && n.Left.Type.IsUntyped(), noReuse) 278 t = n.Left.Type 279 if t != nil && t.Etype == TIDEAL && n.Val().Ctype() != CTINT { 280 n.SetVal(toint(n.Val())) 281 } 282 if t != nil && !t.IsInteger() { 283 yyerror("invalid operation: %v (shift of type %v)", n, t) 284 t = nil 285 } 286 287 n.Type = t 288 return n 289 290 case OCOMPLEX: 291 if n.Type.Etype == TIDEAL { 292 switch t.Etype { 293 default: 294 // If trying to convert to non-complex type, 295 // leave as complex128 and let typechecker complain. 296 t = types.Types[TCOMPLEX128] 297 fallthrough 298 case types.TCOMPLEX128: 299 n.Type = t 300 n.Left = convlit(n.Left, types.Types[TFLOAT64]) 301 n.Right = convlit(n.Right, types.Types[TFLOAT64]) 302 303 case TCOMPLEX64: 304 n.Type = t 305 n.Left = convlit(n.Left, types.Types[TFLOAT32]) 306 n.Right = convlit(n.Right, types.Types[TFLOAT32]) 307 } 308 } 309 310 return n 311 } 312 313 // avoid repeated calculations, errors 314 if types.Identical(n.Type, t) { 315 return n 316 } 317 318 ct := consttype(n) 319 var et types.EType 320 if ct == 0 { 321 goto bad 322 } 323 324 et = t.Etype 325 if et == TINTER { 326 if ct == CTNIL && n.Type == types.Types[TNIL] { 327 n.Type = t 328 return n 329 } 330 return defaultlitreuse(n, nil, reuse) 331 } 332 333 switch ct { 334 default: 335 goto bad 336 337 case CTNIL: 338 switch et { 339 default: 340 n.Type = nil 341 goto bad 342 343 // let normal conversion code handle it 344 case TSTRING: 345 return n 346 347 case TARRAY: 348 goto bad 349 350 case TPTR, TUNSAFEPTR: 351 n.SetVal(Val{new(Mpint)}) 352 353 case TCHAN, TFUNC, TINTER, TMAP, TSLICE: 354 break 355 } 356 357 case CTSTR, CTBOOL: 358 if et != n.Type.Etype { 359 goto bad 360 } 361 362 case CTINT, CTRUNE, CTFLT, CTCPLX: 363 if n.Type.Etype == TUNSAFEPTR && t.Etype != TUINTPTR { 364 goto bad 365 } 366 ct := n.Val().Ctype() 367 if isInt[et] { 368 switch ct { 369 default: 370 goto bad 371 372 case CTCPLX, CTFLT, CTRUNE: 373 n.SetVal(toint(n.Val())) 374 fallthrough 375 376 case CTINT: 377 overflow(n.Val(), t) 378 } 379 } else if isFloat[et] { 380 switch ct { 381 default: 382 goto bad 383 384 case CTCPLX, CTINT, CTRUNE: 385 n.SetVal(toflt(n.Val())) 386 fallthrough 387 388 case CTFLT: 389 n.SetVal(Val{truncfltlit(n.Val().U.(*Mpflt), t)}) 390 } 391 } else if isComplex[et] { 392 switch ct { 393 default: 394 goto bad 395 396 case CTFLT, CTINT, CTRUNE: 397 n.SetVal(tocplx(n.Val())) 398 fallthrough 399 400 case CTCPLX: 401 n.SetVal(Val{trunccmplxlit(n.Val().U.(*Mpcplx), t)}) 402 } 403 } else if et == types.TSTRING && (ct == CTINT || ct == CTRUNE) && explicit { 404 n.SetVal(tostr(n.Val())) 405 } else { 406 goto bad 407 } 408 } 409 410 n.Type = t 411 return n 412 413 bad: 414 if !n.Diag() { 415 if !t.Broke() { 416 yyerror("cannot convert %L to type %v", n, t) 417 } 418 n.SetDiag(true) 419 } 420 421 if n.Type.IsUntyped() { 422 n = defaultlitreuse(n, nil, reuse) 423 } 424 return n 425 } 426 427 func tocplx(v Val) Val { 428 switch u := v.U.(type) { 429 case *Mpint: 430 c := new(Mpcplx) 431 c.Real.SetInt(u) 432 c.Imag.SetFloat64(0.0) 433 v.U = c 434 435 case *Mpflt: 436 c := new(Mpcplx) 437 c.Real.Set(u) 438 c.Imag.SetFloat64(0.0) 439 v.U = c 440 } 441 442 return v 443 } 444 445 func toflt(v Val) Val { 446 switch u := v.U.(type) { 447 case *Mpint: 448 f := newMpflt() 449 f.SetInt(u) 450 v.U = f 451 452 case *Mpcplx: 453 f := newMpflt() 454 f.Set(&u.Real) 455 if u.Imag.CmpFloat64(0) != 0 { 456 yyerror("constant %v truncated to real", u.GoString()) 457 } 458 v.U = f 459 } 460 461 return v 462 } 463 464 func toint(v Val) Val { 465 switch u := v.U.(type) { 466 case *Mpint: 467 if u.Rune { 468 i := new(Mpint) 469 i.Set(u) 470 v.U = i 471 } 472 473 case *Mpflt: 474 i := new(Mpint) 475 if !i.SetFloat(u) { 476 if i.checkOverflow(0) { 477 yyerror("integer too large") 478 } else { 479 // The value of u cannot be represented as an integer; 480 // so we need to print an error message. 481 // Unfortunately some float values cannot be 482 // reasonably formatted for inclusion in an error 483 // message (example: 1 + 1e-100), so first we try to 484 // format the float; if the truncation resulted in 485 // something that looks like an integer we omit the 486 // value from the error message. 487 // (See issue #11371). 488 var t big.Float 489 t.Parse(u.GoString(), 10) 490 if t.IsInt() { 491 yyerror("constant truncated to integer") 492 } else { 493 yyerror("constant %v truncated to integer", u.GoString()) 494 } 495 } 496 } 497 v.U = i 498 499 case *Mpcplx: 500 i := new(Mpint) 501 if !i.SetFloat(&u.Real) || u.Imag.CmpFloat64(0) != 0 { 502 yyerror("constant %v truncated to integer", u.GoString()) 503 } 504 505 v.U = i 506 } 507 508 return v 509 } 510 511 func doesoverflow(v Val, t *types.Type) bool { 512 switch u := v.U.(type) { 513 case *Mpint: 514 if !t.IsInteger() { 515 Fatalf("overflow: %v integer constant", t) 516 } 517 return u.Cmp(minintval[t.Etype]) < 0 || u.Cmp(maxintval[t.Etype]) > 0 518 519 case *Mpflt: 520 if !t.IsFloat() { 521 Fatalf("overflow: %v floating-point constant", t) 522 } 523 return u.Cmp(minfltval[t.Etype]) <= 0 || u.Cmp(maxfltval[t.Etype]) >= 0 524 525 case *Mpcplx: 526 if !t.IsComplex() { 527 Fatalf("overflow: %v complex constant", t) 528 } 529 return u.Real.Cmp(minfltval[t.Etype]) <= 0 || u.Real.Cmp(maxfltval[t.Etype]) >= 0 || 530 u.Imag.Cmp(minfltval[t.Etype]) <= 0 || u.Imag.Cmp(maxfltval[t.Etype]) >= 0 531 } 532 533 return false 534 } 535 536 func overflow(v Val, t *types.Type) bool { 537 // v has already been converted 538 // to appropriate form for t. 539 if t == nil || t.Etype == TIDEAL { 540 return false 541 } 542 543 // Only uintptrs may be converted to pointers, which cannot overflow. 544 if t.IsPtr() || t.IsUnsafePtr() { 545 return false 546 } 547 548 if doesoverflow(v, t) { 549 yyerror("constant %v overflows %v", v, t) 550 return true 551 } 552 553 return false 554 555 } 556 557 func tostr(v Val) Val { 558 switch u := v.U.(type) { 559 case *Mpint: 560 var i int64 = 0xFFFD 561 if u.Cmp(minintval[TUINT32]) >= 0 && u.Cmp(maxintval[TUINT32]) <= 0 { 562 i = u.Int64() 563 } 564 v.U = string(i) 565 } 566 567 return v 568 } 569 570 func consttype(n *Node) Ctype { 571 if n == nil || n.Op != OLITERAL { 572 return 0 573 } 574 return n.Val().Ctype() 575 } 576 577 func Isconst(n *Node, ct Ctype) bool { 578 t := consttype(n) 579 580 // If the caller is asking for CTINT, allow CTRUNE too. 581 // Makes life easier for back ends. 582 return t == ct || (ct == CTINT && t == CTRUNE) 583 } 584 585 // evconst rewrites constant expressions into OLITERAL nodes. 586 func evconst(n *Node) { 587 if !n.isGoConst() { 588 // Avoid constant evaluation of things that aren't actually constants 589 // according to the spec. See issue 24760. 590 // The SSA backend has a more robust optimizer that will catch 591 // all of these weird cases (like uintptr(unsafe.Pointer(uintptr(1)))). 592 return 593 } 594 595 nl, nr := n.Left, n.Right 596 597 // Pick off just the opcodes that can be constant evaluated. 598 switch op := n.Op; op { 599 case OPLUS, ONEG, OBITNOT, ONOT: 600 if nl.Op == OLITERAL { 601 setconst(n, unaryOp(op, nl.Val(), n.Type)) 602 } 603 604 case OADD, OSUB, OMUL, ODIV, OMOD, OOR, OXOR, OAND, OANDNOT, OOROR, OANDAND: 605 if nl.Op == OLITERAL && nr.Op == OLITERAL { 606 setconst(n, binaryOp(nl.Val(), op, nr.Val())) 607 } 608 609 case OEQ, ONE, OLT, OLE, OGT, OGE: 610 if nl.Op == OLITERAL && nr.Op == OLITERAL { 611 if nl.Type.IsInterface() != nr.Type.IsInterface() { 612 // Mixed interface/non-interface 613 // constant comparison means comparing 614 // nil interface with some typed 615 // constant, which is always unequal. 616 // E.g., interface{}(nil) == (*int)(nil). 617 setboolconst(n, op == ONE) 618 } else { 619 setboolconst(n, compareOp(nl.Val(), op, nr.Val())) 620 } 621 } 622 623 case OLSH, ORSH: 624 if nl.Op == OLITERAL && nr.Op == OLITERAL { 625 setconst(n, shiftOp(nl.Val(), op, nr.Val())) 626 } 627 628 case OCONV: 629 if n.Type != nil && okforconst[n.Type.Etype] && nl.Op == OLITERAL { 630 // TODO(mdempsky): There should be a convval function. 631 setconst(n, convlit1(nl, n.Type, true, false).Val()) 632 } 633 634 case OBYTES2STR: 635 // string([]byte(nil)) or string([]rune(nil)) 636 if nl.Op == OLITERAL && nl.Val().Ctype() == CTNIL { 637 setconst(n, Val{U: ""}) 638 } 639 640 case OADDSTR: 641 // Merge adjacent constants in the argument list. 642 s := n.List.Slice() 643 for i1 := 0; i1 < len(s); i1++ { 644 if Isconst(s[i1], CTSTR) && i1+1 < len(s) && Isconst(s[i1+1], CTSTR) { 645 // merge from i1 up to but not including i2 646 var strs []string 647 i2 := i1 648 for i2 < len(s) && Isconst(s[i2], CTSTR) { 649 strs = append(strs, s[i2].Val().U.(string)) 650 i2++ 651 } 652 653 nl := *s[i1] 654 nl.Orig = &nl 655 nl.SetVal(Val{strings.Join(strs, "")}) 656 s[i1] = &nl 657 s = append(s[:i1+1], s[i2:]...) 658 } 659 } 660 661 if len(s) == 1 && Isconst(s[0], CTSTR) { 662 n.Op = OLITERAL 663 n.SetVal(s[0].Val()) 664 } else { 665 n.List.Set(s) 666 } 667 } 668 } 669 670 func match(x, y Val) (Val, Val) { 671 switch { 672 case x.Ctype() == CTCPLX || y.Ctype() == CTCPLX: 673 return tocplx(x), tocplx(y) 674 case x.Ctype() == CTFLT || y.Ctype() == CTFLT: 675 return toflt(x), toflt(y) 676 } 677 678 // Mixed int/rune are fine. 679 return x, y 680 } 681 682 func compareOp(x Val, op Op, y Val) bool { 683 x, y = match(x, y) 684 685 switch x.Ctype() { 686 case CTNIL: 687 _, _ = x.U.(*NilVal), y.U.(*NilVal) // assert dynamic types match 688 switch op { 689 case OEQ: 690 return true 691 case ONE: 692 return false 693 } 694 695 case CTBOOL: 696 x, y := x.U.(bool), y.U.(bool) 697 switch op { 698 case OEQ: 699 return x == y 700 case ONE: 701 return x != y 702 } 703 704 case CTINT, CTRUNE: 705 x, y := x.U.(*Mpint), y.U.(*Mpint) 706 return cmpZero(x.Cmp(y), op) 707 708 case CTFLT: 709 x, y := x.U.(*Mpflt), y.U.(*Mpflt) 710 return cmpZero(x.Cmp(y), op) 711 712 case CTCPLX: 713 x, y := x.U.(*Mpcplx), y.U.(*Mpcplx) 714 eq := x.Real.Cmp(&y.Real) == 0 && x.Imag.Cmp(&y.Imag) == 0 715 switch op { 716 case OEQ: 717 return eq 718 case ONE: 719 return !eq 720 } 721 722 case CTSTR: 723 x, y := x.U.(string), y.U.(string) 724 switch op { 725 case OEQ: 726 return x == y 727 case ONE: 728 return x != y 729 case OLT: 730 return x < y 731 case OLE: 732 return x <= y 733 case OGT: 734 return x > y 735 case OGE: 736 return x >= y 737 } 738 } 739 740 Fatalf("compareOp: bad comparison: %v %v %v", x, op, y) 741 panic("unreachable") 742 } 743 744 func cmpZero(x int, op Op) bool { 745 switch op { 746 case OEQ: 747 return x == 0 748 case ONE: 749 return x != 0 750 case OLT: 751 return x < 0 752 case OLE: 753 return x <= 0 754 case OGT: 755 return x > 0 756 case OGE: 757 return x >= 0 758 } 759 760 Fatalf("cmpZero: want comparison operator, got %v", op) 761 panic("unreachable") 762 } 763 764 func binaryOp(x Val, op Op, y Val) Val { 765 x, y = match(x, y) 766 767 Outer: 768 switch x.Ctype() { 769 case CTBOOL: 770 x, y := x.U.(bool), y.U.(bool) 771 switch op { 772 case OANDAND: 773 return Val{U: x && y} 774 case OOROR: 775 return Val{U: x || y} 776 } 777 778 case CTINT, CTRUNE: 779 x, y := x.U.(*Mpint), y.U.(*Mpint) 780 781 u := new(Mpint) 782 u.Rune = x.Rune || y.Rune 783 u.Set(x) 784 switch op { 785 case OADD: 786 u.Add(y) 787 case OSUB: 788 u.Sub(y) 789 case OMUL: 790 u.Mul(y) 791 case ODIV: 792 if y.CmpInt64(0) == 0 { 793 yyerror("division by zero") 794 u.SetOverflow() 795 break 796 } 797 u.Quo(y) 798 case OMOD: 799 if y.CmpInt64(0) == 0 { 800 yyerror("division by zero") 801 u.SetOverflow() 802 break 803 } 804 u.Rem(y) 805 case OOR: 806 u.Or(y) 807 case OAND: 808 u.And(y) 809 case OANDNOT: 810 u.AndNot(y) 811 case OXOR: 812 u.Xor(y) 813 default: 814 break Outer 815 } 816 return Val{U: u} 817 818 case CTFLT: 819 x, y := x.U.(*Mpflt), y.U.(*Mpflt) 820 821 u := newMpflt() 822 u.Set(x) 823 switch op { 824 case OADD: 825 u.Add(y) 826 case OSUB: 827 u.Sub(y) 828 case OMUL: 829 u.Mul(y) 830 case ODIV: 831 if y.CmpFloat64(0) == 0 { 832 yyerror("division by zero") 833 u.SetFloat64(1) 834 break 835 } 836 u.Quo(y) 837 case OMOD: 838 // TODO(mdempsky): Move to typecheck. 839 yyerror("illegal constant expression: floating-point %% operation") 840 default: 841 break Outer 842 } 843 return Val{U: u} 844 845 case CTCPLX: 846 x, y := x.U.(*Mpcplx), y.U.(*Mpcplx) 847 848 u := new(Mpcplx) 849 u.Real.Set(&x.Real) 850 u.Imag.Set(&x.Imag) 851 switch op { 852 case OADD: 853 u.Real.Add(&y.Real) 854 u.Imag.Add(&y.Imag) 855 case OSUB: 856 u.Real.Sub(&y.Real) 857 u.Imag.Sub(&y.Imag) 858 case OMUL: 859 u.Mul(y) 860 case ODIV: 861 if !u.Div(y) { 862 yyerror("complex division by zero") 863 u.Real.SetFloat64(1) 864 u.Imag.SetFloat64(0) 865 } 866 default: 867 break Outer 868 } 869 return Val{U: u} 870 } 871 872 Fatalf("binaryOp: bad operation: %v %v %v", x, op, y) 873 panic("unreachable") 874 } 875 876 func unaryOp(op Op, x Val, t *types.Type) Val { 877 switch op { 878 case OPLUS: 879 switch x.Ctype() { 880 case CTINT, CTRUNE, CTFLT, CTCPLX: 881 return x 882 } 883 884 case ONEG: 885 switch x.Ctype() { 886 case CTINT, CTRUNE: 887 x := x.U.(*Mpint) 888 u := new(Mpint) 889 u.Rune = x.Rune 890 u.Set(x) 891 u.Neg() 892 return Val{U: u} 893 894 case CTFLT: 895 x := x.U.(*Mpflt) 896 u := newMpflt() 897 u.Set(x) 898 u.Neg() 899 return Val{U: u} 900 901 case CTCPLX: 902 x := x.U.(*Mpcplx) 903 u := new(Mpcplx) 904 u.Real.Set(&x.Real) 905 u.Imag.Set(&x.Imag) 906 u.Real.Neg() 907 u.Imag.Neg() 908 return Val{U: u} 909 } 910 911 case OBITNOT: 912 x := x.U.(*Mpint) 913 914 u := new(Mpint) 915 u.Rune = x.Rune 916 if t.IsSigned() || t.IsUntyped() { 917 // Signed values change sign. 918 u.SetInt64(-1) 919 } else { 920 // Unsigned values invert their bits. 921 u.Set(maxintval[t.Etype]) 922 } 923 u.Xor(x) 924 return Val{U: u} 925 926 case ONOT: 927 return Val{U: !x.U.(bool)} 928 } 929 930 Fatalf("unaryOp: bad operation: %v %v", op, x) 931 panic("unreachable") 932 } 933 934 func shiftOp(x Val, op Op, y Val) Val { 935 if x.Ctype() != CTRUNE { 936 x = toint(x) 937 } 938 y = toint(y) 939 940 u := new(Mpint) 941 u.Set(x.U.(*Mpint)) 942 u.Rune = x.U.(*Mpint).Rune 943 switch op { 944 case OLSH: 945 u.Lsh(y.U.(*Mpint)) 946 case ORSH: 947 u.Rsh(y.U.(*Mpint)) 948 default: 949 Fatalf("shiftOp: bad operator: %v", op) 950 panic("unreachable") 951 } 952 return Val{U: u} 953 } 954 955 // setconst rewrites n as an OLITERAL with value v. 956 func setconst(n *Node, v Val) { 957 // Ensure n.Orig still points to a semantically-equivalent 958 // expression after we rewrite n into a constant. 959 if n.Orig == n { 960 n.Orig = n.sepcopy() 961 } 962 963 *n = Node{ 964 Op: OLITERAL, 965 Pos: n.Pos, 966 Orig: n.Orig, 967 Type: n.Type, 968 Xoffset: BADWIDTH, 969 } 970 n.SetVal(v) 971 972 // Check range. 973 lno := setlineno(n) 974 overflow(v, n.Type) 975 lineno = lno 976 977 // Truncate precision for non-ideal float. 978 if v.Ctype() == CTFLT && n.Type.Etype != TIDEAL { 979 n.SetVal(Val{truncfltlit(v.U.(*Mpflt), n.Type)}) 980 } 981 } 982 983 func setboolconst(n *Node, v bool) { 984 setconst(n, Val{U: v}) 985 } 986 987 func setintconst(n *Node, v int64) { 988 u := new(Mpint) 989 u.SetInt64(v) 990 setconst(n, Val{u}) 991 } 992 993 // nodlit returns a new untyped constant with value v. 994 func nodlit(v Val) *Node { 995 n := nod(OLITERAL, nil, nil) 996 n.SetVal(v) 997 switch v.Ctype() { 998 default: 999 Fatalf("nodlit ctype %d", v.Ctype()) 1000 1001 case CTSTR: 1002 n.Type = types.Idealstring 1003 1004 case CTBOOL: 1005 n.Type = types.Idealbool 1006 1007 case CTINT, CTRUNE, CTFLT, CTCPLX: 1008 n.Type = types.Types[TIDEAL] 1009 1010 case CTNIL: 1011 n.Type = types.Types[TNIL] 1012 } 1013 1014 return n 1015 } 1016 1017 // idealkind returns a constant kind like consttype 1018 // but for an arbitrary "ideal" (untyped constant) expression. 1019 func idealkind(n *Node) Ctype { 1020 if n == nil || !n.Type.IsUntyped() { 1021 return CTxxx 1022 } 1023 1024 switch n.Op { 1025 default: 1026 return CTxxx 1027 1028 case OLITERAL: 1029 return n.Val().Ctype() 1030 1031 // numeric kinds. 1032 case OADD, 1033 OAND, 1034 OANDNOT, 1035 OBITNOT, 1036 ODIV, 1037 ONEG, 1038 OMOD, 1039 OMUL, 1040 OSUB, 1041 OXOR, 1042 OOR, 1043 OPLUS: 1044 k1 := idealkind(n.Left) 1045 k2 := idealkind(n.Right) 1046 if k1 > k2 { 1047 return k1 1048 } else { 1049 return k2 1050 } 1051 1052 case OREAL, OIMAG: 1053 return CTFLT 1054 1055 case OCOMPLEX: 1056 return CTCPLX 1057 1058 case OADDSTR: 1059 return CTSTR 1060 1061 case OANDAND, 1062 OEQ, 1063 OGE, 1064 OGT, 1065 OLE, 1066 OLT, 1067 ONE, 1068 ONOT, 1069 OOROR: 1070 return CTBOOL 1071 1072 // shifts (beware!). 1073 case OLSH, ORSH: 1074 return idealkind(n.Left) 1075 } 1076 } 1077 1078 // The result of defaultlit MUST be assigned back to n, e.g. 1079 // n.Left = defaultlit(n.Left, t) 1080 func defaultlit(n *Node, t *types.Type) *Node { 1081 return defaultlitreuse(n, t, noReuse) 1082 } 1083 1084 // The result of defaultlitreuse MUST be assigned back to n, e.g. 1085 // n.Left = defaultlitreuse(n.Left, t, reuse) 1086 func defaultlitreuse(n *Node, t *types.Type, reuse canReuseNode) *Node { 1087 if n == nil || !n.Type.IsUntyped() { 1088 return n 1089 } 1090 1091 if n.Op == OLITERAL && !reuse { 1092 n = n.rawcopy() 1093 reuse = true 1094 } 1095 1096 lno := setlineno(n) 1097 ctype := idealkind(n) 1098 var t1 *types.Type 1099 switch ctype { 1100 default: 1101 if t != nil { 1102 return convlit(n, t) 1103 } 1104 1105 switch n.Val().Ctype() { 1106 case CTNIL: 1107 lineno = lno 1108 if !n.Diag() { 1109 yyerror("use of untyped nil") 1110 n.SetDiag(true) 1111 } 1112 1113 n.Type = nil 1114 case CTSTR: 1115 t1 := types.Types[TSTRING] 1116 n = convlit1(n, t1, false, reuse) 1117 default: 1118 yyerror("defaultlit: unknown literal: %v", n) 1119 } 1120 lineno = lno 1121 return n 1122 1123 case CTxxx: 1124 Fatalf("defaultlit: idealkind is CTxxx: %+v", n) 1125 1126 case CTBOOL: 1127 t1 := types.Types[TBOOL] 1128 if t != nil && t.IsBoolean() { 1129 t1 = t 1130 } 1131 n = convlit1(n, t1, false, reuse) 1132 lineno = lno 1133 return n 1134 1135 case CTINT: 1136 t1 = types.Types[TINT] 1137 case CTRUNE: 1138 t1 = types.Runetype 1139 case CTFLT: 1140 t1 = types.Types[TFLOAT64] 1141 case CTCPLX: 1142 t1 = types.Types[TCOMPLEX128] 1143 } 1144 1145 // Note: n.Val().Ctype() can be CTxxx (not a constant) here 1146 // in the case of an untyped non-constant value, like 1<<i. 1147 v1 := n.Val() 1148 if t != nil { 1149 if t.IsInteger() { 1150 t1 = t 1151 v1 = toint(n.Val()) 1152 } else if t.IsFloat() { 1153 t1 = t 1154 v1 = toflt(n.Val()) 1155 } else if t.IsComplex() { 1156 t1 = t 1157 v1 = tocplx(n.Val()) 1158 } 1159 if n.Val().Ctype() != CTxxx { 1160 n.SetVal(v1) 1161 } 1162 } 1163 1164 if n.Val().Ctype() != CTxxx { 1165 overflow(n.Val(), t1) 1166 } 1167 n = convlit1(n, t1, false, reuse) 1168 lineno = lno 1169 return n 1170 } 1171 1172 // defaultlit on both nodes simultaneously; 1173 // if they're both ideal going in they better 1174 // get the same type going out. 1175 // force means must assign concrete (non-ideal) type. 1176 // The results of defaultlit2 MUST be assigned back to l and r, e.g. 1177 // n.Left, n.Right = defaultlit2(n.Left, n.Right, force) 1178 func defaultlit2(l *Node, r *Node, force bool) (*Node, *Node) { 1179 if l.Type == nil || r.Type == nil { 1180 return l, r 1181 } 1182 if !l.Type.IsUntyped() { 1183 r = convlit(r, l.Type) 1184 return l, r 1185 } 1186 1187 if !r.Type.IsUntyped() { 1188 l = convlit(l, r.Type) 1189 return l, r 1190 } 1191 1192 if !force { 1193 return l, r 1194 } 1195 1196 if l.Type.IsBoolean() { 1197 l = convlit(l, types.Types[TBOOL]) 1198 r = convlit(r, types.Types[TBOOL]) 1199 } 1200 1201 lkind := idealkind(l) 1202 rkind := idealkind(r) 1203 if lkind == CTCPLX || rkind == CTCPLX { 1204 l = convlit(l, types.Types[TCOMPLEX128]) 1205 r = convlit(r, types.Types[TCOMPLEX128]) 1206 return l, r 1207 } 1208 1209 if lkind == CTFLT || rkind == CTFLT { 1210 l = convlit(l, types.Types[TFLOAT64]) 1211 r = convlit(r, types.Types[TFLOAT64]) 1212 return l, r 1213 } 1214 1215 if lkind == CTRUNE || rkind == CTRUNE { 1216 l = convlit(l, types.Runetype) 1217 r = convlit(r, types.Runetype) 1218 return l, r 1219 } 1220 1221 l = convlit(l, types.Types[TINT]) 1222 r = convlit(r, types.Types[TINT]) 1223 1224 return l, r 1225 } 1226 1227 // strlit returns the value of a literal string Node as a string. 1228 func strlit(n *Node) string { 1229 return n.Val().U.(string) 1230 } 1231 1232 // TODO(gri) smallintconst is only used in one place - can we used indexconst? 1233 func smallintconst(n *Node) bool { 1234 if n.Op == OLITERAL && Isconst(n, CTINT) && n.Type != nil { 1235 switch simtype[n.Type.Etype] { 1236 case TINT8, 1237 TUINT8, 1238 TINT16, 1239 TUINT16, 1240 TINT32, 1241 TUINT32, 1242 TBOOL: 1243 return true 1244 1245 case TIDEAL, TINT64, TUINT64, TPTR: 1246 v, ok := n.Val().U.(*Mpint) 1247 if ok && v.Cmp(minintval[TINT32]) >= 0 && v.Cmp(maxintval[TINT32]) <= 0 { 1248 return true 1249 } 1250 } 1251 } 1252 1253 return false 1254 } 1255 1256 // indexconst checks if Node n contains a constant expression 1257 // representable as a non-negative int and returns its value. 1258 // If n is not a constant expression, not representable as an 1259 // integer, or negative, it returns -1. If n is too large, it 1260 // returns -2. 1261 func indexconst(n *Node) int64 { 1262 if n.Op != OLITERAL { 1263 return -1 1264 } 1265 1266 v := toint(n.Val()) // toint returns argument unchanged if not representable as an *Mpint 1267 vi, ok := v.U.(*Mpint) 1268 if !ok || vi.CmpInt64(0) < 0 { 1269 return -1 1270 } 1271 if vi.Cmp(maxintval[TINT]) > 0 { 1272 return -2 1273 } 1274 1275 return vi.Int64() 1276 } 1277 1278 // isGoConst reports whether n is a Go language constant (as opposed to a 1279 // compile-time constant). 1280 // 1281 // Expressions derived from nil, like string([]byte(nil)), while they 1282 // may be known at compile time, are not Go language constants. 1283 // Only called for expressions known to evaluate to compile-time 1284 // constants. 1285 func (n *Node) isGoConst() bool { 1286 if n.Orig != nil { 1287 n = n.Orig 1288 } 1289 1290 switch n.Op { 1291 case OADD, 1292 OAND, 1293 OANDAND, 1294 OANDNOT, 1295 OBITNOT, 1296 ODIV, 1297 OEQ, 1298 OGE, 1299 OGT, 1300 OLE, 1301 OLSH, 1302 OLT, 1303 ONEG, 1304 OMOD, 1305 OMUL, 1306 ONE, 1307 ONOT, 1308 OOR, 1309 OOROR, 1310 OPLUS, 1311 ORSH, 1312 OSUB, 1313 OXOR, 1314 OIOTA, 1315 OREAL, 1316 OIMAG: 1317 if n.Left.isGoConst() && (n.Right == nil || n.Right.isGoConst()) { 1318 return true 1319 } 1320 1321 case OCOMPLEX: 1322 if n.List.Len() == 0 && n.Left.isGoConst() && n.Right.isGoConst() { 1323 return true 1324 } 1325 1326 case OADDSTR: 1327 for _, n1 := range n.List.Slice() { 1328 if !n1.isGoConst() { 1329 return false 1330 } 1331 } 1332 return true 1333 1334 case OCONV, OCONVNOP: 1335 if okforconst[n.Type.Etype] && n.Left.isGoConst() { 1336 return true 1337 } 1338 1339 case OLEN, OCAP: 1340 l := n.Left 1341 if l.isGoConst() { 1342 return true 1343 } 1344 1345 // Special case: len/cap is constant when applied to array or 1346 // pointer to array when the expression does not contain 1347 // function calls or channel receive operations. 1348 t := l.Type 1349 1350 if t != nil && t.IsPtr() { 1351 t = t.Elem() 1352 } 1353 if t != nil && t.IsArray() && !hascallchan(l) { 1354 return true 1355 } 1356 1357 case OLITERAL: 1358 if n.Val().Ctype() != CTNIL { 1359 return true 1360 } 1361 1362 case ONAME: 1363 l := asNode(n.Sym.Def) 1364 if l != nil && l.Op == OLITERAL && n.Val().Ctype() != CTNIL { 1365 return true 1366 } 1367 1368 case ONONAME: 1369 if asNode(n.Sym.Def) != nil && asNode(n.Sym.Def).Op == OIOTA { 1370 return true 1371 } 1372 1373 case OALIGNOF, OOFFSETOF, OSIZEOF: 1374 return true 1375 } 1376 1377 //dump("nonconst", n); 1378 return false 1379 } 1380 1381 func hascallchan(n *Node) bool { 1382 if n == nil { 1383 return false 1384 } 1385 switch n.Op { 1386 case OAPPEND, 1387 OCALL, 1388 OCALLFUNC, 1389 OCALLINTER, 1390 OCALLMETH, 1391 OCAP, 1392 OCLOSE, 1393 OCOMPLEX, 1394 OCOPY, 1395 ODELETE, 1396 OIMAG, 1397 OLEN, 1398 OMAKE, 1399 ONEW, 1400 OPANIC, 1401 OPRINT, 1402 OPRINTN, 1403 OREAL, 1404 ORECOVER, 1405 ORECV: 1406 return true 1407 } 1408 1409 if hascallchan(n.Left) || hascallchan(n.Right) { 1410 return true 1411 } 1412 for _, n1 := range n.List.Slice() { 1413 if hascallchan(n1) { 1414 return true 1415 } 1416 } 1417 for _, n2 := range n.Rlist.Slice() { 1418 if hascallchan(n2) { 1419 return true 1420 } 1421 } 1422 1423 return false 1424 }