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: String() on structs containing empty structs has changed #19246

Closed
heschi opened this issue Feb 22, 2017 · 4 comments
Closed

cmd/compile: String() on structs containing empty structs has changed #19246

heschi opened this issue Feb 22, 2017 · 4 comments
Labels
FrozenDueToAge NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one.
Milestone

Comments

@heschi
Copy link
Contributor

heschi commented Feb 22, 2017

Prior to 8958d8c (cmd/compile: skip convT2E for empty structs), the below test didn't call B.String(). After that commit it does, breaking a test that compared the result. I think this is actually a bug fix, but since that commit was supposed to be a pure performance improvement, some investigation is probably warranted.

package test

import (
	"fmt"
	"testing"
)

type A struct {
	Cs []*C
}

func (a *A) String() string {
	return fmt.Sprintf("%+v", *a)
}

type B struct{}

func (b *B) String() string {
	return fmt.Sprintf("B.STRING WAS CALLED %+v", *b)
}

type C struct {
	Name string
	B    *B
}

func (c *C) String() string {
	return fmt.Sprintf("%+v", *c)
}

func TestString(t *testing.T) {
	a := A{
		Cs: []*C{{
			Name: "ae1",
		}},
	}
	want := "{Cs:[{Name:ae1 B:<nil>}]}"

	if g, w := a.String(), want; g != w {
		t.Errorf("got %q want %q", g, w)
	}
}
@heschi
Copy link
Contributor Author

heschi commented Feb 22, 2017

@randall77 @josharian

@dsnet dsnet added the NeedsFix The path to resolution is known, but the work has not been done. label Feb 22, 2017
@dsnet dsnet added this to the Go1.9 milestone Feb 22, 2017
@dsnet dsnet added NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. and removed NeedsFix The path to resolution is known, but the work has not been done. labels Feb 23, 2017
@cherrymui
Copy link
Member

cherrymui commented Feb 23, 2017

In fact, the String method is called both on tip and on Go 1.8 (and before). On Go 1.8, it panics with nil pointer (*b) and the fmt package recovers it and prints "<nil>". On tip, it doesn't panic, because b is not nil (but should be). A simple repro:

package main

type B struct{}

//go:noinline
func f(i interface{}) {}

func main() {
        var b *B
        f(*b)
}

On Go 1.8, this code panics on f(*b). On tip, it doesn't.

@josharian
Copy link
Contributor

josharian commented Feb 23, 2017

Thanks for the bug report! And thanks, @cherrymui, for the minimization. Fix coming soon.

@gopherbot
Copy link

CL https://golang.org/cl/37395 mentions this issue.

@golang golang locked and limited conversation to collaborators Feb 24, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
FrozenDueToAge NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one.
Projects
None yet
Development

No branches or pull requests

5 participants