Commit c1363b2d authored by Robert Griesemer's avatar Robert Griesemer

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: default avatarMatthew Dempsky <mdempsky@google.com>
parent e546b295
...@@ -115,7 +115,8 @@ func internString(b []byte) string { ...@@ -115,7 +115,8 @@ func internString(b []byte) string {
return s 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) f := pragmaFields(text)
verb := f[0][3:] // skip "go:" verb := f[0][3:] // skip "go:"
...@@ -132,7 +133,7 @@ func pragcgo(text string) string { ...@@ -132,7 +133,7 @@ func pragcgo(text string) string {
return fmt.Sprintln(verb, local, remote) return fmt.Sprintln(verb, local, remote)
default: 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": case "cgo_import_dynamic":
switch { switch {
...@@ -152,7 +153,7 @@ func pragcgo(text string) string { ...@@ -152,7 +153,7 @@ func pragcgo(text string) string {
return fmt.Sprintln(verb, local, remote, library) return fmt.Sprintln(verb, local, remote, library)
default: 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": case "cgo_import_static":
switch { switch {
...@@ -161,7 +162,7 @@ func pragcgo(text string) string { ...@@ -161,7 +162,7 @@ func pragcgo(text string) string {
return fmt.Sprintln(verb, local) return fmt.Sprintln(verb, local)
default: 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": case "cgo_dynamic_linker":
switch { switch {
...@@ -170,7 +171,7 @@ func pragcgo(text string) string { ...@@ -170,7 +171,7 @@ func pragcgo(text string) string {
return fmt.Sprintln(verb, path) return fmt.Sprintln(verb, path)
default: default:
yyerror(`usage: //go:cgo_dynamic_linker "path"`) p.error(syntax.Error{Pos: pos, Msg: `usage: //go:cgo_dynamic_linker "path"`})
} }
case "cgo_ldflag": case "cgo_ldflag":
switch { switch {
...@@ -179,7 +180,7 @@ func pragcgo(text string) string { ...@@ -179,7 +180,7 @@ func pragcgo(text string) string {
return fmt.Sprintln(verb, arg) return fmt.Sprintln(verb, arg)
default: default:
yyerror(`usage: //go:cgo_ldflag "arg"`) p.error(syntax.Error{Pos: pos, Msg: `usage: //go:cgo_ldflag "arg"`})
} }
} }
return "" return ""
......
...@@ -4,7 +4,10 @@ ...@@ -4,7 +4,10 @@
package gc package gc
import "testing" import (
"cmd/internal/src"
"testing"
)
func eq(a, b []string) bool { func eq(a, b []string) bool {
if len(a) != len(b) { if len(a) != len(b) {
...@@ -69,8 +72,9 @@ func TestPragcgo(t *testing.T) { ...@@ -69,8 +72,9 @@ func TestPragcgo(t *testing.T) {
{`go:cgo_ldflag "a rg"`, "cgo_ldflag 'a rg'\n"}, {`go:cgo_ldflag "a rg"`, "cgo_ldflag 'a rg'\n"},
} }
var p noder
for _, tt := range tests { for _, tt := range tests {
got := pragcgo(tt.in) got := p.pragcgo(src.NoPos, tt.in)
if got != tt.want { if got != tt.want {
t.Errorf("pragcgo(%q) = %q; want %q", tt.in, got, tt.want) t.Errorf("pragcgo(%q) = %q; want %q", tt.in, got, tt.want)
continue continue
......
...@@ -1105,10 +1105,12 @@ func (p *noder) lineno(n syntax.Node) { ...@@ -1105,10 +1105,12 @@ func (p *noder) lineno(n syntax.Node) {
lineno = Ctxt.PosTable.XPos(pos) lineno = Ctxt.PosTable.XPos(pos)
} }
// error is called concurrently if files are parsed concurrently.
func (p *noder) error(err error) { func (p *noder) error(err error) {
p.err <- err.(syntax.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 { func (p *noder) pragma(pos src.Pos, text string) syntax.Pragma {
switch { switch {
case strings.HasPrefix(text, "line "): case strings.HasPrefix(text, "line "):
...@@ -1124,8 +1126,7 @@ func (p *noder) pragma(pos src.Pos, text string) syntax.Pragma { ...@@ -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]}) p.linknames = append(p.linknames, linkname{pos, f[1], f[2]})
case strings.HasPrefix(text, "go:cgo_"): case strings.HasPrefix(text, "go:cgo_"):
// TODO(gri): lineno = p.baseline + int32(line) - 1 // pragcgo may call yyerror p.pragcgobuf += p.pragcgo(pos, text)
p.pragcgobuf += pragcgo(text)
fallthrough // because of //go:cgo_unsafe_args fallthrough // because of //go:cgo_unsafe_args
default: default:
verb := text verb := text
...@@ -1135,7 +1136,7 @@ func (p *noder) pragma(pos src.Pos, text string) syntax.Pragma { ...@@ -1135,7 +1136,7 @@ func (p *noder) pragma(pos src.Pos, text string) syntax.Pragma {
prag := pragmaValue(verb) prag := pragmaValue(verb)
const runtimePragmas = Systemstack | Nowritebarrier | Nowritebarrierrec | Yeswritebarrierrec const runtimePragmas = Systemstack | Nowritebarrier | Nowritebarrierrec | Yeswritebarrierrec
if !compiling_runtime && prag&runtimePragmas != 0 { 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 return prag
} }
......
...@@ -158,6 +158,7 @@ func TestStdFixed(t *testing.T) { ...@@ -158,6 +158,7 @@ func TestStdFixed(t *testing.T) {
"issue15002.go", // uses Mmap; testTestDir should consult build tags "issue15002.go", // uses Mmap; testTestDir should consult build tags
"issue16369.go", // go/types handles this correctly - not an issue "issue16369.go", // go/types handles this correctly - not an issue
"issue18459.go", // go/types doesn't check validity of //go:xxx directives "issue18459.go", // go/types doesn't check validity of //go:xxx directives
"issue18882.go", // go/types doesn't check validity of //go:xxx directives
) )
} }
......
...@@ -8,6 +8,6 @@ ...@@ -8,6 +8,6 @@
package main package main
//go:nowritebarrier // ERROR "go:nowritebarrier only allowed in runtime" //go:nowritebarrier // ERROR "//go:nowritebarrier only allowed in runtime"
func main() { func main() {
} }
// 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() {
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment