"cmd/compile/internal/base"
"cmd/compile/internal/ir"
"cmd/compile/internal/types"
- "cmd/internal/src"
)
func roundFloat(v constant.Value, sz int64) constant.Value {
})
}
-// A constSet represents a set of Go constant expressions.
-type constSet struct {
- m map[constSetKey]src.XPos
-}
-
-type constSetKey struct {
- typ *types.Type
- val interface{}
-}
-
-// 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.
-//
-// pos provides position information for where expression n occurred
-// (in case n does not have its own position information). what and
-// where are used in the error message.
-//
-// n must not be an untyped constant.
-func (s *constSet) add(pos src.XPos, n ir.Node, what, where string) {
- if conv := n; conv.Op() == ir.OCONVIFACE {
- conv := conv.(*ir.ConvExpr)
- if conv.Implicit() {
- n = conv.X
- }
- }
-
- if !ir.IsConstNode(n) || n.Type() == nil {
- return
- }
- if n.Type().IsUntyped() {
- base.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[types.TUINT8]
- case types.RuneType:
- typ = types.Types[types.TINT32]
- }
- k := constSetKey{typ, ir.ConstValue(n)}
-
- if ir.HasUniquePos(n) {
- pos = n.Pos()
- }
-
- if s.m == nil {
- s.m = make(map[constSetKey]src.XPos)
- }
-
- if prevPos, isDup := s.m[k]; isDup {
- base.ErrorfAt(pos, "duplicate %s %s in %s\n\tprevious %s at %v",
- what, nodeAndVal(n), where,
- what, base.FmtPos(prevPos))
- } else {
- s.m[k] = pos
- }
-}
-
-// 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 ir.Node) string {
- show := fmt.Sprint(n)
- val := ir.ConstValue(n)
- if s := fmt.Sprintf("%#v", val); show != s {
- show += " (value " + s + ")"
- }
- return show
-}
-
// evalunsafe evaluates a package unsafe operation and returns the result.
func evalunsafe(n ir.Node) int64 {
switch n.Op() {
}
var defCase ir.Node
- var cs constSet
for _, ncase := range n.Cases {
ls := ncase.List
if len(ls) == 0 { // default:
}
}
}
-
- // Don't check for duplicate bools. Although the spec allows it,
- // (1) the compiler hasn't checked it in the past, so compatibility mandates it, and
- // (2) it would disallow useful things like
- // case GOARCH == "arm" && GOARM == "5":
- // case GOARCH == "arm":
- // which would both evaluate to false for non-ARM compiles.
- if !n1.Type().IsBoolean() {
- cs.add(ncase.Pos(), n1, "case", "switch")
- }
}
Stmts(ncase.Body)