mirror of
https://github.com/golang/go
synced 2024-11-16 21:04:45 -07:00
cmd/compile: avoid follow-on errors for literals with syntax errors
- only convert literal strings if there were no syntax errors (some of the conversion routines exit if there is an error) - mark nodes for literals with syntax errors to avoid follow-on errors - don't attempt to import packages whose path had syntax errors Fixes #32133. Change-Id: I1803ad48c65abfecf6f48ddff1e27eded5e282c5 Reviewed-on: https://go-review.googlesource.com/c/go/+/192437 Reviewed-by: Matthew Dempsky <mdempsky@google.com>
This commit is contained in:
parent
117400ec09
commit
5411953df5
@ -309,6 +309,10 @@ func (p *noder) decls(decls []syntax.Decl) (l []*Node) {
|
||||
}
|
||||
|
||||
func (p *noder) importDecl(imp *syntax.ImportDecl) {
|
||||
if imp.Path.Bad {
|
||||
return // avoid follow-on errors if there was a syntax error
|
||||
}
|
||||
|
||||
val := p.basicLit(imp.Path)
|
||||
ipkg := importfile(&val)
|
||||
|
||||
@ -602,7 +606,9 @@ func (p *noder) expr(expr syntax.Expr) *Node {
|
||||
case *syntax.Name:
|
||||
return p.mkname(expr)
|
||||
case *syntax.BasicLit:
|
||||
return nodlit(p.basicLit(expr))
|
||||
n := nodlit(p.basicLit(expr))
|
||||
n.SetDiag(expr.Bad) // avoid follow-on errors if there was a syntax error
|
||||
return n
|
||||
case *syntax.CompositeLit:
|
||||
n := p.nod(expr, OCOMPLIT, nil, nil)
|
||||
if expr.Type != nil {
|
||||
@ -1351,55 +1357,60 @@ func checkLangCompat(lit *syntax.BasicLit) {
|
||||
}
|
||||
|
||||
func (p *noder) basicLit(lit *syntax.BasicLit) Val {
|
||||
// TODO: Don't try to convert if we had syntax errors (conversions may fail).
|
||||
// Use dummy values so we can continue to compile. Eventually, use a
|
||||
// form of "unknown" literals that are ignored during type-checking so
|
||||
// we can continue type-checking w/o spurious follow-up errors.
|
||||
// We don't use the errors of the conversion routines to determine
|
||||
// if a literal string is valid because the conversion routines may
|
||||
// accept a wider syntax than the language permits. Rely on lit.Bad
|
||||
// instead.
|
||||
switch s := lit.Value; lit.Kind {
|
||||
case syntax.IntLit:
|
||||
checkLangCompat(lit)
|
||||
x := new(Mpint)
|
||||
x.SetString(s)
|
||||
if !lit.Bad {
|
||||
x.SetString(s)
|
||||
}
|
||||
return Val{U: x}
|
||||
|
||||
case syntax.FloatLit:
|
||||
checkLangCompat(lit)
|
||||
x := newMpflt()
|
||||
x.SetString(s)
|
||||
if !lit.Bad {
|
||||
x.SetString(s)
|
||||
}
|
||||
return Val{U: x}
|
||||
|
||||
case syntax.ImagLit:
|
||||
checkLangCompat(lit)
|
||||
x := newMpcmplx()
|
||||
x.Imag.SetString(strings.TrimSuffix(s, "i"))
|
||||
if !lit.Bad {
|
||||
x.Imag.SetString(strings.TrimSuffix(s, "i"))
|
||||
}
|
||||
return Val{U: x}
|
||||
|
||||
case syntax.RuneLit:
|
||||
var r rune
|
||||
if u, err := strconv.Unquote(s); err == nil && len(u) > 0 {
|
||||
// Package syntax already reported any errors.
|
||||
// Check for them again though because 0 is a
|
||||
// better fallback value for invalid rune
|
||||
// literals than 0xFFFD.
|
||||
x := new(Mpint)
|
||||
x.Rune = true
|
||||
if !lit.Bad {
|
||||
u, _ := strconv.Unquote(s)
|
||||
var r rune
|
||||
if len(u) == 1 {
|
||||
r = rune(u[0])
|
||||
} else {
|
||||
r, _ = utf8.DecodeRuneInString(u)
|
||||
}
|
||||
x.SetInt64(int64(r))
|
||||
}
|
||||
x := new(Mpint)
|
||||
x.SetInt64(int64(r))
|
||||
x.Rune = true
|
||||
return Val{U: x}
|
||||
|
||||
case syntax.StringLit:
|
||||
if len(s) > 0 && s[0] == '`' {
|
||||
// strip carriage returns from raw string
|
||||
s = strings.Replace(s, "\r", "", -1)
|
||||
var x string
|
||||
if !lit.Bad {
|
||||
if len(s) > 0 && s[0] == '`' {
|
||||
// strip carriage returns from raw string
|
||||
s = strings.Replace(s, "\r", "", -1)
|
||||
}
|
||||
x, _ = strconv.Unquote(s)
|
||||
}
|
||||
// Ignore errors because package syntax already reported them.
|
||||
u, _ := strconv.Unquote(s)
|
||||
return Val{U: u}
|
||||
return Val{U: x}
|
||||
|
||||
default:
|
||||
panic("unhandled BasicLit kind")
|
||||
|
43
test/fixedbugs/issue32133.go
Normal file
43
test/fixedbugs/issue32133.go
Normal file
@ -0,0 +1,43 @@
|
||||
// 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
|
||||
|
||||
// errors for the //line-adjusted code below
|
||||
// ERROR "newline in string"
|
||||
// ERROR "newline in character literal"
|
||||
// ERROR "newline in string"
|
||||
// ERROR "string not terminated"
|
||||
|
||||
//line :10:1
|
||||
import "foo
|
||||
|
||||
//line :19:1
|
||||
func _() {
|
||||
0x // ERROR "hexadecimal literal has no digits"
|
||||
}
|
||||
|
||||
func _() {
|
||||
0x1.0 // ERROR "hexadecimal mantissa requires a 'p' exponent"
|
||||
}
|
||||
|
||||
func _() {
|
||||
0_i // ERROR "'_' must separate successive digits"
|
||||
}
|
||||
|
||||
func _() {
|
||||
//line :11:1
|
||||
'
|
||||
}
|
||||
|
||||
func _() {
|
||||
//line :12:1
|
||||
"
|
||||
}
|
||||
|
||||
func _() {
|
||||
//line :13:1
|
||||
`
|
Loading…
Reference in New Issue
Block a user