aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/compile
diff options
context:
space:
mode:
authorRobert Griesemer <gri@golang.org>2023-01-31 11:34:16 -0800
committerGopher Robot <gobot@golang.org>2023-02-01 21:30:59 +0000
commit07dca0fe14d717f7e44593d13d9a6767ec34a9cc (patch)
treebd78151989633a354ecf1165023ba7584e317263 /src/cmd/compile
parentcda461bb79624f9ee14fd0619bef456d27d23d88 (diff)
downloadgo-07dca0fe14d717f7e44593d13d9a6767ec34a9cc.tar.xz
go/types, types2: better error when trying to use ~ as bitwise operation
When coming from C, the bitwise integer complement (bitwise negation) operator is ~, but in Go it is ^. Report an error mentioning ^ when ~ is used with an integer operand. Background: Some articles on the web claim that Go doesn't have a bitwise complement operator. Change-Id: I41185cae4a70d528754e44f42c13c013ed91bf27 Reviewed-on: https://go-review.googlesource.com/c/go/+/463747 Auto-Submit: Robert Griesemer <gri@google.com> Run-TryBot: Robert Griesemer <gri@google.com> Reviewed-by: Robert Griesemer <gri@google.com> Reviewed-by: Robert Findley <rfindley@google.com> TryBot-Result: Gopher Robot <gobot@golang.org>
Diffstat (limited to 'src/cmd/compile')
-rw-r--r--src/cmd/compile/internal/types2/expr.go19
1 files changed, 12 insertions, 7 deletions
diff --git a/src/cmd/compile/internal/types2/expr.go b/src/cmd/compile/internal/types2/expr.go
index 0433f8af95..472e30a069 100644
--- a/src/cmd/compile/internal/types2/expr.go
+++ b/src/cmd/compile/internal/types2/expr.go
@@ -178,7 +178,8 @@ func (check *Checker) unary(x *operand, e *syntax.Operation) {
return
}
- switch e.Op {
+ op := e.Op
+ switch op {
case syntax.And:
// spec: "As an exception to the addressability
// requirement x may also be a composite literal."
@@ -215,13 +216,17 @@ func (check *Checker) unary(x *operand, e *syntax.Operation) {
return
case syntax.Tilde:
- // Provide a better error position and message than what check.op below could do.
- check.error(e, UndefinedOp, "cannot use ~ outside of interface or type constraint")
- x.mode = invalid
- return
+ // Provide a better error position and message than what check.op below would do.
+ if !allInteger(x.typ) {
+ check.error(e, UndefinedOp, "cannot use ~ outside of interface or type constraint")
+ x.mode = invalid
+ return
+ }
+ check.error(e, UndefinedOp, "cannot use ~ outside of interface or type constraint (use ^ for bitwise complement)")
+ op = syntax.Xor
}
- if !check.op(unaryOpPredicates, x, e.Op) {
+ if !check.op(unaryOpPredicates, x, op) {
x.mode = invalid
return
}
@@ -235,7 +240,7 @@ func (check *Checker) unary(x *operand, e *syntax.Operation) {
if isUnsigned(x.typ) {
prec = uint(check.conf.sizeof(x.typ) * 8)
}
- x.val = constant.UnaryOp(op2tok[e.Op], x.val, prec)
+ x.val = constant.UnaryOp(op2tok[op], x.val, prec)
x.expr = e
check.overflow(x)
return