github.com/hikaru7719/go@v0.0.0-20181025140707-c8b2ac68906a/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  	"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  	nl, nr := n.Left, n.Right
   588  
   589  	// Pick off just the opcodes that can be constant evaluated.
   590  	switch op := n.Op; op {
   591  	case OPLUS, OMINUS, OCOM, ONOT:
   592  		if nl.Op == OLITERAL {
   593  			setconst(n, unaryOp(op, nl.Val(), n.Type))
   594  		}
   595  
   596  	case OADD, OSUB, OMUL, ODIV, OMOD, OOR, OXOR, OAND, OANDNOT, OOROR, OANDAND:
   597  		if nl.Op == OLITERAL && nr.Op == OLITERAL {
   598  			setconst(n, binaryOp(nl.Val(), op, nr.Val()))
   599  		}
   600  
   601  	case OEQ, ONE, OLT, OLE, OGT, OGE:
   602  		if nl.Op == OLITERAL && nr.Op == OLITERAL {
   603  			if nl.Type.IsInterface() != nr.Type.IsInterface() {
   604  				// Mixed interface/non-interface
   605  				// constant comparison means comparing
   606  				// nil interface with some typed
   607  				// constant, which is always unequal.
   608  				// E.g., interface{}(nil) == (*int)(nil).
   609  				setboolconst(n, op == ONE)
   610  			} else {
   611  				setboolconst(n, compareOp(nl.Val(), op, nr.Val()))
   612  			}
   613  		}
   614  
   615  	case OLSH, ORSH:
   616  		if nl.Op == OLITERAL && nr.Op == OLITERAL {
   617  			setconst(n, shiftOp(nl.Val(), op, nr.Val()))
   618  		}
   619  
   620  	case OCONV:
   621  		if n.Type != nil && okforconst[n.Type.Etype] && nl.Op == OLITERAL {
   622  			// TODO(mdempsky): There should be a convval function.
   623  			setconst(n, convlit1(nl, n.Type, true, false).Val())
   624  		}
   625  
   626  	case OARRAYBYTESTR:
   627  		// string([]byte(nil)) or string([]rune(nil))
   628  		if nl.Op == OLITERAL && nl.Val().Ctype() == CTNIL {
   629  			setconst(n, Val{U: ""})
   630  		}
   631  
   632  	case OADDSTR:
   633  		// Merge adjacent constants in the argument list.
   634  		s := n.List.Slice()
   635  		for i1 := 0; i1 < len(s); i1++ {
   636  			if Isconst(s[i1], CTSTR) && i1+1 < len(s) && Isconst(s[i1+1], CTSTR) {
   637  				// merge from i1 up to but not including i2
   638  				var strs []string
   639  				i2 := i1
   640  				for i2 < len(s) && Isconst(s[i2], CTSTR) {
   641  					strs = append(strs, s[i2].Val().U.(string))
   642  					i2++
   643  				}
   644  
   645  				nl := *s[i1]
   646  				nl.Orig = &nl
   647  				nl.SetVal(Val{strings.Join(strs, "")})
   648  				s[i1] = &nl
   649  				s = append(s[:i1+1], s[i2:]...)
   650  			}
   651  		}
   652  
   653  		if len(s) == 1 && Isconst(s[0], CTSTR) {
   654  			n.Op = OLITERAL
   655  			n.SetVal(s[0].Val())
   656  		} else {
   657  			n.List.Set(s)
   658  		}
   659  	}
   660  }
   661  
   662  func match(x, y Val) (Val, Val) {
   663  	switch {
   664  	case x.Ctype() == CTCPLX || y.Ctype() == CTCPLX:
   665  		return tocplx(x), tocplx(y)
   666  	case x.Ctype() == CTFLT || y.Ctype() == CTFLT:
   667  		return toflt(x), toflt(y)
   668  	}
   669  
   670  	// Mixed int/rune are fine.
   671  	return x, y
   672  }
   673  
   674  func compareOp(x Val, op Op, y Val) bool {
   675  	x, y = match(x, y)
   676  
   677  	switch x.Ctype() {
   678  	case CTNIL:
   679  		_, _ = x.U.(*NilVal), y.U.(*NilVal) // assert dynamic types match
   680  		switch op {
   681  		case OEQ:
   682  			return true
   683  		case ONE:
   684  			return false
   685  		}
   686  
   687  	case CTBOOL:
   688  		x, y := x.U.(bool), y.U.(bool)
   689  		switch op {
   690  		case OEQ:
   691  			return x == y
   692  		case ONE:
   693  			return x != y
   694  		}
   695  
   696  	case CTINT, CTRUNE:
   697  		x, y := x.U.(*Mpint), y.U.(*Mpint)
   698  		return cmpZero(x.Cmp(y), op)
   699  
   700  	case CTFLT:
   701  		x, y := x.U.(*Mpflt), y.U.(*Mpflt)
   702  		return cmpZero(x.Cmp(y), op)
   703  
   704  	case CTCPLX:
   705  		x, y := x.U.(*Mpcplx), y.U.(*Mpcplx)
   706  		eq := x.Real.Cmp(&y.Real) == 0 && x.Imag.Cmp(&y.Imag) == 0
   707  		switch op {
   708  		case OEQ:
   709  			return eq
   710  		case ONE:
   711  			return !eq
   712  		}
   713  
   714  	case CTSTR:
   715  		x, y := x.U.(string), y.U.(string)
   716  		switch op {
   717  		case OEQ:
   718  			return x == y
   719  		case ONE:
   720  			return x != y
   721  		case OLT:
   722  			return x < y
   723  		case OLE:
   724  			return x <= y
   725  		case OGT:
   726  			return x > y
   727  		case OGE:
   728  			return x >= y
   729  		}
   730  	}
   731  
   732  	Fatalf("compareOp: bad comparison: %v %v %v", x, op, y)
   733  	panic("unreachable")
   734  }
   735  
   736  func cmpZero(x int, op Op) bool {
   737  	switch op {
   738  	case OEQ:
   739  		return x == 0
   740  	case ONE:
   741  		return x != 0
   742  	case OLT:
   743  		return x < 0
   744  	case OLE:
   745  		return x <= 0
   746  	case OGT:
   747  		return x > 0
   748  	case OGE:
   749  		return x >= 0
   750  	}
   751  
   752  	Fatalf("cmpZero: want comparison operator, got %v", op)
   753  	panic("unreachable")
   754  }
   755  
   756  func binaryOp(x Val, op Op, y Val) Val {
   757  	x, y = match(x, y)
   758  
   759  Outer:
   760  	switch x.Ctype() {
   761  	case CTBOOL:
   762  		x, y := x.U.(bool), y.U.(bool)
   763  		switch op {
   764  		case OANDAND:
   765  			return Val{U: x && y}
   766  		case OOROR:
   767  			return Val{U: x || y}
   768  		}
   769  
   770  	case CTINT, CTRUNE:
   771  		x, y := x.U.(*Mpint), y.U.(*Mpint)
   772  
   773  		u := new(Mpint)
   774  		u.Rune = x.Rune || y.Rune
   775  		u.Set(x)
   776  		switch op {
   777  		case OADD:
   778  			u.Add(y)
   779  		case OSUB:
   780  			u.Sub(y)
   781  		case OMUL:
   782  			u.Mul(y)
   783  		case ODIV:
   784  			if y.CmpInt64(0) == 0 {
   785  				yyerror("division by zero")
   786  				u.SetOverflow()
   787  				break
   788  			}
   789  			u.Quo(y)
   790  		case OMOD:
   791  			if y.CmpInt64(0) == 0 {
   792  				yyerror("division by zero")
   793  				u.SetOverflow()
   794  				break
   795  			}
   796  			u.Rem(y)
   797  		case OOR:
   798  			u.Or(y)
   799  		case OAND:
   800  			u.And(y)
   801  		case OANDNOT:
   802  			u.AndNot(y)
   803  		case OXOR:
   804  			u.Xor(y)
   805  		default:
   806  			break Outer
   807  		}
   808  		return Val{U: u}
   809  
   810  	case CTFLT:
   811  		x, y := x.U.(*Mpflt), y.U.(*Mpflt)
   812  
   813  		u := newMpflt()
   814  		u.Set(x)
   815  		switch op {
   816  		case OADD:
   817  			u.Add(y)
   818  		case OSUB:
   819  			u.Sub(y)
   820  		case OMUL:
   821  			u.Mul(y)
   822  		case ODIV:
   823  			if y.CmpFloat64(0) == 0 {
   824  				yyerror("division by zero")
   825  				u.SetFloat64(1)
   826  				break
   827  			}
   828  			u.Quo(y)
   829  		case OMOD:
   830  			// TODO(mdempsky): Move to typecheck.
   831  			yyerror("illegal constant expression: floating-point %% operation")
   832  		default:
   833  			break Outer
   834  		}
   835  		return Val{U: u}
   836  
   837  	case CTCPLX:
   838  		x, y := x.U.(*Mpcplx), y.U.(*Mpcplx)
   839  
   840  		u := new(Mpcplx)
   841  		u.Real.Set(&x.Real)
   842  		u.Imag.Set(&x.Imag)
   843  		switch op {
   844  		case OADD:
   845  			u.Real.Add(&y.Real)
   846  			u.Imag.Add(&y.Imag)
   847  		case OSUB:
   848  			u.Real.Sub(&y.Real)
   849  			u.Imag.Sub(&y.Imag)
   850  		case OMUL:
   851  			u.Mul(y)
   852  		case ODIV:
   853  			if !u.Div(y) {
   854  				yyerror("complex division by zero")
   855  				u.Real.SetFloat64(1)
   856  				u.Imag.SetFloat64(0)
   857  			}
   858  		default:
   859  			break Outer
   860  		}
   861  		return Val{U: u}
   862  	}
   863  
   864  	Fatalf("binaryOp: bad operation: %v %v %v", x, op, y)
   865  	panic("unreachable")
   866  }
   867  
   868  func unaryOp(op Op, x Val, t *types.Type) Val {
   869  	switch op {
   870  	case OPLUS:
   871  		switch x.Ctype() {
   872  		case CTINT, CTRUNE, CTFLT, CTCPLX:
   873  			return x
   874  		}
   875  
   876  	case OMINUS:
   877  		switch x.Ctype() {
   878  		case CTINT, CTRUNE:
   879  			x := x.U.(*Mpint)
   880  			u := new(Mpint)
   881  			u.Rune = x.Rune
   882  			u.Set(x)
   883  			u.Neg()
   884  			return Val{U: u}
   885  
   886  		case CTFLT:
   887  			x := x.U.(*Mpflt)
   888  			u := newMpflt()
   889  			u.Set(x)
   890  			u.Neg()
   891  			return Val{U: u}
   892  
   893  		case CTCPLX:
   894  			x := x.U.(*Mpcplx)
   895  			u := new(Mpcplx)
   896  			u.Real.Set(&x.Real)
   897  			u.Imag.Set(&x.Imag)
   898  			u.Real.Neg()
   899  			u.Imag.Neg()
   900  			return Val{U: u}
   901  		}
   902  
   903  	case OCOM:
   904  		x := x.U.(*Mpint)
   905  
   906  		u := new(Mpint)
   907  		u.Rune = x.Rune
   908  		if t.IsSigned() || t.IsUntyped() {
   909  			// Signed values change sign.
   910  			u.SetInt64(-1)
   911  		} else {
   912  			// Unsigned values invert their bits.
   913  			u.Set(maxintval[t.Etype])
   914  		}
   915  		u.Xor(x)
   916  		return Val{U: u}
   917  
   918  	case ONOT:
   919  		return Val{U: !x.U.(bool)}
   920  	}
   921  
   922  	Fatalf("unaryOp: bad operation: %v %v", op, x)
   923  	panic("unreachable")
   924  }
   925  
   926  func shiftOp(x Val, op Op, y Val) Val {
   927  	if x.Ctype() != CTRUNE {
   928  		x = toint(x)
   929  	}
   930  	y = toint(y)
   931  
   932  	u := new(Mpint)
   933  	u.Set(x.U.(*Mpint))
   934  	u.Rune = x.U.(*Mpint).Rune
   935  	switch op {
   936  	case OLSH:
   937  		u.Lsh(y.U.(*Mpint))
   938  	case ORSH:
   939  		u.Rsh(y.U.(*Mpint))
   940  	default:
   941  		Fatalf("shiftOp: bad operator: %v", op)
   942  		panic("unreachable")
   943  	}
   944  	return Val{U: u}
   945  }
   946  
   947  // setconst rewrites n as an OLITERAL with value v.
   948  func setconst(n *Node, v Val) {
   949  	// Ensure n.Orig still points to a semantically-equivalent
   950  	// expression after we rewrite n into a constant.
   951  	if n.Orig == n {
   952  		n.Orig = n.sepcopy()
   953  	}
   954  
   955  	*n = Node{
   956  		Op:      OLITERAL,
   957  		Pos:     n.Pos,
   958  		Orig:    n.Orig,
   959  		Type:    n.Type,
   960  		Xoffset: BADWIDTH,
   961  	}
   962  	n.SetVal(v)
   963  
   964  	// Check range.
   965  	lno := setlineno(n)
   966  	overflow(v, n.Type)
   967  	lineno = lno
   968  
   969  	// Truncate precision for non-ideal float.
   970  	if v.Ctype() == CTFLT && n.Type.Etype != TIDEAL {
   971  		n.SetVal(Val{truncfltlit(v.U.(*Mpflt), n.Type)})
   972  	}
   973  }
   974  
   975  func setboolconst(n *Node, v bool) {
   976  	setconst(n, Val{U: v})
   977  }
   978  
   979  func setintconst(n *Node, v int64) {
   980  	u := new(Mpint)
   981  	u.SetInt64(v)
   982  	setconst(n, Val{u})
   983  }
   984  
   985  // nodlit returns a new untyped constant with value v.
   986  func nodlit(v Val) *Node {
   987  	n := nod(OLITERAL, nil, nil)
   988  	n.SetVal(v)
   989  	switch v.Ctype() {
   990  	default:
   991  		Fatalf("nodlit ctype %d", v.Ctype())
   992  
   993  	case CTSTR:
   994  		n.Type = types.Idealstring
   995  
   996  	case CTBOOL:
   997  		n.Type = types.Idealbool
   998  
   999  	case CTINT, CTRUNE, CTFLT, CTCPLX:
  1000  		n.Type = types.Types[TIDEAL]
  1001  
  1002  	case CTNIL:
  1003  		n.Type = types.Types[TNIL]
  1004  	}
  1005  
  1006  	return n
  1007  }
  1008  
  1009  // idealkind returns a constant kind like consttype
  1010  // but for an arbitrary "ideal" (untyped constant) expression.
  1011  func idealkind(n *Node) Ctype {
  1012  	if n == nil || !n.Type.IsUntyped() {
  1013  		return CTxxx
  1014  	}
  1015  
  1016  	switch n.Op {
  1017  	default:
  1018  		return CTxxx
  1019  
  1020  	case OLITERAL:
  1021  		return n.Val().Ctype()
  1022  
  1023  		// numeric kinds.
  1024  	case OADD,
  1025  		OAND,
  1026  		OANDNOT,
  1027  		OCOM,
  1028  		ODIV,
  1029  		OMINUS,
  1030  		OMOD,
  1031  		OMUL,
  1032  		OSUB,
  1033  		OXOR,
  1034  		OOR,
  1035  		OPLUS:
  1036  		k1 := idealkind(n.Left)
  1037  		k2 := idealkind(n.Right)
  1038  		if k1 > k2 {
  1039  			return k1
  1040  		} else {
  1041  			return k2
  1042  		}
  1043  
  1044  	case OREAL, OIMAG:
  1045  		return CTFLT
  1046  
  1047  	case OCOMPLEX:
  1048  		return CTCPLX
  1049  
  1050  	case OADDSTR:
  1051  		return CTSTR
  1052  
  1053  	case OANDAND,
  1054  		OEQ,
  1055  		OGE,
  1056  		OGT,
  1057  		OLE,
  1058  		OLT,
  1059  		ONE,
  1060  		ONOT,
  1061  		OOROR:
  1062  		return CTBOOL
  1063  
  1064  		// shifts (beware!).
  1065  	case OLSH, ORSH:
  1066  		return idealkind(n.Left)
  1067  	}
  1068  }
  1069  
  1070  // The result of defaultlit MUST be assigned back to n, e.g.
  1071  // 	n.Left = defaultlit(n.Left, t)
  1072  func defaultlit(n *Node, t *types.Type) *Node {
  1073  	return defaultlitreuse(n, t, noReuse)
  1074  }
  1075  
  1076  // The result of defaultlitreuse MUST be assigned back to n, e.g.
  1077  // 	n.Left = defaultlitreuse(n.Left, t, reuse)
  1078  func defaultlitreuse(n *Node, t *types.Type, reuse canReuseNode) *Node {
  1079  	if n == nil || !n.Type.IsUntyped() {
  1080  		return n
  1081  	}
  1082  
  1083  	if n.Op == OLITERAL && !reuse {
  1084  		n = n.rawcopy()
  1085  		reuse = true
  1086  	}
  1087  
  1088  	lno := setlineno(n)
  1089  	ctype := idealkind(n)
  1090  	var t1 *types.Type
  1091  	switch ctype {
  1092  	default:
  1093  		if t != nil {
  1094  			return convlit(n, t)
  1095  		}
  1096  
  1097  		switch n.Val().Ctype() {
  1098  		case CTNIL:
  1099  			lineno = lno
  1100  			if !n.Diag() {
  1101  				yyerror("use of untyped nil")
  1102  				n.SetDiag(true)
  1103  			}
  1104  
  1105  			n.Type = nil
  1106  		case CTSTR:
  1107  			t1 := types.Types[TSTRING]
  1108  			n = convlit1(n, t1, false, reuse)
  1109  		default:
  1110  			yyerror("defaultlit: unknown literal: %v", n)
  1111  		}
  1112  		lineno = lno
  1113  		return n
  1114  
  1115  	case CTxxx:
  1116  		Fatalf("defaultlit: idealkind is CTxxx: %+v", n)
  1117  
  1118  	case CTBOOL:
  1119  		t1 := types.Types[TBOOL]
  1120  		if t != nil && t.IsBoolean() {
  1121  			t1 = t
  1122  		}
  1123  		n = convlit1(n, t1, false, reuse)
  1124  		lineno = lno
  1125  		return n
  1126  
  1127  	case CTINT:
  1128  		t1 = types.Types[TINT]
  1129  	case CTRUNE:
  1130  		t1 = types.Runetype
  1131  	case CTFLT:
  1132  		t1 = types.Types[TFLOAT64]
  1133  	case CTCPLX:
  1134  		t1 = types.Types[TCOMPLEX128]
  1135  	}
  1136  
  1137  	// Note: n.Val().Ctype() can be CTxxx (not a constant) here
  1138  	// in the case of an untyped non-constant value, like 1<<i.
  1139  	v1 := n.Val()
  1140  	if t != nil {
  1141  		if t.IsInteger() {
  1142  			t1 = t
  1143  			v1 = toint(n.Val())
  1144  		} else if t.IsFloat() {
  1145  			t1 = t
  1146  			v1 = toflt(n.Val())
  1147  		} else if t.IsComplex() {
  1148  			t1 = t
  1149  			v1 = tocplx(n.Val())
  1150  		}
  1151  		if n.Val().Ctype() != CTxxx {
  1152  			n.SetVal(v1)
  1153  		}
  1154  	}
  1155  
  1156  	if n.Val().Ctype() != CTxxx {
  1157  		overflow(n.Val(), t1)
  1158  	}
  1159  	n = convlit1(n, t1, false, reuse)
  1160  	lineno = lno
  1161  	return n
  1162  }
  1163  
  1164  // defaultlit on both nodes simultaneously;
  1165  // if they're both ideal going in they better
  1166  // get the same type going out.
  1167  // force means must assign concrete (non-ideal) type.
  1168  // The results of defaultlit2 MUST be assigned back to l and r, e.g.
  1169  // 	n.Left, n.Right = defaultlit2(n.Left, n.Right, force)
  1170  func defaultlit2(l *Node, r *Node, force bool) (*Node, *Node) {
  1171  	if l.Type == nil || r.Type == nil {
  1172  		return l, r
  1173  	}
  1174  	if !l.Type.IsUntyped() {
  1175  		r = convlit(r, l.Type)
  1176  		return l, r
  1177  	}
  1178  
  1179  	if !r.Type.IsUntyped() {
  1180  		l = convlit(l, r.Type)
  1181  		return l, r
  1182  	}
  1183  
  1184  	if !force {
  1185  		return l, r
  1186  	}
  1187  
  1188  	if l.Type.IsBoolean() {
  1189  		l = convlit(l, types.Types[TBOOL])
  1190  		r = convlit(r, types.Types[TBOOL])
  1191  	}
  1192  
  1193  	lkind := idealkind(l)
  1194  	rkind := idealkind(r)
  1195  	if lkind == CTCPLX || rkind == CTCPLX {
  1196  		l = convlit(l, types.Types[TCOMPLEX128])
  1197  		r = convlit(r, types.Types[TCOMPLEX128])
  1198  		return l, r
  1199  	}
  1200  
  1201  	if lkind == CTFLT || rkind == CTFLT {
  1202  		l = convlit(l, types.Types[TFLOAT64])
  1203  		r = convlit(r, types.Types[TFLOAT64])
  1204  		return l, r
  1205  	}
  1206  
  1207  	if lkind == CTRUNE || rkind == CTRUNE {
  1208  		l = convlit(l, types.Runetype)
  1209  		r = convlit(r, types.Runetype)
  1210  		return l, r
  1211  	}
  1212  
  1213  	l = convlit(l, types.Types[TINT])
  1214  	r = convlit(r, types.Types[TINT])
  1215  
  1216  	return l, r
  1217  }
  1218  
  1219  // strlit returns the value of a literal string Node as a string.
  1220  func strlit(n *Node) string {
  1221  	return n.Val().U.(string)
  1222  }
  1223  
  1224  func smallintconst(n *Node) bool {
  1225  	if n.Op == OLITERAL && Isconst(n, CTINT) && n.Type != nil {
  1226  		switch simtype[n.Type.Etype] {
  1227  		case TINT8,
  1228  			TUINT8,
  1229  			TINT16,
  1230  			TUINT16,
  1231  			TINT32,
  1232  			TUINT32,
  1233  			TBOOL:
  1234  			return true
  1235  
  1236  		case TIDEAL, TINT64, TUINT64, TPTR:
  1237  			v, ok := n.Val().U.(*Mpint)
  1238  			if ok && v.Cmp(minintval[TINT32]) > 0 && v.Cmp(maxintval[TINT32]) < 0 {
  1239  				return true
  1240  			}
  1241  		}
  1242  	}
  1243  
  1244  	return false
  1245  }
  1246  
  1247  // nonnegintconst checks if Node n contains a constant expression
  1248  // representable as a non-negative small integer, and returns its
  1249  // (integer) value if that's the case. Otherwise, it returns -1.
  1250  func nonnegintconst(n *Node) int64 {
  1251  	if n.Op != OLITERAL {
  1252  		return -1
  1253  	}
  1254  
  1255  	// toint will leave n.Val unchanged if it's not castable to an
  1256  	// Mpint, so we still have to guard the conversion.
  1257  	v := toint(n.Val())
  1258  	vi, ok := v.U.(*Mpint)
  1259  	if !ok || vi.CmpInt64(0) < 0 || vi.Cmp(maxintval[TINT32]) > 0 {
  1260  		return -1
  1261  	}
  1262  
  1263  	return vi.Int64()
  1264  }
  1265  
  1266  // isGoConst reports whether n is a Go language constant (as opposed to a
  1267  // compile-time constant).
  1268  //
  1269  // Expressions derived from nil, like string([]byte(nil)), while they
  1270  // may be known at compile time, are not Go language constants.
  1271  // Only called for expressions known to evaluated to compile-time
  1272  // constants.
  1273  func (n *Node) isGoConst() bool {
  1274  	if n.Orig != nil {
  1275  		n = n.Orig
  1276  	}
  1277  
  1278  	switch n.Op {
  1279  	case OADD,
  1280  		OADDSTR,
  1281  		OAND,
  1282  		OANDAND,
  1283  		OANDNOT,
  1284  		OCOM,
  1285  		ODIV,
  1286  		OEQ,
  1287  		OGE,
  1288  		OGT,
  1289  		OLE,
  1290  		OLSH,
  1291  		OLT,
  1292  		OMINUS,
  1293  		OMOD,
  1294  		OMUL,
  1295  		ONE,
  1296  		ONOT,
  1297  		OOR,
  1298  		OOROR,
  1299  		OPLUS,
  1300  		ORSH,
  1301  		OSUB,
  1302  		OXOR,
  1303  		OIOTA,
  1304  		OCOMPLEX,
  1305  		OREAL,
  1306  		OIMAG:
  1307  		if n.Left.isGoConst() && (n.Right == nil || n.Right.isGoConst()) {
  1308  			return true
  1309  		}
  1310  
  1311  	case OCONV:
  1312  		if okforconst[n.Type.Etype] && n.Left.isGoConst() {
  1313  			return true
  1314  		}
  1315  
  1316  	case OLEN, OCAP:
  1317  		l := n.Left
  1318  		if l.isGoConst() {
  1319  			return true
  1320  		}
  1321  
  1322  		// Special case: len/cap is constant when applied to array or
  1323  		// pointer to array when the expression does not contain
  1324  		// function calls or channel receive operations.
  1325  		t := l.Type
  1326  
  1327  		if t != nil && t.IsPtr() {
  1328  			t = t.Elem()
  1329  		}
  1330  		if t != nil && t.IsArray() && !hascallchan(l) {
  1331  			return true
  1332  		}
  1333  
  1334  	case OLITERAL:
  1335  		if n.Val().Ctype() != CTNIL {
  1336  			return true
  1337  		}
  1338  
  1339  	case ONAME:
  1340  		l := asNode(n.Sym.Def)
  1341  		if l != nil && l.Op == OLITERAL && n.Val().Ctype() != CTNIL {
  1342  			return true
  1343  		}
  1344  
  1345  	case ONONAME:
  1346  		if asNode(n.Sym.Def) != nil && asNode(n.Sym.Def).Op == OIOTA {
  1347  			return true
  1348  		}
  1349  
  1350  	case OALIGNOF, OOFFSETOF, OSIZEOF:
  1351  		return true
  1352  	}
  1353  
  1354  	//dump("nonconst", n);
  1355  	return false
  1356  }
  1357  
  1358  func hascallchan(n *Node) bool {
  1359  	if n == nil {
  1360  		return false
  1361  	}
  1362  	switch n.Op {
  1363  	case OAPPEND,
  1364  		OCALL,
  1365  		OCALLFUNC,
  1366  		OCALLINTER,
  1367  		OCALLMETH,
  1368  		OCAP,
  1369  		OCLOSE,
  1370  		OCOMPLEX,
  1371  		OCOPY,
  1372  		ODELETE,
  1373  		OIMAG,
  1374  		OLEN,
  1375  		OMAKE,
  1376  		ONEW,
  1377  		OPANIC,
  1378  		OPRINT,
  1379  		OPRINTN,
  1380  		OREAL,
  1381  		ORECOVER,
  1382  		ORECV:
  1383  		return true
  1384  	}
  1385  
  1386  	if hascallchan(n.Left) || hascallchan(n.Right) {
  1387  		return true
  1388  	}
  1389  	for _, n1 := range n.List.Slice() {
  1390  		if hascallchan(n1) {
  1391  			return true
  1392  		}
  1393  	}
  1394  	for _, n2 := range n.Rlist.Slice() {
  1395  		if hascallchan(n2) {
  1396  			return true
  1397  		}
  1398  	}
  1399  
  1400  	return false
  1401  }