aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/compile/doc.go
diff options
context:
space:
mode:
authorRuss Cox <rsc@golang.org>2020-04-01 15:51:08 -0400
committerRuss Cox <rsc@golang.org>2020-04-21 16:47:01 +0000
commit768201729df89a28aae2cc5e41a33ffcb759c113 (patch)
tree212e9376ed8948f04fb2bedaa712313396ac149a /src/cmd/compile/doc.go
parent4f27e1d7aadba639cceaa93f77ec0c7ee3fee01b (diff)
downloadgo-768201729df89a28aae2cc5e41a33ffcb759c113.tar.gz
go-768201729df89a28aae2cc5e41a33ffcb759c113.zip
cmd/compile: detect and diagnose invalid //go: directive placement
Thie CL changes cmd/compile/internal/syntax to give the gc half of the compiler more control over pragma handling, so that it can prepare better errors, diagnose misuse, and so on. Before, the API between the two was hard-coded as a uint16. Now it is an interface{}. This should set us up better for future directives. In addition to the split, this CL emits a "misplaced compiler directive" error for any directive that is in a place where it has no effect. I've certainly been confused in the past by adding comments that were doing nothing and not realizing it. This should help avoid that kind of confusion. The rule, now applied consistently, is that a //go: directive must appear on a line by itself immediately before the declaration specifier it means to apply to. See cmd/compile/doc.go for precise text and test/directive.go for examples. This may cause some code to stop compiling, but that code was broken. For example, this code formerly applied the //go:noinline to f (not c) but now will fail to compile: //go:noinline const c = 1 func f() {} Change-Id: Ieba9b8d90a27cfab25de79d2790a895cefe5296f Reviewed-on: https://go-review.googlesource.com/c/go/+/228578 Run-TryBot: Russ Cox <rsc@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Robert Griesemer <gri@golang.org>
Diffstat (limited to 'src/cmd/compile/doc.go')
-rw-r--r--src/cmd/compile/doc.go58
1 files changed, 43 insertions, 15 deletions
diff --git a/src/cmd/compile/doc.go b/src/cmd/compile/doc.go
index 11d48154ad..36dd4bb5cd 100644
--- a/src/cmd/compile/doc.go
+++ b/src/cmd/compile/doc.go
@@ -195,30 +195,58 @@ directive can skip over a directive like any other comment.
// Line directives typically appear in machine-generated code, so that compilers and debuggers
// will report positions in the original input to the generator.
/*
-The line directive is an historical special case; all other directives are of the form
-//go:name and must start at the beginning of a line, indicating that the directive is defined
-by the Go toolchain.
+The line directive is a historical special case; all other directives are of the form
+//go:name, indicating that they are defined by the Go toolchain.
+Each directive must be placed its own line, with only leading spaces and tabs
+allowed before the comment.
+Each directive applies to the Go code that immediately follows it,
+which typically must be a declaration.
//go:noescape
-The //go:noescape directive specifies that the next declaration in the file, which
-must be a func without a body (meaning that it has an implementation not written
-in Go) does not allow any of the pointers passed as arguments to escape into the
-heap or into the values returned from the function. This information can be used
-during the compiler's escape analysis of Go code calling the function.
+The //go:noescape directive must be followed by a function declaration without
+a body (meaning that the function has an implementation not written in Go).
+It specifies that the function does not allow any of the pointers passed as
+arguments to escape into the heap or into the values returned from the function.
+This information can be used during the compiler's escape analysis of Go code
+calling the function.
+
+ //go:uintptrescapes
+
+The //go:uintptrescapes directive must be followed by a function declaration.
+It specifies that the function's uintptr arguments may be pointer values
+that have been converted to uintptr and must be treated as such by the
+garbage collector. The conversion from pointer to uintptr must appear in
+the argument list of any call to this function. This directive is necessary
+for some low-level system call implementations and should be avoided otherwise.
+
+ //go:noinline
+
+The //go:noinline directive must be followed by a function declaration.
+It specifies that calls to the function should not be inlined, overriding
+the compiler's usual optimization rules. This is typically only needed
+for special runtime functions or when debugging the compiler.
+
+ //go:norace
+
+The //go:norace directive must be followed by a function declaration.
+It specifies that the function's memory accesses must be ignored by the
+race detector. This is most commonly used in low-level code invoked
+at times when it is unsafe to call into the race detector runtime.
//go:nosplit
-The //go:nosplit directive specifies that the next function declared in the file must
-not include a stack overflow check. This is most commonly used by low-level
-runtime sources invoked at times when it is unsafe for the calling goroutine to be
-preempted.
+The //go:nosplit directive must be followed by a function declaration.
+It specifies that the function must omit its usual stack overflow check.
+This is most commonly used by low-level runtime code invoked
+at times when it is unsafe for the calling goroutine to be preempted.
//go:linkname localname [importpath.name]
-The //go:linkname directive instructs the compiler to use ``importpath.name'' as the
-object file symbol name for the variable or function declared as ``localname'' in the
-source code.
+This special directive does not apply to the Go code that follows it.
+Instead, the //go:linkname directive instructs the compiler to use ``importpath.name''
+as the object file symbol name for the variable or function declared as ``localname''
+in the source code.
If the ``importpath.name'' argument is omitted, the directive uses the
symbol's default object file symbol name and only has the effect of making
the symbol accessible to other packages.