}
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)
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 {
}
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")
--- /dev/null
+// 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
+ `
\ No newline at end of file