summaryrefslogtreecommitdiff
path: root/test/directive.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 /test/directive.go
parent4f27e1d7aadba639cceaa93f77ec0c7ee3fee01b (diff)
downloadgo-git-768201729df89a28aae2cc5e41a33ffcb759c113.tar.gz
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 'test/directive.go')
-rw-r--r--test/directive.go95
1 files changed, 95 insertions, 0 deletions
diff --git a/test/directive.go b/test/directive.go
new file mode 100644
index 0000000000..6167cd6279
--- /dev/null
+++ b/test/directive.go
@@ -0,0 +1,95 @@
+// errorcheck
+
+// Copyright 2020 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 misplaced directives are diagnosed.
+
+//go:noinline // ERROR "misplaced compiler directive"
+
+//go:noinline // ERROR "misplaced compiler directive"
+package main
+
+//go:nosplit
+func f1() {}
+
+//go:nosplit
+//go:noinline
+func f2() {}
+
+//go:noinline // ERROR "misplaced compiler directive"
+
+//go:noinline // ERROR "misplaced compiler directive"
+var x int
+
+//go:noinline // ERROR "misplaced compiler directive"
+const c = 1
+
+//go:noinline // ERROR "misplaced compiler directive"
+type T int
+
+// ok
+//go:notinheap
+type T1 int
+
+//go:notinheap // ERROR "misplaced compiler directive"
+type (
+ //go:notinheap
+ //go:noinline // ERROR "misplaced compiler directive"
+ T2 int //go:notinheap // ERROR "misplaced compiler directive"
+ T2b int
+ //go:notinheap
+ T2c int
+ //go:noinline // ERROR "misplaced compiler directive"
+ T3 int
+)
+
+//go:notinheap // ERROR "misplaced compiler directive"
+type (
+ //go:notinheap
+ T4 int
+)
+
+//go:notinheap // ERROR "misplaced compiler directive"
+type ()
+
+type T5 int
+
+func g() {} //go:noinline // ERROR "misplaced compiler directive"
+
+// ok: attached to f (duplicated yes, but ok)
+//go:noinline
+
+//go:noinline
+func f() {
+ //go:noinline // ERROR "misplaced compiler directive"
+ x := 1
+
+ //go:noinline // ERROR "misplaced compiler directive"
+ {
+ _ = x //go:noinline // ERROR "misplaced compiler directive"
+ }
+ //go:noinline // ERROR "misplaced compiler directive"
+ var y int //go:noinline // ERROR "misplaced compiler directive"
+ //go:noinline // ERROR "misplaced compiler directive"
+ _ = y
+
+ //go:noinline // ERROR "misplaced compiler directive"
+ const c = 1
+
+ //go:noinline // ERROR "misplaced compiler directive"
+ _ = func() {}
+
+ //go:noinline // ERROR "misplaced compiler directive"
+ // ok:
+ //go:notinheap
+ type T int
+}
+
+// someday there might be a directive that can apply to type aliases, but go:notinheap doesn't.
+//go:notinheap // ERROR "misplaced compiler directive"
+type T6 = int
+
+// EOF
+//go:noinline // ERROR "misplaced compiler directive"