case ODIV:
if y.CmpInt64(0) == 0 {
yyerror("division by zero")
- u.SetOverflow()
- break
+ return Val{}
}
u.Quo(y)
case OMOD:
if y.CmpInt64(0) == 0 {
yyerror("division by zero")
- u.SetOverflow()
- break
+ return Val{}
}
u.Rem(y)
case OOR:
case ODIV:
if y.CmpFloat64(0) == 0 {
yyerror("division by zero")
- u.SetFloat64(1)
- break
+ return Val{}
}
u.Quo(y)
- case OMOD:
- // TODO(mdempsky): Move to typecheck.
- yyerror("illegal constant expression: floating-point %% operation")
+ 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{}
default:
break Outer
}
case ODIV:
if !u.Div(y) {
yyerror("complex division by zero")
- u.Real.SetFloat64(1)
- u.Imag.SetFloat64(0)
+ return Val{}
}
+ 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{}
default:
break Outer
}
}
case OBITNOT:
- x := x.U.(*Mpint)
+ switch x.Ctype() {
+ case CTINT, CTRUNE:
+ x := x.U.(*Mpint)
- 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 := 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{}
}
- u.Xor(x)
- return Val{U: u}
case ONOT:
return Val{U: !x.U.(bool)}
// setconst rewrites n as an OLITERAL with value v.
func setconst(n *Node, v Val) {
+ // If constant folding failed, mark n as broken and give up.
+ if v.U == nil {
+ n.Type = nil
+ return
+ }
+
// Ensure n.Orig still points to a semantically-equivalent
// expression after we rewrite n into a constant.
if n.Orig == n {
--- /dev/null
+// errorcheck
+
+// Copyright 2019 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 p
+
+const (
+ f = 1.0
+ c = 1.0i
+
+ _ = ^f // ERROR "invalid operation|expected integer"
+ _ = ^c // ERROR "invalid operation|expected integer"
+
+ _ = f % f // ERROR "invalid operation|expected integer"
+ _ = c % c // ERROR "invalid operation|expected integer"
+
+ _ = f & f // ERROR "invalid operation|expected integer"
+ _ = c & c // ERROR "invalid operation|expected integer"
+
+ _ = f | f // ERROR "invalid operation|expected integer"
+ _ = c | c // ERROR "invalid operation|expected integer"
+
+ _ = f ^ f // ERROR "invalid operation|expected integer"
+ _ = c ^ c // ERROR "invalid operation|expected integer"
+
+ _ = f &^ f // ERROR "invalid operation|expected integer"
+ _ = c &^ c // ERROR "invalid operation|expected integer"
+)