1// errorcheck -+
2
3// Copyright 2016 The Go Authors. All rights reserved.
4// Use of this source code is governed by a BSD-style
5// license that can be found in the LICENSE file.
6
7// Test walk errors for go:notinheap.
8
9package p
10
11//go:notinheap
12type nih struct {
13	next *nih
14}
15
16// Global variables are okay.
17
18var x nih
19
20// Stack variables are not okay.
21
22func f() {
23	var y nih // ERROR "nih is incomplete \(or unallocatable\); stack allocation disallowed"
24	x = y
25}
26
27// Heap allocation is not okay.
28
29var y *nih
30var y2 *struct{ x nih }
31var y3 *[1]nih
32var z []nih
33var w []nih
34var n int
35var sink interface{}
36
37type embed1 struct { // implicitly notinheap
38	x nih
39}
40
41type embed2 [1]nih // implicitly notinheap
42
43type embed3 struct { // implicitly notinheap
44	x [1]nih
45}
46
47// Type aliases inherit the go:notinheap-ness of the type they alias.
48type nihAlias = nih
49
50type embedAlias1 struct { // implicitly notinheap
51	x nihAlias
52}
53type embedAlias2 [1]nihAlias // implicitly notinheap
54
55func g() {
56	y = new(nih)              // ERROR "can't be allocated in Go"
57	y2 = new(struct{ x nih }) // ERROR "can't be allocated in Go"
58	y3 = new([1]nih)          // ERROR "can't be allocated in Go"
59	z = make([]nih, 1)        // ERROR "can't be allocated in Go"
60	z = append(z, x)          // ERROR "can't be allocated in Go"
61
62	sink = new(embed1)      // ERROR "can't be allocated in Go"
63	sink = new(embed2)      // ERROR "can't be allocated in Go"
64	sink = new(embed3)      // ERROR "can't be allocated in Go"
65	sink = new(embedAlias1) // ERROR "can't be allocated in Go"
66	sink = new(embedAlias2) // ERROR "can't be allocated in Go"
67
68	// Test for special case of OMAKESLICECOPY
69	x := make([]nih, n) // ERROR "can't be allocated in Go"
70	copy(x, z)
71	z = x
72}
73
74// Writes don't produce write barriers.
75
76var p *nih
77
78//go:nowritebarrier
79func h() {
80	y.next = p.next
81}
82