diff options
| author | Robert Griesemer <gri@golang.org> | 2023-01-31 11:34:16 -0800 |
|---|---|---|
| committer | Gopher Robot <gobot@golang.org> | 2023-02-01 21:30:59 +0000 |
| commit | 07dca0fe14d717f7e44593d13d9a6767ec34a9cc (patch) | |
| tree | bd78151989633a354ecf1165023ba7584e317263 /src/cmd/compile | |
| parent | cda461bb79624f9ee14fd0619bef456d27d23d88 (diff) | |
| download | go-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.go | 19 |
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 |
