Skip to content

Commit 40c1d88

Browse files
committed
add new Clone API test case
Change-Id: I639df00ca5101d6287eb2c08e9fc9f8ce34fee02
1 parent 0ff056d commit 40c1d88

File tree

1 file changed

+40
-8
lines changed

1 file changed

+40
-8
lines changed

test/devirtualization_with_type_assertions_interleaved.go

Lines changed: 40 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@ type hashIface interface {
1010
Sum() []byte
1111
}
1212

13-
type clonableHashIface interface {
14-
Sum() []byte
13+
type cloneableHashIface interface {
14+
hashIface
1515
Clone() hashIface
1616
}
1717

@@ -42,42 +42,42 @@ func newHash() hashIface { // ERROR "can inline newHash$"
4242
}
4343

4444
func cloneHash1(h hashIface) hashIface { // ERROR "can inline cloneHash1$" "leaking param: h$"
45-
if h, ok := h.(clonableHashIface); ok {
45+
if h, ok := h.(cloneableHashIface); ok {
4646
return h.Clone()
4747
}
4848
return &hash{} // ERROR "&hash{} escapes to heap$"
4949
}
5050

5151
func cloneHash2(h hashIface) hashIface { // ERROR "can inline cloneHash2$" "leaking param: h$"
52-
if h, ok := h.(clonableHashIface); ok {
52+
if h, ok := h.(cloneableHashIface); ok {
5353
return h.Clone()
5454
}
5555
return nil
5656
}
5757

5858
func cloneHash3(h hashIface) hashIface { // ERROR "can inline cloneHash3$" "leaking param: h$"
59-
if h, ok := h.(clonableHashIface); ok {
59+
if h, ok := h.(cloneableHashIface); ok {
6060
return h.Clone()
6161
}
6262
return &hash2{} // ERROR "&hash2{} escapes to heap$"
6363
}
6464

6565
func cloneHashWithBool1(h hashIface) (hashIface, bool) { // ERROR "can inline cloneHashWithBool1$" "leaking param: h$"
66-
if h, ok := h.(clonableHashIface); ok {
66+
if h, ok := h.(cloneableHashIface); ok {
6767
return h.Clone(), true
6868
}
6969
return &hash{}, false // ERROR "&hash{} escapes to heap$"
7070
}
7171

7272
func cloneHashWithBool2(h hashIface) (hashIface, bool) { // ERROR "can inline cloneHashWithBool2$" "leaking param: h$"
73-
if h, ok := h.(clonableHashIface); ok {
73+
if h, ok := h.(cloneableHashIface); ok {
7474
return h.Clone(), true
7575
}
7676
return nil, false
7777
}
7878

7979
func cloneHashWithBool3(h hashIface) (hashIface, bool) { // ERROR "can inline cloneHashWithBool3$" "leaking param: h$"
80-
if h, ok := h.(clonableHashIface); ok {
80+
if h, ok := h.(cloneableHashIface); ok {
8181
return h.Clone(), true
8282
}
8383
return &hash2{}, false // ERROR "&hash2{} escapes to heap$"
@@ -105,3 +105,35 @@ func interleavedWithTypeAssertions() {
105105
h7, _ := cloneHashWithBool3(h1) // ERROR "&hash2{} escapes to heap$" "devirtualizing h.Clone to \*hash$" "inlining call to \(\*hash\).Clone" "inlining call to cloneHashWithBool3" "moved to heap: c$"
106106
_ = h7.Sum()
107107
}
108+
109+
type cloneableHashError interface {
110+
hashIface
111+
Clone() (hashIface, error)
112+
}
113+
114+
type hash3 struct{ state [32]byte }
115+
116+
func newHash3() hashIface { // ERROR "can inline newHash3$"
117+
return &hash3{} // ERROR "&hash3{} escapes to heap$"
118+
}
119+
120+
func (h *hash3) Sum() []byte { // ERROR "can inline \(\*hash3\).Sum$" "h does not escape$"
121+
return make([]byte, 32) // ERROR "make\(\[\]byte, 32\) escapes to heap$"
122+
}
123+
124+
func (h *hash3) Clone() (hashIface, error) { // ERROR "can inline \(\*hash3\).Clone$" "h does not escape$"
125+
c := *h // ERROR "moved to heap: c$"
126+
return &c, nil
127+
}
128+
129+
func interleavedCloneableHashError() {
130+
h1 := newHash3() // ERROR "&hash3{} does not escape$" "inlining call to newHash3"
131+
_ = h1.Sum() // ERROR "devirtualizing h1.Sum to \*hash3$" "inlining call to \(\*hash3\).Sum" "make\(\[\]byte, 32\) does not escape$"
132+
133+
if h1, ok := h1.(cloneableHashError); ok {
134+
h2, err := h1.Clone() // ERROR "devirtualizing h1.Clone to \*hash3$" "inlining call to \(\*hash3\).Clone"
135+
if err == nil {
136+
_ = h2.Sum() // ERROR "devirtualizing h2.Sum to \*hash3$" "inlining call to \(\*hash3\).Sum" "make\(\[\]byte, 32\) does not escape$"
137+
}
138+
}
139+
}

0 commit comments

Comments
 (0)