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: as of Go 1.10 it seems pointers to C.size_t or C.ulong are treated as the same type #24207

Closed
cstyan opened this issue Mar 1, 2018 · 4 comments

Comments

@cstyan
Copy link

commented Mar 1, 2018

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

go version go1.10 linux/amd64

Does this issue reproduce with the latest release?

I am on latest release, but I have not tried the latest commit in master.

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

GOBIN=""
GOCACHE="/home/callum/.cache/go-build"
GOEXE=""
GOHOSTARCH="amd64"
GOHOSTOS="linux"
GOOS="linux"
GOPATH="/home/callum/go"
GORACE=""
GOROOT="/usr/local/go"
GOTMPDIR=""
GOTOOLDIR="/usr/local/go/pkg/tool/linux_amd64"
GCCGO="/usr/bin/gccgo"
CC="gcc"
CXX="g++"
CGO_ENABLED="1"
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"
PKG_CONFIG="pkg-config"
GOGCCFLAGS="-fPIC -m64 -pthread -fmessage-length=0 -fdebug-prefix-map=/tmp/go-build518258673=/tmp/go-build -gno-record-gcc-switches"

What did you do?

I have the following code which compiled in 1.8.x and 1.9.x:


import "C"

func setValue(to interface{}, from interface{}) {

	switch to.(type) {
	case *C.size_t:
		t := to.(*C.size_t)
		f := from.(int)
		*t = C.size_t(f)
	case *C.ulong:
		t := to.(*C.ulong)
		f := from.(int)
		*t = C.ulong(f)
	default:
		panic("Invalid type in command line parameter")
	}
}

func main() {
	someVal := 3
	var someUlong C.ulong
	var someSizeT C.size_t
	setValue(&someUlong, someVal)
	setValue(&someSizeT, someVal)
}

What did you expect to see?

Proper compilation, switch is able to determine if interface is a *C.size_t or *C.ulong.

What did you see instead?

./main.go:12: duplicate case *_Ctype_ulong in type switch
	previous case at ./main.go:8

Longer output from go build main.go -v -x:

WORK=/tmp/go-build207868665
_/home/callum/cgo_tests
mkdir -p $WORK/b001/
cd /home/callum/cgo_tests
CGO_LDFLAGS='"-g" "-O2"' /usr/local/go/pkg/tool/linux_amd64/cgo -objdir $WORK/b001/ -importpath _/home/callum/cgo_tests -- -I $WORK/b001/ -g -O2 ./main.go
cd $WORK
gcc -fno-caret-diagnostics -c -x c - || true
gcc -Qunused-arguments -c -x c - || true
gcc -fdebug-prefix-map=a=b -c -x c - || true
gcc -gno-record-gcc-switches -c -x c - || true
cd $WORK/b001
gcc -I /home/callum/cgo_tests -fPIC -m64 -pthread -fmessage-length=0 -fdebug-prefix-map=$WORK/b001=/tmp/go-build -gno-record-gcc-switches -I ./ -g -O2 -o ./_x001.o -c _cgo_export.c
gcc -I /home/callum/cgo_tests -fPIC -m64 -pthread -fmessage-length=0 -fdebug-prefix-map=$WORK/b001=/tmp/go-build -gno-record-gcc-switches -I ./ -g -O2 -o ./_x002.o -c main.cgo2.c
gcc -I /home/callum/cgo_tests -fPIC -m64 -pthread -fmessage-length=0 -fdebug-prefix-map=$WORK/b001=/tmp/go-build -gno-record-gcc-switches -I ./ -g -O2 -o ./_cgo_main.o -c _cgo_main.c
cd /home/callum/cgo_tests
gcc -I . -fPIC -m64 -pthread -fmessage-length=0 -fdebug-prefix-map=$WORK/b001=/tmp/go-build -gno-record-gcc-switches -o $WORK/b001/_cgo_.o $WORK/b001/_cgo_main.o $WORK/b001/_x001.o $WORK/b001/_x002.o -g -O2
/usr/local/go/pkg/tool/linux_amd64/cgo -dynpackage main -dynimport $WORK/b001/_cgo_.o -dynout $WORK/b001/_cgo_import.go
cat >$WORK/b001/importcfg << 'EOF' # internal
# import config
packagefile runtime/cgo=/usr/local/go/pkg/linux_amd64/runtime/cgo.a
packagefile syscall=/usr/local/go/pkg/linux_amd64/syscall.a
packagefile runtime=/usr/local/go/pkg/linux_amd64/runtime.a
EOF
/usr/local/go/pkg/tool/linux_amd64/compile -o $WORK/b001/_pkg_.a -trimpath $WORK/b001 -p main -buildid 08aSbaUFAXjxqgEqqzbJ/08aSbaUFAXjxqgEqqzbJ -goversion go1.10 -D _/home/callum/cgo_tests -importcfg $WORK/b001/importcfg -pack -c=4 $WORK/b001/_cgo_gotypes.go $WORK/b001/main.cgo1.go $WORK/b001/_cgo_import.go
# _/home/callum/cgo_tests
./main.go:12: duplicate case *_Ctype_ulong in type switch
	previous case at ./main.go:8

@ianlancetaylor ianlancetaylor changed the title cgo: as of Go 1.10 it seems pointers to C.size_t or C.ulong are treated as the same type cmd/cgo: as of Go 1.10 it seems pointers to C.size_t or C.ulong are treated as the same type Mar 2, 2018

@ianlancetaylor

This comment has been minimized.

Copy link
Contributor

commented Mar 2, 2018

It's not obvious to me that this is fixable. C is not Go. C types are not Go types. In C, unlike Go, a typedef does not introduce a new type. In some implementations of C, size_t and unsigned long really are the exact same type. It has two names but it's the same type. On such an implementation, if we pretend that C.size_t and C.ulong are different types, then we will wind up forbidding calls to C functions that according to the C type rules should be permitted. That would not be a good experience.

@cstyan

This comment has been minimized.

Copy link
Author

commented Mar 2, 2018

No worries, I just wanted to confirm that this wasn't something I was doing wrong with regards to any of the 1.10 changes. As I said, this compiled in 1.8.x and 1.9.x so just wanted to check that it wasn't some kind of unintended regression.

@ianlancetaylor

This comment has been minimized.

Copy link
Contributor

commented Mar 2, 2018

It was a fix for #21809.

Closing this issue.

@cstyan

This comment has been minimized.

Copy link
Author

commented Mar 3, 2018

So I noticed that this only comes up in our buiilds for 32bit linux systems, which I plan on deprecating anyways (-m32 passed to ./Configure). Just passing this info along in case anyone else sees this issue.

@golang golang locked and limited conversation to collaborators Mar 3, 2019

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
3 participants
You can’t perform that action at this time.