Skip to content

gccgo: inconsistent behaviour of %s fmt verb #23642

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

Closed
tamird opened this issue Jan 31, 2018 · 9 comments
Closed

gccgo: inconsistent behaviour of %s fmt verb #23642

tamird opened this issue Jan 31, 2018 · 9 comments
Milestone

Comments

@tamird
Copy link
Contributor

tamird commented Jan 31, 2018

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

go version go1.10rc1 gccgo (GCC) 8.0.1 20180131 (experimental) linux/amd64

Does this issue reproduce with the latest release?

N/A

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

GOARCH="amd64"
GOBIN=""
GOCACHE="/home/tduberstein/.cache/go-build"
GOEXE=""
GOHOSTARCH="amd64"
GOHOSTOS="linux"
GOOS="linux"
GOPATH="/home/tduberstein/local/go"
GORACE=""
GOROOT="/home/tduberstein/local/gcc/gcc"
GOTMPDIR=""
GOTOOLDIR="/home/tduberstein/local/gcc/gcc/libexec/gcc/x86_64-pc-linux-gnu/8.0.1"
GCCGO="/home/tduberstein/local/gcc/gcc/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-build297122770=/tmp/go-build -gno-record-gcc-switches -funwind-tables"

What did you do?

package main

import (
	"fmt"
)

type foo struct{}

func (foo) String() string {
	return "hello"
}

func main() {
	fmt.Printf("%s\n", (*foo)(nil))
}

https://play.golang.org/p/c7WLq7pKKYv

What did you expect to see?

<nil>

What did you see instead?

hello

@tamird
Copy link
Contributor Author

tamird commented Jan 31, 2018

Modifying the example slightly:

package main

import (
	"fmt"
)

type foo struct{}

func (foo) String() string {
	return "hello"
}

func main() {
	f := (*foo)(nil)
	fmt.Println(f.String())
}

https://play.golang.org/p/_jgX6qz3cvB

produces an NPE under cmd/compile but prints hello under gccgo.

@tamird
Copy link
Contributor Author

tamird commented Jan 31, 2018

Duplicate of #19806, I think.

@tamird tamird closed this as completed Jan 31, 2018
@tamird
Copy link
Contributor Author

tamird commented Feb 1, 2018

@ianlancetaylor do you think the fix for #19806 also fixes this issue? I think there may be a second bug here (the behaviour of %s with respect to nil pointers).

@tamird tamird reopened this Feb 1, 2018
@ianlancetaylor
Copy link
Contributor

@tamird The two programs above now behave the same with gccgo as they do with gc. What leads you to think there is a second bug here?

@cznic
Copy link
Contributor

cznic commented Feb 1, 2018

I cannot reproduce the "What did you see instead?" output with the OP playground link.

package main

import (
	"fmt"
)

type foo struct{}

func (foo) String() string {
	return "hello"
}

type baz struct{}

func (*baz) String() string {
	return "hello"
}

func main() {
	fmt.Printf("%s\n", (*foo)(nil))
	fmt.Printf("%s\n", (*baz)(nil))
}

playground

Output:

<nil>
hello

Seems to work as intended.

@tamird
Copy link
Contributor Author

tamird commented Feb 1, 2018

@cznic did you test this in gccgo?

@ianlancetaylor I don't see how the fix (explicit nil check) would change the behaviour of %s. I'm rebuilding gcc and will test. Can you help me understand why that nil check would change the behaviour of fmt.Printf("%s\n", (*foo)(nil)) in the first program?

@cznic
Copy link
Contributor

cznic commented Feb 1, 2018

Heh, no, sorry. Missed that piece of info. The playground link convinced me, mistakenly, that it fails using the playground.

@ianlancetaylor
Copy link
Contributor

@tamird fmt.Printf works by catching the panic thrown by the nil dereference and uses that to decide to print <nil>. The bug was that there was no such panic for the case of a value method called using a nil pointer when the method did not use the receiver, and that is what my patch fixed.

@tamird
Copy link
Contributor Author

tamird commented Feb 1, 2018

Ah, didn't know that. Works for me, thanks!

@tamird tamird closed this as completed Feb 1, 2018
@golang golang locked and limited conversation to collaborators Feb 1, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

4 participants