cmd/compile: provide line number for cgo directive error (fix a TODO)

Also: Remove double "go:" prefix in related error message.

Fixes #18882.

Change-Id: Ifbbd8e2f7529b43f035d3dbf7ca4a91f212bc6b6
Reviewed-on: https://go-review.googlesource.com/36121
Run-TryBot: Robert Griesemer <gri@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
This commit is contained in:
Robert Griesemer 2017-02-01 15:17:32 -08:00
parent e546b295b8
commit c1363b2d91
6 changed files with 32 additions and 12 deletions

View file

@ -115,7 +115,8 @@ func internString(b []byte) string {
return s
}
func pragcgo(text string) string {
// pragcgo is called concurrently if files are parsed concurrently.
func (p *noder) pragcgo(pos src.Pos, text string) string {
f := pragmaFields(text)
verb := f[0][3:] // skip "go:"
@ -132,7 +133,7 @@ func pragcgo(text string) string {
return fmt.Sprintln(verb, local, remote)
default:
yyerror(`usage: //go:%s local [remote]`, verb)
p.error(syntax.Error{Pos: pos, Msg: fmt.Sprintf(`usage: //go:%s local [remote]`, verb)})
}
case "cgo_import_dynamic":
switch {
@ -152,7 +153,7 @@ func pragcgo(text string) string {
return fmt.Sprintln(verb, local, remote, library)
default:
yyerror(`usage: //go:cgo_import_dynamic local [remote ["library"]]`)
p.error(syntax.Error{Pos: pos, Msg: `usage: //go:cgo_import_dynamic local [remote ["library"]]`})
}
case "cgo_import_static":
switch {
@ -161,7 +162,7 @@ func pragcgo(text string) string {
return fmt.Sprintln(verb, local)
default:
yyerror(`usage: //go:cgo_import_static local`)
p.error(syntax.Error{Pos: pos, Msg: `usage: //go:cgo_import_static local`})
}
case "cgo_dynamic_linker":
switch {
@ -170,7 +171,7 @@ func pragcgo(text string) string {
return fmt.Sprintln(verb, path)
default:
yyerror(`usage: //go:cgo_dynamic_linker "path"`)
p.error(syntax.Error{Pos: pos, Msg: `usage: //go:cgo_dynamic_linker "path"`})
}
case "cgo_ldflag":
switch {
@ -179,7 +180,7 @@ func pragcgo(text string) string {
return fmt.Sprintln(verb, arg)
default:
yyerror(`usage: //go:cgo_ldflag "arg"`)
p.error(syntax.Error{Pos: pos, Msg: `usage: //go:cgo_ldflag "arg"`})
}
}
return ""

View file

@ -4,7 +4,10 @@
package gc
import "testing"
import (
"cmd/internal/src"
"testing"
)
func eq(a, b []string) bool {
if len(a) != len(b) {
@ -69,8 +72,9 @@ func TestPragcgo(t *testing.T) {
{`go:cgo_ldflag "a rg"`, "cgo_ldflag 'a rg'\n"},
}
var p noder
for _, tt := range tests {
got := pragcgo(tt.in)
got := p.pragcgo(src.NoPos, tt.in)
if got != tt.want {
t.Errorf("pragcgo(%q) = %q; want %q", tt.in, got, tt.want)
continue

View file

@ -1105,10 +1105,12 @@ func (p *noder) lineno(n syntax.Node) {
lineno = Ctxt.PosTable.XPos(pos)
}
// error is called concurrently if files are parsed concurrently.
func (p *noder) error(err error) {
p.err <- err.(syntax.Error)
}
// pragma is called concurrently if files are parsed concurrently.
func (p *noder) pragma(pos src.Pos, text string) syntax.Pragma {
switch {
case strings.HasPrefix(text, "line "):
@ -1124,8 +1126,7 @@ func (p *noder) pragma(pos src.Pos, text string) syntax.Pragma {
p.linknames = append(p.linknames, linkname{pos, f[1], f[2]})
case strings.HasPrefix(text, "go:cgo_"):
// TODO(gri): lineno = p.baseline + int32(line) - 1 // pragcgo may call yyerror
p.pragcgobuf += pragcgo(text)
p.pragcgobuf += p.pragcgo(pos, text)
fallthrough // because of //go:cgo_unsafe_args
default:
verb := text
@ -1135,7 +1136,7 @@ func (p *noder) pragma(pos src.Pos, text string) syntax.Pragma {
prag := pragmaValue(verb)
const runtimePragmas = Systemstack | Nowritebarrier | Nowritebarrierrec | Yeswritebarrierrec
if !compiling_runtime && prag&runtimePragmas != 0 {
p.error(syntax.Error{Pos: pos, Msg: fmt.Sprintf("//go:%s only allowed in runtime", verb)})
p.error(syntax.Error{Pos: pos, Msg: fmt.Sprintf("//%s only allowed in runtime", verb)})
}
return prag
}

View file

@ -158,6 +158,7 @@ func TestStdFixed(t *testing.T) {
"issue15002.go", // uses Mmap; testTestDir should consult build tags
"issue16369.go", // go/types handles this correctly - not an issue
"issue18459.go", // go/types doesn't check validity of //go:xxx directives
"issue18882.go", // go/types doesn't check validity of //go:xxx directives
)
}

View file

@ -8,6 +8,6 @@
package main
//go:nowritebarrier // ERROR "go:nowritebarrier only allowed in runtime"
//go:nowritebarrier // ERROR "//go:nowritebarrier only allowed in runtime"
func main() {
}

View file

@ -0,0 +1,13 @@
// errorcheck
// Copyright 2017 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.
// Verify that we have a line number for this error.
package main
//go:cgo_ldflag // ERROR "usage: //go:cgo_ldflag"
func main() {
}