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  }