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
30 changes: 26 additions & 4 deletions cl/_testgo/genericembediface/in.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,20 @@ type ReflectionServer interface {
// CHECK-NEXT: unreachable
// CHECK-NEXT: }

// CHECK-LABEL: define void @"{{.*}}/cl/_testgo/genericembediface.init"(){{.*}} {
// CHECK-NEXT: _llgo_0:
// CHECK-NEXT: %0 = load i1, ptr @"{{.*}}/cl/_testgo/genericembediface.init$guard", align 1
// CHECK-NEXT: br i1 %0, label %_llgo_2, label %_llgo_1
// CHECK-EMPTY:
// CHECK-NEXT: _llgo_1: ; preds = %_llgo_0
// CHECK-NEXT: store i1 true, ptr @"{{.*}}/cl/_testgo/genericembediface.init$guard", align 1
// CHECK-NEXT: call void @"{{.*}}/cl/_testgo/genericembediface/streamlib.init"()
// CHECK-NEXT: br label %_llgo_2
// CHECK-EMPTY:
// CHECK-NEXT: _llgo_2: ; preds = %_llgo_1, %_llgo_0
// CHECK-NEXT: ret void
// CHECK-NEXT: }

func handler(srv any, stream streamlib.ServerStream) error {
return srv.(ReflectionServer).ServerReflectionInfo(&streamlib.GenericServerStream[Request, Response]{ServerStream: stream})
}
Expand Down Expand Up @@ -96,8 +110,9 @@ func main() {

// CHECK-LABEL: define %"{{.*}}/runtime/internal/runtime.iface" @"{{.*}}/cl/_testgo/genericembediface.(*server).ServerReflectionInfo"(ptr %0, %"{{.*}}/runtime/internal/runtime.iface" %1){{.*}} {
// CHECK-NEXT: _llgo_0:
// CHECK-NEXT: %2 = load %"{{.*}}/cl/_testgo/genericembediface.server", ptr %0, align 1
// CHECK-NEXT: %3 = call %"{{.*}}/runtime/internal/runtime.iface" @"{{.*}}/cl/_testgo/genericembediface.server.ServerReflectionInfo"(%"{{.*}}/cl/_testgo/genericembediface.server" %2, %"{{.*}}/runtime/internal/runtime.iface" %1)
// CHECK-NEXT: %2 = icmp eq ptr %0, null
// CHECK-NEXT: call void @"{{.*}}/runtime/internal/runtime.AssertNilDeref"(i1 %2)
// CHECK-NEXT: %3 = call %"{{.*}}/runtime/internal/runtime.iface" @"{{.*}}/cl/_testgo/genericembediface.server.ServerReflectionInfo"(%"{{.*}}/cl/_testgo/genericembediface.server" zeroinitializer, %"{{.*}}/runtime/internal/runtime.iface" %1)
// CHECK-NEXT: ret %"{{.*}}/runtime/internal/runtime.iface" %3
// CHECK-NEXT: }

Expand All @@ -108,8 +123,9 @@ func main() {

// CHECK-LABEL: define %"{{.*}}/runtime/internal/runtime.String" @"{{.*}}/cl/_testgo/genericembediface.(*stream).Context"(ptr %0){{.*}} {
// CHECK-NEXT: _llgo_0:
// CHECK-NEXT: %1 = load %"{{.*}}/cl/_testgo/genericembediface.stream", ptr %0, align 1
// CHECK-NEXT: %2 = call %"{{.*}}/runtime/internal/runtime.String" @"{{.*}}/cl/_testgo/genericembediface.stream.Context"(%"{{.*}}/cl/_testgo/genericembediface.stream" %1)
// CHECK-NEXT: %1 = icmp eq ptr %0, null
// CHECK-NEXT: call void @"{{.*}}/runtime/internal/runtime.AssertNilDeref"(i1 %1)
// CHECK-NEXT: %2 = call %"{{.*}}/runtime/internal/runtime.String" @"{{.*}}/cl/_testgo/genericembediface.stream.Context"(%"{{.*}}/cl/_testgo/genericembediface.stream" zeroinitializer)
// CHECK-NEXT: ret %"{{.*}}/runtime/internal/runtime.String" %2
// CHECK-NEXT: }

Expand Down Expand Up @@ -153,3 +169,9 @@ func main() {
// CHECK-NEXT: %12 = call %"{{.*}}/runtime/internal/runtime.String" %11(ptr %10)
// CHECK-NEXT: ret %"{{.*}}/runtime/internal/runtime.String" %12
// CHECK-NEXT: }

// CHECK-LABEL: define linkonce i1 @"__llgo_stub.{{.*}}/runtime/internal/runtime.memequal0"(ptr %0, ptr %1, ptr %2){{.*}} {
// CHECK-NEXT: _llgo_0:
// CHECK-NEXT: %3 = tail call i1 @"{{.*}}/runtime/internal/runtime.memequal0"(ptr %1, ptr %2)
// CHECK-NEXT: ret i1 %3
// CHECK-NEXT: }
188 changes: 119 additions & 69 deletions cl/_testgo/ifaceconv/in.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,19 @@ package main

// Tests of interface conversions and type assertions.

// CHECK-LINE: @2 = private unnamed_addr constant [21 x i8] c"nil i0.(I0) succeeded", align 1
// CHECK-LINE: @7 = private unnamed_addr constant [21 x i8] c"nil i1.(I1) succeeded", align 1
// CHECK-LINE: @10 = private unnamed_addr constant [21 x i8] c"nil i2.(I2) succeeded", align 1
// CHECK-LINE: @14 = private unnamed_addr constant [17 x i8] c"C1 i1.(I0) failed", align 1
// CHECK-LINE: @16 = private unnamed_addr constant [17 x i8] c"C1 i1.(I1) failed", align 1
// CHECK-LINE: @17 = private unnamed_addr constant [20 x i8] c"C1 i1.(I2) succeeded", align 1
// CHECK-LINE: @20 = private unnamed_addr constant [17 x i8] c"C2 i1.(I0) failed", align 1
// CHECK-LINE: @21 = private unnamed_addr constant [17 x i8] c"C2 i1.(I1) failed", align 1
// CHECK-LINE: @22 = private unnamed_addr constant [17 x i8] c"C2 i1.(I2) failed", align 1
// CHECK-LINE: @23 = private unnamed_addr constant [17 x i8] c"C1 I0(i1) was nil", align 1
// CHECK-LINE: @24 = private unnamed_addr constant [17 x i8] c"C1 I1(i1) was nil", align 1
// CHECK-LINE: @25 = private unnamed_addr constant [4 x i8] c"pass", align 1

type I0 interface {
}
type I1 interface {
Expand All @@ -21,15 +34,82 @@ type C1 struct{}
// CHECK-NEXT: ret void
// CHECK-NEXT: }

func (C1) f() {}

type C2 struct{}

func (C2) f() {}
func (C2) g() {}

func main() {
var i0 I0
var i1 I1
var i2 I2

// Nil always causes a type assertion to fail, even to the
// same type.
if _, ok := i0.(I0); ok {
panic("nil i0.(I0) succeeded")
}
if _, ok := i1.(I1); ok {
panic("nil i1.(I1) succeeded")
}
if _, ok := i2.(I2); ok {
panic("nil i2.(I2) succeeded")
}

// Conversions can't fail, even with nil.
_ = I0(i0)

_ = I0(i1)
_ = I1(i1)

_ = I0(i2)
_ = I1(i2)
_ = I2(i2)

// Non-nil type assertions pass or fail based on the concrete type.
i1 = C1{}
if _, ok := i1.(I0); !ok {
panic("C1 i1.(I0) failed")
}
if _, ok := i1.(I1); !ok {
panic("C1 i1.(I1) failed")
}
if _, ok := i1.(I2); ok {
panic("C1 i1.(I2) succeeded")
}

i1 = C2{}
if _, ok := i1.(I0); !ok {
panic("C2 i1.(I0) failed")
}
if _, ok := i1.(I1); !ok {
panic("C2 i1.(I1) failed")
}
if _, ok := i1.(I2); !ok {
panic("C2 i1.(I2) failed")
}

// Conversions can't fail.
i1 = C1{}
if I0(i1) == nil {
panic("C1 I0(i1) was nil")
}
if I1(i1) == nil {
panic("C1 I1(i1) was nil")
}

println("pass")
}

// CHECK-LABEL: define void @"{{.*}}/cl/_testgo/ifaceconv.(*C1).f"(ptr %0){{.*}} {
// CHECK-NEXT: _llgo_0:
// CHECK-NEXT: %1 = load %"{{.*}}/cl/_testgo/ifaceconv.C1", ptr %0, align 1
// CHECK-NEXT: call void @"{{.*}}/cl/_testgo/ifaceconv.C1.f"(%"{{.*}}/cl/_testgo/ifaceconv.C1" %1)
// CHECK-NEXT: %1 = icmp eq ptr %0, null
// CHECK-NEXT: call void @"{{.*}}/runtime/internal/runtime.AssertNilDeref"(i1 %1)
// CHECK-NEXT: call void @"{{.*}}/cl/_testgo/ifaceconv.C1.f"(%"{{.*}}/cl/_testgo/ifaceconv.C1" zeroinitializer)
// CHECK-NEXT: ret void
// CHECK-NEXT: }
func (C1) f() {}

type C2 struct{}

// CHECK-LABEL: define void @"{{.*}}/cl/_testgo/ifaceconv.C2.f"(%"{{.*}}/cl/_testgo/ifaceconv.C2" %0){{.*}} {
// CHECK-NEXT: _llgo_0:
Expand All @@ -43,19 +123,32 @@ type C2 struct{}

// CHECK-LABEL: define void @"{{.*}}/cl/_testgo/ifaceconv.(*C2).f"(ptr %0){{.*}} {
// CHECK-NEXT: _llgo_0:
// CHECK-NEXT: %1 = load %"{{.*}}/cl/_testgo/ifaceconv.C2", ptr %0, align 1
// CHECK-NEXT: call void @"{{.*}}/cl/_testgo/ifaceconv.C2.f"(%"{{.*}}/cl/_testgo/ifaceconv.C2" %1)
// CHECK-NEXT: %1 = icmp eq ptr %0, null
// CHECK-NEXT: call void @"{{.*}}/runtime/internal/runtime.AssertNilDeref"(i1 %1)
// CHECK-NEXT: call void @"{{.*}}/cl/_testgo/ifaceconv.C2.f"(%"{{.*}}/cl/_testgo/ifaceconv.C2" zeroinitializer)
// CHECK-NEXT: ret void
// CHECK-NEXT: }

// CHECK-LABEL: define void @"{{.*}}/cl/_testgo/ifaceconv.(*C2).g"(ptr %0){{.*}} {
// CHECK-NEXT: _llgo_0:
// CHECK-NEXT: %1 = load %"{{.*}}/cl/_testgo/ifaceconv.C2", ptr %0, align 1
// CHECK-NEXT: call void @"{{.*}}/cl/_testgo/ifaceconv.C2.g"(%"{{.*}}/cl/_testgo/ifaceconv.C2" %1)
// CHECK-NEXT: %1 = icmp eq ptr %0, null
// CHECK-NEXT: call void @"{{.*}}/runtime/internal/runtime.AssertNilDeref"(i1 %1)
// CHECK-NEXT: call void @"{{.*}}/cl/_testgo/ifaceconv.C2.g"(%"{{.*}}/cl/_testgo/ifaceconv.C2" zeroinitializer)
// CHECK-NEXT: ret void
// CHECK-NEXT: }

// CHECK-LABEL: define void @"{{.*}}/cl/_testgo/ifaceconv.init"(){{.*}} {
// CHECK-NEXT: _llgo_0:
// CHECK-NEXT: %0 = load i1, ptr @"{{.*}}/cl/_testgo/ifaceconv.init$guard", align 1
// CHECK-NEXT: br i1 %0, label %_llgo_2, label %_llgo_1
// CHECK-EMPTY:
// CHECK-NEXT: _llgo_1: ; preds = %_llgo_0
// CHECK-NEXT: store i1 true, ptr @"{{.*}}/cl/_testgo/ifaceconv.init$guard", align 1
// CHECK-NEXT: br label %_llgo_2
// CHECK-EMPTY:
// CHECK-NEXT: _llgo_2: ; preds = %_llgo_1, %_llgo_0
// CHECK-NEXT: ret void
// CHECK-NEXT: }
func (C2) f() {}
func (C2) g() {}

// CHECK-LABEL: define void @"{{.*}}/cl/_testgo/ifaceconv.main"(){{.*}} {
// CHECK-NEXT: _llgo_0:
Expand Down Expand Up @@ -361,64 +454,21 @@ func (C2) g() {}
// CHECK-NEXT: %125 = extractvalue { %"{{.*}}/runtime/internal/runtime.iface", i1 } %123, 1
// CHECK-NEXT: br i1 %125, label %_llgo_18, label %_llgo_17
// CHECK-NEXT: }
func main() {
var i0 I0
var i1 I1
var i2 I2

// Nil always causes a type assertion to fail, even to the
// same type.
if _, ok := i0.(I0); ok {
panic("nil i0.(I0) succeeded")
}
if _, ok := i1.(I1); ok {
panic("nil i1.(I1) succeeded")
}
if _, ok := i2.(I2); ok {
panic("nil i2.(I2) succeeded")
}

// Conversions can't fail, even with nil.
_ = I0(i0)

_ = I0(i1)
_ = I1(i1)

_ = I0(i2)
_ = I1(i2)
_ = I2(i2)

// Non-nil type assertions pass or fail based on the concrete type.
i1 = C1{}
if _, ok := i1.(I0); !ok {
panic("C1 i1.(I0) failed")
}
if _, ok := i1.(I1); !ok {
panic("C1 i1.(I1) failed")
}
if _, ok := i1.(I2); ok {
panic("C1 i1.(I2) succeeded")
}

i1 = C2{}
if _, ok := i1.(I0); !ok {
panic("C2 i1.(I0) failed")
}
if _, ok := i1.(I1); !ok {
panic("C2 i1.(I1) failed")
}
if _, ok := i1.(I2); !ok {
panic("C2 i1.(I2) failed")
}
// CHECK-LABEL: define linkonce i1 @"__llgo_stub.{{.*}}/runtime/internal/runtime.nilinterequal"(ptr %0, ptr %1, ptr %2){{.*}} {
// CHECK-NEXT: _llgo_0:
// CHECK-NEXT: %3 = tail call i1 @"{{.*}}/runtime/internal/runtime.nilinterequal"(ptr %1, ptr %2)
// CHECK-NEXT: ret i1 %3
// CHECK-NEXT: }

// Conversions can't fail.
i1 = C1{}
if I0(i1) == nil {
panic("C1 I0(i1) was nil")
}
if I1(i1) == nil {
panic("C1 I1(i1) was nil")
}
// CHECK-LABEL: define linkonce i1 @"__llgo_stub.{{.*}}/runtime/internal/runtime.interequal"(ptr %0, ptr %1, ptr %2){{.*}} {
// CHECK-NEXT: _llgo_0:
// CHECK-NEXT: %3 = tail call i1 @"{{.*}}/runtime/internal/runtime.interequal"(ptr %1, ptr %2)
// CHECK-NEXT: ret i1 %3
// CHECK-NEXT: }

println("pass")
}
// CHECK-LABEL: define linkonce i1 @"__llgo_stub.{{.*}}/runtime/internal/runtime.memequal0"(ptr %0, ptr %1, ptr %2){{.*}} {
// CHECK-NEXT: _llgo_0:
// CHECK-NEXT: %3 = tail call i1 @"{{.*}}/runtime/internal/runtime.memequal0"(ptr %1, ptr %2)
// CHECK-NEXT: ret i1 %3
// CHECK-NEXT: }
Loading
Loading