2015-02-13 14:40:36 -05:00
|
|
|
// Copyright 2009 The Go Authors. All rights reserved.
|
|
|
|
|
// Use of this source code is governed by a BSD-style
|
|
|
|
|
// license that can be found in the LICENSE file.
|
|
|
|
|
|
|
|
|
|
package gc
|
|
|
|
|
|
2016-12-06 17:08:06 -08:00
|
|
|
import (
|
cmd/compile: factor out Pkg, Sym, and Type into package types
- created new package cmd/compile/internal/types
- moved Pkg, Sym, Type to new package
- to break cycles, for now we need the (ugly) types/utils.go
file which contains a handful of functions that must be installed
early by the gc frontend
- to break cycles, for now we need two functions to convert between
*gc.Node and *types.Node (the latter is a dummy type)
- adjusted the gc's code to use the new package and the conversion
functions as needed
- made several Pkg, Sym, and Type methods functions as needed
- renamed constructors typ, typPtr, typArray, etc. to types.New,
types.NewPtr, types.NewArray, etc.
Passes toolstash-check -all.
Change-Id: I8adfa5e85c731645d0a7fd2030375ed6ebf54b72
Reviewed-on: https://go-review.googlesource.com/39855
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2017-04-04 17:54:02 -07:00
|
|
|
"cmd/compile/internal/types"
|
cmd/compile: fix "previous" position info for duplicate switch cases
Because the Node AST represents references to declared objects (e.g.,
variables, packages, types, constants) by directly pointing to the
referred object, we don't have use-position info for these objects.
For switch statements with duplicate cases, we report back where the
first duplicate value appeared. However, due to the AST
representation, if the value was a declared constant, we mistakenly
reported the constant declaration position as the previous case
position.
This CL reports back against the 'case' keyword's position instead, if
there's no more precise information available to us.
It also refactors code to emit the same "previous at" error message
for duplicate values in map literals.
Thanks to Emmanuel Odeke for the test case.
Fixes #33460.
Change-Id: Iec69542ccd4aad594dde8df02d1b880a422c5622
Reviewed-on: https://go-review.googlesource.com/c/go/+/188901
Reviewed-by: Robert Griesemer <gri@golang.org>
Reviewed-by: Emmanuel Odeke <emm.odeke@gmail.com>
Run-TryBot: Emmanuel Odeke <emm.odeke@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
2019-08-05 13:12:01 -07:00
|
|
|
"cmd/internal/src"
|
|
|
|
|
"fmt"
|
cmd/compile: fix misleading "truncated to int" messages
When defining an int const, the compiler tries to cast the RHS
expression to int. The cast may fail for three reasons:
1. expr is an integer constant that overflows int
2. expr is a floating point constant
3. expr is a complex constant, or not a number
In the second case, in order to print a sensible error message, we
must distinguish between a floating point constant that should be
included in the error message and a floating point constant that
cannot be reasonably formatted for inclusion in an error message.
For example, in:
const a int = 1.1
const b int = 1 + 1e-100
a is in the former group, while b is in the latter, since the floating
point value resulting from the evaluation of the rhs of the assignment
(1.00...01) is too long to be fully printed in an error message, and
cannot be shortened without making the error message misleading
(rounding or truncating it would result in a "1", which looks like an
integer constant, and it makes little sense in an error message about
an invalid floating point expression).
To fix this problem, we try to format the float value using fconv
(which is used by the error reporting mechanism to format float
arguments), and then parse the resulting string back to a
big.Float. If the result is an integer, we assume that expr is a float
value that cannot be reasonably be formatted as a string, and we emit
an error message that does not include its string representation.
Also, change the error message for overflows to a more conservative
"integer too large", which does not mention overflows that are only
caused by an internal implementation restriction.
Also, change (*Mpint) SetFloat so that it returns a bool (instead of
0/-1 for success/failure).
Fixes #11371
Change-Id: Ibbc73e2ed2eaf41f07827b0649d0eb637150ecaa
Reviewed-on: https://go-review.googlesource.com/35411
Run-TryBot: Alberto Donizetti <alb.donizetti@gmail.com>
Run-TryBot: Robert Griesemer <gri@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Robert Griesemer <gri@golang.org>
2017-01-18 11:48:14 +01:00
|
|
|
"math/big"
|
2016-12-06 17:08:06 -08:00
|
|
|
"strings"
|
|
|
|
|
)
|
2015-02-13 14:40:36 -05:00
|
|
|
|
2016-04-05 14:20:04 -07:00
|
|
|
// Ctype describes the constant kind of an "ideal" (untyped) constant.
|
2017-10-10 17:36:03 +01:00
|
|
|
type Ctype uint8
|
2016-04-05 14:20:04 -07:00
|
|
|
|
|
|
|
|
const (
|
|
|
|
|
CTxxx Ctype = iota
|
|
|
|
|
|
|
|
|
|
CTINT
|
|
|
|
|
CTRUNE
|
|
|
|
|
CTFLT
|
|
|
|
|
CTCPLX
|
|
|
|
|
CTSTR
|
|
|
|
|
CTBOOL
|
|
|
|
|
CTNIL
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
type Val struct {
|
|
|
|
|
// U contains one of:
|
2019-06-18 01:14:22 +07:00
|
|
|
// bool bool when Ctype() == CTBOOL
|
|
|
|
|
// *Mpint int when Ctype() == CTINT, rune when Ctype() == CTRUNE
|
|
|
|
|
// *Mpflt float when Ctype() == CTFLT
|
|
|
|
|
// *Mpcplx pair of floats when Ctype() == CTCPLX
|
|
|
|
|
// string string when Ctype() == CTSTR
|
|
|
|
|
// *Nilval when Ctype() == CTNIL
|
2016-04-05 14:20:04 -07:00
|
|
|
U interface{}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (v Val) Ctype() Ctype {
|
|
|
|
|
switch x := v.U.(type) {
|
|
|
|
|
default:
|
|
|
|
|
Fatalf("unexpected Ctype for %T", v.U)
|
2018-10-04 16:49:53 -07:00
|
|
|
panic("unreachable")
|
2016-04-05 14:20:04 -07:00
|
|
|
case nil:
|
|
|
|
|
return 0
|
|
|
|
|
case *NilVal:
|
|
|
|
|
return CTNIL
|
|
|
|
|
case bool:
|
|
|
|
|
return CTBOOL
|
|
|
|
|
case *Mpint:
|
|
|
|
|
if x.Rune {
|
|
|
|
|
return CTRUNE
|
|
|
|
|
}
|
|
|
|
|
return CTINT
|
|
|
|
|
case *Mpflt:
|
|
|
|
|
return CTFLT
|
|
|
|
|
case *Mpcplx:
|
|
|
|
|
return CTCPLX
|
|
|
|
|
case string:
|
|
|
|
|
return CTSTR
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2016-06-01 10:58:30 -07:00
|
|
|
func eqval(a, b Val) bool {
|
|
|
|
|
if a.Ctype() != b.Ctype() {
|
|
|
|
|
return false
|
|
|
|
|
}
|
|
|
|
|
switch x := a.U.(type) {
|
|
|
|
|
default:
|
|
|
|
|
Fatalf("unexpected Ctype for %T", a.U)
|
2018-10-04 16:49:53 -07:00
|
|
|
panic("unreachable")
|
2016-06-01 10:58:30 -07:00
|
|
|
case *NilVal:
|
|
|
|
|
return true
|
|
|
|
|
case bool:
|
|
|
|
|
y := b.U.(bool)
|
|
|
|
|
return x == y
|
|
|
|
|
case *Mpint:
|
|
|
|
|
y := b.U.(*Mpint)
|
|
|
|
|
return x.Cmp(y) == 0
|
|
|
|
|
case *Mpflt:
|
|
|
|
|
y := b.U.(*Mpflt)
|
|
|
|
|
return x.Cmp(y) == 0
|
|
|
|
|
case *Mpcplx:
|
|
|
|
|
y := b.U.(*Mpcplx)
|
|
|
|
|
return x.Real.Cmp(&y.Real) == 0 && x.Imag.Cmp(&y.Imag) == 0
|
|
|
|
|
case string:
|
|
|
|
|
y := b.U.(string)
|
|
|
|
|
return x == y
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2016-06-05 17:28:28 -07:00
|
|
|
// Interface returns the constant value stored in v as an interface{}.
|
|
|
|
|
// It returns int64s for ints and runes, float64s for floats,
|
|
|
|
|
// complex128s for complex values, and nil for constant nils.
|
|
|
|
|
func (v Val) Interface() interface{} {
|
|
|
|
|
switch x := v.U.(type) {
|
|
|
|
|
default:
|
|
|
|
|
Fatalf("unexpected Interface for %T", v.U)
|
2018-10-04 16:49:53 -07:00
|
|
|
panic("unreachable")
|
2016-06-05 17:28:28 -07:00
|
|
|
case *NilVal:
|
|
|
|
|
return nil
|
|
|
|
|
case bool, string:
|
|
|
|
|
return x
|
|
|
|
|
case *Mpint:
|
|
|
|
|
return x.Int64()
|
|
|
|
|
case *Mpflt:
|
|
|
|
|
return x.Float64()
|
|
|
|
|
case *Mpcplx:
|
|
|
|
|
return complex(x.Real.Float64(), x.Imag.Float64())
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2016-04-05 14:20:04 -07:00
|
|
|
type NilVal struct{}
|
|
|
|
|
|
2016-04-01 14:51:02 -07:00
|
|
|
// Int64 returns n as an int64.
|
|
|
|
|
// n must be an integer or rune constant.
|
|
|
|
|
func (n *Node) Int64() int64 {
|
2015-04-22 20:08:03 -07:00
|
|
|
if !Isconst(n, CTINT) {
|
2017-02-26 15:25:57 -08:00
|
|
|
Fatalf("Int64(%v)", n)
|
2015-04-22 20:08:03 -07:00
|
|
|
}
|
2016-03-20 13:55:42 -07:00
|
|
|
return n.Val().U.(*Mpint).Int64()
|
2015-04-22 20:08:03 -07:00
|
|
|
}
|
|
|
|
|
|
2018-08-22 14:01:22 +02:00
|
|
|
// CanInt64 reports whether it is safe to call Int64() on n.
|
|
|
|
|
func (n *Node) CanInt64() bool {
|
|
|
|
|
if !Isconst(n, CTINT) {
|
|
|
|
|
return false
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// if the value inside n cannot be represented as an int64, the
|
|
|
|
|
// return value of Int64 is undefined
|
|
|
|
|
return n.Val().U.(*Mpint).CmpInt64(n.Int64()) == 0
|
|
|
|
|
}
|
|
|
|
|
|
2017-02-26 15:25:57 -08:00
|
|
|
// Bool returns n as a bool.
|
|
|
|
|
// n must be a boolean constant.
|
|
|
|
|
func (n *Node) Bool() bool {
|
|
|
|
|
if !Isconst(n, CTBOOL) {
|
|
|
|
|
Fatalf("Bool(%v)", n)
|
|
|
|
|
}
|
|
|
|
|
return n.Val().U.(bool)
|
|
|
|
|
}
|
|
|
|
|
|
2015-10-22 09:51:12 +09:00
|
|
|
// truncate float literal fv to 32-bit or 64-bit precision
|
|
|
|
|
// according to type; return truncated value.
|
cmd/compile: factor out Pkg, Sym, and Type into package types
- created new package cmd/compile/internal/types
- moved Pkg, Sym, Type to new package
- to break cycles, for now we need the (ugly) types/utils.go
file which contains a handful of functions that must be installed
early by the gc frontend
- to break cycles, for now we need two functions to convert between
*gc.Node and *types.Node (the latter is a dummy type)
- adjusted the gc's code to use the new package and the conversion
functions as needed
- made several Pkg, Sym, and Type methods functions as needed
- renamed constructors typ, typPtr, typArray, etc. to types.New,
types.NewPtr, types.NewArray, etc.
Passes toolstash-check -all.
Change-Id: I8adfa5e85c731645d0a7fd2030375ed6ebf54b72
Reviewed-on: https://go-review.googlesource.com/39855
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2017-04-04 17:54:02 -07:00
|
|
|
func truncfltlit(oldv *Mpflt, t *types.Type) *Mpflt {
|
2015-02-13 14:40:36 -05:00
|
|
|
if t == nil {
|
|
|
|
|
return oldv
|
|
|
|
|
}
|
|
|
|
|
|
2017-04-12 20:57:13 +02:00
|
|
|
if overflow(Val{oldv}, t) {
|
|
|
|
|
// If there was overflow, simply continuing would set the
|
|
|
|
|
// value to Inf which in turn would lead to spurious follow-on
|
|
|
|
|
// errors. Avoid this by returning the existing value.
|
|
|
|
|
return oldv
|
|
|
|
|
}
|
2015-02-13 14:40:36 -05:00
|
|
|
|
2015-03-20 16:59:08 -07:00
|
|
|
fv := newMpflt()
|
2015-02-13 14:40:36 -05:00
|
|
|
|
|
|
|
|
// convert large precision literal floating
|
|
|
|
|
// into limited precision (float64 or float32)
|
|
|
|
|
switch t.Etype {
|
2017-04-12 20:57:13 +02:00
|
|
|
case types.TFLOAT32:
|
|
|
|
|
fv.SetFloat64(oldv.Float32())
|
cmd/compile: factor out Pkg, Sym, and Type into package types
- created new package cmd/compile/internal/types
- moved Pkg, Sym, Type to new package
- to break cycles, for now we need the (ugly) types/utils.go
file which contains a handful of functions that must be installed
early by the gc frontend
- to break cycles, for now we need two functions to convert between
*gc.Node and *types.Node (the latter is a dummy type)
- adjusted the gc's code to use the new package and the conversion
functions as needed
- made several Pkg, Sym, and Type methods functions as needed
- renamed constructors typ, typPtr, typArray, etc. to types.New,
types.NewPtr, types.NewArray, etc.
Passes toolstash-check -all.
Change-Id: I8adfa5e85c731645d0a7fd2030375ed6ebf54b72
Reviewed-on: https://go-review.googlesource.com/39855
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2017-04-04 17:54:02 -07:00
|
|
|
case types.TFLOAT64:
|
2017-04-12 20:57:13 +02:00
|
|
|
fv.SetFloat64(oldv.Float64())
|
|
|
|
|
default:
|
|
|
|
|
Fatalf("truncfltlit: unexpected Etype %v", t.Etype)
|
2015-02-13 14:40:36 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return fv
|
|
|
|
|
}
|
|
|
|
|
|
2017-03-07 11:54:29 +01:00
|
|
|
// truncate Real and Imag parts of Mpcplx to 32-bit or 64-bit
|
|
|
|
|
// precision, according to type; return truncated value. In case of
|
|
|
|
|
// overflow, calls yyerror but does not truncate the input value.
|
|
|
|
|
func trunccmplxlit(oldv *Mpcplx, t *types.Type) *Mpcplx {
|
|
|
|
|
if t == nil {
|
|
|
|
|
return oldv
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if overflow(Val{oldv}, t) {
|
2017-04-12 20:57:13 +02:00
|
|
|
// If there was overflow, simply continuing would set the
|
|
|
|
|
// value to Inf which in turn would lead to spurious follow-on
|
|
|
|
|
// errors. Avoid this by returning the existing value.
|
2017-03-07 11:54:29 +01:00
|
|
|
return oldv
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
cv := newMpcmplx()
|
|
|
|
|
|
|
|
|
|
switch t.Etype {
|
2017-04-12 20:57:13 +02:00
|
|
|
case types.TCOMPLEX64:
|
2017-03-07 11:54:29 +01:00
|
|
|
cv.Real.SetFloat64(oldv.Real.Float32())
|
|
|
|
|
cv.Imag.SetFloat64(oldv.Imag.Float32())
|
2017-04-12 20:57:13 +02:00
|
|
|
case types.TCOMPLEX128:
|
2017-03-07 11:54:29 +01:00
|
|
|
cv.Real.SetFloat64(oldv.Real.Float64())
|
|
|
|
|
cv.Imag.SetFloat64(oldv.Imag.Float64())
|
|
|
|
|
default:
|
|
|
|
|
Fatalf("trunccplxlit: unexpected Etype %v", t.Etype)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return cv
|
|
|
|
|
}
|
|
|
|
|
|
cmd/compile: rewrite untyped constant conversion logic
This CL detangles the hairy mess that was convlit+defaultlit. In
particular, it makes the following changes:
1. convlit1 now follows the standard typecheck behavior of setting
"n.Type = nil" if there's an error. Notably, this means for a lot of
test cases, we now avoid reporting useless follow-on error messages.
For example, after reporting that "1 << s + 1.0" has an invalid shift,
we no longer also report that it can't be assigned to string.
2. Previously, assignconvfn had some extra logic for trying to
suppress errors from convlit/defaultlit so that it could provide its
own errors with better context information. Instead, this extra
context information is now passed down into convlit1 directly.
3. Relatedly, this CL also removes redundant calls to defaultlit prior
to assignconv. As a consequence, when an expression doesn't make sense
for a particular assignment (e.g., assigning an untyped string to an
integer), the error messages now say "untyped string" instead of just
"string". This is more consistent with go/types behavior.
4. defaultlit2 is now smarter about only trying to convert pairs of
untyped constants when it's likely to succeed. This allows us to
report better error messages for things like 3+"x"; instead of "cannot
convert 3 to string" we now report "mismatched types untyped number
and untyped string".
Passes toolstash-check.
Change-Id: I26822a02dc35855bd0ac774907b1cf5737e91882
Reviewed-on: https://go-review.googlesource.com/c/go/+/187657
Run-TryBot: Matthew Dempsky <mdempsky@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Robert Griesemer <gri@golang.org>
2019-09-05 13:33:06 -07:00
|
|
|
// TODO(mdempsky): Replace these with better APIs.
|
|
|
|
|
func convlit(n *Node, t *types.Type) *Node { return convlit1(n, t, false, nil) }
|
|
|
|
|
func defaultlit(n *Node, t *types.Type) *Node { return convlit1(n, t, false, nil) }
|
|
|
|
|
|
|
|
|
|
// convlit1 converts an untyped expression n to type t. If n already
|
|
|
|
|
// has a type, convlit1 has no effect.
|
|
|
|
|
//
|
|
|
|
|
// For explicit conversions, t must be non-nil, and integer-to-string
|
|
|
|
|
// conversions are allowed.
|
|
|
|
|
//
|
|
|
|
|
// For implicit conversions (e.g., assignments), t may be nil; if so,
|
|
|
|
|
// n is converted to its default type.
|
|
|
|
|
//
|
|
|
|
|
// If there's an error converting n to t, context is used in the error
|
|
|
|
|
// message.
|
|
|
|
|
func convlit1(n *Node, t *types.Type, explicit bool, context func() string) *Node {
|
|
|
|
|
if explicit && t == nil {
|
|
|
|
|
Fatalf("explicit conversion missing type")
|
|
|
|
|
}
|
|
|
|
|
if t != nil && t.IsUntyped() {
|
|
|
|
|
Fatalf("bad conversion to untyped: %v", t)
|
|
|
|
|
}
|
2015-02-13 14:40:36 -05:00
|
|
|
|
cmd/compile: rewrite untyped constant conversion logic
This CL detangles the hairy mess that was convlit+defaultlit. In
particular, it makes the following changes:
1. convlit1 now follows the standard typecheck behavior of setting
"n.Type = nil" if there's an error. Notably, this means for a lot of
test cases, we now avoid reporting useless follow-on error messages.
For example, after reporting that "1 << s + 1.0" has an invalid shift,
we no longer also report that it can't be assigned to string.
2. Previously, assignconvfn had some extra logic for trying to
suppress errors from convlit/defaultlit so that it could provide its
own errors with better context information. Instead, this extra
context information is now passed down into convlit1 directly.
3. Relatedly, this CL also removes redundant calls to defaultlit prior
to assignconv. As a consequence, when an expression doesn't make sense
for a particular assignment (e.g., assigning an untyped string to an
integer), the error messages now say "untyped string" instead of just
"string". This is more consistent with go/types behavior.
4. defaultlit2 is now smarter about only trying to convert pairs of
untyped constants when it's likely to succeed. This allows us to
report better error messages for things like 3+"x"; instead of "cannot
convert 3 to string" we now report "mismatched types untyped number
and untyped string".
Passes toolstash-check.
Change-Id: I26822a02dc35855bd0ac774907b1cf5737e91882
Reviewed-on: https://go-review.googlesource.com/c/go/+/187657
Run-TryBot: Matthew Dempsky <mdempsky@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Robert Griesemer <gri@golang.org>
2019-09-05 13:33:06 -07:00
|
|
|
if n == nil || n.Type == nil {
|
|
|
|
|
// Allow sloppy callers.
|
cmd/compile: reduce use of **Node parameters
Escape analysis has a hard time with tree-like
structures (see #13493 and #14858).
This is unlikely to change.
As a result, when invoking a function that accepts
a **Node parameter, we usually allocate a *Node
on the heap. This happens a whole lot.
This CL changes functions from taking a **Node
to acting more like append: It both modifies
the input and returns a replacement for it.
Because of the cascading nature of escape analysis,
in order to get the benefits, I had to modify
almost all such functions. The remaining functions
are in racewalk and the backend. I would be happy
to update them as well in a separate CL.
This CL was created by manually updating the
function signatures and the directly impacted
bits of code. The callsites were then automatically
updated using a bespoke script:
https://gist.github.com/josharian/046b1be7aceae244de39
For ease of reviewing and future understanding,
this CL is also broken down into four CLs,
mailed separately, which show the manual
and the automated changes separately.
They are CLs 20990, 20991, 20992, and 20993.
Passes toolstash -cmp.
name old time/op new time/op delta
Template 335ms ± 5% 324ms ± 5% -3.35% (p=0.000 n=23+24)
Unicode 176ms ± 9% 165ms ± 6% -6.12% (p=0.000 n=23+24)
GoTypes 1.10s ± 4% 1.07s ± 2% -2.77% (p=0.000 n=24+24)
Compiler 5.31s ± 3% 5.15s ± 3% -2.95% (p=0.000 n=24+24)
MakeBash 41.6s ± 1% 41.7s ± 2% ~ (p=0.586 n=23+23)
name old alloc/op new alloc/op delta
Template 63.3MB ± 0% 62.4MB ± 0% -1.36% (p=0.000 n=25+23)
Unicode 42.4MB ± 0% 41.6MB ± 0% -1.99% (p=0.000 n=24+25)
GoTypes 220MB ± 0% 217MB ± 0% -1.11% (p=0.000 n=25+25)
Compiler 994MB ± 0% 973MB ± 0% -2.08% (p=0.000 n=24+25)
name old allocs/op new allocs/op delta
Template 681k ± 0% 574k ± 0% -15.71% (p=0.000 n=24+25)
Unicode 518k ± 0% 413k ± 0% -20.34% (p=0.000 n=25+24)
GoTypes 2.08M ± 0% 1.78M ± 0% -14.62% (p=0.000 n=25+25)
Compiler 9.26M ± 0% 7.64M ± 0% -17.48% (p=0.000 n=25+25)
name old text-bytes new text-bytes delta
HelloSize 578k ± 0% 578k ± 0% ~ (all samples are equal)
CmdGoSize 6.46M ± 0% 6.46M ± 0% ~ (all samples are equal)
name old data-bytes new data-bytes delta
HelloSize 128k ± 0% 128k ± 0% ~ (all samples are equal)
CmdGoSize 281k ± 0% 281k ± 0% ~ (all samples are equal)
name old exe-bytes new exe-bytes delta
HelloSize 921k ± 0% 921k ± 0% ~ (all samples are equal)
CmdGoSize 9.86M ± 0% 9.86M ± 0% ~ (all samples are equal)
Change-Id: I277d95bd56d51c166ef7f560647aeaa092f3f475
Reviewed-on: https://go-review.googlesource.com/20959
Reviewed-by: Dave Cheney <dave@cheney.net>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
2016-03-20 08:03:31 -07:00
|
|
|
return n
|
2015-02-13 14:40:36 -05:00
|
|
|
}
|
cmd/compile: rewrite untyped constant conversion logic
This CL detangles the hairy mess that was convlit+defaultlit. In
particular, it makes the following changes:
1. convlit1 now follows the standard typecheck behavior of setting
"n.Type = nil" if there's an error. Notably, this means for a lot of
test cases, we now avoid reporting useless follow-on error messages.
For example, after reporting that "1 << s + 1.0" has an invalid shift,
we no longer also report that it can't be assigned to string.
2. Previously, assignconvfn had some extra logic for trying to
suppress errors from convlit/defaultlit so that it could provide its
own errors with better context information. Instead, this extra
context information is now passed down into convlit1 directly.
3. Relatedly, this CL also removes redundant calls to defaultlit prior
to assignconv. As a consequence, when an expression doesn't make sense
for a particular assignment (e.g., assigning an untyped string to an
integer), the error messages now say "untyped string" instead of just
"string". This is more consistent with go/types behavior.
4. defaultlit2 is now smarter about only trying to convert pairs of
untyped constants when it's likely to succeed. This allows us to
report better error messages for things like 3+"x"; instead of "cannot
convert 3 to string" we now report "mismatched types untyped number
and untyped string".
Passes toolstash-check.
Change-Id: I26822a02dc35855bd0ac774907b1cf5737e91882
Reviewed-on: https://go-review.googlesource.com/c/go/+/187657
Run-TryBot: Matthew Dempsky <mdempsky@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Robert Griesemer <gri@golang.org>
2019-09-05 13:33:06 -07:00
|
|
|
if !n.Type.IsUntyped() {
|
|
|
|
|
// Already typed; nothing to do.
|
cmd/compile: reduce use of **Node parameters
Escape analysis has a hard time with tree-like
structures (see #13493 and #14858).
This is unlikely to change.
As a result, when invoking a function that accepts
a **Node parameter, we usually allocate a *Node
on the heap. This happens a whole lot.
This CL changes functions from taking a **Node
to acting more like append: It both modifies
the input and returns a replacement for it.
Because of the cascading nature of escape analysis,
in order to get the benefits, I had to modify
almost all such functions. The remaining functions
are in racewalk and the backend. I would be happy
to update them as well in a separate CL.
This CL was created by manually updating the
function signatures and the directly impacted
bits of code. The callsites were then automatically
updated using a bespoke script:
https://gist.github.com/josharian/046b1be7aceae244de39
For ease of reviewing and future understanding,
this CL is also broken down into four CLs,
mailed separately, which show the manual
and the automated changes separately.
They are CLs 20990, 20991, 20992, and 20993.
Passes toolstash -cmp.
name old time/op new time/op delta
Template 335ms ± 5% 324ms ± 5% -3.35% (p=0.000 n=23+24)
Unicode 176ms ± 9% 165ms ± 6% -6.12% (p=0.000 n=23+24)
GoTypes 1.10s ± 4% 1.07s ± 2% -2.77% (p=0.000 n=24+24)
Compiler 5.31s ± 3% 5.15s ± 3% -2.95% (p=0.000 n=24+24)
MakeBash 41.6s ± 1% 41.7s ± 2% ~ (p=0.586 n=23+23)
name old alloc/op new alloc/op delta
Template 63.3MB ± 0% 62.4MB ± 0% -1.36% (p=0.000 n=25+23)
Unicode 42.4MB ± 0% 41.6MB ± 0% -1.99% (p=0.000 n=24+25)
GoTypes 220MB ± 0% 217MB ± 0% -1.11% (p=0.000 n=25+25)
Compiler 994MB ± 0% 973MB ± 0% -2.08% (p=0.000 n=24+25)
name old allocs/op new allocs/op delta
Template 681k ± 0% 574k ± 0% -15.71% (p=0.000 n=24+25)
Unicode 518k ± 0% 413k ± 0% -20.34% (p=0.000 n=25+24)
GoTypes 2.08M ± 0% 1.78M ± 0% -14.62% (p=0.000 n=25+25)
Compiler 9.26M ± 0% 7.64M ± 0% -17.48% (p=0.000 n=25+25)
name old text-bytes new text-bytes delta
HelloSize 578k ± 0% 578k ± 0% ~ (all samples are equal)
CmdGoSize 6.46M ± 0% 6.46M ± 0% ~ (all samples are equal)
name old data-bytes new data-bytes delta
HelloSize 128k ± 0% 128k ± 0% ~ (all samples are equal)
CmdGoSize 281k ± 0% 281k ± 0% ~ (all samples are equal)
name old exe-bytes new exe-bytes delta
HelloSize 921k ± 0% 921k ± 0% ~ (all samples are equal)
CmdGoSize 9.86M ± 0% 9.86M ± 0% ~ (all samples are equal)
Change-Id: I277d95bd56d51c166ef7f560647aeaa092f3f475
Reviewed-on: https://go-review.googlesource.com/20959
Reviewed-by: Dave Cheney <dave@cheney.net>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
2016-03-20 08:03:31 -07:00
|
|
|
return n
|
2015-02-13 14:40:36 -05:00
|
|
|
}
|
|
|
|
|
|
cmd/compile: rewrite untyped constant conversion logic
This CL detangles the hairy mess that was convlit+defaultlit. In
particular, it makes the following changes:
1. convlit1 now follows the standard typecheck behavior of setting
"n.Type = nil" if there's an error. Notably, this means for a lot of
test cases, we now avoid reporting useless follow-on error messages.
For example, after reporting that "1 << s + 1.0" has an invalid shift,
we no longer also report that it can't be assigned to string.
2. Previously, assignconvfn had some extra logic for trying to
suppress errors from convlit/defaultlit so that it could provide its
own errors with better context information. Instead, this extra
context information is now passed down into convlit1 directly.
3. Relatedly, this CL also removes redundant calls to defaultlit prior
to assignconv. As a consequence, when an expression doesn't make sense
for a particular assignment (e.g., assigning an untyped string to an
integer), the error messages now say "untyped string" instead of just
"string". This is more consistent with go/types behavior.
4. defaultlit2 is now smarter about only trying to convert pairs of
untyped constants when it's likely to succeed. This allows us to
report better error messages for things like 3+"x"; instead of "cannot
convert 3 to string" we now report "mismatched types untyped number
and untyped string".
Passes toolstash-check.
Change-Id: I26822a02dc35855bd0ac774907b1cf5737e91882
Reviewed-on: https://go-review.googlesource.com/c/go/+/187657
Run-TryBot: Matthew Dempsky <mdempsky@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Robert Griesemer <gri@golang.org>
2019-09-05 13:33:06 -07:00
|
|
|
if n.Op == OLITERAL {
|
2016-03-17 12:24:11 -07:00
|
|
|
// Can't always set n.Type directly on OLITERAL nodes.
|
|
|
|
|
// See discussion on CL 20813.
|
2018-09-20 15:22:33 -07:00
|
|
|
n = n.rawcopy()
|
2015-02-13 14:40:36 -05:00
|
|
|
}
|
|
|
|
|
|
cmd/compile: rewrite untyped constant conversion logic
This CL detangles the hairy mess that was convlit+defaultlit. In
particular, it makes the following changes:
1. convlit1 now follows the standard typecheck behavior of setting
"n.Type = nil" if there's an error. Notably, this means for a lot of
test cases, we now avoid reporting useless follow-on error messages.
For example, after reporting that "1 << s + 1.0" has an invalid shift,
we no longer also report that it can't be assigned to string.
2. Previously, assignconvfn had some extra logic for trying to
suppress errors from convlit/defaultlit so that it could provide its
own errors with better context information. Instead, this extra
context information is now passed down into convlit1 directly.
3. Relatedly, this CL also removes redundant calls to defaultlit prior
to assignconv. As a consequence, when an expression doesn't make sense
for a particular assignment (e.g., assigning an untyped string to an
integer), the error messages now say "untyped string" instead of just
"string". This is more consistent with go/types behavior.
4. defaultlit2 is now smarter about only trying to convert pairs of
untyped constants when it's likely to succeed. This allows us to
report better error messages for things like 3+"x"; instead of "cannot
convert 3 to string" we now report "mismatched types untyped number
and untyped string".
Passes toolstash-check.
Change-Id: I26822a02dc35855bd0ac774907b1cf5737e91882
Reviewed-on: https://go-review.googlesource.com/c/go/+/187657
Run-TryBot: Matthew Dempsky <mdempsky@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Robert Griesemer <gri@golang.org>
2019-09-05 13:33:06 -07:00
|
|
|
// Nil is technically not a constant, so handle it specially.
|
|
|
|
|
if n.Type.Etype == TNIL {
|
|
|
|
|
if t == nil {
|
|
|
|
|
yyerror("use of untyped nil")
|
|
|
|
|
n.SetDiag(true)
|
|
|
|
|
n.Type = nil
|
|
|
|
|
return n
|
2015-02-13 14:40:36 -05:00
|
|
|
}
|
|
|
|
|
|
cmd/compile: rewrite untyped constant conversion logic
This CL detangles the hairy mess that was convlit+defaultlit. In
particular, it makes the following changes:
1. convlit1 now follows the standard typecheck behavior of setting
"n.Type = nil" if there's an error. Notably, this means for a lot of
test cases, we now avoid reporting useless follow-on error messages.
For example, after reporting that "1 << s + 1.0" has an invalid shift,
we no longer also report that it can't be assigned to string.
2. Previously, assignconvfn had some extra logic for trying to
suppress errors from convlit/defaultlit so that it could provide its
own errors with better context information. Instead, this extra
context information is now passed down into convlit1 directly.
3. Relatedly, this CL also removes redundant calls to defaultlit prior
to assignconv. As a consequence, when an expression doesn't make sense
for a particular assignment (e.g., assigning an untyped string to an
integer), the error messages now say "untyped string" instead of just
"string". This is more consistent with go/types behavior.
4. defaultlit2 is now smarter about only trying to convert pairs of
untyped constants when it's likely to succeed. This allows us to
report better error messages for things like 3+"x"; instead of "cannot
convert 3 to string" we now report "mismatched types untyped number
and untyped string".
Passes toolstash-check.
Change-Id: I26822a02dc35855bd0ac774907b1cf5737e91882
Reviewed-on: https://go-review.googlesource.com/c/go/+/187657
Run-TryBot: Matthew Dempsky <mdempsky@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Robert Griesemer <gri@golang.org>
2019-09-05 13:33:06 -07:00
|
|
|
if !t.HasNil() {
|
|
|
|
|
// Leave for caller to handle.
|
|
|
|
|
return n
|
2015-02-13 14:40:36 -05:00
|
|
|
}
|
|
|
|
|
|
cmd/compile: rewrite untyped constant conversion logic
This CL detangles the hairy mess that was convlit+defaultlit. In
particular, it makes the following changes:
1. convlit1 now follows the standard typecheck behavior of setting
"n.Type = nil" if there's an error. Notably, this means for a lot of
test cases, we now avoid reporting useless follow-on error messages.
For example, after reporting that "1 << s + 1.0" has an invalid shift,
we no longer also report that it can't be assigned to string.
2. Previously, assignconvfn had some extra logic for trying to
suppress errors from convlit/defaultlit so that it could provide its
own errors with better context information. Instead, this extra
context information is now passed down into convlit1 directly.
3. Relatedly, this CL also removes redundant calls to defaultlit prior
to assignconv. As a consequence, when an expression doesn't make sense
for a particular assignment (e.g., assigning an untyped string to an
integer), the error messages now say "untyped string" instead of just
"string". This is more consistent with go/types behavior.
4. defaultlit2 is now smarter about only trying to convert pairs of
untyped constants when it's likely to succeed. This allows us to
report better error messages for things like 3+"x"; instead of "cannot
convert 3 to string" we now report "mismatched types untyped number
and untyped string".
Passes toolstash-check.
Change-Id: I26822a02dc35855bd0ac774907b1cf5737e91882
Reviewed-on: https://go-review.googlesource.com/c/go/+/187657
Run-TryBot: Matthew Dempsky <mdempsky@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Robert Griesemer <gri@golang.org>
2019-09-05 13:33:06 -07:00
|
|
|
n.Type = t
|
cmd/compile: reduce use of **Node parameters
Escape analysis has a hard time with tree-like
structures (see #13493 and #14858).
This is unlikely to change.
As a result, when invoking a function that accepts
a **Node parameter, we usually allocate a *Node
on the heap. This happens a whole lot.
This CL changes functions from taking a **Node
to acting more like append: It both modifies
the input and returns a replacement for it.
Because of the cascading nature of escape analysis,
in order to get the benefits, I had to modify
almost all such functions. The remaining functions
are in racewalk and the backend. I would be happy
to update them as well in a separate CL.
This CL was created by manually updating the
function signatures and the directly impacted
bits of code. The callsites were then automatically
updated using a bespoke script:
https://gist.github.com/josharian/046b1be7aceae244de39
For ease of reviewing and future understanding,
this CL is also broken down into four CLs,
mailed separately, which show the manual
and the automated changes separately.
They are CLs 20990, 20991, 20992, and 20993.
Passes toolstash -cmp.
name old time/op new time/op delta
Template 335ms ± 5% 324ms ± 5% -3.35% (p=0.000 n=23+24)
Unicode 176ms ± 9% 165ms ± 6% -6.12% (p=0.000 n=23+24)
GoTypes 1.10s ± 4% 1.07s ± 2% -2.77% (p=0.000 n=24+24)
Compiler 5.31s ± 3% 5.15s ± 3% -2.95% (p=0.000 n=24+24)
MakeBash 41.6s ± 1% 41.7s ± 2% ~ (p=0.586 n=23+23)
name old alloc/op new alloc/op delta
Template 63.3MB ± 0% 62.4MB ± 0% -1.36% (p=0.000 n=25+23)
Unicode 42.4MB ± 0% 41.6MB ± 0% -1.99% (p=0.000 n=24+25)
GoTypes 220MB ± 0% 217MB ± 0% -1.11% (p=0.000 n=25+25)
Compiler 994MB ± 0% 973MB ± 0% -2.08% (p=0.000 n=24+25)
name old allocs/op new allocs/op delta
Template 681k ± 0% 574k ± 0% -15.71% (p=0.000 n=24+25)
Unicode 518k ± 0% 413k ± 0% -20.34% (p=0.000 n=25+24)
GoTypes 2.08M ± 0% 1.78M ± 0% -14.62% (p=0.000 n=25+25)
Compiler 9.26M ± 0% 7.64M ± 0% -17.48% (p=0.000 n=25+25)
name old text-bytes new text-bytes delta
HelloSize 578k ± 0% 578k ± 0% ~ (all samples are equal)
CmdGoSize 6.46M ± 0% 6.46M ± 0% ~ (all samples are equal)
name old data-bytes new data-bytes delta
HelloSize 128k ± 0% 128k ± 0% ~ (all samples are equal)
CmdGoSize 281k ± 0% 281k ± 0% ~ (all samples are equal)
name old exe-bytes new exe-bytes delta
HelloSize 921k ± 0% 921k ± 0% ~ (all samples are equal)
CmdGoSize 9.86M ± 0% 9.86M ± 0% ~ (all samples are equal)
Change-Id: I277d95bd56d51c166ef7f560647aeaa092f3f475
Reviewed-on: https://go-review.googlesource.com/20959
Reviewed-by: Dave Cheney <dave@cheney.net>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
2016-03-20 08:03:31 -07:00
|
|
|
return n
|
cmd/compile: rewrite untyped constant conversion logic
This CL detangles the hairy mess that was convlit+defaultlit. In
particular, it makes the following changes:
1. convlit1 now follows the standard typecheck behavior of setting
"n.Type = nil" if there's an error. Notably, this means for a lot of
test cases, we now avoid reporting useless follow-on error messages.
For example, after reporting that "1 << s + 1.0" has an invalid shift,
we no longer also report that it can't be assigned to string.
2. Previously, assignconvfn had some extra logic for trying to
suppress errors from convlit/defaultlit so that it could provide its
own errors with better context information. Instead, this extra
context information is now passed down into convlit1 directly.
3. Relatedly, this CL also removes redundant calls to defaultlit prior
to assignconv. As a consequence, when an expression doesn't make sense
for a particular assignment (e.g., assigning an untyped string to an
integer), the error messages now say "untyped string" instead of just
"string". This is more consistent with go/types behavior.
4. defaultlit2 is now smarter about only trying to convert pairs of
untyped constants when it's likely to succeed. This allows us to
report better error messages for things like 3+"x"; instead of "cannot
convert 3 to string" we now report "mismatched types untyped number
and untyped string".
Passes toolstash-check.
Change-Id: I26822a02dc35855bd0ac774907b1cf5737e91882
Reviewed-on: https://go-review.googlesource.com/c/go/+/187657
Run-TryBot: Matthew Dempsky <mdempsky@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Robert Griesemer <gri@golang.org>
2019-09-05 13:33:06 -07:00
|
|
|
}
|
2015-02-13 14:40:36 -05:00
|
|
|
|
cmd/compile: rewrite untyped constant conversion logic
This CL detangles the hairy mess that was convlit+defaultlit. In
particular, it makes the following changes:
1. convlit1 now follows the standard typecheck behavior of setting
"n.Type = nil" if there's an error. Notably, this means for a lot of
test cases, we now avoid reporting useless follow-on error messages.
For example, after reporting that "1 << s + 1.0" has an invalid shift,
we no longer also report that it can't be assigned to string.
2. Previously, assignconvfn had some extra logic for trying to
suppress errors from convlit/defaultlit so that it could provide its
own errors with better context information. Instead, this extra
context information is now passed down into convlit1 directly.
3. Relatedly, this CL also removes redundant calls to defaultlit prior
to assignconv. As a consequence, when an expression doesn't make sense
for a particular assignment (e.g., assigning an untyped string to an
integer), the error messages now say "untyped string" instead of just
"string". This is more consistent with go/types behavior.
4. defaultlit2 is now smarter about only trying to convert pairs of
untyped constants when it's likely to succeed. This allows us to
report better error messages for things like 3+"x"; instead of "cannot
convert 3 to string" we now report "mismatched types untyped number
and untyped string".
Passes toolstash-check.
Change-Id: I26822a02dc35855bd0ac774907b1cf5737e91882
Reviewed-on: https://go-review.googlesource.com/c/go/+/187657
Run-TryBot: Matthew Dempsky <mdempsky@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Robert Griesemer <gri@golang.org>
2019-09-05 13:33:06 -07:00
|
|
|
if t == nil || !okforconst[t.Etype] {
|
|
|
|
|
t = defaultType(idealkind(n))
|
|
|
|
|
}
|
2015-02-13 14:40:36 -05:00
|
|
|
|
cmd/compile: rewrite untyped constant conversion logic
This CL detangles the hairy mess that was convlit+defaultlit. In
particular, it makes the following changes:
1. convlit1 now follows the standard typecheck behavior of setting
"n.Type = nil" if there's an error. Notably, this means for a lot of
test cases, we now avoid reporting useless follow-on error messages.
For example, after reporting that "1 << s + 1.0" has an invalid shift,
we no longer also report that it can't be assigned to string.
2. Previously, assignconvfn had some extra logic for trying to
suppress errors from convlit/defaultlit so that it could provide its
own errors with better context information. Instead, this extra
context information is now passed down into convlit1 directly.
3. Relatedly, this CL also removes redundant calls to defaultlit prior
to assignconv. As a consequence, when an expression doesn't make sense
for a particular assignment (e.g., assigning an untyped string to an
integer), the error messages now say "untyped string" instead of just
"string". This is more consistent with go/types behavior.
4. defaultlit2 is now smarter about only trying to convert pairs of
untyped constants when it's likely to succeed. This allows us to
report better error messages for things like 3+"x"; instead of "cannot
convert 3 to string" we now report "mismatched types untyped number
and untyped string".
Passes toolstash-check.
Change-Id: I26822a02dc35855bd0ac774907b1cf5737e91882
Reviewed-on: https://go-review.googlesource.com/c/go/+/187657
Run-TryBot: Matthew Dempsky <mdempsky@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Robert Griesemer <gri@golang.org>
2019-09-05 13:33:06 -07:00
|
|
|
switch n.Op {
|
|
|
|
|
default:
|
|
|
|
|
Fatalf("unexpected untyped expression: %v", n)
|
2015-02-13 14:40:36 -05:00
|
|
|
|
cmd/compile: rewrite untyped constant conversion logic
This CL detangles the hairy mess that was convlit+defaultlit. In
particular, it makes the following changes:
1. convlit1 now follows the standard typecheck behavior of setting
"n.Type = nil" if there's an error. Notably, this means for a lot of
test cases, we now avoid reporting useless follow-on error messages.
For example, after reporting that "1 << s + 1.0" has an invalid shift,
we no longer also report that it can't be assigned to string.
2. Previously, assignconvfn had some extra logic for trying to
suppress errors from convlit/defaultlit so that it could provide its
own errors with better context information. Instead, this extra
context information is now passed down into convlit1 directly.
3. Relatedly, this CL also removes redundant calls to defaultlit prior
to assignconv. As a consequence, when an expression doesn't make sense
for a particular assignment (e.g., assigning an untyped string to an
integer), the error messages now say "untyped string" instead of just
"string". This is more consistent with go/types behavior.
4. defaultlit2 is now smarter about only trying to convert pairs of
untyped constants when it's likely to succeed. This allows us to
report better error messages for things like 3+"x"; instead of "cannot
convert 3 to string" we now report "mismatched types untyped number
and untyped string".
Passes toolstash-check.
Change-Id: I26822a02dc35855bd0ac774907b1cf5737e91882
Reviewed-on: https://go-review.googlesource.com/c/go/+/187657
Run-TryBot: Matthew Dempsky <mdempsky@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Robert Griesemer <gri@golang.org>
2019-09-05 13:33:06 -07:00
|
|
|
case OLITERAL:
|
|
|
|
|
v := convertVal(n.Val(), t, explicit)
|
|
|
|
|
if v.U == nil {
|
|
|
|
|
break
|
|
|
|
|
}
|
|
|
|
|
n.SetVal(v)
|
2015-02-13 14:40:36 -05:00
|
|
|
n.Type = t
|
cmd/compile: reduce use of **Node parameters
Escape analysis has a hard time with tree-like
structures (see #13493 and #14858).
This is unlikely to change.
As a result, when invoking a function that accepts
a **Node parameter, we usually allocate a *Node
on the heap. This happens a whole lot.
This CL changes functions from taking a **Node
to acting more like append: It both modifies
the input and returns a replacement for it.
Because of the cascading nature of escape analysis,
in order to get the benefits, I had to modify
almost all such functions. The remaining functions
are in racewalk and the backend. I would be happy
to update them as well in a separate CL.
This CL was created by manually updating the
function signatures and the directly impacted
bits of code. The callsites were then automatically
updated using a bespoke script:
https://gist.github.com/josharian/046b1be7aceae244de39
For ease of reviewing and future understanding,
this CL is also broken down into four CLs,
mailed separately, which show the manual
and the automated changes separately.
They are CLs 20990, 20991, 20992, and 20993.
Passes toolstash -cmp.
name old time/op new time/op delta
Template 335ms ± 5% 324ms ± 5% -3.35% (p=0.000 n=23+24)
Unicode 176ms ± 9% 165ms ± 6% -6.12% (p=0.000 n=23+24)
GoTypes 1.10s ± 4% 1.07s ± 2% -2.77% (p=0.000 n=24+24)
Compiler 5.31s ± 3% 5.15s ± 3% -2.95% (p=0.000 n=24+24)
MakeBash 41.6s ± 1% 41.7s ± 2% ~ (p=0.586 n=23+23)
name old alloc/op new alloc/op delta
Template 63.3MB ± 0% 62.4MB ± 0% -1.36% (p=0.000 n=25+23)
Unicode 42.4MB ± 0% 41.6MB ± 0% -1.99% (p=0.000 n=24+25)
GoTypes 220MB ± 0% 217MB ± 0% -1.11% (p=0.000 n=25+25)
Compiler 994MB ± 0% 973MB ± 0% -2.08% (p=0.000 n=24+25)
name old allocs/op new allocs/op delta
Template 681k ± 0% 574k ± 0% -15.71% (p=0.000 n=24+25)
Unicode 518k ± 0% 413k ± 0% -20.34% (p=0.000 n=25+24)
GoTypes 2.08M ± 0% 1.78M ± 0% -14.62% (p=0.000 n=25+25)
Compiler 9.26M ± 0% 7.64M ± 0% -17.48% (p=0.000 n=25+25)
name old text-bytes new text-bytes delta
HelloSize 578k ± 0% 578k ± 0% ~ (all samples are equal)
CmdGoSize 6.46M ± 0% 6.46M ± 0% ~ (all samples are equal)
name old data-bytes new data-bytes delta
HelloSize 128k ± 0% 128k ± 0% ~ (all samples are equal)
CmdGoSize 281k ± 0% 281k ± 0% ~ (all samples are equal)
name old exe-bytes new exe-bytes delta
HelloSize 921k ± 0% 921k ± 0% ~ (all samples are equal)
CmdGoSize 9.86M ± 0% 9.86M ± 0% ~ (all samples are equal)
Change-Id: I277d95bd56d51c166ef7f560647aeaa092f3f475
Reviewed-on: https://go-review.googlesource.com/20959
Reviewed-by: Dave Cheney <dave@cheney.net>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
2016-03-20 08:03:31 -07:00
|
|
|
return n
|
2015-02-13 14:40:36 -05:00
|
|
|
|
cmd/compile: rewrite untyped constant conversion logic
This CL detangles the hairy mess that was convlit+defaultlit. In
particular, it makes the following changes:
1. convlit1 now follows the standard typecheck behavior of setting
"n.Type = nil" if there's an error. Notably, this means for a lot of
test cases, we now avoid reporting useless follow-on error messages.
For example, after reporting that "1 << s + 1.0" has an invalid shift,
we no longer also report that it can't be assigned to string.
2. Previously, assignconvfn had some extra logic for trying to
suppress errors from convlit/defaultlit so that it could provide its
own errors with better context information. Instead, this extra
context information is now passed down into convlit1 directly.
3. Relatedly, this CL also removes redundant calls to defaultlit prior
to assignconv. As a consequence, when an expression doesn't make sense
for a particular assignment (e.g., assigning an untyped string to an
integer), the error messages now say "untyped string" instead of just
"string". This is more consistent with go/types behavior.
4. defaultlit2 is now smarter about only trying to convert pairs of
untyped constants when it's likely to succeed. This allows us to
report better error messages for things like 3+"x"; instead of "cannot
convert 3 to string" we now report "mismatched types untyped number
and untyped string".
Passes toolstash-check.
Change-Id: I26822a02dc35855bd0ac774907b1cf5737e91882
Reviewed-on: https://go-review.googlesource.com/c/go/+/187657
Run-TryBot: Matthew Dempsky <mdempsky@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Robert Griesemer <gri@golang.org>
2019-09-05 13:33:06 -07:00
|
|
|
case OPLUS, ONEG, OBITNOT, ONOT, OREAL, OIMAG:
|
|
|
|
|
ot := operandType(n.Op, t)
|
|
|
|
|
if ot == nil {
|
|
|
|
|
n = defaultlit(n, nil)
|
|
|
|
|
break
|
2015-02-13 14:40:36 -05:00
|
|
|
}
|
|
|
|
|
|
cmd/compile: rewrite untyped constant conversion logic
This CL detangles the hairy mess that was convlit+defaultlit. In
particular, it makes the following changes:
1. convlit1 now follows the standard typecheck behavior of setting
"n.Type = nil" if there's an error. Notably, this means for a lot of
test cases, we now avoid reporting useless follow-on error messages.
For example, after reporting that "1 << s + 1.0" has an invalid shift,
we no longer also report that it can't be assigned to string.
2. Previously, assignconvfn had some extra logic for trying to
suppress errors from convlit/defaultlit so that it could provide its
own errors with better context information. Instead, this extra
context information is now passed down into convlit1 directly.
3. Relatedly, this CL also removes redundant calls to defaultlit prior
to assignconv. As a consequence, when an expression doesn't make sense
for a particular assignment (e.g., assigning an untyped string to an
integer), the error messages now say "untyped string" instead of just
"string". This is more consistent with go/types behavior.
4. defaultlit2 is now smarter about only trying to convert pairs of
untyped constants when it's likely to succeed. This allows us to
report better error messages for things like 3+"x"; instead of "cannot
convert 3 to string" we now report "mismatched types untyped number
and untyped string".
Passes toolstash-check.
Change-Id: I26822a02dc35855bd0ac774907b1cf5737e91882
Reviewed-on: https://go-review.googlesource.com/c/go/+/187657
Run-TryBot: Matthew Dempsky <mdempsky@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Robert Griesemer <gri@golang.org>
2019-09-05 13:33:06 -07:00
|
|
|
n.Left = convlit(n.Left, ot)
|
|
|
|
|
if n.Left.Type == nil {
|
|
|
|
|
n.Type = nil
|
|
|
|
|
return n
|
|
|
|
|
}
|
|
|
|
|
n.Type = t
|
cmd/compile: reduce use of **Node parameters
Escape analysis has a hard time with tree-like
structures (see #13493 and #14858).
This is unlikely to change.
As a result, when invoking a function that accepts
a **Node parameter, we usually allocate a *Node
on the heap. This happens a whole lot.
This CL changes functions from taking a **Node
to acting more like append: It both modifies
the input and returns a replacement for it.
Because of the cascading nature of escape analysis,
in order to get the benefits, I had to modify
almost all such functions. The remaining functions
are in racewalk and the backend. I would be happy
to update them as well in a separate CL.
This CL was created by manually updating the
function signatures and the directly impacted
bits of code. The callsites were then automatically
updated using a bespoke script:
https://gist.github.com/josharian/046b1be7aceae244de39
For ease of reviewing and future understanding,
this CL is also broken down into four CLs,
mailed separately, which show the manual
and the automated changes separately.
They are CLs 20990, 20991, 20992, and 20993.
Passes toolstash -cmp.
name old time/op new time/op delta
Template 335ms ± 5% 324ms ± 5% -3.35% (p=0.000 n=23+24)
Unicode 176ms ± 9% 165ms ± 6% -6.12% (p=0.000 n=23+24)
GoTypes 1.10s ± 4% 1.07s ± 2% -2.77% (p=0.000 n=24+24)
Compiler 5.31s ± 3% 5.15s ± 3% -2.95% (p=0.000 n=24+24)
MakeBash 41.6s ± 1% 41.7s ± 2% ~ (p=0.586 n=23+23)
name old alloc/op new alloc/op delta
Template 63.3MB ± 0% 62.4MB ± 0% -1.36% (p=0.000 n=25+23)
Unicode 42.4MB ± 0% 41.6MB ± 0% -1.99% (p=0.000 n=24+25)
GoTypes 220MB ± 0% 217MB ± 0% -1.11% (p=0.000 n=25+25)
Compiler 994MB ± 0% 973MB ± 0% -2.08% (p=0.000 n=24+25)
name old allocs/op new allocs/op delta
Template 681k ± 0% 574k ± 0% -15.71% (p=0.000 n=24+25)
Unicode 518k ± 0% 413k ± 0% -20.34% (p=0.000 n=25+24)
GoTypes 2.08M ± 0% 1.78M ± 0% -14.62% (p=0.000 n=25+25)
Compiler 9.26M ± 0% 7.64M ± 0% -17.48% (p=0.000 n=25+25)
name old text-bytes new text-bytes delta
HelloSize 578k ± 0% 578k ± 0% ~ (all samples are equal)
CmdGoSize 6.46M ± 0% 6.46M ± 0% ~ (all samples are equal)
name old data-bytes new data-bytes delta
HelloSize 128k ± 0% 128k ± 0% ~ (all samples are equal)
CmdGoSize 281k ± 0% 281k ± 0% ~ (all samples are equal)
name old exe-bytes new exe-bytes delta
HelloSize 921k ± 0% 921k ± 0% ~ (all samples are equal)
CmdGoSize 9.86M ± 0% 9.86M ± 0% ~ (all samples are equal)
Change-Id: I277d95bd56d51c166ef7f560647aeaa092f3f475
Reviewed-on: https://go-review.googlesource.com/20959
Reviewed-by: Dave Cheney <dave@cheney.net>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
2016-03-20 08:03:31 -07:00
|
|
|
return n
|
2015-02-13 14:40:36 -05:00
|
|
|
|
cmd/compile: rewrite untyped constant conversion logic
This CL detangles the hairy mess that was convlit+defaultlit. In
particular, it makes the following changes:
1. convlit1 now follows the standard typecheck behavior of setting
"n.Type = nil" if there's an error. Notably, this means for a lot of
test cases, we now avoid reporting useless follow-on error messages.
For example, after reporting that "1 << s + 1.0" has an invalid shift,
we no longer also report that it can't be assigned to string.
2. Previously, assignconvfn had some extra logic for trying to
suppress errors from convlit/defaultlit so that it could provide its
own errors with better context information. Instead, this extra
context information is now passed down into convlit1 directly.
3. Relatedly, this CL also removes redundant calls to defaultlit prior
to assignconv. As a consequence, when an expression doesn't make sense
for a particular assignment (e.g., assigning an untyped string to an
integer), the error messages now say "untyped string" instead of just
"string". This is more consistent with go/types behavior.
4. defaultlit2 is now smarter about only trying to convert pairs of
untyped constants when it's likely to succeed. This allows us to
report better error messages for things like 3+"x"; instead of "cannot
convert 3 to string" we now report "mismatched types untyped number
and untyped string".
Passes toolstash-check.
Change-Id: I26822a02dc35855bd0ac774907b1cf5737e91882
Reviewed-on: https://go-review.googlesource.com/c/go/+/187657
Run-TryBot: Matthew Dempsky <mdempsky@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Robert Griesemer <gri@golang.org>
2019-09-05 13:33:06 -07:00
|
|
|
case OADD, OSUB, OMUL, ODIV, OMOD, OOR, OXOR, OAND, OANDNOT, OOROR, OANDAND, OCOMPLEX:
|
|
|
|
|
ot := operandType(n.Op, t)
|
|
|
|
|
if ot == nil {
|
|
|
|
|
n = defaultlit(n, nil)
|
|
|
|
|
break
|
|
|
|
|
}
|
2015-02-13 14:40:36 -05:00
|
|
|
|
cmd/compile: rewrite untyped constant conversion logic
This CL detangles the hairy mess that was convlit+defaultlit. In
particular, it makes the following changes:
1. convlit1 now follows the standard typecheck behavior of setting
"n.Type = nil" if there's an error. Notably, this means for a lot of
test cases, we now avoid reporting useless follow-on error messages.
For example, after reporting that "1 << s + 1.0" has an invalid shift,
we no longer also report that it can't be assigned to string.
2. Previously, assignconvfn had some extra logic for trying to
suppress errors from convlit/defaultlit so that it could provide its
own errors with better context information. Instead, this extra
context information is now passed down into convlit1 directly.
3. Relatedly, this CL also removes redundant calls to defaultlit prior
to assignconv. As a consequence, when an expression doesn't make sense
for a particular assignment (e.g., assigning an untyped string to an
integer), the error messages now say "untyped string" instead of just
"string". This is more consistent with go/types behavior.
4. defaultlit2 is now smarter about only trying to convert pairs of
untyped constants when it's likely to succeed. This allows us to
report better error messages for things like 3+"x"; instead of "cannot
convert 3 to string" we now report "mismatched types untyped number
and untyped string".
Passes toolstash-check.
Change-Id: I26822a02dc35855bd0ac774907b1cf5737e91882
Reviewed-on: https://go-review.googlesource.com/c/go/+/187657
Run-TryBot: Matthew Dempsky <mdempsky@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Robert Griesemer <gri@golang.org>
2019-09-05 13:33:06 -07:00
|
|
|
n.Left = convlit(n.Left, ot)
|
|
|
|
|
n.Right = convlit(n.Right, ot)
|
|
|
|
|
if n.Left.Type == nil || n.Right.Type == nil {
|
|
|
|
|
n.Type = nil
|
cmd/compile: reduce use of **Node parameters
Escape analysis has a hard time with tree-like
structures (see #13493 and #14858).
This is unlikely to change.
As a result, when invoking a function that accepts
a **Node parameter, we usually allocate a *Node
on the heap. This happens a whole lot.
This CL changes functions from taking a **Node
to acting more like append: It both modifies
the input and returns a replacement for it.
Because of the cascading nature of escape analysis,
in order to get the benefits, I had to modify
almost all such functions. The remaining functions
are in racewalk and the backend. I would be happy
to update them as well in a separate CL.
This CL was created by manually updating the
function signatures and the directly impacted
bits of code. The callsites were then automatically
updated using a bespoke script:
https://gist.github.com/josharian/046b1be7aceae244de39
For ease of reviewing and future understanding,
this CL is also broken down into four CLs,
mailed separately, which show the manual
and the automated changes separately.
They are CLs 20990, 20991, 20992, and 20993.
Passes toolstash -cmp.
name old time/op new time/op delta
Template 335ms ± 5% 324ms ± 5% -3.35% (p=0.000 n=23+24)
Unicode 176ms ± 9% 165ms ± 6% -6.12% (p=0.000 n=23+24)
GoTypes 1.10s ± 4% 1.07s ± 2% -2.77% (p=0.000 n=24+24)
Compiler 5.31s ± 3% 5.15s ± 3% -2.95% (p=0.000 n=24+24)
MakeBash 41.6s ± 1% 41.7s ± 2% ~ (p=0.586 n=23+23)
name old alloc/op new alloc/op delta
Template 63.3MB ± 0% 62.4MB ± 0% -1.36% (p=0.000 n=25+23)
Unicode 42.4MB ± 0% 41.6MB ± 0% -1.99% (p=0.000 n=24+25)
GoTypes 220MB ± 0% 217MB ± 0% -1.11% (p=0.000 n=25+25)
Compiler 994MB ± 0% 973MB ± 0% -2.08% (p=0.000 n=24+25)
name old allocs/op new allocs/op delta
Template 681k ± 0% 574k ± 0% -15.71% (p=0.000 n=24+25)
Unicode 518k ± 0% 413k ± 0% -20.34% (p=0.000 n=25+24)
GoTypes 2.08M ± 0% 1.78M ± 0% -14.62% (p=0.000 n=25+25)
Compiler 9.26M ± 0% 7.64M ± 0% -17.48% (p=0.000 n=25+25)
name old text-bytes new text-bytes delta
HelloSize 578k ± 0% 578k ± 0% ~ (all samples are equal)
CmdGoSize 6.46M ± 0% 6.46M ± 0% ~ (all samples are equal)
name old data-bytes new data-bytes delta
HelloSize 128k ± 0% 128k ± 0% ~ (all samples are equal)
CmdGoSize 281k ± 0% 281k ± 0% ~ (all samples are equal)
name old exe-bytes new exe-bytes delta
HelloSize 921k ± 0% 921k ± 0% ~ (all samples are equal)
CmdGoSize 9.86M ± 0% 9.86M ± 0% ~ (all samples are equal)
Change-Id: I277d95bd56d51c166ef7f560647aeaa092f3f475
Reviewed-on: https://go-review.googlesource.com/20959
Reviewed-by: Dave Cheney <dave@cheney.net>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
2016-03-20 08:03:31 -07:00
|
|
|
return n
|
2015-02-13 14:40:36 -05:00
|
|
|
}
|
cmd/compile: rewrite untyped constant conversion logic
This CL detangles the hairy mess that was convlit+defaultlit. In
particular, it makes the following changes:
1. convlit1 now follows the standard typecheck behavior of setting
"n.Type = nil" if there's an error. Notably, this means for a lot of
test cases, we now avoid reporting useless follow-on error messages.
For example, after reporting that "1 << s + 1.0" has an invalid shift,
we no longer also report that it can't be assigned to string.
2. Previously, assignconvfn had some extra logic for trying to
suppress errors from convlit/defaultlit so that it could provide its
own errors with better context information. Instead, this extra
context information is now passed down into convlit1 directly.
3. Relatedly, this CL also removes redundant calls to defaultlit prior
to assignconv. As a consequence, when an expression doesn't make sense
for a particular assignment (e.g., assigning an untyped string to an
integer), the error messages now say "untyped string" instead of just
"string". This is more consistent with go/types behavior.
4. defaultlit2 is now smarter about only trying to convert pairs of
untyped constants when it's likely to succeed. This allows us to
report better error messages for things like 3+"x"; instead of "cannot
convert 3 to string" we now report "mismatched types untyped number
and untyped string".
Passes toolstash-check.
Change-Id: I26822a02dc35855bd0ac774907b1cf5737e91882
Reviewed-on: https://go-review.googlesource.com/c/go/+/187657
Run-TryBot: Matthew Dempsky <mdempsky@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Robert Griesemer <gri@golang.org>
2019-09-05 13:33:06 -07:00
|
|
|
if !types.Identical(n.Left.Type, n.Right.Type) {
|
|
|
|
|
yyerror("invalid operation: %v (mismatched types %v and %v)", n, n.Left.Type, n.Right.Type)
|
2015-02-13 14:40:36 -05:00
|
|
|
n.Type = nil
|
cmd/compile: reduce use of **Node parameters
Escape analysis has a hard time with tree-like
structures (see #13493 and #14858).
This is unlikely to change.
As a result, when invoking a function that accepts
a **Node parameter, we usually allocate a *Node
on the heap. This happens a whole lot.
This CL changes functions from taking a **Node
to acting more like append: It both modifies
the input and returns a replacement for it.
Because of the cascading nature of escape analysis,
in order to get the benefits, I had to modify
almost all such functions. The remaining functions
are in racewalk and the backend. I would be happy
to update them as well in a separate CL.
This CL was created by manually updating the
function signatures and the directly impacted
bits of code. The callsites were then automatically
updated using a bespoke script:
https://gist.github.com/josharian/046b1be7aceae244de39
For ease of reviewing and future understanding,
this CL is also broken down into four CLs,
mailed separately, which show the manual
and the automated changes separately.
They are CLs 20990, 20991, 20992, and 20993.
Passes toolstash -cmp.
name old time/op new time/op delta
Template 335ms ± 5% 324ms ± 5% -3.35% (p=0.000 n=23+24)
Unicode 176ms ± 9% 165ms ± 6% -6.12% (p=0.000 n=23+24)
GoTypes 1.10s ± 4% 1.07s ± 2% -2.77% (p=0.000 n=24+24)
Compiler 5.31s ± 3% 5.15s ± 3% -2.95% (p=0.000 n=24+24)
MakeBash 41.6s ± 1% 41.7s ± 2% ~ (p=0.586 n=23+23)
name old alloc/op new alloc/op delta
Template 63.3MB ± 0% 62.4MB ± 0% -1.36% (p=0.000 n=25+23)
Unicode 42.4MB ± 0% 41.6MB ± 0% -1.99% (p=0.000 n=24+25)
GoTypes 220MB ± 0% 217MB ± 0% -1.11% (p=0.000 n=25+25)
Compiler 994MB ± 0% 973MB ± 0% -2.08% (p=0.000 n=24+25)
name old allocs/op new allocs/op delta
Template 681k ± 0% 574k ± 0% -15.71% (p=0.000 n=24+25)
Unicode 518k ± 0% 413k ± 0% -20.34% (p=0.000 n=25+24)
GoTypes 2.08M ± 0% 1.78M ± 0% -14.62% (p=0.000 n=25+25)
Compiler 9.26M ± 0% 7.64M ± 0% -17.48% (p=0.000 n=25+25)
name old text-bytes new text-bytes delta
HelloSize 578k ± 0% 578k ± 0% ~ (all samples are equal)
CmdGoSize 6.46M ± 0% 6.46M ± 0% ~ (all samples are equal)
name old data-bytes new data-bytes delta
HelloSize 128k ± 0% 128k ± 0% ~ (all samples are equal)
CmdGoSize 281k ± 0% 281k ± 0% ~ (all samples are equal)
name old exe-bytes new exe-bytes delta
HelloSize 921k ± 0% 921k ± 0% ~ (all samples are equal)
CmdGoSize 9.86M ± 0% 9.86M ± 0% ~ (all samples are equal)
Change-Id: I277d95bd56d51c166ef7f560647aeaa092f3f475
Reviewed-on: https://go-review.googlesource.com/20959
Reviewed-by: Dave Cheney <dave@cheney.net>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
2016-03-20 08:03:31 -07:00
|
|
|
return n
|
cmd/compile: rewrite untyped constant conversion logic
This CL detangles the hairy mess that was convlit+defaultlit. In
particular, it makes the following changes:
1. convlit1 now follows the standard typecheck behavior of setting
"n.Type = nil" if there's an error. Notably, this means for a lot of
test cases, we now avoid reporting useless follow-on error messages.
For example, after reporting that "1 << s + 1.0" has an invalid shift,
we no longer also report that it can't be assigned to string.
2. Previously, assignconvfn had some extra logic for trying to
suppress errors from convlit/defaultlit so that it could provide its
own errors with better context information. Instead, this extra
context information is now passed down into convlit1 directly.
3. Relatedly, this CL also removes redundant calls to defaultlit prior
to assignconv. As a consequence, when an expression doesn't make sense
for a particular assignment (e.g., assigning an untyped string to an
integer), the error messages now say "untyped string" instead of just
"string". This is more consistent with go/types behavior.
4. defaultlit2 is now smarter about only trying to convert pairs of
untyped constants when it's likely to succeed. This allows us to
report better error messages for things like 3+"x"; instead of "cannot
convert 3 to string" we now report "mismatched types untyped number
and untyped string".
Passes toolstash-check.
Change-Id: I26822a02dc35855bd0ac774907b1cf5737e91882
Reviewed-on: https://go-review.googlesource.com/c/go/+/187657
Run-TryBot: Matthew Dempsky <mdempsky@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Robert Griesemer <gri@golang.org>
2019-09-05 13:33:06 -07:00
|
|
|
}
|
2015-02-13 14:40:36 -05:00
|
|
|
|
cmd/compile: rewrite untyped constant conversion logic
This CL detangles the hairy mess that was convlit+defaultlit. In
particular, it makes the following changes:
1. convlit1 now follows the standard typecheck behavior of setting
"n.Type = nil" if there's an error. Notably, this means for a lot of
test cases, we now avoid reporting useless follow-on error messages.
For example, after reporting that "1 << s + 1.0" has an invalid shift,
we no longer also report that it can't be assigned to string.
2. Previously, assignconvfn had some extra logic for trying to
suppress errors from convlit/defaultlit so that it could provide its
own errors with better context information. Instead, this extra
context information is now passed down into convlit1 directly.
3. Relatedly, this CL also removes redundant calls to defaultlit prior
to assignconv. As a consequence, when an expression doesn't make sense
for a particular assignment (e.g., assigning an untyped string to an
integer), the error messages now say "untyped string" instead of just
"string". This is more consistent with go/types behavior.
4. defaultlit2 is now smarter about only trying to convert pairs of
untyped constants when it's likely to succeed. This allows us to
report better error messages for things like 3+"x"; instead of "cannot
convert 3 to string" we now report "mismatched types untyped number
and untyped string".
Passes toolstash-check.
Change-Id: I26822a02dc35855bd0ac774907b1cf5737e91882
Reviewed-on: https://go-review.googlesource.com/c/go/+/187657
Run-TryBot: Matthew Dempsky <mdempsky@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Robert Griesemer <gri@golang.org>
2019-09-05 13:33:06 -07:00
|
|
|
n.Type = t
|
|
|
|
|
return n
|
2015-02-13 14:40:36 -05:00
|
|
|
|
cmd/compile: rewrite untyped constant conversion logic
This CL detangles the hairy mess that was convlit+defaultlit. In
particular, it makes the following changes:
1. convlit1 now follows the standard typecheck behavior of setting
"n.Type = nil" if there's an error. Notably, this means for a lot of
test cases, we now avoid reporting useless follow-on error messages.
For example, after reporting that "1 << s + 1.0" has an invalid shift,
we no longer also report that it can't be assigned to string.
2. Previously, assignconvfn had some extra logic for trying to
suppress errors from convlit/defaultlit so that it could provide its
own errors with better context information. Instead, this extra
context information is now passed down into convlit1 directly.
3. Relatedly, this CL also removes redundant calls to defaultlit prior
to assignconv. As a consequence, when an expression doesn't make sense
for a particular assignment (e.g., assigning an untyped string to an
integer), the error messages now say "untyped string" instead of just
"string". This is more consistent with go/types behavior.
4. defaultlit2 is now smarter about only trying to convert pairs of
untyped constants when it's likely to succeed. This allows us to
report better error messages for things like 3+"x"; instead of "cannot
convert 3 to string" we now report "mismatched types untyped number
and untyped string".
Passes toolstash-check.
Change-Id: I26822a02dc35855bd0ac774907b1cf5737e91882
Reviewed-on: https://go-review.googlesource.com/c/go/+/187657
Run-TryBot: Matthew Dempsky <mdempsky@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Robert Griesemer <gri@golang.org>
2019-09-05 13:33:06 -07:00
|
|
|
case OEQ, ONE, OLT, OLE, OGT, OGE:
|
|
|
|
|
if !t.IsBoolean() {
|
2018-04-07 03:08:46 -07:00
|
|
|
break
|
2015-02-13 14:40:36 -05:00
|
|
|
}
|
cmd/compile: rewrite untyped constant conversion logic
This CL detangles the hairy mess that was convlit+defaultlit. In
particular, it makes the following changes:
1. convlit1 now follows the standard typecheck behavior of setting
"n.Type = nil" if there's an error. Notably, this means for a lot of
test cases, we now avoid reporting useless follow-on error messages.
For example, after reporting that "1 << s + 1.0" has an invalid shift,
we no longer also report that it can't be assigned to string.
2. Previously, assignconvfn had some extra logic for trying to
suppress errors from convlit/defaultlit so that it could provide its
own errors with better context information. Instead, this extra
context information is now passed down into convlit1 directly.
3. Relatedly, this CL also removes redundant calls to defaultlit prior
to assignconv. As a consequence, when an expression doesn't make sense
for a particular assignment (e.g., assigning an untyped string to an
integer), the error messages now say "untyped string" instead of just
"string". This is more consistent with go/types behavior.
4. defaultlit2 is now smarter about only trying to convert pairs of
untyped constants when it's likely to succeed. This allows us to
report better error messages for things like 3+"x"; instead of "cannot
convert 3 to string" we now report "mismatched types untyped number
and untyped string".
Passes toolstash-check.
Change-Id: I26822a02dc35855bd0ac774907b1cf5737e91882
Reviewed-on: https://go-review.googlesource.com/c/go/+/187657
Run-TryBot: Matthew Dempsky <mdempsky@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Robert Griesemer <gri@golang.org>
2019-09-05 13:33:06 -07:00
|
|
|
n.Type = t
|
|
|
|
|
return n
|
2015-02-13 14:40:36 -05:00
|
|
|
|
cmd/compile: rewrite untyped constant conversion logic
This CL detangles the hairy mess that was convlit+defaultlit. In
particular, it makes the following changes:
1. convlit1 now follows the standard typecheck behavior of setting
"n.Type = nil" if there's an error. Notably, this means for a lot of
test cases, we now avoid reporting useless follow-on error messages.
For example, after reporting that "1 << s + 1.0" has an invalid shift,
we no longer also report that it can't be assigned to string.
2. Previously, assignconvfn had some extra logic for trying to
suppress errors from convlit/defaultlit so that it could provide its
own errors with better context information. Instead, this extra
context information is now passed down into convlit1 directly.
3. Relatedly, this CL also removes redundant calls to defaultlit prior
to assignconv. As a consequence, when an expression doesn't make sense
for a particular assignment (e.g., assigning an untyped string to an
integer), the error messages now say "untyped string" instead of just
"string". This is more consistent with go/types behavior.
4. defaultlit2 is now smarter about only trying to convert pairs of
untyped constants when it's likely to succeed. This allows us to
report better error messages for things like 3+"x"; instead of "cannot
convert 3 to string" we now report "mismatched types untyped number
and untyped string".
Passes toolstash-check.
Change-Id: I26822a02dc35855bd0ac774907b1cf5737e91882
Reviewed-on: https://go-review.googlesource.com/c/go/+/187657
Run-TryBot: Matthew Dempsky <mdempsky@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Robert Griesemer <gri@golang.org>
2019-09-05 13:33:06 -07:00
|
|
|
case OLSH, ORSH:
|
|
|
|
|
n.Left = convlit1(n.Left, t, explicit, nil)
|
|
|
|
|
n.Type = n.Left.Type
|
|
|
|
|
if n.Type != nil && !n.Type.IsInteger() {
|
|
|
|
|
yyerror("invalid operation: %v (shift of type %v)", n, n.Type)
|
|
|
|
|
n.Type = nil
|
2015-05-01 19:50:27 -07:00
|
|
|
}
|
cmd/compile: rewrite untyped constant conversion logic
This CL detangles the hairy mess that was convlit+defaultlit. In
particular, it makes the following changes:
1. convlit1 now follows the standard typecheck behavior of setting
"n.Type = nil" if there's an error. Notably, this means for a lot of
test cases, we now avoid reporting useless follow-on error messages.
For example, after reporting that "1 << s + 1.0" has an invalid shift,
we no longer also report that it can't be assigned to string.
2. Previously, assignconvfn had some extra logic for trying to
suppress errors from convlit/defaultlit so that it could provide its
own errors with better context information. Instead, this extra
context information is now passed down into convlit1 directly.
3. Relatedly, this CL also removes redundant calls to defaultlit prior
to assignconv. As a consequence, when an expression doesn't make sense
for a particular assignment (e.g., assigning an untyped string to an
integer), the error messages now say "untyped string" instead of just
"string". This is more consistent with go/types behavior.
4. defaultlit2 is now smarter about only trying to convert pairs of
untyped constants when it's likely to succeed. This allows us to
report better error messages for things like 3+"x"; instead of "cannot
convert 3 to string" we now report "mismatched types untyped number
and untyped string".
Passes toolstash-check.
Change-Id: I26822a02dc35855bd0ac774907b1cf5737e91882
Reviewed-on: https://go-review.googlesource.com/c/go/+/187657
Run-TryBot: Matthew Dempsky <mdempsky@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Robert Griesemer <gri@golang.org>
2019-09-05 13:33:06 -07:00
|
|
|
return n
|
|
|
|
|
}
|
2015-02-13 14:40:36 -05:00
|
|
|
|
cmd/compile: rewrite untyped constant conversion logic
This CL detangles the hairy mess that was convlit+defaultlit. In
particular, it makes the following changes:
1. convlit1 now follows the standard typecheck behavior of setting
"n.Type = nil" if there's an error. Notably, this means for a lot of
test cases, we now avoid reporting useless follow-on error messages.
For example, after reporting that "1 << s + 1.0" has an invalid shift,
we no longer also report that it can't be assigned to string.
2. Previously, assignconvfn had some extra logic for trying to
suppress errors from convlit/defaultlit so that it could provide its
own errors with better context information. Instead, this extra
context information is now passed down into convlit1 directly.
3. Relatedly, this CL also removes redundant calls to defaultlit prior
to assignconv. As a consequence, when an expression doesn't make sense
for a particular assignment (e.g., assigning an untyped string to an
integer), the error messages now say "untyped string" instead of just
"string". This is more consistent with go/types behavior.
4. defaultlit2 is now smarter about only trying to convert pairs of
untyped constants when it's likely to succeed. This allows us to
report better error messages for things like 3+"x"; instead of "cannot
convert 3 to string" we now report "mismatched types untyped number
and untyped string".
Passes toolstash-check.
Change-Id: I26822a02dc35855bd0ac774907b1cf5737e91882
Reviewed-on: https://go-review.googlesource.com/c/go/+/187657
Run-TryBot: Matthew Dempsky <mdempsky@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Robert Griesemer <gri@golang.org>
2019-09-05 13:33:06 -07:00
|
|
|
if !n.Diag() {
|
|
|
|
|
if !t.Broke() {
|
|
|
|
|
if explicit {
|
|
|
|
|
yyerror("cannot convert %L to type %v", n, t)
|
|
|
|
|
} else if context != nil {
|
|
|
|
|
yyerror("cannot use %L as type %v in %s", n, t, context())
|
|
|
|
|
} else {
|
|
|
|
|
yyerror("cannot use %L as type %v", n, t)
|
2015-02-13 14:40:36 -05:00
|
|
|
}
|
|
|
|
|
}
|
cmd/compile: rewrite untyped constant conversion logic
This CL detangles the hairy mess that was convlit+defaultlit. In
particular, it makes the following changes:
1. convlit1 now follows the standard typecheck behavior of setting
"n.Type = nil" if there's an error. Notably, this means for a lot of
test cases, we now avoid reporting useless follow-on error messages.
For example, after reporting that "1 << s + 1.0" has an invalid shift,
we no longer also report that it can't be assigned to string.
2. Previously, assignconvfn had some extra logic for trying to
suppress errors from convlit/defaultlit so that it could provide its
own errors with better context information. Instead, this extra
context information is now passed down into convlit1 directly.
3. Relatedly, this CL also removes redundant calls to defaultlit prior
to assignconv. As a consequence, when an expression doesn't make sense
for a particular assignment (e.g., assigning an untyped string to an
integer), the error messages now say "untyped string" instead of just
"string". This is more consistent with go/types behavior.
4. defaultlit2 is now smarter about only trying to convert pairs of
untyped constants when it's likely to succeed. This allows us to
report better error messages for things like 3+"x"; instead of "cannot
convert 3 to string" we now report "mismatched types untyped number
and untyped string".
Passes toolstash-check.
Change-Id: I26822a02dc35855bd0ac774907b1cf5737e91882
Reviewed-on: https://go-review.googlesource.com/c/go/+/187657
Run-TryBot: Matthew Dempsky <mdempsky@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Robert Griesemer <gri@golang.org>
2019-09-05 13:33:06 -07:00
|
|
|
n.SetDiag(true)
|
2015-02-13 14:40:36 -05:00
|
|
|
}
|
cmd/compile: rewrite untyped constant conversion logic
This CL detangles the hairy mess that was convlit+defaultlit. In
particular, it makes the following changes:
1. convlit1 now follows the standard typecheck behavior of setting
"n.Type = nil" if there's an error. Notably, this means for a lot of
test cases, we now avoid reporting useless follow-on error messages.
For example, after reporting that "1 << s + 1.0" has an invalid shift,
we no longer also report that it can't be assigned to string.
2. Previously, assignconvfn had some extra logic for trying to
suppress errors from convlit/defaultlit so that it could provide its
own errors with better context information. Instead, this extra
context information is now passed down into convlit1 directly.
3. Relatedly, this CL also removes redundant calls to defaultlit prior
to assignconv. As a consequence, when an expression doesn't make sense
for a particular assignment (e.g., assigning an untyped string to an
integer), the error messages now say "untyped string" instead of just
"string". This is more consistent with go/types behavior.
4. defaultlit2 is now smarter about only trying to convert pairs of
untyped constants when it's likely to succeed. This allows us to
report better error messages for things like 3+"x"; instead of "cannot
convert 3 to string" we now report "mismatched types untyped number
and untyped string".
Passes toolstash-check.
Change-Id: I26822a02dc35855bd0ac774907b1cf5737e91882
Reviewed-on: https://go-review.googlesource.com/c/go/+/187657
Run-TryBot: Matthew Dempsky <mdempsky@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Robert Griesemer <gri@golang.org>
2019-09-05 13:33:06 -07:00
|
|
|
n.Type = nil
|
cmd/compile: reduce use of **Node parameters
Escape analysis has a hard time with tree-like
structures (see #13493 and #14858).
This is unlikely to change.
As a result, when invoking a function that accepts
a **Node parameter, we usually allocate a *Node
on the heap. This happens a whole lot.
This CL changes functions from taking a **Node
to acting more like append: It both modifies
the input and returns a replacement for it.
Because of the cascading nature of escape analysis,
in order to get the benefits, I had to modify
almost all such functions. The remaining functions
are in racewalk and the backend. I would be happy
to update them as well in a separate CL.
This CL was created by manually updating the
function signatures and the directly impacted
bits of code. The callsites were then automatically
updated using a bespoke script:
https://gist.github.com/josharian/046b1be7aceae244de39
For ease of reviewing and future understanding,
this CL is also broken down into four CLs,
mailed separately, which show the manual
and the automated changes separately.
They are CLs 20990, 20991, 20992, and 20993.
Passes toolstash -cmp.
name old time/op new time/op delta
Template 335ms ± 5% 324ms ± 5% -3.35% (p=0.000 n=23+24)
Unicode 176ms ± 9% 165ms ± 6% -6.12% (p=0.000 n=23+24)
GoTypes 1.10s ± 4% 1.07s ± 2% -2.77% (p=0.000 n=24+24)
Compiler 5.31s ± 3% 5.15s ± 3% -2.95% (p=0.000 n=24+24)
MakeBash 41.6s ± 1% 41.7s ± 2% ~ (p=0.586 n=23+23)
name old alloc/op new alloc/op delta
Template 63.3MB ± 0% 62.4MB ± 0% -1.36% (p=0.000 n=25+23)
Unicode 42.4MB ± 0% 41.6MB ± 0% -1.99% (p=0.000 n=24+25)
GoTypes 220MB ± 0% 217MB ± 0% -1.11% (p=0.000 n=25+25)
Compiler 994MB ± 0% 973MB ± 0% -2.08% (p=0.000 n=24+25)
name old allocs/op new allocs/op delta
Template 681k ± 0% 574k ± 0% -15.71% (p=0.000 n=24+25)
Unicode 518k ± 0% 413k ± 0% -20.34% (p=0.000 n=25+24)
GoTypes 2.08M ± 0% 1.78M ± 0% -14.62% (p=0.000 n=25+25)
Compiler 9.26M ± 0% 7.64M ± 0% -17.48% (p=0.000 n=25+25)
name old text-bytes new text-bytes delta
HelloSize 578k ± 0% 578k ± 0% ~ (all samples are equal)
CmdGoSize 6.46M ± 0% 6.46M ± 0% ~ (all samples are equal)
name old data-bytes new data-bytes delta
HelloSize 128k ± 0% 128k ± 0% ~ (all samples are equal)
CmdGoSize 281k ± 0% 281k ± 0% ~ (all samples are equal)
name old exe-bytes new exe-bytes delta
HelloSize 921k ± 0% 921k ± 0% ~ (all samples are equal)
CmdGoSize 9.86M ± 0% 9.86M ± 0% ~ (all samples are equal)
Change-Id: I277d95bd56d51c166ef7f560647aeaa092f3f475
Reviewed-on: https://go-review.googlesource.com/20959
Reviewed-by: Dave Cheney <dave@cheney.net>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
2016-03-20 08:03:31 -07:00
|
|
|
return n
|
cmd/compile: rewrite untyped constant conversion logic
This CL detangles the hairy mess that was convlit+defaultlit. In
particular, it makes the following changes:
1. convlit1 now follows the standard typecheck behavior of setting
"n.Type = nil" if there's an error. Notably, this means for a lot of
test cases, we now avoid reporting useless follow-on error messages.
For example, after reporting that "1 << s + 1.0" has an invalid shift,
we no longer also report that it can't be assigned to string.
2. Previously, assignconvfn had some extra logic for trying to
suppress errors from convlit/defaultlit so that it could provide its
own errors with better context information. Instead, this extra
context information is now passed down into convlit1 directly.
3. Relatedly, this CL also removes redundant calls to defaultlit prior
to assignconv. As a consequence, when an expression doesn't make sense
for a particular assignment (e.g., assigning an untyped string to an
integer), the error messages now say "untyped string" instead of just
"string". This is more consistent with go/types behavior.
4. defaultlit2 is now smarter about only trying to convert pairs of
untyped constants when it's likely to succeed. This allows us to
report better error messages for things like 3+"x"; instead of "cannot
convert 3 to string" we now report "mismatched types untyped number
and untyped string".
Passes toolstash-check.
Change-Id: I26822a02dc35855bd0ac774907b1cf5737e91882
Reviewed-on: https://go-review.googlesource.com/c/go/+/187657
Run-TryBot: Matthew Dempsky <mdempsky@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Robert Griesemer <gri@golang.org>
2019-09-05 13:33:06 -07:00
|
|
|
}
|
2015-02-13 14:40:36 -05:00
|
|
|
|
cmd/compile: rewrite untyped constant conversion logic
This CL detangles the hairy mess that was convlit+defaultlit. In
particular, it makes the following changes:
1. convlit1 now follows the standard typecheck behavior of setting
"n.Type = nil" if there's an error. Notably, this means for a lot of
test cases, we now avoid reporting useless follow-on error messages.
For example, after reporting that "1 << s + 1.0" has an invalid shift,
we no longer also report that it can't be assigned to string.
2. Previously, assignconvfn had some extra logic for trying to
suppress errors from convlit/defaultlit so that it could provide its
own errors with better context information. Instead, this extra
context information is now passed down into convlit1 directly.
3. Relatedly, this CL also removes redundant calls to defaultlit prior
to assignconv. As a consequence, when an expression doesn't make sense
for a particular assignment (e.g., assigning an untyped string to an
integer), the error messages now say "untyped string" instead of just
"string". This is more consistent with go/types behavior.
4. defaultlit2 is now smarter about only trying to convert pairs of
untyped constants when it's likely to succeed. This allows us to
report better error messages for things like 3+"x"; instead of "cannot
convert 3 to string" we now report "mismatched types untyped number
and untyped string".
Passes toolstash-check.
Change-Id: I26822a02dc35855bd0ac774907b1cf5737e91882
Reviewed-on: https://go-review.googlesource.com/c/go/+/187657
Run-TryBot: Matthew Dempsky <mdempsky@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Robert Griesemer <gri@golang.org>
2019-09-05 13:33:06 -07:00
|
|
|
func operandType(op Op, t *types.Type) *types.Type {
|
|
|
|
|
switch op {
|
|
|
|
|
case OCOMPLEX:
|
|
|
|
|
if t.IsComplex() {
|
|
|
|
|
return floatForComplex(t)
|
|
|
|
|
}
|
|
|
|
|
case OREAL, OIMAG:
|
|
|
|
|
if t.IsFloat() {
|
|
|
|
|
return complexForFloat(t)
|
|
|
|
|
}
|
|
|
|
|
default:
|
|
|
|
|
if okfor[op][t.Etype] {
|
|
|
|
|
return t
|
2019-09-06 20:54:36 +00:00
|
|
|
}
|
2015-02-13 14:40:36 -05:00
|
|
|
}
|
cmd/compile: rewrite untyped constant conversion logic
This CL detangles the hairy mess that was convlit+defaultlit. In
particular, it makes the following changes:
1. convlit1 now follows the standard typecheck behavior of setting
"n.Type = nil" if there's an error. Notably, this means for a lot of
test cases, we now avoid reporting useless follow-on error messages.
For example, after reporting that "1 << s + 1.0" has an invalid shift,
we no longer also report that it can't be assigned to string.
2. Previously, assignconvfn had some extra logic for trying to
suppress errors from convlit/defaultlit so that it could provide its
own errors with better context information. Instead, this extra
context information is now passed down into convlit1 directly.
3. Relatedly, this CL also removes redundant calls to defaultlit prior
to assignconv. As a consequence, when an expression doesn't make sense
for a particular assignment (e.g., assigning an untyped string to an
integer), the error messages now say "untyped string" instead of just
"string". This is more consistent with go/types behavior.
4. defaultlit2 is now smarter about only trying to convert pairs of
untyped constants when it's likely to succeed. This allows us to
report better error messages for things like 3+"x"; instead of "cannot
convert 3 to string" we now report "mismatched types untyped number
and untyped string".
Passes toolstash-check.
Change-Id: I26822a02dc35855bd0ac774907b1cf5737e91882
Reviewed-on: https://go-review.googlesource.com/c/go/+/187657
Run-TryBot: Matthew Dempsky <mdempsky@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Robert Griesemer <gri@golang.org>
2019-09-05 13:33:06 -07:00
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// convertVal converts v into a representation appropriate for t. If
|
|
|
|
|
// no such representation exists, it returns Val{} instead.
|
|
|
|
|
//
|
|
|
|
|
// If explicit is true, then conversions from integer to string are
|
|
|
|
|
// also allowed.
|
|
|
|
|
func convertVal(v Val, t *types.Type, explicit bool) Val {
|
|
|
|
|
switch ct := v.Ctype(); ct {
|
|
|
|
|
case CTBOOL:
|
|
|
|
|
if t.IsBoolean() {
|
|
|
|
|
return v
|
|
|
|
|
}
|
2015-02-13 14:40:36 -05:00
|
|
|
|
cmd/compile: rewrite untyped constant conversion logic
This CL detangles the hairy mess that was convlit+defaultlit. In
particular, it makes the following changes:
1. convlit1 now follows the standard typecheck behavior of setting
"n.Type = nil" if there's an error. Notably, this means for a lot of
test cases, we now avoid reporting useless follow-on error messages.
For example, after reporting that "1 << s + 1.0" has an invalid shift,
we no longer also report that it can't be assigned to string.
2. Previously, assignconvfn had some extra logic for trying to
suppress errors from convlit/defaultlit so that it could provide its
own errors with better context information. Instead, this extra
context information is now passed down into convlit1 directly.
3. Relatedly, this CL also removes redundant calls to defaultlit prior
to assignconv. As a consequence, when an expression doesn't make sense
for a particular assignment (e.g., assigning an untyped string to an
integer), the error messages now say "untyped string" instead of just
"string". This is more consistent with go/types behavior.
4. defaultlit2 is now smarter about only trying to convert pairs of
untyped constants when it's likely to succeed. This allows us to
report better error messages for things like 3+"x"; instead of "cannot
convert 3 to string" we now report "mismatched types untyped number
and untyped string".
Passes toolstash-check.
Change-Id: I26822a02dc35855bd0ac774907b1cf5737e91882
Reviewed-on: https://go-review.googlesource.com/c/go/+/187657
Run-TryBot: Matthew Dempsky <mdempsky@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Robert Griesemer <gri@golang.org>
2019-09-05 13:33:06 -07:00
|
|
|
case CTSTR:
|
|
|
|
|
if t.IsString() {
|
|
|
|
|
return v
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
case CTINT, CTRUNE:
|
|
|
|
|
if explicit && t.IsString() {
|
|
|
|
|
return tostr(v)
|
|
|
|
|
}
|
|
|
|
|
fallthrough
|
|
|
|
|
case CTFLT, CTCPLX:
|
|
|
|
|
switch {
|
|
|
|
|
case t.IsInteger():
|
|
|
|
|
v = toint(v)
|
|
|
|
|
overflow(v, t)
|
|
|
|
|
return v
|
|
|
|
|
case t.IsFloat():
|
|
|
|
|
v = toflt(v)
|
|
|
|
|
v = Val{truncfltlit(v.U.(*Mpflt), t)}
|
|
|
|
|
return v
|
|
|
|
|
case t.IsComplex():
|
|
|
|
|
v = tocplx(v)
|
|
|
|
|
v = Val{trunccmplxlit(v.U.(*Mpcplx), t)}
|
|
|
|
|
return v
|
|
|
|
|
}
|
2015-02-13 14:40:36 -05:00
|
|
|
}
|
cmd/compile: rewrite untyped constant conversion logic
This CL detangles the hairy mess that was convlit+defaultlit. In
particular, it makes the following changes:
1. convlit1 now follows the standard typecheck behavior of setting
"n.Type = nil" if there's an error. Notably, this means for a lot of
test cases, we now avoid reporting useless follow-on error messages.
For example, after reporting that "1 << s + 1.0" has an invalid shift,
we no longer also report that it can't be assigned to string.
2. Previously, assignconvfn had some extra logic for trying to
suppress errors from convlit/defaultlit so that it could provide its
own errors with better context information. Instead, this extra
context information is now passed down into convlit1 directly.
3. Relatedly, this CL also removes redundant calls to defaultlit prior
to assignconv. As a consequence, when an expression doesn't make sense
for a particular assignment (e.g., assigning an untyped string to an
integer), the error messages now say "untyped string" instead of just
"string". This is more consistent with go/types behavior.
4. defaultlit2 is now smarter about only trying to convert pairs of
untyped constants when it's likely to succeed. This allows us to
report better error messages for things like 3+"x"; instead of "cannot
convert 3 to string" we now report "mismatched types untyped number
and untyped string".
Passes toolstash-check.
Change-Id: I26822a02dc35855bd0ac774907b1cf5737e91882
Reviewed-on: https://go-review.googlesource.com/c/go/+/187657
Run-TryBot: Matthew Dempsky <mdempsky@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Robert Griesemer <gri@golang.org>
2019-09-05 13:33:06 -07:00
|
|
|
|
|
|
|
|
return Val{}
|
2015-02-13 14:40:36 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func tocplx(v Val) Val {
|
2016-04-22 12:27:29 -07:00
|
|
|
switch u := v.U.(type) {
|
|
|
|
|
case *Mpint:
|
2019-02-17 15:35:52 -08:00
|
|
|
c := newMpcmplx()
|
2016-04-22 12:27:29 -07:00
|
|
|
c.Real.SetInt(u)
|
2016-03-20 13:55:42 -07:00
|
|
|
c.Imag.SetFloat64(0.0)
|
2015-05-14 17:57:42 -07:00
|
|
|
v.U = c
|
2015-02-13 14:40:36 -05:00
|
|
|
|
2016-04-22 12:27:29 -07:00
|
|
|
case *Mpflt:
|
2019-02-17 15:35:52 -08:00
|
|
|
c := newMpcmplx()
|
2016-04-22 12:27:29 -07:00
|
|
|
c.Real.Set(u)
|
2016-03-20 13:55:42 -07:00
|
|
|
c.Imag.SetFloat64(0.0)
|
2015-05-14 17:57:42 -07:00
|
|
|
v.U = c
|
2015-02-13 14:40:36 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return v
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func toflt(v Val) Val {
|
2016-04-22 12:27:29 -07:00
|
|
|
switch u := v.U.(type) {
|
|
|
|
|
case *Mpint:
|
2015-03-20 16:59:08 -07:00
|
|
|
f := newMpflt()
|
2016-04-22 12:27:29 -07:00
|
|
|
f.SetInt(u)
|
2015-05-14 17:57:42 -07:00
|
|
|
v.U = f
|
2015-02-13 14:40:36 -05:00
|
|
|
|
2016-04-22 12:27:29 -07:00
|
|
|
case *Mpcplx:
|
2015-03-20 16:59:08 -07:00
|
|
|
f := newMpflt()
|
2016-04-22 12:27:29 -07:00
|
|
|
f.Set(&u.Real)
|
|
|
|
|
if u.Imag.CmpFloat64(0) != 0 {
|
2018-09-18 21:55:35 -07:00
|
|
|
yyerror("constant %v truncated to real", u.GoString())
|
2015-02-13 14:40:36 -05:00
|
|
|
}
|
2015-05-14 17:57:42 -07:00
|
|
|
v.U = f
|
2015-02-13 14:40:36 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return v
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func toint(v Val) Val {
|
2016-04-22 12:27:29 -07:00
|
|
|
switch u := v.U.(type) {
|
|
|
|
|
case *Mpint:
|
|
|
|
|
if u.Rune {
|
|
|
|
|
i := new(Mpint)
|
|
|
|
|
i.Set(u)
|
|
|
|
|
v.U = i
|
|
|
|
|
}
|
2015-02-13 14:40:36 -05:00
|
|
|
|
2016-04-22 12:27:29 -07:00
|
|
|
case *Mpflt:
|
2015-02-23 16:07:24 -05:00
|
|
|
i := new(Mpint)
|
cmd/compile: fix misleading "truncated to int" messages
When defining an int const, the compiler tries to cast the RHS
expression to int. The cast may fail for three reasons:
1. expr is an integer constant that overflows int
2. expr is a floating point constant
3. expr is a complex constant, or not a number
In the second case, in order to print a sensible error message, we
must distinguish between a floating point constant that should be
included in the error message and a floating point constant that
cannot be reasonably formatted for inclusion in an error message.
For example, in:
const a int = 1.1
const b int = 1 + 1e-100
a is in the former group, while b is in the latter, since the floating
point value resulting from the evaluation of the rhs of the assignment
(1.00...01) is too long to be fully printed in an error message, and
cannot be shortened without making the error message misleading
(rounding or truncating it would result in a "1", which looks like an
integer constant, and it makes little sense in an error message about
an invalid floating point expression).
To fix this problem, we try to format the float value using fconv
(which is used by the error reporting mechanism to format float
arguments), and then parse the resulting string back to a
big.Float. If the result is an integer, we assume that expr is a float
value that cannot be reasonably be formatted as a string, and we emit
an error message that does not include its string representation.
Also, change the error message for overflows to a more conservative
"integer too large", which does not mention overflows that are only
caused by an internal implementation restriction.
Also, change (*Mpint) SetFloat so that it returns a bool (instead of
0/-1 for success/failure).
Fixes #11371
Change-Id: Ibbc73e2ed2eaf41f07827b0649d0eb637150ecaa
Reviewed-on: https://go-review.googlesource.com/35411
Run-TryBot: Alberto Donizetti <alb.donizetti@gmail.com>
Run-TryBot: Robert Griesemer <gri@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Robert Griesemer <gri@golang.org>
2017-01-18 11:48:14 +01:00
|
|
|
if !i.SetFloat(u) {
|
2017-04-07 09:09:17 +02:00
|
|
|
if i.checkOverflow(0) {
|
cmd/compile: fix misleading "truncated to int" messages
When defining an int const, the compiler tries to cast the RHS
expression to int. The cast may fail for three reasons:
1. expr is an integer constant that overflows int
2. expr is a floating point constant
3. expr is a complex constant, or not a number
In the second case, in order to print a sensible error message, we
must distinguish between a floating point constant that should be
included in the error message and a floating point constant that
cannot be reasonably formatted for inclusion in an error message.
For example, in:
const a int = 1.1
const b int = 1 + 1e-100
a is in the former group, while b is in the latter, since the floating
point value resulting from the evaluation of the rhs of the assignment
(1.00...01) is too long to be fully printed in an error message, and
cannot be shortened without making the error message misleading
(rounding or truncating it would result in a "1", which looks like an
integer constant, and it makes little sense in an error message about
an invalid floating point expression).
To fix this problem, we try to format the float value using fconv
(which is used by the error reporting mechanism to format float
arguments), and then parse the resulting string back to a
big.Float. If the result is an integer, we assume that expr is a float
value that cannot be reasonably be formatted as a string, and we emit
an error message that does not include its string representation.
Also, change the error message for overflows to a more conservative
"integer too large", which does not mention overflows that are only
caused by an internal implementation restriction.
Also, change (*Mpint) SetFloat so that it returns a bool (instead of
0/-1 for success/failure).
Fixes #11371
Change-Id: Ibbc73e2ed2eaf41f07827b0649d0eb637150ecaa
Reviewed-on: https://go-review.googlesource.com/35411
Run-TryBot: Alberto Donizetti <alb.donizetti@gmail.com>
Run-TryBot: Robert Griesemer <gri@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Robert Griesemer <gri@golang.org>
2017-01-18 11:48:14 +01:00
|
|
|
yyerror("integer too large")
|
|
|
|
|
} else {
|
|
|
|
|
// The value of u cannot be represented as an integer;
|
|
|
|
|
// so we need to print an error message.
|
|
|
|
|
// Unfortunately some float values cannot be
|
|
|
|
|
// reasonably formatted for inclusion in an error
|
|
|
|
|
// message (example: 1 + 1e-100), so first we try to
|
|
|
|
|
// format the float; if the truncation resulted in
|
|
|
|
|
// something that looks like an integer we omit the
|
|
|
|
|
// value from the error message.
|
|
|
|
|
// (See issue #11371).
|
|
|
|
|
var t big.Float
|
2018-09-18 21:55:35 -07:00
|
|
|
t.Parse(u.GoString(), 10)
|
cmd/compile: fix misleading "truncated to int" messages
When defining an int const, the compiler tries to cast the RHS
expression to int. The cast may fail for three reasons:
1. expr is an integer constant that overflows int
2. expr is a floating point constant
3. expr is a complex constant, or not a number
In the second case, in order to print a sensible error message, we
must distinguish between a floating point constant that should be
included in the error message and a floating point constant that
cannot be reasonably formatted for inclusion in an error message.
For example, in:
const a int = 1.1
const b int = 1 + 1e-100
a is in the former group, while b is in the latter, since the floating
point value resulting from the evaluation of the rhs of the assignment
(1.00...01) is too long to be fully printed in an error message, and
cannot be shortened without making the error message misleading
(rounding or truncating it would result in a "1", which looks like an
integer constant, and it makes little sense in an error message about
an invalid floating point expression).
To fix this problem, we try to format the float value using fconv
(which is used by the error reporting mechanism to format float
arguments), and then parse the resulting string back to a
big.Float. If the result is an integer, we assume that expr is a float
value that cannot be reasonably be formatted as a string, and we emit
an error message that does not include its string representation.
Also, change the error message for overflows to a more conservative
"integer too large", which does not mention overflows that are only
caused by an internal implementation restriction.
Also, change (*Mpint) SetFloat so that it returns a bool (instead of
0/-1 for success/failure).
Fixes #11371
Change-Id: Ibbc73e2ed2eaf41f07827b0649d0eb637150ecaa
Reviewed-on: https://go-review.googlesource.com/35411
Run-TryBot: Alberto Donizetti <alb.donizetti@gmail.com>
Run-TryBot: Robert Griesemer <gri@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Robert Griesemer <gri@golang.org>
2017-01-18 11:48:14 +01:00
|
|
|
if t.IsInt() {
|
|
|
|
|
yyerror("constant truncated to integer")
|
|
|
|
|
} else {
|
2018-09-18 21:55:35 -07:00
|
|
|
yyerror("constant %v truncated to integer", u.GoString())
|
cmd/compile: fix misleading "truncated to int" messages
When defining an int const, the compiler tries to cast the RHS
expression to int. The cast may fail for three reasons:
1. expr is an integer constant that overflows int
2. expr is a floating point constant
3. expr is a complex constant, or not a number
In the second case, in order to print a sensible error message, we
must distinguish between a floating point constant that should be
included in the error message and a floating point constant that
cannot be reasonably formatted for inclusion in an error message.
For example, in:
const a int = 1.1
const b int = 1 + 1e-100
a is in the former group, while b is in the latter, since the floating
point value resulting from the evaluation of the rhs of the assignment
(1.00...01) is too long to be fully printed in an error message, and
cannot be shortened without making the error message misleading
(rounding or truncating it would result in a "1", which looks like an
integer constant, and it makes little sense in an error message about
an invalid floating point expression).
To fix this problem, we try to format the float value using fconv
(which is used by the error reporting mechanism to format float
arguments), and then parse the resulting string back to a
big.Float. If the result is an integer, we assume that expr is a float
value that cannot be reasonably be formatted as a string, and we emit
an error message that does not include its string representation.
Also, change the error message for overflows to a more conservative
"integer too large", which does not mention overflows that are only
caused by an internal implementation restriction.
Also, change (*Mpint) SetFloat so that it returns a bool (instead of
0/-1 for success/failure).
Fixes #11371
Change-Id: Ibbc73e2ed2eaf41f07827b0649d0eb637150ecaa
Reviewed-on: https://go-review.googlesource.com/35411
Run-TryBot: Alberto Donizetti <alb.donizetti@gmail.com>
Run-TryBot: Robert Griesemer <gri@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Robert Griesemer <gri@golang.org>
2017-01-18 11:48:14 +01:00
|
|
|
}
|
2015-12-03 15:51:03 -08:00
|
|
|
}
|
2015-02-13 14:40:36 -05:00
|
|
|
}
|
2015-05-14 17:57:42 -07:00
|
|
|
v.U = i
|
2015-02-13 14:40:36 -05:00
|
|
|
|
2016-04-22 12:27:29 -07:00
|
|
|
case *Mpcplx:
|
2015-02-23 16:07:24 -05:00
|
|
|
i := new(Mpint)
|
cmd/compile: fix misleading "truncated to int" messages
When defining an int const, the compiler tries to cast the RHS
expression to int. The cast may fail for three reasons:
1. expr is an integer constant that overflows int
2. expr is a floating point constant
3. expr is a complex constant, or not a number
In the second case, in order to print a sensible error message, we
must distinguish between a floating point constant that should be
included in the error message and a floating point constant that
cannot be reasonably formatted for inclusion in an error message.
For example, in:
const a int = 1.1
const b int = 1 + 1e-100
a is in the former group, while b is in the latter, since the floating
point value resulting from the evaluation of the rhs of the assignment
(1.00...01) is too long to be fully printed in an error message, and
cannot be shortened without making the error message misleading
(rounding or truncating it would result in a "1", which looks like an
integer constant, and it makes little sense in an error message about
an invalid floating point expression).
To fix this problem, we try to format the float value using fconv
(which is used by the error reporting mechanism to format float
arguments), and then parse the resulting string back to a
big.Float. If the result is an integer, we assume that expr is a float
value that cannot be reasonably be formatted as a string, and we emit
an error message that does not include its string representation.
Also, change the error message for overflows to a more conservative
"integer too large", which does not mention overflows that are only
caused by an internal implementation restriction.
Also, change (*Mpint) SetFloat so that it returns a bool (instead of
0/-1 for success/failure).
Fixes #11371
Change-Id: Ibbc73e2ed2eaf41f07827b0649d0eb637150ecaa
Reviewed-on: https://go-review.googlesource.com/35411
Run-TryBot: Alberto Donizetti <alb.donizetti@gmail.com>
Run-TryBot: Robert Griesemer <gri@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Robert Griesemer <gri@golang.org>
2017-01-18 11:48:14 +01:00
|
|
|
if !i.SetFloat(&u.Real) || u.Imag.CmpFloat64(0) != 0 {
|
2018-09-18 21:55:35 -07:00
|
|
|
yyerror("constant %v truncated to integer", u.GoString())
|
2015-02-13 14:40:36 -05:00
|
|
|
}
|
2016-12-21 11:07:11 +01:00
|
|
|
|
2015-05-14 17:57:42 -07:00
|
|
|
v.U = i
|
2015-02-13 14:40:36 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return v
|
|
|
|
|
}
|
|
|
|
|
|
cmd/compile: factor out Pkg, Sym, and Type into package types
- created new package cmd/compile/internal/types
- moved Pkg, Sym, Type to new package
- to break cycles, for now we need the (ugly) types/utils.go
file which contains a handful of functions that must be installed
early by the gc frontend
- to break cycles, for now we need two functions to convert between
*gc.Node and *types.Node (the latter is a dummy type)
- adjusted the gc's code to use the new package and the conversion
functions as needed
- made several Pkg, Sym, and Type methods functions as needed
- renamed constructors typ, typPtr, typArray, etc. to types.New,
types.NewPtr, types.NewArray, etc.
Passes toolstash-check -all.
Change-Id: I8adfa5e85c731645d0a7fd2030375ed6ebf54b72
Reviewed-on: https://go-review.googlesource.com/39855
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2017-04-04 17:54:02 -07:00
|
|
|
func doesoverflow(v Val, t *types.Type) bool {
|
2016-04-22 12:27:29 -07:00
|
|
|
switch u := v.U.(type) {
|
|
|
|
|
case *Mpint:
|
2016-03-30 15:09:25 -07:00
|
|
|
if !t.IsInteger() {
|
2015-08-30 23:10:03 +02:00
|
|
|
Fatalf("overflow: %v integer constant", t)
|
2015-02-13 14:40:36 -05:00
|
|
|
}
|
2016-09-16 00:33:29 +10:00
|
|
|
return u.Cmp(minintval[t.Etype]) < 0 || u.Cmp(maxintval[t.Etype]) > 0
|
2015-02-13 14:40:36 -05:00
|
|
|
|
2016-04-22 12:27:29 -07:00
|
|
|
case *Mpflt:
|
2016-03-30 15:09:25 -07:00
|
|
|
if !t.IsFloat() {
|
2015-08-30 23:10:03 +02:00
|
|
|
Fatalf("overflow: %v floating-point constant", t)
|
2015-02-13 14:40:36 -05:00
|
|
|
}
|
2016-04-22 12:27:29 -07:00
|
|
|
return u.Cmp(minfltval[t.Etype]) <= 0 || u.Cmp(maxfltval[t.Etype]) >= 0
|
2015-02-13 14:40:36 -05:00
|
|
|
|
2016-04-22 12:27:29 -07:00
|
|
|
case *Mpcplx:
|
2016-03-30 15:09:25 -07:00
|
|
|
if !t.IsComplex() {
|
2015-08-30 23:10:03 +02:00
|
|
|
Fatalf("overflow: %v complex constant", t)
|
2015-02-13 14:40:36 -05:00
|
|
|
}
|
2016-04-22 12:27:29 -07:00
|
|
|
return u.Real.Cmp(minfltval[t.Etype]) <= 0 || u.Real.Cmp(maxfltval[t.Etype]) >= 0 ||
|
|
|
|
|
u.Imag.Cmp(minfltval[t.Etype]) <= 0 || u.Imag.Cmp(maxfltval[t.Etype]) >= 0
|
2015-02-13 14:40:36 -05:00
|
|
|
}
|
|
|
|
|
|
2015-02-17 22:13:49 -05:00
|
|
|
return false
|
2015-02-13 14:40:36 -05:00
|
|
|
}
|
|
|
|
|
|
2017-03-07 11:54:29 +01:00
|
|
|
func overflow(v Val, t *types.Type) bool {
|
2015-02-13 14:40:36 -05:00
|
|
|
// v has already been converted
|
|
|
|
|
// to appropriate form for t.
|
|
|
|
|
if t == nil || t.Etype == TIDEAL {
|
2017-03-07 11:54:29 +01:00
|
|
|
return false
|
2015-02-13 14:40:36 -05:00
|
|
|
}
|
|
|
|
|
|
2018-03-31 16:49:07 -07:00
|
|
|
// Only uintptrs may be converted to pointers, which cannot overflow.
|
|
|
|
|
if t.IsPtr() || t.IsUnsafePtr() {
|
2017-03-07 11:54:29 +01:00
|
|
|
return false
|
2015-05-01 19:50:27 -07:00
|
|
|
}
|
|
|
|
|
|
2015-09-15 11:16:58 -07:00
|
|
|
if doesoverflow(v, t) {
|
2016-09-15 15:45:10 +10:00
|
|
|
yyerror("constant %v overflows %v", v, t)
|
2017-03-07 11:54:29 +01:00
|
|
|
return true
|
2015-02-13 14:40:36 -05:00
|
|
|
}
|
2017-03-07 11:54:29 +01:00
|
|
|
|
|
|
|
|
return false
|
|
|
|
|
|
2015-02-13 14:40:36 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func tostr(v Val) Val {
|
2016-04-22 12:27:29 -07:00
|
|
|
switch u := v.U.(type) {
|
|
|
|
|
case *Mpint:
|
2020-02-27 11:08:30 -08:00
|
|
|
var r rune = 0xFFFD
|
|
|
|
|
if u.Cmp(minintval[TINT32]) >= 0 && u.Cmp(maxintval[TINT32]) <= 0 {
|
|
|
|
|
r = rune(u.Int64())
|
2015-02-13 14:40:36 -05:00
|
|
|
}
|
2020-02-27 11:08:30 -08:00
|
|
|
v.U = string(r)
|
2015-02-13 14:40:36 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return v
|
|
|
|
|
}
|
|
|
|
|
|
2015-10-26 16:00:59 -07:00
|
|
|
func consttype(n *Node) Ctype {
|
2015-02-13 14:40:36 -05:00
|
|
|
if n == nil || n.Op != OLITERAL {
|
2019-10-13 23:37:14 +07:00
|
|
|
return CTxxx
|
2015-02-13 14:40:36 -05:00
|
|
|
}
|
2015-10-26 16:00:59 -07:00
|
|
|
return n.Val().Ctype()
|
2015-02-13 14:40:36 -05:00
|
|
|
}
|
|
|
|
|
|
2015-10-26 16:00:59 -07:00
|
|
|
func Isconst(n *Node, ct Ctype) bool {
|
2015-02-23 16:07:24 -05:00
|
|
|
t := consttype(n)
|
2015-02-13 14:40:36 -05:00
|
|
|
|
|
|
|
|
// If the caller is asking for CTINT, allow CTRUNE too.
|
|
|
|
|
// Makes life easier for back ends.
|
2015-02-17 22:13:49 -05:00
|
|
|
return t == ct || (ct == CTINT && t == CTRUNE)
|
2015-02-13 14:40:36 -05:00
|
|
|
}
|
|
|
|
|
|
2018-10-04 16:49:53 -07:00
|
|
|
// evconst rewrites constant expressions into OLITERAL nodes.
|
2015-02-13 14:40:36 -05:00
|
|
|
func evconst(n *Node) {
|
2018-10-04 16:49:53 -07:00
|
|
|
nl, nr := n.Left, n.Right
|
|
|
|
|
|
|
|
|
|
// Pick off just the opcodes that can be constant evaluated.
|
|
|
|
|
switch op := n.Op; op {
|
2018-11-18 08:34:38 -08:00
|
|
|
case OPLUS, ONEG, OBITNOT, ONOT:
|
2018-10-04 16:49:53 -07:00
|
|
|
if nl.Op == OLITERAL {
|
|
|
|
|
setconst(n, unaryOp(op, nl.Val(), n.Type))
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
case OADD, OSUB, OMUL, ODIV, OMOD, OOR, OXOR, OAND, OANDNOT, OOROR, OANDAND:
|
|
|
|
|
if nl.Op == OLITERAL && nr.Op == OLITERAL {
|
|
|
|
|
setconst(n, binaryOp(nl.Val(), op, nr.Val()))
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
case OEQ, ONE, OLT, OLE, OGT, OGE:
|
|
|
|
|
if nl.Op == OLITERAL && nr.Op == OLITERAL {
|
2019-09-04 17:45:50 -07:00
|
|
|
setboolconst(n, compareOp(nl.Val(), op, nr.Val()))
|
2018-10-04 16:49:53 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
case OLSH, ORSH:
|
|
|
|
|
if nl.Op == OLITERAL && nr.Op == OLITERAL {
|
|
|
|
|
setconst(n, shiftOp(nl.Val(), op, nr.Val()))
|
|
|
|
|
}
|
2015-02-13 14:40:36 -05:00
|
|
|
|
2019-09-26 16:32:34 -07:00
|
|
|
case OCONV, ORUNESTR:
|
2019-02-27 18:18:47 -08:00
|
|
|
if okforconst[n.Type.Etype] && nl.Op == OLITERAL {
|
cmd/compile: rewrite untyped constant conversion logic
This CL detangles the hairy mess that was convlit+defaultlit. In
particular, it makes the following changes:
1. convlit1 now follows the standard typecheck behavior of setting
"n.Type = nil" if there's an error. Notably, this means for a lot of
test cases, we now avoid reporting useless follow-on error messages.
For example, after reporting that "1 << s + 1.0" has an invalid shift,
we no longer also report that it can't be assigned to string.
2. Previously, assignconvfn had some extra logic for trying to
suppress errors from convlit/defaultlit so that it could provide its
own errors with better context information. Instead, this extra
context information is now passed down into convlit1 directly.
3. Relatedly, this CL also removes redundant calls to defaultlit prior
to assignconv. As a consequence, when an expression doesn't make sense
for a particular assignment (e.g., assigning an untyped string to an
integer), the error messages now say "untyped string" instead of just
"string". This is more consistent with go/types behavior.
4. defaultlit2 is now smarter about only trying to convert pairs of
untyped constants when it's likely to succeed. This allows us to
report better error messages for things like 3+"x"; instead of "cannot
convert 3 to string" we now report "mismatched types untyped number
and untyped string".
Passes toolstash-check.
Change-Id: I26822a02dc35855bd0ac774907b1cf5737e91882
Reviewed-on: https://go-review.googlesource.com/c/go/+/187657
Run-TryBot: Matthew Dempsky <mdempsky@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Robert Griesemer <gri@golang.org>
2019-09-05 13:33:06 -07:00
|
|
|
setconst(n, convertVal(nl.Val(), n.Type, true))
|
2015-02-13 14:40:36 -05:00
|
|
|
}
|
2018-10-04 16:49:53 -07:00
|
|
|
|
2019-02-27 17:34:07 -08:00
|
|
|
case OCONVNOP:
|
2019-02-27 18:18:47 -08:00
|
|
|
if okforconst[n.Type.Etype] && nl.Op == OLITERAL {
|
2019-02-27 17:34:07 -08:00
|
|
|
// set so n.Orig gets OCONV instead of OCONVNOP
|
|
|
|
|
n.Op = OCONV
|
|
|
|
|
setconst(n, nl.Val())
|
|
|
|
|
}
|
|
|
|
|
|
2015-02-13 14:40:36 -05:00
|
|
|
case OADDSTR:
|
2018-10-04 16:49:53 -07:00
|
|
|
// Merge adjacent constants in the argument list.
|
2016-03-08 15:10:26 -08:00
|
|
|
s := n.List.Slice()
|
2016-03-07 09:36:24 -08:00
|
|
|
for i1 := 0; i1 < len(s); i1++ {
|
|
|
|
|
if Isconst(s[i1], CTSTR) && i1+1 < len(s) && Isconst(s[i1+1], CTSTR) {
|
|
|
|
|
// merge from i1 up to but not including i2
|
|
|
|
|
var strs []string
|
|
|
|
|
i2 := i1
|
|
|
|
|
for i2 < len(s) && Isconst(s[i2], CTSTR) {
|
2019-09-14 01:29:19 +07:00
|
|
|
strs = append(strs, strlit(s[i2]))
|
2016-03-07 09:36:24 -08:00
|
|
|
i2++
|
|
|
|
|
}
|
|
|
|
|
|
2016-03-23 16:01:15 +11:00
|
|
|
nl := *s[i1]
|
|
|
|
|
nl.Orig = &nl
|
2016-03-07 09:36:24 -08:00
|
|
|
nl.SetVal(Val{strings.Join(strs, "")})
|
2016-03-23 16:01:15 +11:00
|
|
|
s[i1] = &nl
|
2016-03-07 09:36:24 -08:00
|
|
|
s = append(s[:i1+1], s[i2:]...)
|
2015-06-09 18:37:26 -07:00
|
|
|
}
|
2015-02-13 14:40:36 -05:00
|
|
|
}
|
|
|
|
|
|
2016-03-07 09:36:24 -08:00
|
|
|
if len(s) == 1 && Isconst(s[0], CTSTR) {
|
2015-02-13 14:40:36 -05:00
|
|
|
n.Op = OLITERAL
|
2016-03-07 09:36:24 -08:00
|
|
|
n.SetVal(s[0].Val())
|
|
|
|
|
} else {
|
2016-03-08 15:10:26 -08:00
|
|
|
n.List.Set(s)
|
2015-02-13 14:40:36 -05:00
|
|
|
}
|
2019-02-27 17:34:07 -08:00
|
|
|
|
|
|
|
|
case OCAP, OLEN:
|
|
|
|
|
switch nl.Type.Etype {
|
|
|
|
|
case TSTRING:
|
|
|
|
|
if Isconst(nl, CTSTR) {
|
2019-09-14 01:29:19 +07:00
|
|
|
setintconst(n, int64(len(strlit(nl))))
|
2019-02-27 17:34:07 -08:00
|
|
|
}
|
|
|
|
|
case TARRAY:
|
|
|
|
|
if !hascallchan(nl) {
|
|
|
|
|
setintconst(n, nl.Type.NumElem())
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
case OALIGNOF, OOFFSETOF, OSIZEOF:
|
|
|
|
|
setintconst(n, evalunsafe(n))
|
|
|
|
|
|
|
|
|
|
case OREAL, OIMAG:
|
|
|
|
|
if nl.Op == OLITERAL {
|
|
|
|
|
var re, im *Mpflt
|
2019-03-13 15:51:15 -07:00
|
|
|
switch u := nl.Val().U.(type) {
|
|
|
|
|
case *Mpint:
|
2019-02-27 17:34:07 -08:00
|
|
|
re = newMpflt()
|
2019-03-13 15:51:15 -07:00
|
|
|
re.SetInt(u)
|
2019-02-27 17:34:07 -08:00
|
|
|
// im = 0
|
2019-03-13 15:51:15 -07:00
|
|
|
case *Mpflt:
|
|
|
|
|
re = u
|
2019-02-27 17:34:07 -08:00
|
|
|
// im = 0
|
2019-03-13 15:51:15 -07:00
|
|
|
case *Mpcplx:
|
|
|
|
|
re = &u.Real
|
|
|
|
|
im = &u.Imag
|
2019-02-27 17:34:07 -08:00
|
|
|
default:
|
|
|
|
|
Fatalf("impossible")
|
|
|
|
|
}
|
|
|
|
|
if n.Op == OIMAG {
|
|
|
|
|
if im == nil {
|
|
|
|
|
im = newMpflt()
|
|
|
|
|
}
|
|
|
|
|
re = im
|
|
|
|
|
}
|
|
|
|
|
setconst(n, Val{re})
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
case OCOMPLEX:
|
|
|
|
|
if nl.Op == OLITERAL && nr.Op == OLITERAL {
|
|
|
|
|
// make it a complex literal
|
|
|
|
|
c := newMpcmplx()
|
|
|
|
|
c.Real.Set(toflt(nl.Val()).U.(*Mpflt))
|
|
|
|
|
c.Imag.Set(toflt(nr.Val()).U.(*Mpflt))
|
|
|
|
|
setconst(n, Val{c})
|
|
|
|
|
}
|
2015-02-13 14:40:36 -05:00
|
|
|
}
|
2018-10-04 16:49:53 -07:00
|
|
|
}
|
2015-02-13 14:40:36 -05:00
|
|
|
|
2018-10-04 16:49:53 -07:00
|
|
|
func match(x, y Val) (Val, Val) {
|
|
|
|
|
switch {
|
|
|
|
|
case x.Ctype() == CTCPLX || y.Ctype() == CTCPLX:
|
|
|
|
|
return tocplx(x), tocplx(y)
|
|
|
|
|
case x.Ctype() == CTFLT || y.Ctype() == CTFLT:
|
|
|
|
|
return toflt(x), toflt(y)
|
2015-02-13 14:40:36 -05:00
|
|
|
}
|
|
|
|
|
|
2018-10-04 16:49:53 -07:00
|
|
|
// Mixed int/rune are fine.
|
|
|
|
|
return x, y
|
|
|
|
|
}
|
2015-03-02 12:35:15 -05:00
|
|
|
|
2018-10-04 16:49:53 -07:00
|
|
|
func compareOp(x Val, op Op, y Val) bool {
|
|
|
|
|
x, y = match(x, y)
|
2015-03-02 12:35:15 -05:00
|
|
|
|
2018-10-04 16:49:53 -07:00
|
|
|
switch x.Ctype() {
|
|
|
|
|
case CTBOOL:
|
|
|
|
|
x, y := x.U.(bool), y.U.(bool)
|
|
|
|
|
switch op {
|
|
|
|
|
case OEQ:
|
|
|
|
|
return x == y
|
|
|
|
|
case ONE:
|
|
|
|
|
return x != y
|
2016-08-23 16:43:43 -04:00
|
|
|
}
|
2015-02-13 14:40:36 -05:00
|
|
|
|
2018-10-04 16:49:53 -07:00
|
|
|
case CTINT, CTRUNE:
|
|
|
|
|
x, y := x.U.(*Mpint), y.U.(*Mpint)
|
|
|
|
|
return cmpZero(x.Cmp(y), op)
|
2015-02-13 14:40:36 -05:00
|
|
|
|
2018-10-04 16:49:53 -07:00
|
|
|
case CTFLT:
|
|
|
|
|
x, y := x.U.(*Mpflt), y.U.(*Mpflt)
|
|
|
|
|
return cmpZero(x.Cmp(y), op)
|
2015-02-13 14:40:36 -05:00
|
|
|
|
2018-10-04 16:49:53 -07:00
|
|
|
case CTCPLX:
|
|
|
|
|
x, y := x.U.(*Mpcplx), y.U.(*Mpcplx)
|
|
|
|
|
eq := x.Real.Cmp(&y.Real) == 0 && x.Imag.Cmp(&y.Imag) == 0
|
|
|
|
|
switch op {
|
|
|
|
|
case OEQ:
|
|
|
|
|
return eq
|
|
|
|
|
case ONE:
|
|
|
|
|
return !eq
|
2015-02-13 14:40:36 -05:00
|
|
|
}
|
|
|
|
|
|
2018-10-04 16:49:53 -07:00
|
|
|
case CTSTR:
|
|
|
|
|
x, y := x.U.(string), y.U.(string)
|
|
|
|
|
switch op {
|
|
|
|
|
case OEQ:
|
|
|
|
|
return x == y
|
|
|
|
|
case ONE:
|
|
|
|
|
return x != y
|
|
|
|
|
case OLT:
|
|
|
|
|
return x < y
|
|
|
|
|
case OLE:
|
|
|
|
|
return x <= y
|
|
|
|
|
case OGT:
|
|
|
|
|
return x > y
|
|
|
|
|
case OGE:
|
|
|
|
|
return x >= y
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Fatalf("compareOp: bad comparison: %v %v %v", x, op, y)
|
|
|
|
|
panic("unreachable")
|
|
|
|
|
}
|
2015-02-13 14:40:36 -05:00
|
|
|
|
2018-10-04 16:49:53 -07:00
|
|
|
func cmpZero(x int, op Op) bool {
|
|
|
|
|
switch op {
|
|
|
|
|
case OEQ:
|
|
|
|
|
return x == 0
|
|
|
|
|
case ONE:
|
|
|
|
|
return x != 0
|
|
|
|
|
case OLT:
|
|
|
|
|
return x < 0
|
|
|
|
|
case OLE:
|
|
|
|
|
return x <= 0
|
|
|
|
|
case OGT:
|
|
|
|
|
return x > 0
|
|
|
|
|
case OGE:
|
|
|
|
|
return x >= 0
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Fatalf("cmpZero: want comparison operator, got %v", op)
|
|
|
|
|
panic("unreachable")
|
|
|
|
|
}
|
2015-02-13 14:40:36 -05:00
|
|
|
|
2018-10-04 16:49:53 -07:00
|
|
|
func binaryOp(x Val, op Op, y Val) Val {
|
|
|
|
|
x, y = match(x, y)
|
2015-02-13 14:40:36 -05:00
|
|
|
|
2018-10-04 16:49:53 -07:00
|
|
|
Outer:
|
|
|
|
|
switch x.Ctype() {
|
|
|
|
|
case CTBOOL:
|
|
|
|
|
x, y := x.U.(bool), y.U.(bool)
|
|
|
|
|
switch op {
|
|
|
|
|
case OANDAND:
|
|
|
|
|
return Val{U: x && y}
|
|
|
|
|
case OOROR:
|
|
|
|
|
return Val{U: x || y}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
case CTINT, CTRUNE:
|
|
|
|
|
x, y := x.U.(*Mpint), y.U.(*Mpint)
|
|
|
|
|
|
|
|
|
|
u := new(Mpint)
|
|
|
|
|
u.Rune = x.Rune || y.Rune
|
|
|
|
|
u.Set(x)
|
|
|
|
|
switch op {
|
|
|
|
|
case OADD:
|
|
|
|
|
u.Add(y)
|
|
|
|
|
case OSUB:
|
|
|
|
|
u.Sub(y)
|
|
|
|
|
case OMUL:
|
|
|
|
|
u.Mul(y)
|
|
|
|
|
case ODIV:
|
|
|
|
|
if y.CmpInt64(0) == 0 {
|
|
|
|
|
yyerror("division by zero")
|
2019-03-27 12:15:47 -07:00
|
|
|
return Val{}
|
2018-10-04 16:49:53 -07:00
|
|
|
}
|
|
|
|
|
u.Quo(y)
|
|
|
|
|
case OMOD:
|
|
|
|
|
if y.CmpInt64(0) == 0 {
|
|
|
|
|
yyerror("division by zero")
|
2019-03-27 12:15:47 -07:00
|
|
|
return Val{}
|
2018-10-04 16:49:53 -07:00
|
|
|
}
|
|
|
|
|
u.Rem(y)
|
|
|
|
|
case OOR:
|
|
|
|
|
u.Or(y)
|
|
|
|
|
case OAND:
|
|
|
|
|
u.And(y)
|
|
|
|
|
case OANDNOT:
|
|
|
|
|
u.AndNot(y)
|
|
|
|
|
case OXOR:
|
|
|
|
|
u.Xor(y)
|
|
|
|
|
default:
|
|
|
|
|
break Outer
|
|
|
|
|
}
|
|
|
|
|
return Val{U: u}
|
|
|
|
|
|
|
|
|
|
case CTFLT:
|
|
|
|
|
x, y := x.U.(*Mpflt), y.U.(*Mpflt)
|
|
|
|
|
|
|
|
|
|
u := newMpflt()
|
|
|
|
|
u.Set(x)
|
|
|
|
|
switch op {
|
|
|
|
|
case OADD:
|
|
|
|
|
u.Add(y)
|
|
|
|
|
case OSUB:
|
|
|
|
|
u.Sub(y)
|
|
|
|
|
case OMUL:
|
|
|
|
|
u.Mul(y)
|
|
|
|
|
case ODIV:
|
|
|
|
|
if y.CmpFloat64(0) == 0 {
|
|
|
|
|
yyerror("division by zero")
|
2019-03-27 12:15:47 -07:00
|
|
|
return Val{}
|
2018-10-04 16:49:53 -07:00
|
|
|
}
|
|
|
|
|
u.Quo(y)
|
2019-03-27 12:15:47 -07:00
|
|
|
case OMOD, OOR, OAND, OANDNOT, OXOR:
|
|
|
|
|
// TODO(mdempsky): Move to typecheck; see #31060.
|
|
|
|
|
yyerror("invalid operation: operator %v not defined on untyped float", op)
|
|
|
|
|
return Val{}
|
2018-10-04 16:49:53 -07:00
|
|
|
default:
|
|
|
|
|
break Outer
|
|
|
|
|
}
|
|
|
|
|
return Val{U: u}
|
|
|
|
|
|
|
|
|
|
case CTCPLX:
|
|
|
|
|
x, y := x.U.(*Mpcplx), y.U.(*Mpcplx)
|
|
|
|
|
|
2019-02-17 15:35:52 -08:00
|
|
|
u := newMpcmplx()
|
2018-10-04 16:49:53 -07:00
|
|
|
u.Real.Set(&x.Real)
|
|
|
|
|
u.Imag.Set(&x.Imag)
|
|
|
|
|
switch op {
|
|
|
|
|
case OADD:
|
|
|
|
|
u.Real.Add(&y.Real)
|
|
|
|
|
u.Imag.Add(&y.Imag)
|
|
|
|
|
case OSUB:
|
|
|
|
|
u.Real.Sub(&y.Real)
|
|
|
|
|
u.Imag.Sub(&y.Imag)
|
|
|
|
|
case OMUL:
|
|
|
|
|
u.Mul(y)
|
|
|
|
|
case ODIV:
|
|
|
|
|
if !u.Div(y) {
|
|
|
|
|
yyerror("complex division by zero")
|
2019-03-27 12:15:47 -07:00
|
|
|
return Val{}
|
2018-10-04 16:49:53 -07:00
|
|
|
}
|
2019-03-27 12:15:47 -07:00
|
|
|
case OMOD, OOR, OAND, OANDNOT, OXOR:
|
|
|
|
|
// TODO(mdempsky): Move to typecheck; see #31060.
|
|
|
|
|
yyerror("invalid operation: operator %v not defined on untyped complex", op)
|
|
|
|
|
return Val{}
|
2018-10-04 16:49:53 -07:00
|
|
|
default:
|
|
|
|
|
break Outer
|
|
|
|
|
}
|
|
|
|
|
return Val{U: u}
|
2015-02-13 14:40:36 -05:00
|
|
|
}
|
|
|
|
|
|
2018-10-04 16:49:53 -07:00
|
|
|
Fatalf("binaryOp: bad operation: %v %v %v", x, op, y)
|
|
|
|
|
panic("unreachable")
|
|
|
|
|
}
|
2015-02-13 14:40:36 -05:00
|
|
|
|
2018-10-04 16:49:53 -07:00
|
|
|
func unaryOp(op Op, x Val, t *types.Type) Val {
|
|
|
|
|
switch op {
|
|
|
|
|
case OPLUS:
|
|
|
|
|
switch x.Ctype() {
|
|
|
|
|
case CTINT, CTRUNE, CTFLT, CTCPLX:
|
|
|
|
|
return x
|
|
|
|
|
}
|
|
|
|
|
|
2018-11-18 08:34:38 -08:00
|
|
|
case ONEG:
|
2018-10-04 16:49:53 -07:00
|
|
|
switch x.Ctype() {
|
|
|
|
|
case CTINT, CTRUNE:
|
|
|
|
|
x := x.U.(*Mpint)
|
|
|
|
|
u := new(Mpint)
|
|
|
|
|
u.Rune = x.Rune
|
|
|
|
|
u.Set(x)
|
|
|
|
|
u.Neg()
|
|
|
|
|
return Val{U: u}
|
|
|
|
|
|
|
|
|
|
case CTFLT:
|
|
|
|
|
x := x.U.(*Mpflt)
|
|
|
|
|
u := newMpflt()
|
|
|
|
|
u.Set(x)
|
|
|
|
|
u.Neg()
|
|
|
|
|
return Val{U: u}
|
|
|
|
|
|
|
|
|
|
case CTCPLX:
|
|
|
|
|
x := x.U.(*Mpcplx)
|
2019-02-17 15:35:52 -08:00
|
|
|
u := newMpcmplx()
|
2018-10-04 16:49:53 -07:00
|
|
|
u.Real.Set(&x.Real)
|
|
|
|
|
u.Imag.Set(&x.Imag)
|
|
|
|
|
u.Real.Neg()
|
|
|
|
|
u.Imag.Neg()
|
|
|
|
|
return Val{U: u}
|
|
|
|
|
}
|
|
|
|
|
|
2018-11-18 08:34:38 -08:00
|
|
|
case OBITNOT:
|
2019-03-27 12:15:47 -07:00
|
|
|
switch x.Ctype() {
|
|
|
|
|
case CTINT, CTRUNE:
|
|
|
|
|
x := x.U.(*Mpint)
|
2018-10-04 16:49:53 -07:00
|
|
|
|
2019-03-27 12:15:47 -07:00
|
|
|
u := new(Mpint)
|
|
|
|
|
u.Rune = x.Rune
|
|
|
|
|
if t.IsSigned() || t.IsUntyped() {
|
|
|
|
|
// Signed values change sign.
|
|
|
|
|
u.SetInt64(-1)
|
|
|
|
|
} else {
|
|
|
|
|
// Unsigned values invert their bits.
|
|
|
|
|
u.Set(maxintval[t.Etype])
|
|
|
|
|
}
|
|
|
|
|
u.Xor(x)
|
|
|
|
|
return Val{U: u}
|
|
|
|
|
|
|
|
|
|
case CTFLT:
|
|
|
|
|
// TODO(mdempsky): Move to typecheck; see #31060.
|
|
|
|
|
yyerror("invalid operation: operator %v not defined on untyped float", op)
|
|
|
|
|
return Val{}
|
|
|
|
|
case CTCPLX:
|
|
|
|
|
// TODO(mdempsky): Move to typecheck; see #31060.
|
|
|
|
|
yyerror("invalid operation: operator %v not defined on untyped complex", op)
|
|
|
|
|
return Val{}
|
2015-02-13 14:40:36 -05:00
|
|
|
}
|
|
|
|
|
|
2018-10-04 16:49:53 -07:00
|
|
|
case ONOT:
|
|
|
|
|
return Val{U: !x.U.(bool)}
|
2017-04-07 08:31:52 +02:00
|
|
|
}
|
|
|
|
|
|
2018-10-04 16:49:53 -07:00
|
|
|
Fatalf("unaryOp: bad operation: %v %v", op, x)
|
|
|
|
|
panic("unreachable")
|
|
|
|
|
}
|
2015-02-13 14:40:36 -05:00
|
|
|
|
2018-10-04 16:49:53 -07:00
|
|
|
func shiftOp(x Val, op Op, y Val) Val {
|
|
|
|
|
if x.Ctype() != CTRUNE {
|
|
|
|
|
x = toint(x)
|
2015-02-13 14:40:36 -05:00
|
|
|
}
|
2018-10-04 16:49:53 -07:00
|
|
|
y = toint(y)
|
2015-02-13 14:40:36 -05:00
|
|
|
|
2018-10-04 16:49:53 -07:00
|
|
|
u := new(Mpint)
|
|
|
|
|
u.Set(x.U.(*Mpint))
|
|
|
|
|
u.Rune = x.U.(*Mpint).Rune
|
|
|
|
|
switch op {
|
|
|
|
|
case OLSH:
|
|
|
|
|
u.Lsh(y.U.(*Mpint))
|
|
|
|
|
case ORSH:
|
|
|
|
|
u.Rsh(y.U.(*Mpint))
|
|
|
|
|
default:
|
|
|
|
|
Fatalf("shiftOp: bad operator: %v", op)
|
|
|
|
|
panic("unreachable")
|
2015-02-13 14:40:36 -05:00
|
|
|
}
|
2018-10-04 16:49:53 -07:00
|
|
|
return Val{U: u}
|
2015-02-13 14:40:36 -05:00
|
|
|
}
|
|
|
|
|
|
2018-03-31 16:49:07 -07:00
|
|
|
// setconst rewrites n as an OLITERAL with value v.
|
|
|
|
|
func setconst(n *Node, v Val) {
|
2019-03-27 12:15:47 -07:00
|
|
|
// If constant folding failed, mark n as broken and give up.
|
|
|
|
|
if v.U == nil {
|
|
|
|
|
n.Type = nil
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
2018-03-31 16:49:07 -07:00
|
|
|
// Ensure n.Orig still points to a semantically-equivalent
|
|
|
|
|
// expression after we rewrite n into a constant.
|
|
|
|
|
if n.Orig == n {
|
2018-09-20 15:22:33 -07:00
|
|
|
n.Orig = n.sepcopy()
|
2018-03-31 16:49:07 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
*n = Node{
|
|
|
|
|
Op: OLITERAL,
|
|
|
|
|
Pos: n.Pos,
|
|
|
|
|
Orig: n.Orig,
|
|
|
|
|
Type: n.Type,
|
|
|
|
|
Xoffset: BADWIDTH,
|
|
|
|
|
}
|
|
|
|
|
n.SetVal(v)
|
2019-09-06 16:05:36 -07:00
|
|
|
if n.Type.IsUntyped() {
|
|
|
|
|
// TODO(mdempsky): Make typecheck responsible for setting
|
|
|
|
|
// the correct untyped type.
|
|
|
|
|
n.Type = idealType(v.Ctype())
|
|
|
|
|
}
|
2018-03-31 16:49:07 -07:00
|
|
|
|
|
|
|
|
// Check range.
|
|
|
|
|
lno := setlineno(n)
|
|
|
|
|
overflow(v, n.Type)
|
|
|
|
|
lineno = lno
|
|
|
|
|
|
2019-07-26 13:22:08 +08:00
|
|
|
if !n.Type.IsUntyped() {
|
|
|
|
|
switch v.Ctype() {
|
|
|
|
|
// Truncate precision for non-ideal float.
|
|
|
|
|
case CTFLT:
|
|
|
|
|
n.SetVal(Val{truncfltlit(v.U.(*Mpflt), n.Type)})
|
|
|
|
|
// Truncate precision for non-ideal complex.
|
|
|
|
|
case CTCPLX:
|
|
|
|
|
n.SetVal(Val{trunccmplxlit(v.U.(*Mpcplx), n.Type)})
|
|
|
|
|
}
|
2018-03-31 16:49:07 -07:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2018-10-04 16:49:53 -07:00
|
|
|
func setboolconst(n *Node, v bool) {
|
|
|
|
|
setconst(n, Val{U: v})
|
|
|
|
|
}
|
|
|
|
|
|
2018-03-31 16:49:07 -07:00
|
|
|
func setintconst(n *Node, v int64) {
|
|
|
|
|
u := new(Mpint)
|
|
|
|
|
u.SetInt64(v)
|
|
|
|
|
setconst(n, Val{u})
|
|
|
|
|
}
|
|
|
|
|
|
2018-03-31 15:53:21 -07:00
|
|
|
// nodlit returns a new untyped constant with value v.
|
2015-02-13 14:40:36 -05:00
|
|
|
func nodlit(v Val) *Node {
|
2016-09-16 11:00:54 +10:00
|
|
|
n := nod(OLITERAL, nil, nil)
|
2015-05-27 00:47:05 -04:00
|
|
|
n.SetVal(v)
|
2019-09-06 16:05:36 -07:00
|
|
|
n.Type = idealType(v.Ctype())
|
|
|
|
|
return n
|
|
|
|
|
}
|
2015-02-13 14:40:36 -05:00
|
|
|
|
2019-09-06 16:05:36 -07:00
|
|
|
func idealType(ct Ctype) *types.Type {
|
|
|
|
|
switch ct {
|
2015-02-13 14:40:36 -05:00
|
|
|
case CTSTR:
|
2019-09-06 16:05:36 -07:00
|
|
|
return types.Idealstring
|
2015-02-13 14:40:36 -05:00
|
|
|
case CTBOOL:
|
2019-09-06 16:05:36 -07:00
|
|
|
return types.Idealbool
|
|
|
|
|
case CTINT:
|
|
|
|
|
return types.Idealint
|
|
|
|
|
case CTRUNE:
|
|
|
|
|
return types.Idealrune
|
|
|
|
|
case CTFLT:
|
|
|
|
|
return types.Idealfloat
|
|
|
|
|
case CTCPLX:
|
|
|
|
|
return types.Idealcomplex
|
2015-02-13 14:40:36 -05:00
|
|
|
case CTNIL:
|
2019-09-06 16:05:36 -07:00
|
|
|
return types.Types[TNIL]
|
2015-02-13 14:40:36 -05:00
|
|
|
}
|
2019-09-06 16:05:36 -07:00
|
|
|
Fatalf("unexpected Ctype: %v", ct)
|
|
|
|
|
return nil
|
2015-02-13 14:40:36 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// idealkind returns a constant kind like consttype
|
|
|
|
|
// but for an arbitrary "ideal" (untyped constant) expression.
|
2015-10-26 16:00:59 -07:00
|
|
|
func idealkind(n *Node) Ctype {
|
2016-04-01 13:36:24 -07:00
|
|
|
if n == nil || !n.Type.IsUntyped() {
|
2015-02-13 14:40:36 -05:00
|
|
|
return CTxxx
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
switch n.Op {
|
|
|
|
|
default:
|
|
|
|
|
return CTxxx
|
|
|
|
|
|
|
|
|
|
case OLITERAL:
|
2015-10-26 16:00:59 -07:00
|
|
|
return n.Val().Ctype()
|
2015-02-13 14:40:36 -05:00
|
|
|
|
|
|
|
|
// numeric kinds.
|
|
|
|
|
case OADD,
|
|
|
|
|
OAND,
|
|
|
|
|
OANDNOT,
|
2018-11-18 08:34:38 -08:00
|
|
|
OBITNOT,
|
2015-02-13 14:40:36 -05:00
|
|
|
ODIV,
|
2018-11-18 08:34:38 -08:00
|
|
|
ONEG,
|
2015-02-13 14:40:36 -05:00
|
|
|
OMOD,
|
|
|
|
|
OMUL,
|
|
|
|
|
OSUB,
|
|
|
|
|
OXOR,
|
|
|
|
|
OOR,
|
|
|
|
|
OPLUS:
|
2015-02-23 16:07:24 -05:00
|
|
|
k1 := idealkind(n.Left)
|
|
|
|
|
k2 := idealkind(n.Right)
|
2015-02-13 14:40:36 -05:00
|
|
|
if k1 > k2 {
|
|
|
|
|
return k1
|
|
|
|
|
} else {
|
|
|
|
|
return k2
|
|
|
|
|
}
|
|
|
|
|
|
2015-04-01 09:38:44 -07:00
|
|
|
case OREAL, OIMAG:
|
2015-02-13 14:40:36 -05:00
|
|
|
return CTFLT
|
|
|
|
|
|
|
|
|
|
case OCOMPLEX:
|
|
|
|
|
return CTCPLX
|
|
|
|
|
|
|
|
|
|
case OADDSTR:
|
|
|
|
|
return CTSTR
|
|
|
|
|
|
|
|
|
|
case OANDAND,
|
|
|
|
|
OEQ,
|
|
|
|
|
OGE,
|
|
|
|
|
OGT,
|
|
|
|
|
OLE,
|
|
|
|
|
OLT,
|
|
|
|
|
ONE,
|
|
|
|
|
ONOT,
|
2018-10-10 16:47:47 -07:00
|
|
|
OOROR:
|
2015-02-13 14:40:36 -05:00
|
|
|
return CTBOOL
|
|
|
|
|
|
|
|
|
|
// shifts (beware!).
|
2015-04-01 09:38:44 -07:00
|
|
|
case OLSH, ORSH:
|
2015-02-13 14:40:36 -05:00
|
|
|
return idealkind(n.Left)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2015-10-22 09:51:12 +09:00
|
|
|
// defaultlit on both nodes simultaneously;
|
|
|
|
|
// if they're both ideal going in they better
|
|
|
|
|
// get the same type going out.
|
|
|
|
|
// force means must assign concrete (non-ideal) type.
|
cmd/compile: reduce use of **Node parameters
Escape analysis has a hard time with tree-like
structures (see #13493 and #14858).
This is unlikely to change.
As a result, when invoking a function that accepts
a **Node parameter, we usually allocate a *Node
on the heap. This happens a whole lot.
This CL changes functions from taking a **Node
to acting more like append: It both modifies
the input and returns a replacement for it.
Because of the cascading nature of escape analysis,
in order to get the benefits, I had to modify
almost all such functions. The remaining functions
are in racewalk and the backend. I would be happy
to update them as well in a separate CL.
This CL was created by manually updating the
function signatures and the directly impacted
bits of code. The callsites were then automatically
updated using a bespoke script:
https://gist.github.com/josharian/046b1be7aceae244de39
For ease of reviewing and future understanding,
this CL is also broken down into four CLs,
mailed separately, which show the manual
and the automated changes separately.
They are CLs 20990, 20991, 20992, and 20993.
Passes toolstash -cmp.
name old time/op new time/op delta
Template 335ms ± 5% 324ms ± 5% -3.35% (p=0.000 n=23+24)
Unicode 176ms ± 9% 165ms ± 6% -6.12% (p=0.000 n=23+24)
GoTypes 1.10s ± 4% 1.07s ± 2% -2.77% (p=0.000 n=24+24)
Compiler 5.31s ± 3% 5.15s ± 3% -2.95% (p=0.000 n=24+24)
MakeBash 41.6s ± 1% 41.7s ± 2% ~ (p=0.586 n=23+23)
name old alloc/op new alloc/op delta
Template 63.3MB ± 0% 62.4MB ± 0% -1.36% (p=0.000 n=25+23)
Unicode 42.4MB ± 0% 41.6MB ± 0% -1.99% (p=0.000 n=24+25)
GoTypes 220MB ± 0% 217MB ± 0% -1.11% (p=0.000 n=25+25)
Compiler 994MB ± 0% 973MB ± 0% -2.08% (p=0.000 n=24+25)
name old allocs/op new allocs/op delta
Template 681k ± 0% 574k ± 0% -15.71% (p=0.000 n=24+25)
Unicode 518k ± 0% 413k ± 0% -20.34% (p=0.000 n=25+24)
GoTypes 2.08M ± 0% 1.78M ± 0% -14.62% (p=0.000 n=25+25)
Compiler 9.26M ± 0% 7.64M ± 0% -17.48% (p=0.000 n=25+25)
name old text-bytes new text-bytes delta
HelloSize 578k ± 0% 578k ± 0% ~ (all samples are equal)
CmdGoSize 6.46M ± 0% 6.46M ± 0% ~ (all samples are equal)
name old data-bytes new data-bytes delta
HelloSize 128k ± 0% 128k ± 0% ~ (all samples are equal)
CmdGoSize 281k ± 0% 281k ± 0% ~ (all samples are equal)
name old exe-bytes new exe-bytes delta
HelloSize 921k ± 0% 921k ± 0% ~ (all samples are equal)
CmdGoSize 9.86M ± 0% 9.86M ± 0% ~ (all samples are equal)
Change-Id: I277d95bd56d51c166ef7f560647aeaa092f3f475
Reviewed-on: https://go-review.googlesource.com/20959
Reviewed-by: Dave Cheney <dave@cheney.net>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
2016-03-20 08:03:31 -07:00
|
|
|
// The results of defaultlit2 MUST be assigned back to l and r, e.g.
|
|
|
|
|
// n.Left, n.Right = defaultlit2(n.Left, n.Right, force)
|
|
|
|
|
func defaultlit2(l *Node, r *Node, force bool) (*Node, *Node) {
|
2015-02-13 14:40:36 -05:00
|
|
|
if l.Type == nil || r.Type == nil {
|
cmd/compile: reduce use of **Node parameters
Escape analysis has a hard time with tree-like
structures (see #13493 and #14858).
This is unlikely to change.
As a result, when invoking a function that accepts
a **Node parameter, we usually allocate a *Node
on the heap. This happens a whole lot.
This CL changes functions from taking a **Node
to acting more like append: It both modifies
the input and returns a replacement for it.
Because of the cascading nature of escape analysis,
in order to get the benefits, I had to modify
almost all such functions. The remaining functions
are in racewalk and the backend. I would be happy
to update them as well in a separate CL.
This CL was created by manually updating the
function signatures and the directly impacted
bits of code. The callsites were then automatically
updated using a bespoke script:
https://gist.github.com/josharian/046b1be7aceae244de39
For ease of reviewing and future understanding,
this CL is also broken down into four CLs,
mailed separately, which show the manual
and the automated changes separately.
They are CLs 20990, 20991, 20992, and 20993.
Passes toolstash -cmp.
name old time/op new time/op delta
Template 335ms ± 5% 324ms ± 5% -3.35% (p=0.000 n=23+24)
Unicode 176ms ± 9% 165ms ± 6% -6.12% (p=0.000 n=23+24)
GoTypes 1.10s ± 4% 1.07s ± 2% -2.77% (p=0.000 n=24+24)
Compiler 5.31s ± 3% 5.15s ± 3% -2.95% (p=0.000 n=24+24)
MakeBash 41.6s ± 1% 41.7s ± 2% ~ (p=0.586 n=23+23)
name old alloc/op new alloc/op delta
Template 63.3MB ± 0% 62.4MB ± 0% -1.36% (p=0.000 n=25+23)
Unicode 42.4MB ± 0% 41.6MB ± 0% -1.99% (p=0.000 n=24+25)
GoTypes 220MB ± 0% 217MB ± 0% -1.11% (p=0.000 n=25+25)
Compiler 994MB ± 0% 973MB ± 0% -2.08% (p=0.000 n=24+25)
name old allocs/op new allocs/op delta
Template 681k ± 0% 574k ± 0% -15.71% (p=0.000 n=24+25)
Unicode 518k ± 0% 413k ± 0% -20.34% (p=0.000 n=25+24)
GoTypes 2.08M ± 0% 1.78M ± 0% -14.62% (p=0.000 n=25+25)
Compiler 9.26M ± 0% 7.64M ± 0% -17.48% (p=0.000 n=25+25)
name old text-bytes new text-bytes delta
HelloSize 578k ± 0% 578k ± 0% ~ (all samples are equal)
CmdGoSize 6.46M ± 0% 6.46M ± 0% ~ (all samples are equal)
name old data-bytes new data-bytes delta
HelloSize 128k ± 0% 128k ± 0% ~ (all samples are equal)
CmdGoSize 281k ± 0% 281k ± 0% ~ (all samples are equal)
name old exe-bytes new exe-bytes delta
HelloSize 921k ± 0% 921k ± 0% ~ (all samples are equal)
CmdGoSize 9.86M ± 0% 9.86M ± 0% ~ (all samples are equal)
Change-Id: I277d95bd56d51c166ef7f560647aeaa092f3f475
Reviewed-on: https://go-review.googlesource.com/20959
Reviewed-by: Dave Cheney <dave@cheney.net>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
2016-03-20 08:03:31 -07:00
|
|
|
return l, r
|
2015-02-13 14:40:36 -05:00
|
|
|
}
|
2016-04-01 13:36:24 -07:00
|
|
|
if !l.Type.IsUntyped() {
|
cmd/compile: reduce use of **Node parameters
Escape analysis has a hard time with tree-like
structures (see #13493 and #14858).
This is unlikely to change.
As a result, when invoking a function that accepts
a **Node parameter, we usually allocate a *Node
on the heap. This happens a whole lot.
This CL changes functions from taking a **Node
to acting more like append: It both modifies
the input and returns a replacement for it.
Because of the cascading nature of escape analysis,
in order to get the benefits, I had to modify
almost all such functions. The remaining functions
are in racewalk and the backend. I would be happy
to update them as well in a separate CL.
This CL was created by manually updating the
function signatures and the directly impacted
bits of code. The callsites were then automatically
updated using a bespoke script:
https://gist.github.com/josharian/046b1be7aceae244de39
For ease of reviewing and future understanding,
this CL is also broken down into four CLs,
mailed separately, which show the manual
and the automated changes separately.
They are CLs 20990, 20991, 20992, and 20993.
Passes toolstash -cmp.
name old time/op new time/op delta
Template 335ms ± 5% 324ms ± 5% -3.35% (p=0.000 n=23+24)
Unicode 176ms ± 9% 165ms ± 6% -6.12% (p=0.000 n=23+24)
GoTypes 1.10s ± 4% 1.07s ± 2% -2.77% (p=0.000 n=24+24)
Compiler 5.31s ± 3% 5.15s ± 3% -2.95% (p=0.000 n=24+24)
MakeBash 41.6s ± 1% 41.7s ± 2% ~ (p=0.586 n=23+23)
name old alloc/op new alloc/op delta
Template 63.3MB ± 0% 62.4MB ± 0% -1.36% (p=0.000 n=25+23)
Unicode 42.4MB ± 0% 41.6MB ± 0% -1.99% (p=0.000 n=24+25)
GoTypes 220MB ± 0% 217MB ± 0% -1.11% (p=0.000 n=25+25)
Compiler 994MB ± 0% 973MB ± 0% -2.08% (p=0.000 n=24+25)
name old allocs/op new allocs/op delta
Template 681k ± 0% 574k ± 0% -15.71% (p=0.000 n=24+25)
Unicode 518k ± 0% 413k ± 0% -20.34% (p=0.000 n=25+24)
GoTypes 2.08M ± 0% 1.78M ± 0% -14.62% (p=0.000 n=25+25)
Compiler 9.26M ± 0% 7.64M ± 0% -17.48% (p=0.000 n=25+25)
name old text-bytes new text-bytes delta
HelloSize 578k ± 0% 578k ± 0% ~ (all samples are equal)
CmdGoSize 6.46M ± 0% 6.46M ± 0% ~ (all samples are equal)
name old data-bytes new data-bytes delta
HelloSize 128k ± 0% 128k ± 0% ~ (all samples are equal)
CmdGoSize 281k ± 0% 281k ± 0% ~ (all samples are equal)
name old exe-bytes new exe-bytes delta
HelloSize 921k ± 0% 921k ± 0% ~ (all samples are equal)
CmdGoSize 9.86M ± 0% 9.86M ± 0% ~ (all samples are equal)
Change-Id: I277d95bd56d51c166ef7f560647aeaa092f3f475
Reviewed-on: https://go-review.googlesource.com/20959
Reviewed-by: Dave Cheney <dave@cheney.net>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
2016-03-20 08:03:31 -07:00
|
|
|
r = convlit(r, l.Type)
|
|
|
|
|
return l, r
|
2015-02-13 14:40:36 -05:00
|
|
|
}
|
|
|
|
|
|
2016-04-01 13:36:24 -07:00
|
|
|
if !r.Type.IsUntyped() {
|
cmd/compile: reduce use of **Node parameters
Escape analysis has a hard time with tree-like
structures (see #13493 and #14858).
This is unlikely to change.
As a result, when invoking a function that accepts
a **Node parameter, we usually allocate a *Node
on the heap. This happens a whole lot.
This CL changes functions from taking a **Node
to acting more like append: It both modifies
the input and returns a replacement for it.
Because of the cascading nature of escape analysis,
in order to get the benefits, I had to modify
almost all such functions. The remaining functions
are in racewalk and the backend. I would be happy
to update them as well in a separate CL.
This CL was created by manually updating the
function signatures and the directly impacted
bits of code. The callsites were then automatically
updated using a bespoke script:
https://gist.github.com/josharian/046b1be7aceae244de39
For ease of reviewing and future understanding,
this CL is also broken down into four CLs,
mailed separately, which show the manual
and the automated changes separately.
They are CLs 20990, 20991, 20992, and 20993.
Passes toolstash -cmp.
name old time/op new time/op delta
Template 335ms ± 5% 324ms ± 5% -3.35% (p=0.000 n=23+24)
Unicode 176ms ± 9% 165ms ± 6% -6.12% (p=0.000 n=23+24)
GoTypes 1.10s ± 4% 1.07s ± 2% -2.77% (p=0.000 n=24+24)
Compiler 5.31s ± 3% 5.15s ± 3% -2.95% (p=0.000 n=24+24)
MakeBash 41.6s ± 1% 41.7s ± 2% ~ (p=0.586 n=23+23)
name old alloc/op new alloc/op delta
Template 63.3MB ± 0% 62.4MB ± 0% -1.36% (p=0.000 n=25+23)
Unicode 42.4MB ± 0% 41.6MB ± 0% -1.99% (p=0.000 n=24+25)
GoTypes 220MB ± 0% 217MB ± 0% -1.11% (p=0.000 n=25+25)
Compiler 994MB ± 0% 973MB ± 0% -2.08% (p=0.000 n=24+25)
name old allocs/op new allocs/op delta
Template 681k ± 0% 574k ± 0% -15.71% (p=0.000 n=24+25)
Unicode 518k ± 0% 413k ± 0% -20.34% (p=0.000 n=25+24)
GoTypes 2.08M ± 0% 1.78M ± 0% -14.62% (p=0.000 n=25+25)
Compiler 9.26M ± 0% 7.64M ± 0% -17.48% (p=0.000 n=25+25)
name old text-bytes new text-bytes delta
HelloSize 578k ± 0% 578k ± 0% ~ (all samples are equal)
CmdGoSize 6.46M ± 0% 6.46M ± 0% ~ (all samples are equal)
name old data-bytes new data-bytes delta
HelloSize 128k ± 0% 128k ± 0% ~ (all samples are equal)
CmdGoSize 281k ± 0% 281k ± 0% ~ (all samples are equal)
name old exe-bytes new exe-bytes delta
HelloSize 921k ± 0% 921k ± 0% ~ (all samples are equal)
CmdGoSize 9.86M ± 0% 9.86M ± 0% ~ (all samples are equal)
Change-Id: I277d95bd56d51c166ef7f560647aeaa092f3f475
Reviewed-on: https://go-review.googlesource.com/20959
Reviewed-by: Dave Cheney <dave@cheney.net>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
2016-03-20 08:03:31 -07:00
|
|
|
l = convlit(l, r.Type)
|
|
|
|
|
return l, r
|
2015-02-13 14:40:36 -05:00
|
|
|
}
|
|
|
|
|
|
2016-03-01 00:15:27 -08:00
|
|
|
if !force {
|
cmd/compile: reduce use of **Node parameters
Escape analysis has a hard time with tree-like
structures (see #13493 and #14858).
This is unlikely to change.
As a result, when invoking a function that accepts
a **Node parameter, we usually allocate a *Node
on the heap. This happens a whole lot.
This CL changes functions from taking a **Node
to acting more like append: It both modifies
the input and returns a replacement for it.
Because of the cascading nature of escape analysis,
in order to get the benefits, I had to modify
almost all such functions. The remaining functions
are in racewalk and the backend. I would be happy
to update them as well in a separate CL.
This CL was created by manually updating the
function signatures and the directly impacted
bits of code. The callsites were then automatically
updated using a bespoke script:
https://gist.github.com/josharian/046b1be7aceae244de39
For ease of reviewing and future understanding,
this CL is also broken down into four CLs,
mailed separately, which show the manual
and the automated changes separately.
They are CLs 20990, 20991, 20992, and 20993.
Passes toolstash -cmp.
name old time/op new time/op delta
Template 335ms ± 5% 324ms ± 5% -3.35% (p=0.000 n=23+24)
Unicode 176ms ± 9% 165ms ± 6% -6.12% (p=0.000 n=23+24)
GoTypes 1.10s ± 4% 1.07s ± 2% -2.77% (p=0.000 n=24+24)
Compiler 5.31s ± 3% 5.15s ± 3% -2.95% (p=0.000 n=24+24)
MakeBash 41.6s ± 1% 41.7s ± 2% ~ (p=0.586 n=23+23)
name old alloc/op new alloc/op delta
Template 63.3MB ± 0% 62.4MB ± 0% -1.36% (p=0.000 n=25+23)
Unicode 42.4MB ± 0% 41.6MB ± 0% -1.99% (p=0.000 n=24+25)
GoTypes 220MB ± 0% 217MB ± 0% -1.11% (p=0.000 n=25+25)
Compiler 994MB ± 0% 973MB ± 0% -2.08% (p=0.000 n=24+25)
name old allocs/op new allocs/op delta
Template 681k ± 0% 574k ± 0% -15.71% (p=0.000 n=24+25)
Unicode 518k ± 0% 413k ± 0% -20.34% (p=0.000 n=25+24)
GoTypes 2.08M ± 0% 1.78M ± 0% -14.62% (p=0.000 n=25+25)
Compiler 9.26M ± 0% 7.64M ± 0% -17.48% (p=0.000 n=25+25)
name old text-bytes new text-bytes delta
HelloSize 578k ± 0% 578k ± 0% ~ (all samples are equal)
CmdGoSize 6.46M ± 0% 6.46M ± 0% ~ (all samples are equal)
name old data-bytes new data-bytes delta
HelloSize 128k ± 0% 128k ± 0% ~ (all samples are equal)
CmdGoSize 281k ± 0% 281k ± 0% ~ (all samples are equal)
name old exe-bytes new exe-bytes delta
HelloSize 921k ± 0% 921k ± 0% ~ (all samples are equal)
CmdGoSize 9.86M ± 0% 9.86M ± 0% ~ (all samples are equal)
Change-Id: I277d95bd56d51c166ef7f560647aeaa092f3f475
Reviewed-on: https://go-review.googlesource.com/20959
Reviewed-by: Dave Cheney <dave@cheney.net>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
2016-03-20 08:03:31 -07:00
|
|
|
return l, r
|
2015-02-13 14:40:36 -05:00
|
|
|
}
|
2016-03-01 00:15:27 -08:00
|
|
|
|
cmd/compile: rewrite untyped constant conversion logic
This CL detangles the hairy mess that was convlit+defaultlit. In
particular, it makes the following changes:
1. convlit1 now follows the standard typecheck behavior of setting
"n.Type = nil" if there's an error. Notably, this means for a lot of
test cases, we now avoid reporting useless follow-on error messages.
For example, after reporting that "1 << s + 1.0" has an invalid shift,
we no longer also report that it can't be assigned to string.
2. Previously, assignconvfn had some extra logic for trying to
suppress errors from convlit/defaultlit so that it could provide its
own errors with better context information. Instead, this extra
context information is now passed down into convlit1 directly.
3. Relatedly, this CL also removes redundant calls to defaultlit prior
to assignconv. As a consequence, when an expression doesn't make sense
for a particular assignment (e.g., assigning an untyped string to an
integer), the error messages now say "untyped string" instead of just
"string". This is more consistent with go/types behavior.
4. defaultlit2 is now smarter about only trying to convert pairs of
untyped constants when it's likely to succeed. This allows us to
report better error messages for things like 3+"x"; instead of "cannot
convert 3 to string" we now report "mismatched types untyped number
and untyped string".
Passes toolstash-check.
Change-Id: I26822a02dc35855bd0ac774907b1cf5737e91882
Reviewed-on: https://go-review.googlesource.com/c/go/+/187657
Run-TryBot: Matthew Dempsky <mdempsky@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Robert Griesemer <gri@golang.org>
2019-09-05 13:33:06 -07:00
|
|
|
// Can't mix bool with non-bool, string with non-string, or nil with anything (untyped).
|
|
|
|
|
if l.Type.IsBoolean() != r.Type.IsBoolean() {
|
cmd/compile: reduce use of **Node parameters
Escape analysis has a hard time with tree-like
structures (see #13493 and #14858).
This is unlikely to change.
As a result, when invoking a function that accepts
a **Node parameter, we usually allocate a *Node
on the heap. This happens a whole lot.
This CL changes functions from taking a **Node
to acting more like append: It both modifies
the input and returns a replacement for it.
Because of the cascading nature of escape analysis,
in order to get the benefits, I had to modify
almost all such functions. The remaining functions
are in racewalk and the backend. I would be happy
to update them as well in a separate CL.
This CL was created by manually updating the
function signatures and the directly impacted
bits of code. The callsites were then automatically
updated using a bespoke script:
https://gist.github.com/josharian/046b1be7aceae244de39
For ease of reviewing and future understanding,
this CL is also broken down into four CLs,
mailed separately, which show the manual
and the automated changes separately.
They are CLs 20990, 20991, 20992, and 20993.
Passes toolstash -cmp.
name old time/op new time/op delta
Template 335ms ± 5% 324ms ± 5% -3.35% (p=0.000 n=23+24)
Unicode 176ms ± 9% 165ms ± 6% -6.12% (p=0.000 n=23+24)
GoTypes 1.10s ± 4% 1.07s ± 2% -2.77% (p=0.000 n=24+24)
Compiler 5.31s ± 3% 5.15s ± 3% -2.95% (p=0.000 n=24+24)
MakeBash 41.6s ± 1% 41.7s ± 2% ~ (p=0.586 n=23+23)
name old alloc/op new alloc/op delta
Template 63.3MB ± 0% 62.4MB ± 0% -1.36% (p=0.000 n=25+23)
Unicode 42.4MB ± 0% 41.6MB ± 0% -1.99% (p=0.000 n=24+25)
GoTypes 220MB ± 0% 217MB ± 0% -1.11% (p=0.000 n=25+25)
Compiler 994MB ± 0% 973MB ± 0% -2.08% (p=0.000 n=24+25)
name old allocs/op new allocs/op delta
Template 681k ± 0% 574k ± 0% -15.71% (p=0.000 n=24+25)
Unicode 518k ± 0% 413k ± 0% -20.34% (p=0.000 n=25+24)
GoTypes 2.08M ± 0% 1.78M ± 0% -14.62% (p=0.000 n=25+25)
Compiler 9.26M ± 0% 7.64M ± 0% -17.48% (p=0.000 n=25+25)
name old text-bytes new text-bytes delta
HelloSize 578k ± 0% 578k ± 0% ~ (all samples are equal)
CmdGoSize 6.46M ± 0% 6.46M ± 0% ~ (all samples are equal)
name old data-bytes new data-bytes delta
HelloSize 128k ± 0% 128k ± 0% ~ (all samples are equal)
CmdGoSize 281k ± 0% 281k ± 0% ~ (all samples are equal)
name old exe-bytes new exe-bytes delta
HelloSize 921k ± 0% 921k ± 0% ~ (all samples are equal)
CmdGoSize 9.86M ± 0% 9.86M ± 0% ~ (all samples are equal)
Change-Id: I277d95bd56d51c166ef7f560647aeaa092f3f475
Reviewed-on: https://go-review.googlesource.com/20959
Reviewed-by: Dave Cheney <dave@cheney.net>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
2016-03-20 08:03:31 -07:00
|
|
|
return l, r
|
2015-02-13 14:40:36 -05:00
|
|
|
}
|
cmd/compile: rewrite untyped constant conversion logic
This CL detangles the hairy mess that was convlit+defaultlit. In
particular, it makes the following changes:
1. convlit1 now follows the standard typecheck behavior of setting
"n.Type = nil" if there's an error. Notably, this means for a lot of
test cases, we now avoid reporting useless follow-on error messages.
For example, after reporting that "1 << s + 1.0" has an invalid shift,
we no longer also report that it can't be assigned to string.
2. Previously, assignconvfn had some extra logic for trying to
suppress errors from convlit/defaultlit so that it could provide its
own errors with better context information. Instead, this extra
context information is now passed down into convlit1 directly.
3. Relatedly, this CL also removes redundant calls to defaultlit prior
to assignconv. As a consequence, when an expression doesn't make sense
for a particular assignment (e.g., assigning an untyped string to an
integer), the error messages now say "untyped string" instead of just
"string". This is more consistent with go/types behavior.
4. defaultlit2 is now smarter about only trying to convert pairs of
untyped constants when it's likely to succeed. This allows us to
report better error messages for things like 3+"x"; instead of "cannot
convert 3 to string" we now report "mismatched types untyped number
and untyped string".
Passes toolstash-check.
Change-Id: I26822a02dc35855bd0ac774907b1cf5737e91882
Reviewed-on: https://go-review.googlesource.com/c/go/+/187657
Run-TryBot: Matthew Dempsky <mdempsky@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Robert Griesemer <gri@golang.org>
2019-09-05 13:33:06 -07:00
|
|
|
if l.Type.IsString() != r.Type.IsString() {
|
cmd/compile: reduce use of **Node parameters
Escape analysis has a hard time with tree-like
structures (see #13493 and #14858).
This is unlikely to change.
As a result, when invoking a function that accepts
a **Node parameter, we usually allocate a *Node
on the heap. This happens a whole lot.
This CL changes functions from taking a **Node
to acting more like append: It both modifies
the input and returns a replacement for it.
Because of the cascading nature of escape analysis,
in order to get the benefits, I had to modify
almost all such functions. The remaining functions
are in racewalk and the backend. I would be happy
to update them as well in a separate CL.
This CL was created by manually updating the
function signatures and the directly impacted
bits of code. The callsites were then automatically
updated using a bespoke script:
https://gist.github.com/josharian/046b1be7aceae244de39
For ease of reviewing and future understanding,
this CL is also broken down into four CLs,
mailed separately, which show the manual
and the automated changes separately.
They are CLs 20990, 20991, 20992, and 20993.
Passes toolstash -cmp.
name old time/op new time/op delta
Template 335ms ± 5% 324ms ± 5% -3.35% (p=0.000 n=23+24)
Unicode 176ms ± 9% 165ms ± 6% -6.12% (p=0.000 n=23+24)
GoTypes 1.10s ± 4% 1.07s ± 2% -2.77% (p=0.000 n=24+24)
Compiler 5.31s ± 3% 5.15s ± 3% -2.95% (p=0.000 n=24+24)
MakeBash 41.6s ± 1% 41.7s ± 2% ~ (p=0.586 n=23+23)
name old alloc/op new alloc/op delta
Template 63.3MB ± 0% 62.4MB ± 0% -1.36% (p=0.000 n=25+23)
Unicode 42.4MB ± 0% 41.6MB ± 0% -1.99% (p=0.000 n=24+25)
GoTypes 220MB ± 0% 217MB ± 0% -1.11% (p=0.000 n=25+25)
Compiler 994MB ± 0% 973MB ± 0% -2.08% (p=0.000 n=24+25)
name old allocs/op new allocs/op delta
Template 681k ± 0% 574k ± 0% -15.71% (p=0.000 n=24+25)
Unicode 518k ± 0% 413k ± 0% -20.34% (p=0.000 n=25+24)
GoTypes 2.08M ± 0% 1.78M ± 0% -14.62% (p=0.000 n=25+25)
Compiler 9.26M ± 0% 7.64M ± 0% -17.48% (p=0.000 n=25+25)
name old text-bytes new text-bytes delta
HelloSize 578k ± 0% 578k ± 0% ~ (all samples are equal)
CmdGoSize 6.46M ± 0% 6.46M ± 0% ~ (all samples are equal)
name old data-bytes new data-bytes delta
HelloSize 128k ± 0% 128k ± 0% ~ (all samples are equal)
CmdGoSize 281k ± 0% 281k ± 0% ~ (all samples are equal)
name old exe-bytes new exe-bytes delta
HelloSize 921k ± 0% 921k ± 0% ~ (all samples are equal)
CmdGoSize 9.86M ± 0% 9.86M ± 0% ~ (all samples are equal)
Change-Id: I277d95bd56d51c166ef7f560647aeaa092f3f475
Reviewed-on: https://go-review.googlesource.com/20959
Reviewed-by: Dave Cheney <dave@cheney.net>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
2016-03-20 08:03:31 -07:00
|
|
|
return l, r
|
2015-02-13 14:40:36 -05:00
|
|
|
}
|
cmd/compile: rewrite untyped constant conversion logic
This CL detangles the hairy mess that was convlit+defaultlit. In
particular, it makes the following changes:
1. convlit1 now follows the standard typecheck behavior of setting
"n.Type = nil" if there's an error. Notably, this means for a lot of
test cases, we now avoid reporting useless follow-on error messages.
For example, after reporting that "1 << s + 1.0" has an invalid shift,
we no longer also report that it can't be assigned to string.
2. Previously, assignconvfn had some extra logic for trying to
suppress errors from convlit/defaultlit so that it could provide its
own errors with better context information. Instead, this extra
context information is now passed down into convlit1 directly.
3. Relatedly, this CL also removes redundant calls to defaultlit prior
to assignconv. As a consequence, when an expression doesn't make sense
for a particular assignment (e.g., assigning an untyped string to an
integer), the error messages now say "untyped string" instead of just
"string". This is more consistent with go/types behavior.
4. defaultlit2 is now smarter about only trying to convert pairs of
untyped constants when it's likely to succeed. This allows us to
report better error messages for things like 3+"x"; instead of "cannot
convert 3 to string" we now report "mismatched types untyped number
and untyped string".
Passes toolstash-check.
Change-Id: I26822a02dc35855bd0ac774907b1cf5737e91882
Reviewed-on: https://go-review.googlesource.com/c/go/+/187657
Run-TryBot: Matthew Dempsky <mdempsky@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Robert Griesemer <gri@golang.org>
2019-09-05 13:33:06 -07:00
|
|
|
if l.isNil() || r.isNil() {
|
cmd/compile: reduce use of **Node parameters
Escape analysis has a hard time with tree-like
structures (see #13493 and #14858).
This is unlikely to change.
As a result, when invoking a function that accepts
a **Node parameter, we usually allocate a *Node
on the heap. This happens a whole lot.
This CL changes functions from taking a **Node
to acting more like append: It both modifies
the input and returns a replacement for it.
Because of the cascading nature of escape analysis,
in order to get the benefits, I had to modify
almost all such functions. The remaining functions
are in racewalk and the backend. I would be happy
to update them as well in a separate CL.
This CL was created by manually updating the
function signatures and the directly impacted
bits of code. The callsites were then automatically
updated using a bespoke script:
https://gist.github.com/josharian/046b1be7aceae244de39
For ease of reviewing and future understanding,
this CL is also broken down into four CLs,
mailed separately, which show the manual
and the automated changes separately.
They are CLs 20990, 20991, 20992, and 20993.
Passes toolstash -cmp.
name old time/op new time/op delta
Template 335ms ± 5% 324ms ± 5% -3.35% (p=0.000 n=23+24)
Unicode 176ms ± 9% 165ms ± 6% -6.12% (p=0.000 n=23+24)
GoTypes 1.10s ± 4% 1.07s ± 2% -2.77% (p=0.000 n=24+24)
Compiler 5.31s ± 3% 5.15s ± 3% -2.95% (p=0.000 n=24+24)
MakeBash 41.6s ± 1% 41.7s ± 2% ~ (p=0.586 n=23+23)
name old alloc/op new alloc/op delta
Template 63.3MB ± 0% 62.4MB ± 0% -1.36% (p=0.000 n=25+23)
Unicode 42.4MB ± 0% 41.6MB ± 0% -1.99% (p=0.000 n=24+25)
GoTypes 220MB ± 0% 217MB ± 0% -1.11% (p=0.000 n=25+25)
Compiler 994MB ± 0% 973MB ± 0% -2.08% (p=0.000 n=24+25)
name old allocs/op new allocs/op delta
Template 681k ± 0% 574k ± 0% -15.71% (p=0.000 n=24+25)
Unicode 518k ± 0% 413k ± 0% -20.34% (p=0.000 n=25+24)
GoTypes 2.08M ± 0% 1.78M ± 0% -14.62% (p=0.000 n=25+25)
Compiler 9.26M ± 0% 7.64M ± 0% -17.48% (p=0.000 n=25+25)
name old text-bytes new text-bytes delta
HelloSize 578k ± 0% 578k ± 0% ~ (all samples are equal)
CmdGoSize 6.46M ± 0% 6.46M ± 0% ~ (all samples are equal)
name old data-bytes new data-bytes delta
HelloSize 128k ± 0% 128k ± 0% ~ (all samples are equal)
CmdGoSize 281k ± 0% 281k ± 0% ~ (all samples are equal)
name old exe-bytes new exe-bytes delta
HelloSize 921k ± 0% 921k ± 0% ~ (all samples are equal)
CmdGoSize 9.86M ± 0% 9.86M ± 0% ~ (all samples are equal)
Change-Id: I277d95bd56d51c166ef7f560647aeaa092f3f475
Reviewed-on: https://go-review.googlesource.com/20959
Reviewed-by: Dave Cheney <dave@cheney.net>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
2016-03-20 08:03:31 -07:00
|
|
|
return l, r
|
2015-02-13 14:40:36 -05:00
|
|
|
}
|
|
|
|
|
|
cmd/compile: rewrite untyped constant conversion logic
This CL detangles the hairy mess that was convlit+defaultlit. In
particular, it makes the following changes:
1. convlit1 now follows the standard typecheck behavior of setting
"n.Type = nil" if there's an error. Notably, this means for a lot of
test cases, we now avoid reporting useless follow-on error messages.
For example, after reporting that "1 << s + 1.0" has an invalid shift,
we no longer also report that it can't be assigned to string.
2. Previously, assignconvfn had some extra logic for trying to
suppress errors from convlit/defaultlit so that it could provide its
own errors with better context information. Instead, this extra
context information is now passed down into convlit1 directly.
3. Relatedly, this CL also removes redundant calls to defaultlit prior
to assignconv. As a consequence, when an expression doesn't make sense
for a particular assignment (e.g., assigning an untyped string to an
integer), the error messages now say "untyped string" instead of just
"string". This is more consistent with go/types behavior.
4. defaultlit2 is now smarter about only trying to convert pairs of
untyped constants when it's likely to succeed. This allows us to
report better error messages for things like 3+"x"; instead of "cannot
convert 3 to string" we now report "mismatched types untyped number
and untyped string".
Passes toolstash-check.
Change-Id: I26822a02dc35855bd0ac774907b1cf5737e91882
Reviewed-on: https://go-review.googlesource.com/c/go/+/187657
Run-TryBot: Matthew Dempsky <mdempsky@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Robert Griesemer <gri@golang.org>
2019-09-05 13:33:06 -07:00
|
|
|
k := idealkind(l)
|
|
|
|
|
if rk := idealkind(r); rk > k {
|
|
|
|
|
k = rk
|
|
|
|
|
}
|
|
|
|
|
t := defaultType(k)
|
|
|
|
|
l = convlit(l, t)
|
|
|
|
|
r = convlit(r, t)
|
cmd/compile: reduce use of **Node parameters
Escape analysis has a hard time with tree-like
structures (see #13493 and #14858).
This is unlikely to change.
As a result, when invoking a function that accepts
a **Node parameter, we usually allocate a *Node
on the heap. This happens a whole lot.
This CL changes functions from taking a **Node
to acting more like append: It both modifies
the input and returns a replacement for it.
Because of the cascading nature of escape analysis,
in order to get the benefits, I had to modify
almost all such functions. The remaining functions
are in racewalk and the backend. I would be happy
to update them as well in a separate CL.
This CL was created by manually updating the
function signatures and the directly impacted
bits of code. The callsites were then automatically
updated using a bespoke script:
https://gist.github.com/josharian/046b1be7aceae244de39
For ease of reviewing and future understanding,
this CL is also broken down into four CLs,
mailed separately, which show the manual
and the automated changes separately.
They are CLs 20990, 20991, 20992, and 20993.
Passes toolstash -cmp.
name old time/op new time/op delta
Template 335ms ± 5% 324ms ± 5% -3.35% (p=0.000 n=23+24)
Unicode 176ms ± 9% 165ms ± 6% -6.12% (p=0.000 n=23+24)
GoTypes 1.10s ± 4% 1.07s ± 2% -2.77% (p=0.000 n=24+24)
Compiler 5.31s ± 3% 5.15s ± 3% -2.95% (p=0.000 n=24+24)
MakeBash 41.6s ± 1% 41.7s ± 2% ~ (p=0.586 n=23+23)
name old alloc/op new alloc/op delta
Template 63.3MB ± 0% 62.4MB ± 0% -1.36% (p=0.000 n=25+23)
Unicode 42.4MB ± 0% 41.6MB ± 0% -1.99% (p=0.000 n=24+25)
GoTypes 220MB ± 0% 217MB ± 0% -1.11% (p=0.000 n=25+25)
Compiler 994MB ± 0% 973MB ± 0% -2.08% (p=0.000 n=24+25)
name old allocs/op new allocs/op delta
Template 681k ± 0% 574k ± 0% -15.71% (p=0.000 n=24+25)
Unicode 518k ± 0% 413k ± 0% -20.34% (p=0.000 n=25+24)
GoTypes 2.08M ± 0% 1.78M ± 0% -14.62% (p=0.000 n=25+25)
Compiler 9.26M ± 0% 7.64M ± 0% -17.48% (p=0.000 n=25+25)
name old text-bytes new text-bytes delta
HelloSize 578k ± 0% 578k ± 0% ~ (all samples are equal)
CmdGoSize 6.46M ± 0% 6.46M ± 0% ~ (all samples are equal)
name old data-bytes new data-bytes delta
HelloSize 128k ± 0% 128k ± 0% ~ (all samples are equal)
CmdGoSize 281k ± 0% 281k ± 0% ~ (all samples are equal)
name old exe-bytes new exe-bytes delta
HelloSize 921k ± 0% 921k ± 0% ~ (all samples are equal)
CmdGoSize 9.86M ± 0% 9.86M ± 0% ~ (all samples are equal)
Change-Id: I277d95bd56d51c166ef7f560647aeaa092f3f475
Reviewed-on: https://go-review.googlesource.com/20959
Reviewed-by: Dave Cheney <dave@cheney.net>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
2016-03-20 08:03:31 -07:00
|
|
|
return l, r
|
2015-02-13 14:40:36 -05:00
|
|
|
}
|
|
|
|
|
|
cmd/compile: rewrite untyped constant conversion logic
This CL detangles the hairy mess that was convlit+defaultlit. In
particular, it makes the following changes:
1. convlit1 now follows the standard typecheck behavior of setting
"n.Type = nil" if there's an error. Notably, this means for a lot of
test cases, we now avoid reporting useless follow-on error messages.
For example, after reporting that "1 << s + 1.0" has an invalid shift,
we no longer also report that it can't be assigned to string.
2. Previously, assignconvfn had some extra logic for trying to
suppress errors from convlit/defaultlit so that it could provide its
own errors with better context information. Instead, this extra
context information is now passed down into convlit1 directly.
3. Relatedly, this CL also removes redundant calls to defaultlit prior
to assignconv. As a consequence, when an expression doesn't make sense
for a particular assignment (e.g., assigning an untyped string to an
integer), the error messages now say "untyped string" instead of just
"string". This is more consistent with go/types behavior.
4. defaultlit2 is now smarter about only trying to convert pairs of
untyped constants when it's likely to succeed. This allows us to
report better error messages for things like 3+"x"; instead of "cannot
convert 3 to string" we now report "mismatched types untyped number
and untyped string".
Passes toolstash-check.
Change-Id: I26822a02dc35855bd0ac774907b1cf5737e91882
Reviewed-on: https://go-review.googlesource.com/c/go/+/187657
Run-TryBot: Matthew Dempsky <mdempsky@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Robert Griesemer <gri@golang.org>
2019-09-05 13:33:06 -07:00
|
|
|
func defaultType(k Ctype) *types.Type {
|
|
|
|
|
switch k {
|
|
|
|
|
case CTBOOL:
|
|
|
|
|
return types.Types[TBOOL]
|
|
|
|
|
case CTSTR:
|
|
|
|
|
return types.Types[TSTRING]
|
|
|
|
|
case CTINT:
|
|
|
|
|
return types.Types[TINT]
|
|
|
|
|
case CTRUNE:
|
|
|
|
|
return types.Runetype
|
|
|
|
|
case CTFLT:
|
|
|
|
|
return types.Types[TFLOAT64]
|
|
|
|
|
case CTCPLX:
|
|
|
|
|
return types.Types[TCOMPLEX128]
|
|
|
|
|
}
|
|
|
|
|
Fatalf("bad idealkind: %v", k)
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
2015-09-17 21:01:29 +02:00
|
|
|
// strlit returns the value of a literal string Node as a string.
|
|
|
|
|
func strlit(n *Node) string {
|
|
|
|
|
return n.Val().U.(string)
|
2015-02-13 14:40:36 -05:00
|
|
|
}
|
|
|
|
|
|
2018-11-28 14:34:45 -08:00
|
|
|
// TODO(gri) smallintconst is only used in one place - can we used indexconst?
|
2016-09-15 14:34:20 +10:00
|
|
|
func smallintconst(n *Node) bool {
|
2015-02-17 22:13:49 -05:00
|
|
|
if n.Op == OLITERAL && Isconst(n, CTINT) && n.Type != nil {
|
2016-09-16 00:33:29 +10:00
|
|
|
switch simtype[n.Type.Etype] {
|
2015-02-13 14:40:36 -05:00
|
|
|
case TINT8,
|
|
|
|
|
TUINT8,
|
|
|
|
|
TINT16,
|
|
|
|
|
TUINT16,
|
|
|
|
|
TINT32,
|
|
|
|
|
TUINT32,
|
2018-10-03 15:47:16 -07:00
|
|
|
TBOOL:
|
2015-02-17 22:13:49 -05:00
|
|
|
return true
|
2015-02-13 14:40:36 -05:00
|
|
|
|
2017-11-06 14:50:30 -08:00
|
|
|
case TIDEAL, TINT64, TUINT64, TPTR:
|
2016-09-10 13:24:35 +02:00
|
|
|
v, ok := n.Val().U.(*Mpint)
|
2018-11-28 14:34:45 -08:00
|
|
|
if ok && v.Cmp(minintval[TINT32]) >= 0 && v.Cmp(maxintval[TINT32]) <= 0 {
|
2016-09-10 13:24:35 +02:00
|
|
|
return true
|
2015-02-13 14:40:36 -05:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2015-02-17 22:13:49 -05:00
|
|
|
return false
|
2015-02-13 14:40:36 -05:00
|
|
|
}
|
|
|
|
|
|
2018-11-28 14:34:45 -08:00
|
|
|
// indexconst checks if Node n contains a constant expression
|
|
|
|
|
// representable as a non-negative int and returns its value.
|
|
|
|
|
// If n is not a constant expression, not representable as an
|
|
|
|
|
// integer, or negative, it returns -1. If n is too large, it
|
|
|
|
|
// returns -2.
|
|
|
|
|
func indexconst(n *Node) int64 {
|
2016-09-10 13:24:35 +02:00
|
|
|
if n.Op != OLITERAL {
|
|
|
|
|
return -1
|
|
|
|
|
}
|
|
|
|
|
|
2018-11-28 14:34:45 -08:00
|
|
|
v := toint(n.Val()) // toint returns argument unchanged if not representable as an *Mpint
|
2016-09-10 13:24:35 +02:00
|
|
|
vi, ok := v.U.(*Mpint)
|
2018-11-28 14:34:45 -08:00
|
|
|
if !ok || vi.CmpInt64(0) < 0 {
|
2016-09-10 13:24:35 +02:00
|
|
|
return -1
|
2015-02-13 14:40:36 -05:00
|
|
|
}
|
2018-11-28 14:34:45 -08:00
|
|
|
if vi.Cmp(maxintval[TINT]) > 0 {
|
|
|
|
|
return -2
|
|
|
|
|
}
|
2015-02-13 14:40:36 -05:00
|
|
|
|
2016-09-10 13:24:35 +02:00
|
|
|
return vi.Int64()
|
2015-02-13 14:40:36 -05:00
|
|
|
}
|
|
|
|
|
|
2018-04-08 13:39:10 +01:00
|
|
|
// isGoConst reports whether n is a Go language constant (as opposed to a
|
|
|
|
|
// compile-time constant).
|
|
|
|
|
//
|
2015-02-13 14:40:36 -05:00
|
|
|
// Expressions derived from nil, like string([]byte(nil)), while they
|
|
|
|
|
// may be known at compile time, are not Go language constants.
|
2018-04-08 13:39:10 +01:00
|
|
|
func (n *Node) isGoConst() bool {
|
2019-02-27 18:18:47 -08:00
|
|
|
return n.Op == OLITERAL && n.Val().Ctype() != CTNIL
|
2015-02-13 14:40:36 -05:00
|
|
|
}
|
|
|
|
|
|
2015-02-17 22:13:49 -05:00
|
|
|
func hascallchan(n *Node) bool {
|
2015-02-13 14:40:36 -05:00
|
|
|
if n == nil {
|
2015-02-17 22:13:49 -05:00
|
|
|
return false
|
2015-02-13 14:40:36 -05:00
|
|
|
}
|
|
|
|
|
switch n.Op {
|
|
|
|
|
case OAPPEND,
|
|
|
|
|
OCALL,
|
|
|
|
|
OCALLFUNC,
|
|
|
|
|
OCALLINTER,
|
|
|
|
|
OCALLMETH,
|
|
|
|
|
OCAP,
|
|
|
|
|
OCLOSE,
|
|
|
|
|
OCOMPLEX,
|
|
|
|
|
OCOPY,
|
|
|
|
|
ODELETE,
|
|
|
|
|
OIMAG,
|
|
|
|
|
OLEN,
|
|
|
|
|
OMAKE,
|
|
|
|
|
ONEW,
|
|
|
|
|
OPANIC,
|
|
|
|
|
OPRINT,
|
|
|
|
|
OPRINTN,
|
|
|
|
|
OREAL,
|
|
|
|
|
ORECOVER,
|
|
|
|
|
ORECV:
|
2015-02-17 22:13:49 -05:00
|
|
|
return true
|
2015-02-13 14:40:36 -05:00
|
|
|
}
|
|
|
|
|
|
2015-02-17 22:13:49 -05:00
|
|
|
if hascallchan(n.Left) || hascallchan(n.Right) {
|
|
|
|
|
return true
|
2015-02-13 14:40:36 -05:00
|
|
|
}
|
2016-03-08 15:10:26 -08:00
|
|
|
for _, n1 := range n.List.Slice() {
|
|
|
|
|
if hascallchan(n1) {
|
2015-02-17 22:13:49 -05:00
|
|
|
return true
|
2015-02-13 14:40:36 -05:00
|
|
|
}
|
|
|
|
|
}
|
2016-03-08 15:10:26 -08:00
|
|
|
for _, n2 := range n.Rlist.Slice() {
|
|
|
|
|
if hascallchan(n2) {
|
2015-02-17 22:13:49 -05:00
|
|
|
return true
|
2015-02-13 14:40:36 -05:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2015-02-17 22:13:49 -05:00
|
|
|
return false
|
2015-02-13 14:40:36 -05:00
|
|
|
}
|
2018-12-04 15:11:03 -08:00
|
|
|
|
|
|
|
|
// A constSet represents a set of Go constant expressions.
|
|
|
|
|
type constSet struct {
|
cmd/compile: fix "previous" position info for duplicate switch cases
Because the Node AST represents references to declared objects (e.g.,
variables, packages, types, constants) by directly pointing to the
referred object, we don't have use-position info for these objects.
For switch statements with duplicate cases, we report back where the
first duplicate value appeared. However, due to the AST
representation, if the value was a declared constant, we mistakenly
reported the constant declaration position as the previous case
position.
This CL reports back against the 'case' keyword's position instead, if
there's no more precise information available to us.
It also refactors code to emit the same "previous at" error message
for duplicate values in map literals.
Thanks to Emmanuel Odeke for the test case.
Fixes #33460.
Change-Id: Iec69542ccd4aad594dde8df02d1b880a422c5622
Reviewed-on: https://go-review.googlesource.com/c/go/+/188901
Reviewed-by: Robert Griesemer <gri@golang.org>
Reviewed-by: Emmanuel Odeke <emm.odeke@gmail.com>
Run-TryBot: Emmanuel Odeke <emm.odeke@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
2019-08-05 13:12:01 -07:00
|
|
|
m map[constSetKey]src.XPos
|
2018-12-04 15:11:03 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
type constSetKey struct {
|
|
|
|
|
typ *types.Type
|
|
|
|
|
val interface{}
|
|
|
|
|
}
|
|
|
|
|
|
cmd/compile: fix "previous" position info for duplicate switch cases
Because the Node AST represents references to declared objects (e.g.,
variables, packages, types, constants) by directly pointing to the
referred object, we don't have use-position info for these objects.
For switch statements with duplicate cases, we report back where the
first duplicate value appeared. However, due to the AST
representation, if the value was a declared constant, we mistakenly
reported the constant declaration position as the previous case
position.
This CL reports back against the 'case' keyword's position instead, if
there's no more precise information available to us.
It also refactors code to emit the same "previous at" error message
for duplicate values in map literals.
Thanks to Emmanuel Odeke for the test case.
Fixes #33460.
Change-Id: Iec69542ccd4aad594dde8df02d1b880a422c5622
Reviewed-on: https://go-review.googlesource.com/c/go/+/188901
Reviewed-by: Robert Griesemer <gri@golang.org>
Reviewed-by: Emmanuel Odeke <emm.odeke@gmail.com>
Run-TryBot: Emmanuel Odeke <emm.odeke@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
2019-08-05 13:12:01 -07:00
|
|
|
// add adds constant expression n to s. If a constant expression of
|
|
|
|
|
// equal value and identical type has already been added, then add
|
|
|
|
|
// reports an error about the duplicate value.
|
2018-12-04 15:11:03 -08:00
|
|
|
//
|
2019-09-08 19:36:13 +03:00
|
|
|
// pos provides position information for where expression n occurred
|
cmd/compile: fix "previous" position info for duplicate switch cases
Because the Node AST represents references to declared objects (e.g.,
variables, packages, types, constants) by directly pointing to the
referred object, we don't have use-position info for these objects.
For switch statements with duplicate cases, we report back where the
first duplicate value appeared. However, due to the AST
representation, if the value was a declared constant, we mistakenly
reported the constant declaration position as the previous case
position.
This CL reports back against the 'case' keyword's position instead, if
there's no more precise information available to us.
It also refactors code to emit the same "previous at" error message
for duplicate values in map literals.
Thanks to Emmanuel Odeke for the test case.
Fixes #33460.
Change-Id: Iec69542ccd4aad594dde8df02d1b880a422c5622
Reviewed-on: https://go-review.googlesource.com/c/go/+/188901
Reviewed-by: Robert Griesemer <gri@golang.org>
Reviewed-by: Emmanuel Odeke <emm.odeke@gmail.com>
Run-TryBot: Emmanuel Odeke <emm.odeke@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
2019-08-05 13:12:01 -07:00
|
|
|
// (in case n does not have its own position information). what and
|
|
|
|
|
// where are used in the error message.
|
2018-12-04 15:11:03 -08:00
|
|
|
//
|
|
|
|
|
// n must not be an untyped constant.
|
cmd/compile: fix "previous" position info for duplicate switch cases
Because the Node AST represents references to declared objects (e.g.,
variables, packages, types, constants) by directly pointing to the
referred object, we don't have use-position info for these objects.
For switch statements with duplicate cases, we report back where the
first duplicate value appeared. However, due to the AST
representation, if the value was a declared constant, we mistakenly
reported the constant declaration position as the previous case
position.
This CL reports back against the 'case' keyword's position instead, if
there's no more precise information available to us.
It also refactors code to emit the same "previous at" error message
for duplicate values in map literals.
Thanks to Emmanuel Odeke for the test case.
Fixes #33460.
Change-Id: Iec69542ccd4aad594dde8df02d1b880a422c5622
Reviewed-on: https://go-review.googlesource.com/c/go/+/188901
Reviewed-by: Robert Griesemer <gri@golang.org>
Reviewed-by: Emmanuel Odeke <emm.odeke@gmail.com>
Run-TryBot: Emmanuel Odeke <emm.odeke@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
2019-08-05 13:12:01 -07:00
|
|
|
func (s *constSet) add(pos src.XPos, n *Node, what, where string) {
|
2018-12-04 15:11:03 -08:00
|
|
|
if n.Op == OCONVIFACE && n.Implicit() {
|
|
|
|
|
n = n.Left
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if !n.isGoConst() {
|
cmd/compile: fix "previous" position info for duplicate switch cases
Because the Node AST represents references to declared objects (e.g.,
variables, packages, types, constants) by directly pointing to the
referred object, we don't have use-position info for these objects.
For switch statements with duplicate cases, we report back where the
first duplicate value appeared. However, due to the AST
representation, if the value was a declared constant, we mistakenly
reported the constant declaration position as the previous case
position.
This CL reports back against the 'case' keyword's position instead, if
there's no more precise information available to us.
It also refactors code to emit the same "previous at" error message
for duplicate values in map literals.
Thanks to Emmanuel Odeke for the test case.
Fixes #33460.
Change-Id: Iec69542ccd4aad594dde8df02d1b880a422c5622
Reviewed-on: https://go-review.googlesource.com/c/go/+/188901
Reviewed-by: Robert Griesemer <gri@golang.org>
Reviewed-by: Emmanuel Odeke <emm.odeke@gmail.com>
Run-TryBot: Emmanuel Odeke <emm.odeke@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
2019-08-05 13:12:01 -07:00
|
|
|
return
|
2018-12-04 15:11:03 -08:00
|
|
|
}
|
|
|
|
|
if n.Type.IsUntyped() {
|
|
|
|
|
Fatalf("%v is untyped", n)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Consts are only duplicates if they have the same value and
|
|
|
|
|
// identical types.
|
|
|
|
|
//
|
|
|
|
|
// In general, we have to use types.Identical to test type
|
|
|
|
|
// identity, because == gives false negatives for anonymous
|
|
|
|
|
// types and the byte/uint8 and rune/int32 builtin type
|
|
|
|
|
// aliases. However, this is not a problem here, because
|
|
|
|
|
// constant expressions are always untyped or have a named
|
|
|
|
|
// type, and we explicitly handle the builtin type aliases
|
|
|
|
|
// below.
|
|
|
|
|
//
|
|
|
|
|
// This approach may need to be revisited though if we fix
|
|
|
|
|
// #21866 by treating all type aliases like byte/uint8 and
|
|
|
|
|
// rune/int32.
|
|
|
|
|
|
|
|
|
|
typ := n.Type
|
|
|
|
|
switch typ {
|
|
|
|
|
case types.Bytetype:
|
|
|
|
|
typ = types.Types[TUINT8]
|
|
|
|
|
case types.Runetype:
|
|
|
|
|
typ = types.Types[TINT32]
|
|
|
|
|
}
|
|
|
|
|
k := constSetKey{typ, n.Val().Interface()}
|
|
|
|
|
|
cmd/compile: fix "previous" position info for duplicate switch cases
Because the Node AST represents references to declared objects (e.g.,
variables, packages, types, constants) by directly pointing to the
referred object, we don't have use-position info for these objects.
For switch statements with duplicate cases, we report back where the
first duplicate value appeared. However, due to the AST
representation, if the value was a declared constant, we mistakenly
reported the constant declaration position as the previous case
position.
This CL reports back against the 'case' keyword's position instead, if
there's no more precise information available to us.
It also refactors code to emit the same "previous at" error message
for duplicate values in map literals.
Thanks to Emmanuel Odeke for the test case.
Fixes #33460.
Change-Id: Iec69542ccd4aad594dde8df02d1b880a422c5622
Reviewed-on: https://go-review.googlesource.com/c/go/+/188901
Reviewed-by: Robert Griesemer <gri@golang.org>
Reviewed-by: Emmanuel Odeke <emm.odeke@gmail.com>
Run-TryBot: Emmanuel Odeke <emm.odeke@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
2019-08-05 13:12:01 -07:00
|
|
|
if hasUniquePos(n) {
|
|
|
|
|
pos = n.Pos
|
|
|
|
|
}
|
|
|
|
|
|
2018-12-04 15:11:03 -08:00
|
|
|
if s.m == nil {
|
cmd/compile: fix "previous" position info for duplicate switch cases
Because the Node AST represents references to declared objects (e.g.,
variables, packages, types, constants) by directly pointing to the
referred object, we don't have use-position info for these objects.
For switch statements with duplicate cases, we report back where the
first duplicate value appeared. However, due to the AST
representation, if the value was a declared constant, we mistakenly
reported the constant declaration position as the previous case
position.
This CL reports back against the 'case' keyword's position instead, if
there's no more precise information available to us.
It also refactors code to emit the same "previous at" error message
for duplicate values in map literals.
Thanks to Emmanuel Odeke for the test case.
Fixes #33460.
Change-Id: Iec69542ccd4aad594dde8df02d1b880a422c5622
Reviewed-on: https://go-review.googlesource.com/c/go/+/188901
Reviewed-by: Robert Griesemer <gri@golang.org>
Reviewed-by: Emmanuel Odeke <emm.odeke@gmail.com>
Run-TryBot: Emmanuel Odeke <emm.odeke@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
2019-08-05 13:12:01 -07:00
|
|
|
s.m = make(map[constSetKey]src.XPos)
|
2018-12-04 15:11:03 -08:00
|
|
|
}
|
cmd/compile: fix "previous" position info for duplicate switch cases
Because the Node AST represents references to declared objects (e.g.,
variables, packages, types, constants) by directly pointing to the
referred object, we don't have use-position info for these objects.
For switch statements with duplicate cases, we report back where the
first duplicate value appeared. However, due to the AST
representation, if the value was a declared constant, we mistakenly
reported the constant declaration position as the previous case
position.
This CL reports back against the 'case' keyword's position instead, if
there's no more precise information available to us.
It also refactors code to emit the same "previous at" error message
for duplicate values in map literals.
Thanks to Emmanuel Odeke for the test case.
Fixes #33460.
Change-Id: Iec69542ccd4aad594dde8df02d1b880a422c5622
Reviewed-on: https://go-review.googlesource.com/c/go/+/188901
Reviewed-by: Robert Griesemer <gri@golang.org>
Reviewed-by: Emmanuel Odeke <emm.odeke@gmail.com>
Run-TryBot: Emmanuel Odeke <emm.odeke@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
2019-08-05 13:12:01 -07:00
|
|
|
|
|
|
|
|
if prevPos, isDup := s.m[k]; isDup {
|
|
|
|
|
yyerrorl(pos, "duplicate %s %s in %s\n\tprevious %s at %v",
|
|
|
|
|
what, nodeAndVal(n), where,
|
|
|
|
|
what, linestr(prevPos))
|
|
|
|
|
} else {
|
|
|
|
|
s.m[k] = pos
|
2018-12-04 15:11:03 -08:00
|
|
|
}
|
cmd/compile: fix "previous" position info for duplicate switch cases
Because the Node AST represents references to declared objects (e.g.,
variables, packages, types, constants) by directly pointing to the
referred object, we don't have use-position info for these objects.
For switch statements with duplicate cases, we report back where the
first duplicate value appeared. However, due to the AST
representation, if the value was a declared constant, we mistakenly
reported the constant declaration position as the previous case
position.
This CL reports back against the 'case' keyword's position instead, if
there's no more precise information available to us.
It also refactors code to emit the same "previous at" error message
for duplicate values in map literals.
Thanks to Emmanuel Odeke for the test case.
Fixes #33460.
Change-Id: Iec69542ccd4aad594dde8df02d1b880a422c5622
Reviewed-on: https://go-review.googlesource.com/c/go/+/188901
Reviewed-by: Robert Griesemer <gri@golang.org>
Reviewed-by: Emmanuel Odeke <emm.odeke@gmail.com>
Run-TryBot: Emmanuel Odeke <emm.odeke@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
2019-08-05 13:12:01 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// nodeAndVal reports both an expression and its constant value, if
|
|
|
|
|
// the latter is non-obvious.
|
|
|
|
|
//
|
|
|
|
|
// TODO(mdempsky): This could probably be a fmt.go flag.
|
|
|
|
|
func nodeAndVal(n *Node) string {
|
|
|
|
|
show := n.String()
|
|
|
|
|
val := n.Val().Interface()
|
|
|
|
|
if s := fmt.Sprintf("%#v", val); show != s {
|
|
|
|
|
show += " (value " + s + ")"
|
|
|
|
|
}
|
|
|
|
|
return show
|
2018-12-04 15:11:03 -08:00
|
|
|
}
|