go: cmd/compile: memory corruption from `//go:notinheap` interface method wrappers

If T is a //go:notinheap type, then *T is treated like uintptr rather than pointer-shaped. One consequence of this is that the interface method wrappers for T need to use **T instead of *T.

However, reflectdata.methodWrapper doesn’t handle this correctly. For example, this program panics, whereas it succeeds if you remove the //go:notinheap directive: https://play.golang.org/p/p7TiaXlyJzX

Discovered while reimplementing wrapper generation for unified IR.

About this issue

  • Original URL
  • State: closed
  • Created 3 years ago
  • Reactions: 1
  • Comments: 15 (14 by maintainers)

Commits related to this issue

Most upvoted comments

I like the idea of forbidding methods on notinheap types. Or just that their methods don’t satisfy otherwise corresponding interface methods?

The program in the initial comment now causes a compiler crash:

# command-line-arguments
esc
.   CALL tc(1) # <autogenerated>:1:0
.   .   DOTPTR main.M tc(1) # <autogenerated>:1:0
.   .   .   NAME-main..this ld(1) Class:PPARAM Offset:0 OnStack Used PTR-**A tc(1) # <autogenerated>:1:0
<autogenerated>:1: .this.M undefined (type **A has no field or method M)

This only happens when usin the go:notinheap directive, so this doesn’t seem critical. The go:notinheap directive isn’t even documented. So changing milestone to 1.19.