cmd/compile/internal/syntax: don't assume (operator) ~ means operator ^

The scanner assumed that ~ really meant ^, which may be helpful when
coming from C. But ~ is not a valid Go token, and pretending that it
should be ^ can lead to confusing error messages. Better to be upfront
about it and complain about the invalid character in the first place.

This was code "inherited" from the original yacc parser which was
derived from a C compiler. It's 10 years later and we can probably
assume that people are less confused about C and Go.

Fixes #23587.

Change-Id: I8d8f9b55b0dff009b75c1530d729bf9092c5aea6
Reviewed-on: https://go-review.googlesource.com/94160
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
This commit is contained in:
Robert Griesemer 2018-02-14 20:54:28 -08:00
parent e7cbbbe9bb
commit 33eb0633e1
3 changed files with 13 additions and 5 deletions

View file

@ -242,10 +242,6 @@ redo:
s.op, s.prec = Or, precAdd s.op, s.prec = Or, precAdd
goto assignop goto assignop
case '~':
s.error("bitwise complement operator is ^")
fallthrough
case '^': case '^':
s.op, s.prec = Xor, precAdd s.op, s.prec = Xor, precAdd
c = s.getr() c = s.getr()

View file

@ -343,7 +343,7 @@ func TestScanErrors(t *testing.T) {
{"\U0001d7d8" /* 𝟘 */, "identifier cannot begin with digit U+1D7D8 '𝟘'", 0, 0}, {"\U0001d7d8" /* 𝟘 */, "identifier cannot begin with digit U+1D7D8 '𝟘'", 0, 0},
{"foo\U0001d7d8_½" /* foo𝟘_½ */, "invalid identifier character U+00BD '½'", 0, 8 /* byte offset */}, {"foo\U0001d7d8_½" /* foo𝟘_½ */, "invalid identifier character U+00BD '½'", 0, 8 /* byte offset */},
{"x + ~y", "bitwise complement operator is ^", 0, 4}, {"x + ~y", "invalid character U+007E '~'", 0, 4},
{"foo$bar = 0", "invalid character U+0024 '$'", 0, 3}, {"foo$bar = 0", "invalid character U+0024 '$'", 0, 3},
{"const x = 0xyz", "malformed hex constant", 0, 12}, {"const x = 0xyz", "malformed hex constant", 0, 12},
{"0123456789", "malformed octal constant", 0, 10}, {"0123456789", "malformed octal constant", 0, 10},

View file

@ -0,0 +1,12 @@
// errorcheck
// Copyright 2018 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
func f(x int) {
_ = ~x // ERROR "invalid character"
_ = x ~ x // ERROR "invalid character" "unexpected x at end of statement"
}