Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

cmd/cgo: pointer to incomplete C type is mangled when passed through interface type and generic type assert #51733

Closed
kbolino opened this issue Mar 16, 2022 · 4 comments
Labels
FrozenDueToAge NeedsFix The path to resolution is known, but the work has not been done.
Milestone

Comments

@kbolino
Copy link

kbolino commented Mar 16, 2022

What version of Go are you using (go version)?

$ go version
go version go1.18 darwin/arm64

Does this issue reproduce with the latest release?

This is the latest release.

What operating system and processor architecture are you using (go env)?

go env Output
$ go env
GO111MODULE=""
GOARCH="arm64"
GOBIN=""
GOCACHE="/Users/kbolino/Library/Caches/go-build"
GOENV="/Users/kbolino/Library/Application Support/go/env"
GOEXE=""
GOEXPERIMENT=""
GOFLAGS=""
GOHOSTARCH="arm64"
GOHOSTOS="darwin"
GOINSECURE=""
GOMODCACHE="/Users/kbolino/go/pkg/mod"
GONOPROXY=""
GONOSUMDB=""
GOOS="darwin"
GOPATH="/Users/kbolino/go"
GOPRIVATE=""
GOPROXY="https://proxy.golang.org,direct"
GOROOT="/usr/local/go"
GOSUMDB="sum.golang.org"
GOTMPDIR=""
GOTOOLDIR="/usr/local/go/pkg/tool/darwin_arm64"
GOVCS=""
GOVERSION="go1.18"
GCCGO="gccgo"
AR="ar"
CC="clang"
CXX="clang++"
CGO_ENABLED="1"
GOMOD="/Users/kbolino/Documents/GoModules/cgo-generics/go.mod"
GOWORK=""
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"
PKG_CONFIG="pkg-config"
GOGCCFLAGS="-fPIC -arch arm64 -pthread -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -fdebug-prefix-map=/var/folders/59/hjg6jvkd71s8djph6yqbdn0h0000gn/T/go-build78106070=/tmp/go-build -gno-record-gcc-switches -fno-common"

What did you do?

package main

// #include <stdlib.h>
// struct incomplete_type;
import "C"

import (
	"fmt"
	"unsafe"
)

func main() {
	someMem := C.malloc(16)
	defer C.free(someMem)
	ptrIn := (*C.struct_incomplete_type)(someMem)
	fmt.Printf("ptrIn  = %016x\n", uintptr(unsafe.Pointer(ptrIn)))
	var iface interface{} = ptrIn
	ptrOut := recoverPointer[C.struct_incomplete_type](iface)
	fmt.Printf("ptrOut = %016x\n", uintptr(unsafe.Pointer(ptrOut)))	
}

func recoverPointer[T any](val interface{}) *T {
	return val.(*T)
}

This is a minimal example; the original use case involved cgo.Handle and passing pointers across the Go/C boundary.

What did you expect to see?

ptrIn  = <some_val>
ptrOut = <some_val>

A compilation error or panic would also have sufficed.

What did you see instead?

ptrIn  = <some_val>
ptrOut = <some_other_val>

for example,

ptrIn  = 0000600000dbc010
ptrOut = 0000014000059f30
@kbolino kbolino changed the title cmd/cgo: Pointer to incomplete C type is mangled when passed through interface type and generic type assert cmd/cgo: pointer to incomplete C type is mangled when passed through interface type and generic type assert Mar 16, 2022
@ianlancetaylor
Copy link
Contributor

Here is a standalone example that doesn't use cgo. This appears to be a bug in the way that generic code handles type assertions, or notinheap pointers, or something. CC @randall77 .

package main

import (
	"log"
	"unsafe"
)

//go:notinheap
type S struct{}

func main() {
	p := (*S)(unsafe.Pointer(uintptr(0x8000)))
	var v any = p
	p2 := v.(*S)
	if p != p2 {
		log.Fatalf("%p != %p", unsafe.Pointer(p), unsafe.Pointer(p2))
	}
	p2 = typeAssert[*S](v)
	if p != p2 {
		log.Fatalf("%p != %p from typeAssert", unsafe.Pointer(p), unsafe.Pointer(p2))
	}
}

func typeAssert[T any](v any) T {
	return v.(T)
}

@ianlancetaylor
Copy link
Contributor

@gopherbot Please open backport to 1.18

This appears to be invalid code generation, so we should backport a fix when we have one.

@gopherbot
Copy link

Backport issue(s) opened: #51741 (for 1.18).

Remember to create the cherry-pick CL(s) as soon as the patch is submitted to master, according to https://go.dev/wiki/MinorReleases.

@heschi heschi added the NeedsFix The path to resolution is known, but the work has not been done. label Mar 17, 2022
@heschi heschi added this to the Go1.19 milestone Mar 17, 2022
@gopherbot
Copy link

Change https://go.dev/cl/393895 mentions this issue: cmd/compile: pointers to notinheap types need their own shape

@golang golang locked and limited conversation to collaborators Mar 18, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
FrozenDueToAge NeedsFix The path to resolution is known, but the work has not been done.
Projects
None yet
Development

No branches or pull requests

4 participants