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 not-in-heap.
8
9//go:build cgo
10
11package p
12
13import "runtime/cgo"
14
15type nih struct {
16	_    cgo.Incomplete
17	next *nih
18}
19
20// Global variables are okay.
21
22var x nih
23
24// Stack variables are not okay.
25
26func f() {
27	var y nih // ERROR "nih is incomplete \(or unallocatable\); stack allocation disallowed"
28	x = y
29}
30
31// Heap allocation is not okay.
32
33var y *nih
34var y2 *struct{ x nih }
35var y3 *[1]nih
36var z []nih
37var w []nih
38var n int
39var sink interface{}
40
41type embed1 struct { // implicitly notinheap
42	x nih
43}
44
45type embed2 [1]nih // implicitly notinheap
46
47type embed3 struct { // implicitly notinheap
48	x [1]nih
49}
50
51// Type aliases inherit the go:notinheap-ness of the type they alias.
52type nihAlias = nih
53
54type embedAlias1 struct { // implicitly notinheap
55	x nihAlias
56}
57type embedAlias2 [1]nihAlias // implicitly notinheap
58
59func g() {
60	y = new(nih)              // ERROR "can't be allocated in Go"
61	y2 = new(struct{ x nih }) // ERROR "can't be allocated in Go"
62	y3 = new([1]nih)          // ERROR "can't be allocated in Go"
63	z = make([]nih, 1)        // ERROR "can't be allocated in Go"
64	z = append(z, x)          // ERROR "can't be allocated in Go"
65
66	sink = new(embed1)      // ERROR "can't be allocated in Go"
67	sink = new(embed2)      // ERROR "can't be allocated in Go"
68	sink = new(embed3)      // ERROR "can't be allocated in Go"
69	sink = new(embedAlias1) // ERROR "can't be allocated in Go"
70	sink = new(embedAlias2) // ERROR "can't be allocated in Go"
71
72	// Test for special case of OMAKESLICECOPY
73	x := make([]nih, n) // ERROR "can't be allocated in Go"
74	copy(x, z)
75	z = x
76}
77
78// Writes don't produce write barriers.
79
80var p *nih
81
82//go:nowritebarrier
83func h() {
84	y.next = p.next
85}
86