...

Source file src/pkg/cmd/compile/internal/gc/const.go

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

View as plain text