diff options
author | Robert Griesemer <gri@golang.org> | 2017-02-16 12:52:01 -0800 |
---|---|---|
committer | Robert Griesemer <gri@golang.org> | 2017-02-16 21:46:43 +0000 |
commit | 1693e7b6f2ad1bd2a800161e92b5ac8d3d882663 (patch) | |
tree | cd481aa17fedca57de165740e78e439e98af4e17 /src/cmd/compile/internal/syntax/scanner.go | |
parent | 990124da2a6ca5a54b38733b51018e2f8758cfae (diff) | |
download | go-1693e7b6f2ad1bd2a800161e92b5ac8d3d882663.tar.gz go-1693e7b6f2ad1bd2a800161e92b5ac8d3d882663.zip |
cmd/compile/internal/syntax: better errors and recovery for invalid character literals
Fixes #15611.
Change-Id: I352b145026466cafef8cf87addafbd30716bda24
Reviewed-on: https://go-review.googlesource.com/37138
Run-TryBot: Robert Griesemer <gri@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
Diffstat (limited to 'src/cmd/compile/internal/syntax/scanner.go')
-rw-r--r-- | src/cmd/compile/internal/syntax/scanner.go | 79 |
1 files changed, 47 insertions, 32 deletions
diff --git a/src/cmd/compile/internal/syntax/scanner.go b/src/cmd/compile/internal/syntax/scanner.go index edd60609a0..c2de9ce686 100644 --- a/src/cmd/compile/internal/syntax/scanner.go +++ b/src/cmd/compile/internal/syntax/scanner.go @@ -466,6 +466,53 @@ done: s.tok = _Literal } +func (s *scanner) rune() { + s.startLit() + + ok := true // only report errors if we're ok so far + n := 0 + for ; ; n++ { + r := s.getr() + if r == '\'' { + break + } + if r == '\\' { + if !s.escape('\'') { + ok = false + } + continue + } + if r == '\n' { + s.ungetr() // assume newline is not part of literal + if ok { + s.error("newline in character literal") + ok = false + } + break + } + if r < 0 { + if ok { + s.errh(s.line, s.col, "invalid character literal (missing closing ')") + ok = false + } + break + } + } + + if ok { + if n == 0 { + s.error("empty character literal or unescaped ' in character literal") + } else if n != 1 { + s.errh(s.line, s.col, "invalid character literal (more than one character)") + } + } + + s.nlsemi = true + s.lit = string(s.stopLit()) + s.kind = RuneLit + s.tok = _Literal +} + func (s *scanner) stdString() { s.startLit() @@ -518,38 +565,6 @@ func (s *scanner) rawString() { s.tok = _Literal } -func (s *scanner) rune() { - s.startLit() - - r := s.getr() - ok := false - if r == '\'' { - s.error("empty character literal or unescaped ' in character literal") - } else if r == '\n' { - s.ungetr() // assume newline is not part of literal - s.error("newline in character literal") - } else { - ok = true - if r == '\\' { - ok = s.escape('\'') - } - } - - r = s.getr() - if r != '\'' { - // only report error if we're ok so far - if ok { - s.error("missing '") - } - s.ungetr() - } - - s.nlsemi = true - s.lit = string(s.stopLit()) - s.kind = RuneLit - s.tok = _Literal -} - func (s *scanner) skipLine(r rune) { for r >= 0 { if r == '\n' { |