Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions ssa/type.go
Original file line number Diff line number Diff line change
Expand Up @@ -388,8 +388,10 @@ func (p Program) toType(raw types.Type) Type {
return &aType{p.tyVoidPtr(), typ, vkPtr}
}
case *types.Pointer:
elem := p.rawType(t.Elem())
return &aType{llvm.PointerType(elem.ll, 0), typ, vkPtr}
// LLVM pointers are opaque, so the element LLVM type is not needed here.
// Avoid expanding it eagerly: legal Go recursive types often close their
// cycle through a pointer.
return &aType{p.tyVoidPtr(), typ, vkPtr}
case *types.Interface:
if t.Empty() {
return &aType{p.rtEface(), typ, vkEface}
Expand Down
23 changes: 23 additions & 0 deletions ssa/type_patch_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,29 @@ func TestToLLVMFuncPtrUsesVoidPtr(t *testing.T) {
}
}

func TestPointerTypeDoesNotExpandRecursiveNamedElement(t *testing.T) {
fset := token.NewFileSet()
f, err := parser.ParseFile(fset, "recursive.go", `package p

type T18 *[10]T19
type T19 T18
`, 0)
if err != nil {
t.Fatal(err)
}
pkg := types.NewPackage("example.com/p", "p")
if err := types.NewChecker(&types.Config{}, fset, pkg, nil).Files([]*ast.File{f}); err != nil {
t.Fatal(err)
}

prog := NewProgram(nil)
prog.TypeSizes(types.SizesFor("gc", runtime.GOARCH))
t18 := pkg.Scope().Lookup("T18").Type()
if got, want := prog.Type(t18, InGo).ll.String(), prog.tyVoidPtr().String(); got != want {
t.Fatalf("recursive named pointer LLVM type = %q, want %q", got, want)
}
}

func TestNamedStructLayoutEquivalent(t *testing.T) {
prog := NewProgram(nil)
prog.TypeSizes(types.SizesFor("gc", runtime.GOARCH))
Expand Down
91 changes: 91 additions & 0 deletions test/go/recursive_named_types_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
package gotest

import "testing"

type recursiveNamedT1 struct {
Next *recursiveNamedT2
}

type recursiveNamedT2 recursiveNamedT1

type recursiveNamedT3 struct {
Next *recursiveNamedT4
}

type recursiveNamedT4 recursiveNamedT5
type recursiveNamedT5 recursiveNamedT6
type recursiveNamedT6 recursiveNamedT7
type recursiveNamedT7 recursiveNamedT8
type recursiveNamedT8 recursiveNamedT9
type recursiveNamedT9 recursiveNamedT3

type recursiveNamedT10 struct {
x struct {
y ***struct {
z *struct {
Next *recursiveNamedT11
}
}
}
}

type recursiveNamedT11 recursiveNamedT10

type recursiveNamedT12 struct {
F1 *recursiveNamedT15
F2 *recursiveNamedT13
F3 *recursiveNamedT16
}

type recursiveNamedT13 recursiveNamedT14
type recursiveNamedT14 recursiveNamedT15
type recursiveNamedT15 recursiveNamedT16
type recursiveNamedT16 recursiveNamedT17
type recursiveNamedT17 recursiveNamedT12

type recursiveNamedT18 *[10]recursiveNamedT19
type recursiveNamedT19 recursiveNamedT18

func TestRecursiveNamedTypeLiterals(t *testing.T) {
_ = &recursiveNamedT1{&recursiveNamedT2{}}
_ = &recursiveNamedT2{&recursiveNamedT2{}}
_ = &recursiveNamedT3{&recursiveNamedT4{}}
_ = &recursiveNamedT4{&recursiveNamedT4{}}
_ = &recursiveNamedT5{&recursiveNamedT4{}}
_ = &recursiveNamedT6{&recursiveNamedT4{}}
_ = &recursiveNamedT7{&recursiveNamedT4{}}
_ = &recursiveNamedT8{&recursiveNamedT4{}}
_ = &recursiveNamedT9{&recursiveNamedT4{}}
_ = &recursiveNamedT12{&recursiveNamedT15{}, &recursiveNamedT13{}, &recursiveNamedT16{}}

var (
tn struct{ Next *recursiveNamedT11 }
tz struct {
z *struct{ Next *recursiveNamedT11 }
}
tpz *struct {
z *struct{ Next *recursiveNamedT11 }
}
tppz **struct {
z *struct{ Next *recursiveNamedT11 }
}
tpppz ***struct {
z *struct{ Next *recursiveNamedT11 }
}
ty struct {
y ***struct {
z *struct{ Next *recursiveNamedT11 }
}
}
)
tn.Next = &recursiveNamedT11{}
tz.z = &tn
tpz = &tz
tppz = &tpz
tpppz = &tppz
ty.y = tpppz
_ = &recursiveNamedT10{ty}

t19s := &[10]recursiveNamedT19{}
_ = recursiveNamedT18(t19s)
}
19 changes: 0 additions & 19 deletions test/goroot/xfail.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -1826,10 +1826,6 @@ xfails:
directive: run
case: zerodivide.go
reason: current main goroot run failure on darwin/arm64
- platform: darwin/arm64
directive: run
case: fixedbugs/bug336.go
reason: current main goroot run failure on darwin/arm64
- platform: darwin/arm64
directive: run
case: fixedbugs/issue16130.go
Expand Down Expand Up @@ -1957,11 +1953,6 @@ xfails:
directive: run
case: zerodivide.go
reason: go1.24 goroot run failure on linux/amd64
- version: go1.24
platform: linux/amd64
directive: run
case: fixedbugs/bug336.go
reason: go1.24 goroot run failure on linux/amd64
- version: go1.24
platform: linux/amd64
directive: run
Expand Down Expand Up @@ -2067,11 +2058,6 @@ xfails:
directive: run
case: zerodivide.go
reason: go1.25 goroot run failure on linux/amd64
- version: go1.25
platform: linux/amd64
directive: run
case: fixedbugs/bug336.go
reason: go1.25 goroot run failure on linux/amd64
- version: go1.25
platform: linux/amd64
directive: run
Expand Down Expand Up @@ -2182,11 +2168,6 @@ xfails:
directive: run
case: zerodivide.go
reason: go1.26 goroot run failure on linux/amd64
- version: go1.26
platform: linux/amd64
directive: run
case: fixedbugs/bug336.go
reason: go1.26 goroot run failure on linux/amd64
- version: go1.26
platform: linux/amd64
directive: run
Expand Down
Loading