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/compile: internal error converting slice of non-predeclared bytes to string #47322

Closed
gazerro opened this issue Jul 21, 2021 · 14 comments
Closed
Assignees

Comments

@gazerro
Copy link
Contributor

@gazerro gazerro commented Jul 21, 2021

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

$ go version
go version go1.16.6 darwin/amd64

Does this issue reproduce with the latest release?

Yes.

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

go env Output
$ go env
GO111MODULE="on"
GOARCH="amd64"
GOBIN=""
GOCACHE="/Users/marco/Library/Caches/go-build"
GOENV="/Users/marco/Library/Application Support/go/env"
GOEXE=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="darwin"
GOINSECURE=""
GOMODCACHE="/Users/marco/go/pkg/mod"
GOOS="darwin"
GOPATH="/Users/marco/go"
GOPROXY="https://proxy.golang.org,direct"
GOROOT="/usr/local/go"
GOSUMDB="sum.golang.org"
GOTMPDIR=""
GOTOOLDIR="/usr/local/go/pkg/tool/darwin_amd64"
GOVCS=""
GOVERSION="go1.16.6"
GCCGO="gccgo"
AR="ar"
CC="clang"
CXX="clang++"
CGO_ENABLED="1"
GOMOD="/dev/null"
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 x86_64 -m64 -pthread -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -fdebug-prefix-map=/var/folders/z9/xrln_qks56jbzxjbhs04fpm80000gn/T/go-build2609676070=/tmp/go-build -gno-record-gcc-switches -fno-common"

What did you do?

go build

package main

type Byte byte

func main() {
	_ = string([]Byte{})
}

What did you expect to see?

No error.

What did you see instead?

./test.go:6:12: cannot use <node SPTR> (type *Byte) as type *byte in argument to runtime.slicebytetostring

With go tip the error is the same, and with Go 1.14.15 the error is

./test.go:6:19: cannot use []Byte literal (type []Byte) as type []byte in argument to runtime.slicebytetostring
@ianlancetaylor
Copy link
Contributor

@ianlancetaylor ianlancetaylor commented Jul 21, 2021

Interesting. I actually thought that was valid Go. gccgo accepts it.

Loading

@gazerro
Copy link
Contributor Author

@gazerro gazerro commented Jul 21, 2021

It should be valid Go. This is the current status of slice of bytes to string and string to slice of bytes conversions:

package main

type Byte byte

type Slicebyte []byte

type SliceByte []Byte

func main() {
	_ = string([]byte{})    // ok
	_ = string([]Byte{})    // internal error
	_ = string(Slicebyte{}) // ok
	_ = string(SliceByte{}) // internal error

	_ = []byte("")    // ok
	_ = []Byte("")    // ok
	_ = Slicebyte("") // ok
	_ = SliceByte("") // ok
}

Loading

@cuonglm
Copy link
Member

@cuonglm cuonglm commented Jul 22, 2021

I think this is specific to cmd/compile, gotype accept this program. You still get the error with -G=3 because we are still doing old typecheck after typechecking with types2.

Loading

@cuonglm cuonglm changed the title cmd/compile, types2: internal error converting slice of non-predeclared bytes to string cmd/compile: internal error converting slice of non-predeclared bytes to string Jul 22, 2021
@cuonglm cuonglm self-assigned this Jul 22, 2021
@cuonglm
Copy link
Member

@cuonglm cuonglm commented Jul 22, 2021

Go spec allows:

type MyBytes []byte

var _ = string(MyBytes{'g', 'o'})

It's also consistent with conversion rule:

A non-constant value x can be converted to type T in any of these cases:
...
x is an integer or a slice of bytes or runes and T is a string type.

cc @mdempsky @griesemer @findleyr

Loading

@cuonglm
Copy link
Member

@cuonglm cuonglm commented Jul 22, 2021

Hmm, so the problem seems that cmd/compile also accept byte named type, but it generate the wrong code for base pointer to slice to pass to runtime function.

This program compile ok with cmd/compile:

package p

type Byte byte

var _ = string([]Byte{'f'})

Loading

@gazerro
Copy link
Contributor Author

@gazerro gazerro commented Jul 22, 2021

Similar problem exists with slice or runes to string conversions

package main

type Rune rune

type SliceRune []Rune

func main() {
	_ = string([]Rune{})    // internal error
	_ = string(SliceRune{}) // internal error
}
./test.go:8:19: cannot use []Rune{} (type []Rune) as type []rune in argument to runtime.slicerunetostring
./test.go:9:22: cannot use SliceRune{} (type SliceRune) as type []rune in argument to runtime.slicerunetostring

But this time the error is in the call to runtime.slicerunetostring.

As for the slice of bytes, the error occurs only in function bodies.

Loading

@cuonglm
Copy link
Member

@cuonglm cuonglm commented Jul 22, 2021

@gazerro Yes, I think they have the same root cause, for either []Byte or []Rune, the compiler generate a base pointer node of the slice, with either *Byte or *Rune. This base pointer is passed to runtime functions, which expected it to be type *byte. Assigning *Byte to *byte is failed, because Byte and byte are distinct types.

In case of the global variables, the compiler don't generate code to runtime functions, that's why it's ok.

I think this violates the Go spec, since when []Byte is not a slice of bytes []byte.

Loading

@gazerro
Copy link
Contributor Author

@gazerro gazerro commented Jul 22, 2021

@cuonglm I think this violates the Go spec, since when []Byte is not a slice of bytes.

In this case all these conversions should not be valid for Go spec

package p

type Byte byte
type SliceByte []Byte

var _ = []Byte("")
var _ = SliceByte("")
var _ = string([]Byte{})
var _ = string(SliceByte{})

Note that this program currently compiles.

Loading

@mdempsky
Copy link
Member

@mdempsky mdempsky commented Jul 22, 2021

Related: #23814.

Loading

@cuonglm
Copy link
Member

@cuonglm cuonglm commented Jul 22, 2021

@mdempsky Should we close this in favor of #23814?

Loading

@mdempsky
Copy link
Member

@mdempsky mdempsky commented Jul 22, 2021

@cuonglm Probably. I haven't read it too closely yet. If there's nothing new not covered by #23814 already, then closing it as a duplicate seems appropriate.

Loading

@cuonglm
Copy link
Member

@cuonglm cuonglm commented Jul 22, 2021

Closed as duplicated of #23814

Loading

@cuonglm cuonglm closed this Jul 22, 2021
@gazerro
Copy link
Contributor Author

@gazerro gazerro commented Jul 22, 2021

@cuonglm the issue #23814 does not cover the internal error that occurs in the conversion. Could it be worth at least mentioning this error in issue #23814?

Loading

@mdempsky
Copy link
Member

@mdempsky mdempsky commented Jul 22, 2021

#23814 (comment)

(Also notably, cmd/compile's typechecker allows String(Bytes(nil)) and String(Runes(nil)), but then walk.go fails to generate the appropriate conversions when calling runtime.slicebytetostring and runtime.slicerunetostring, so compilation fails. It has a similar problem with the append call too.)

Loading

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
4 participants