Commit a836254d authored by Keith Randall's avatar Keith Randall

cmd/compile: reject unknown //go: comments in std library

Fixes #18331

Change-Id: Ie5c6685be3002533b84604ff1f13f2f0850f29e2
Reviewed-on: https://go-review.googlesource.com/45010
Run-TryBot: Keith Randall <khr@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: default avatarEmmanuel Odeke <emm.odeke@gmail.com>
Reviewed-by: default avatarJosh Bleecher Snyder <josharian@gmail.com>
parent 84530b4f
...@@ -198,6 +198,9 @@ var typecheckok bool ...@@ -198,6 +198,9 @@ var typecheckok bool
var compiling_runtime bool var compiling_runtime bool
// Compiling the standard library
var compiling_std bool
var compiling_wrappers int var compiling_wrappers int
var use_writebarrier bool var use_writebarrier bool
......
...@@ -174,6 +174,7 @@ func Main(archInit func(*Arch)) { ...@@ -174,6 +174,7 @@ func Main(archInit func(*Arch)) {
Nacl = objabi.GOOS == "nacl" Nacl = objabi.GOOS == "nacl"
flag.BoolVar(&compiling_runtime, "+", false, "compiling runtime") flag.BoolVar(&compiling_runtime, "+", false, "compiling runtime")
flag.BoolVar(&compiling_std, "std", false, "compiling standard library")
objabi.Flagcount("%", "debug non-static initializers", &Debug['%']) objabi.Flagcount("%", "debug non-static initializers", &Debug['%'])
objabi.Flagcount("B", "disable bounds checking", &Debug['B']) objabi.Flagcount("B", "disable bounds checking", &Debug['B'])
objabi.Flagcount("C", "disable printing of columns in error messages", &Debug['C']) // TODO(gri) remove eventually objabi.Flagcount("C", "disable printing of columns in error messages", &Debug['C']) // TODO(gri) remove eventually
......
...@@ -1153,6 +1153,18 @@ func (p *noder) error(err error) { ...@@ -1153,6 +1153,18 @@ func (p *noder) error(err error) {
p.err <- err.(syntax.Error) p.err <- err.(syntax.Error)
} }
// pragmas that are allowed in the std lib, but don't have
// a syntax.Pragma value (see lex.go) associated with them.
var allowedStdPragmas = map[string]bool{
"go:cgo_export_static": true,
"go:cgo_export_dynamic": true,
"go:cgo_import_static": true,
"go:cgo_import_dynamic": true,
"go:cgo_ldflag": true,
"go:cgo_dynamic_linker": true,
"go:generate": true,
}
// pragma is called concurrently if files are parsed concurrently. // 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 {
...@@ -1181,6 +1193,9 @@ func (p *noder) pragma(pos src.Pos, text string) syntax.Pragma { ...@@ -1181,6 +1193,9 @@ func (p *noder) pragma(pos src.Pos, text string) syntax.Pragma {
if !compiling_runtime && prag&runtimePragmas != 0 { if !compiling_runtime && prag&runtimePragmas != 0 {
p.error(syntax.Error{Pos: pos, Msg: fmt.Sprintf("//%s only allowed in runtime", verb)}) p.error(syntax.Error{Pos: pos, Msg: fmt.Sprintf("//%s only allowed in runtime", verb)})
} }
if prag == 0 && !allowedStdPragmas[verb] && compiling_std {
p.error(syntax.Error{Pos: pos, Msg: fmt.Sprintf("//%s is not allowed in the standard library", verb)})
}
return prag return prag
} }
......
...@@ -2195,6 +2195,9 @@ func (gcToolchain) gc(b *Builder, p *load.Package, archive, obj string, asmhdr b ...@@ -2195,6 +2195,9 @@ func (gcToolchain) gc(b *Builder, p *load.Package, archive, obj string, asmhdr b
if p.Name == "main" { if p.Name == "main" {
gcargs[1] = "main" gcargs[1] = "main"
} }
if p.Standard {
gcargs = append(gcargs, "-std")
}
compilingRuntime := p.Standard && (p.ImportPath == "runtime" || strings.HasPrefix(p.ImportPath, "runtime/internal")) compilingRuntime := p.Standard && (p.ImportPath == "runtime" || strings.HasPrefix(p.ImportPath, "runtime/internal"))
if compilingRuntime { if compilingRuntime {
// runtime compiles with a special gc flag to emit // runtime compiles with a special gc flag to emit
......
...@@ -104,10 +104,10 @@ func testTestDir(t *testing.T, path string, ignore ...string) { ...@@ -104,10 +104,10 @@ func testTestDir(t *testing.T, path string, ignore ...string) {
case "errorcheck": case "errorcheck":
expectErrors = true expectErrors = true
for _, arg := range fields[1:] { for _, arg := range fields[1:] {
if arg == "-0" || arg == "-+" { if arg == "-0" || arg == "-+" || arg == "-std" {
// Marked explicitly as not expected errors (-0), // Marked explicitly as not expected errors (-0),
// or marked as compiling_runtime, which is only done // or marked as compiling runtime/stdlib, which is only done
// to trigger runtime-only error output. // to trigger runtime/stdlib-only error output.
// In both cases, the code should typecheck. // In both cases, the code should typecheck.
expectErrors = false expectErrors = false
break break
......
// errorcheck -std
// 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.
// Issue 18331: We should catch invalid pragma verbs
// for code that resides in the standard library.
package issue18331
//go:unknown // ERROR "//go:unknown is not allowed in the standard library"
func foo()
//go:nowritebarrierc // ERROR "//go:nowritebarrierc is not allowed in the standard library"
func bar()
//go:noesape // ERROR "//go:noesape is not allowed in the standard library"
func groot()
//go:noescape
func hey() { // ERROR "can only use //go:noescape with external func implementations"
}
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