Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
0690976
ssa,runtime: tighten recover to direct deferred calls (Defer-node model)
cpunion Jul 6, 2026
f7fa18b
ssa,runtime: key recover permission by activation
cpunion Aug 10, 2026
ec1678e
ssa,cl: preserve recover through method wrappers
cpunion Aug 10, 2026
170f176
cl: refresh recover IR snapshots
cpunion Aug 10, 2026
1c873fe
runtime: preserve type metadata in assertion panics
cpunion Aug 10, 2026
fb72c4c
runtime: recover SIGBUS memory faults
cpunion Aug 10, 2026
16aab70
test/goroot: enable panic and recover cases
cpunion Aug 10, 2026
2138523
test/go: cover remaining nested recover semantics
cpunion Aug 10, 2026
3fb85f5
test/go: cover reflected recover wrappers
cpunion Aug 10, 2026
96f9011
runtime: preserve nested recover ownership
cpunion Aug 10, 2026
e2dcfcd
reflect: keep recover through generated wrappers
cpunion Aug 10, 2026
43b4290
runtime: keep recover scope state atomic
cpunion Aug 10, 2026
05fb459
cl: refresh recover state IR checks
cpunion Aug 10, 2026
2c3f2d8
cl: keep recover IR checks portable
cpunion Aug 10, 2026
3d9a493
test/go: cover Goexit replacing an active panic
cpunion Aug 10, 2026
57b5a31
runtime: document recover wrapper state
cpunion Aug 10, 2026
fd65ec6
runtime: let Goexit replace active panics
cpunion Aug 10, 2026
72e9f90
test/goroot: enable remaining recover cases
cpunion Aug 10, 2026
c703a24
cl,ssa,runtime: cache recover classification
cpunion Aug 11, 2026
54da2a1
test/buildcache: run recover check on native
cpunion Aug 11, 2026
c952ad8
runtime: make interface implementation result explicit
cpunion Aug 11, 2026
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
5 changes: 2 additions & 3 deletions cl/_testdata/vargs/in.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,7 @@ package main

import "github.com/goplus/lib/c"

// CHECK: @0 = private unnamed_addr constant [3 x i8] c"int", align 1
// CHECK: @1 = private unnamed_addr constant [4 x i8] c"%d\0A\00", align 1
// CHECK: {{^}}@1 = private unnamed_addr constant [4 x i8] c"%d\0A\00", align 1{{$}}

func main() {
test(1, 2, 3)
Expand Down Expand Up @@ -88,6 +87,6 @@ func test(a ...any) {
// CHECK-NEXT: br label %_llgo_1
// CHECK-EMPTY:
// CHECK-NEXT: _llgo_5: ; preds = %_llgo_2
// CHECK-NEXT: call void @"{{.*}}/runtime/internal/runtime.PanicTypeAssert"(ptr %12, %"{{.*}}/runtime/internal/runtime.String" { ptr @0, i64 3 }, %"{{.*}}/runtime/internal/runtime.String" zeroinitializer)
// CHECK-NEXT: call void @"{{.*}}/runtime/internal/runtime.PanicTypeAssert"(ptr null, ptr %12, ptr @_llgo_int)
// CHECK-NEXT: unreachable
// CHECK-NEXT: }
73 changes: 48 additions & 25 deletions cl/_testgo/abimethod/in.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,6 @@ import (

// CHECK: {{^}}@0 = private unnamed_addr constant [45 x i8] c"{{.*}}/cl/_testgo/abimethod.T", align 1{{$}}
// CHECK: {{^}}@1 = private unnamed_addr constant [5 x i8] c"Demo1", align 1{{$}}
// CHECK: {{^}}@5 = private unnamed_addr constant [3 x i8] c"int", align 1{{$}}
// CHECK: {{^}}@7 = private unnamed_addr constant [6 x i8] c"main.T", align 1{{$}}
// CHECK-NOT: {{^}}@{{[0-9]+}} = private unnamed_addr constant [5 x i8] c"demo3", align 1{{$}}
// CHECK: {{^}}@11 = private unnamed_addr constant [10 x i8] c"main.demo3", align 1{{$}}
// CHECK: {{^}}@13 = private unnamed_addr constant [20 x i8] c"testAnonymous1 error", align 1{{$}}
// CHECK: {{^}}@15 = private unnamed_addr constant [20 x i8] c"testAnonymous2 error", align 1{{$}}
// CHECK: {{^}}@17 = private unnamed_addr constant [20 x i8] c"testAnonymous3 error", align 1{{$}}
Expand All @@ -23,26 +19,16 @@ import (
// CHECK: {{^}}@23 = private unnamed_addr constant [20 x i8] c"testAnonymous7 error", align 1{{$}}
// CHECK: {{^}}@25 = private unnamed_addr constant [20 x i8] c"testAnonymous8 error", align 1{{$}}
// CHECK: {{^}}@26 = private unnamed_addr constant [5 x i8] c"hello", align 1{{$}}
// CHECK: {{^}}@[[ANONBUF_ERR:[0-9]+]] = private unnamed_addr constant [25 x i8] c"testAnonymousBuffer error", align 1{{$}}
// CHECK: {{^}}@[[GENERIC_ERR:[0-9]+]] = private unnamed_addr constant [17 x i8] c"testGeneric error", align 1{{$}}
// CHECK: {{^}}@[[NAMED1_ERR:[0-9]+]] = private unnamed_addr constant [16 x i8] c"testNamed1 error", align 1{{$}}
// CHECK: {{^}}@[[NAMED2_ERR:[0-9]+]] = private unnamed_addr constant [16 x i8] c"testNamed2 error", align 1{{$}}
// CHECK: {{^}}@[[NAMED4_ERR:[0-9]+]] = private unnamed_addr constant [16 x i8] c"testNamed4 error", align 1{{$}}
// CHECK: {{^}}@94 = private unnamed_addr constant [25 x i8] c"testAnonymousBuffer error", align 1{{$}}
// CHECK: {{^}}@107 = private unnamed_addr constant [17 x i8] c"testGeneric error", align 1{{$}}
// CHECK: {{^}}@108 = private unnamed_addr constant [16 x i8] c"testNamed1 error", align 1{{$}}
// CHECK: {{^}}@109 = private unnamed_addr constant [16 x i8] c"testNamed2 error", align 1{{$}}
// CHECK: {{^}}@110 = private unnamed_addr constant [16 x i8] c"testNamed4 error", align 1{{$}}

type T struct {
n int
}

// CHECK-LABEL: define i64 @main.T.Demo1(%main.T %0){{.*}} {
// CHECK-NEXT: _llgo_0:
// CHECK-NEXT: %1 = alloca %main.T, align 8
// CHECK-NEXT: call void @llvm.memset.p0.i64(ptr %1, i8 0, i64 8, i1 false)
// CHECK-NEXT: store %main.T %0, ptr %1, align 8
// CHECK-NEXT: %2 = getelementptr inbounds %main.T, ptr %1, i32 0, i32 0
// CHECK-NEXT: %3 = load i64, ptr %2, align 8
// CHECK-NEXT: ret i64 %3
// CHECK-NEXT: }

func (t T) Demo1() int {
return t.n
}
Expand Down Expand Up @@ -236,6 +222,16 @@ type I2 interface {
Demo2() int
}

// CHECK-LABEL: define i64 @main.T.Demo1(%main.T %0){{.*}} {
// CHECK-NEXT: _llgo_0:
// CHECK-NEXT: %1 = alloca %main.T, align 8
// CHECK-NEXT: call void @llvm.memset.p0.i64(ptr %1, i8 0, i64 8, i1 false)
// CHECK-NEXT: store %main.T %0, ptr %1, align 8
// CHECK-NEXT: %2 = getelementptr inbounds %main.T, ptr %1, i32 0, i32 0
// CHECK-NEXT: %3 = load i64, ptr %2, align 8
// CHECK-NEXT: ret i64 %3
// CHECK-NEXT: }

// CHECK-LABEL: define i64 @"main.(*T).Demo1"(ptr %0){{.*}} {
// CHECK-NEXT: _llgo_0:
// CHECK-NEXT: %1 = icmp eq ptr %0, null
Expand Down Expand Up @@ -681,7 +677,7 @@ type I2 interface {
// CHECK-EMPTY:
// CHECK-NEXT: _llgo_1: ; preds = %_llgo_0
// CHECK-NEXT: %18 = call ptr @"{{.*}}/runtime/internal/runtime.AllocU"(i64 16)
// CHECK-NEXT: store %"{{.*}}/runtime/internal/runtime.String" { ptr @[[ANONBUF_ERR]], i64 25 }, ptr %18, align 8
// CHECK-NEXT: store %"{{.*}}/runtime/internal/runtime.String" { ptr @94, i64 25 }, ptr %18, align 8
// CHECK-NEXT: %19 = insertvalue %"{{.*}}/runtime/internal/runtime.eface" { ptr @_llgo_string, ptr undef }, ptr %18, 1
// CHECK-NEXT: call void @"{{.*}}/runtime/internal/runtime.Panic"(%"{{.*}}/runtime/internal/runtime.eface" %19)
// CHECK-NEXT: unreachable
Expand Down Expand Up @@ -722,7 +718,7 @@ type I2 interface {
// CHECK-EMPTY:
// CHECK-NEXT: _llgo_1: ; preds = %_llgo_3
// CHECK-NEXT: %25 = call ptr @"{{.*}}/runtime/internal/runtime.AllocU"(i64 16)
// CHECK-NEXT: store %"{{.*}}/runtime/internal/runtime.String" { ptr @[[GENERIC_ERR]], i64 17 }, ptr %25, align 8
// CHECK-NEXT: store %"{{.*}}/runtime/internal/runtime.String" { ptr @107, i64 17 }, ptr %25, align 8
// CHECK-NEXT: %26 = insertvalue %"{{.*}}/runtime/internal/runtime.eface" { ptr @_llgo_string, ptr undef }, ptr %25, 1
// CHECK-NEXT: call void @"{{.*}}/runtime/internal/runtime.Panic"(%"{{.*}}/runtime/internal/runtime.eface" %26)
// CHECK-NEXT: unreachable
Expand All @@ -737,7 +733,7 @@ type I2 interface {
// CHECK-NEXT: br i1 %29, label %_llgo_1, label %_llgo_2
// CHECK-EMPTY:
// CHECK-NEXT: _llgo_4: ; preds = %_llgo_0
// CHECK-NEXT: call void @"{{.*}}/runtime/internal/runtime.PanicTypeAssert"(ptr %23, %"{{.*}}/runtime/internal/runtime.String" { ptr @5, i64 3 }, %"{{.*}}/runtime/internal/runtime.String" zeroinitializer)
// CHECK-NEXT: call void @"{{.*}}/runtime/internal/runtime.PanicTypeAssert"(ptr null, ptr %23, ptr @_llgo_int)
// CHECK-NEXT: unreachable
// CHECK-NEXT: }

Expand Down Expand Up @@ -773,7 +769,7 @@ type I2 interface {
// CHECK-EMPTY:
// CHECK-NEXT: _llgo_1: ; preds = %_llgo_0
// CHECK-NEXT: %15 = call ptr @"{{.*}}/runtime/internal/runtime.AllocU"(i64 16)
// CHECK-NEXT: store %"{{.*}}/runtime/internal/runtime.String" { ptr @[[NAMED1_ERR]], i64 16 }, ptr %15, align 8
// CHECK-NEXT: store %"{{.*}}/runtime/internal/runtime.String" { ptr @108, i64 16 }, ptr %15, align 8
// CHECK-NEXT: %16 = insertvalue %"{{.*}}/runtime/internal/runtime.eface" { ptr @_llgo_string, ptr undef }, ptr %15, 1
// CHECK-NEXT: call void @"{{.*}}/runtime/internal/runtime.Panic"(%"{{.*}}/runtime/internal/runtime.eface" %16)
// CHECK-NEXT: unreachable
Expand Down Expand Up @@ -808,7 +804,7 @@ type I2 interface {
// CHECK-EMPTY:
// CHECK-NEXT: _llgo_1: ; preds = %_llgo_0
// CHECK-NEXT: %17 = call ptr @"{{.*}}/runtime/internal/runtime.AllocU"(i64 16)
// CHECK-NEXT: store %"{{.*}}/runtime/internal/runtime.String" { ptr @[[NAMED2_ERR]], i64 16 }, ptr %17, align 8
// CHECK-NEXT: store %"{{.*}}/runtime/internal/runtime.String" { ptr @109, i64 16 }, ptr %17, align 8
// CHECK-NEXT: %18 = insertvalue %"{{.*}}/runtime/internal/runtime.eface" { ptr @_llgo_string, ptr undef }, ptr %17, 1
// CHECK-NEXT: call void @"{{.*}}/runtime/internal/runtime.Panic"(%"{{.*}}/runtime/internal/runtime.eface" %18)
// CHECK-NEXT: unreachable
Expand Down Expand Up @@ -839,7 +835,7 @@ type I2 interface {
// CHECK-EMPTY:
// CHECK-NEXT: _llgo_1: ; preds = %_llgo_0
// CHECK-NEXT: %15 = call ptr @"{{.*}}/runtime/internal/runtime.AllocU"(i64 16)
// CHECK-NEXT: store %"{{.*}}/runtime/internal/runtime.String" { ptr @[[NAMED4_ERR]], i64 16 }, ptr %15, align 8
// CHECK-NEXT: store %"{{.*}}/runtime/internal/runtime.String" { ptr @110, i64 16 }, ptr %15, align 8
// CHECK-NEXT: %16 = insertvalue %"{{.*}}/runtime/internal/runtime.eface" { ptr @_llgo_string, ptr undef }, ptr %15, 1
// CHECK-NEXT: call void @"{{.*}}/runtime/internal/runtime.Panic"(%"{{.*}}/runtime/internal/runtime.eface" %16)
// CHECK-NEXT: unreachable
Expand Down Expand Up @@ -1005,6 +1001,18 @@ type I2 interface {
// CHECK-NEXT: ret %"{{.*}}/runtime/internal/runtime.Slice" %4
// CHECK-NEXT: }

// CHECK-LABEL: define { %"{{.*}}/runtime/internal/runtime.Slice", %"{{.*}}/runtime/internal/runtime.iface" } @"main.*struct{m int; *bytes.Buffer}.Peek"(ptr %0, i64 %1){{.*}} {
// CHECK-NEXT: _llgo_0:
// CHECK-NEXT: %2 = getelementptr inbounds { i64, ptr }, ptr %0, i32 0, i32 1
// CHECK-NEXT: %3 = load ptr, ptr %2, align 8
// CHECK-NEXT: %4 = call { %"{{.*}}/runtime/internal/runtime.Slice", %"{{.*}}/runtime/internal/runtime.iface" } @"bytes.(*Buffer).Peek"(ptr %3, i64 %1)
// CHECK-NEXT: %5 = extractvalue { %"{{.*}}/runtime/internal/runtime.Slice", %"{{.*}}/runtime/internal/runtime.iface" } %4, 0
// CHECK-NEXT: %6 = extractvalue { %"{{.*}}/runtime/internal/runtime.Slice", %"{{.*}}/runtime/internal/runtime.iface" } %4, 1
// CHECK-NEXT: %7 = insertvalue { %"{{.*}}/runtime/internal/runtime.Slice", %"{{.*}}/runtime/internal/runtime.iface" } undef, %"{{.*}}/runtime/internal/runtime.Slice" %5, 0
// CHECK-NEXT: %8 = insertvalue { %"{{.*}}/runtime/internal/runtime.Slice", %"{{.*}}/runtime/internal/runtime.iface" } %7, %"{{.*}}/runtime/internal/runtime.iface" %6, 1
// CHECK-NEXT: ret { %"{{.*}}/runtime/internal/runtime.Slice", %"{{.*}}/runtime/internal/runtime.iface" } %8
// CHECK-NEXT: }

// CHECK-LABEL: define { i64, %"{{.*}}/runtime/internal/runtime.iface" } @"main.*struct{m int; *bytes.Buffer}.Read"(ptr %0, %"{{.*}}/runtime/internal/runtime.Slice" %1){{.*}} {
// CHECK-NEXT: _llgo_0:
// CHECK-NEXT: %2 = getelementptr inbounds { i64, ptr }, ptr %0, i32 0, i32 1
Expand Down Expand Up @@ -1292,6 +1300,21 @@ type I2 interface {
// CHECK-NEXT: ret %"{{.*}}/runtime/internal/runtime.Slice" %5
// CHECK-NEXT: }

// CHECK-LABEL: define { %"{{.*}}/runtime/internal/runtime.Slice", %"{{.*}}/runtime/internal/runtime.iface" } @"main.struct{m int; *bytes.Buffer}.Peek"({ i64, ptr } %0, i64 %1){{.*}} {
// CHECK-NEXT: _llgo_0:
// CHECK-NEXT: %2 = alloca { i64, ptr }, align 8
// CHECK-NEXT: call void @llvm.memset.p0.i64(ptr %2, i8 0, i64 16, i1 false)
// CHECK-NEXT: store { i64, ptr } %0, ptr %2, align 8
// CHECK-NEXT: %3 = getelementptr inbounds { i64, ptr }, ptr %2, i32 0, i32 1
// CHECK-NEXT: %4 = load ptr, ptr %3, align 8
// CHECK-NEXT: %5 = call { %"{{.*}}/runtime/internal/runtime.Slice", %"{{.*}}/runtime/internal/runtime.iface" } @"bytes.(*Buffer).Peek"(ptr %4, i64 %1)
// CHECK-NEXT: %6 = extractvalue { %"{{.*}}/runtime/internal/runtime.Slice", %"{{.*}}/runtime/internal/runtime.iface" } %5, 0
// CHECK-NEXT: %7 = extractvalue { %"{{.*}}/runtime/internal/runtime.Slice", %"{{.*}}/runtime/internal/runtime.iface" } %5, 1
// CHECK-NEXT: %8 = insertvalue { %"{{.*}}/runtime/internal/runtime.Slice", %"{{.*}}/runtime/internal/runtime.iface" } undef, %"{{.*}}/runtime/internal/runtime.Slice" %6, 0
// CHECK-NEXT: %9 = insertvalue { %"{{.*}}/runtime/internal/runtime.Slice", %"{{.*}}/runtime/internal/runtime.iface" } %8, %"{{.*}}/runtime/internal/runtime.iface" %7, 1
// CHECK-NEXT: ret { %"{{.*}}/runtime/internal/runtime.Slice", %"{{.*}}/runtime/internal/runtime.iface" } %9
// CHECK-NEXT: }

// CHECK-LABEL: define { i64, %"{{.*}}/runtime/internal/runtime.iface" } @"main.struct{m int; *bytes.Buffer}.Read"({ i64, ptr } %0, %"{{.*}}/runtime/internal/runtime.Slice" %1){{.*}} {
// CHECK-NEXT: _llgo_0:
// CHECK-NEXT: %2 = alloca { i64, ptr }, align 8
Expand Down
103 changes: 65 additions & 38 deletions cl/_testgo/cgodefer/cgodefer.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,11 @@ package main
*/
import "C"

func main() {
p := C.malloc(1024)
defer C.free(p)
}

// CHECK-LABEL: define [0 x i8] @main._Cfunc_free(ptr %0){{.*}} {
// CHECK-NEXT: _llgo_0:
// CHECK-NEXT: %1 = call ptr @"{{.*}}/runtime/internal/runtime.AllocZ"(i64 8)
Expand All @@ -15,6 +20,27 @@ import "C"
// CHECK-NEXT: ret [0 x i8] %4
// CHECK-NEXT: }

// CHECK-LABEL: define ptr @main._Cgo_ptr(ptr %0){{.*}} {
// CHECK-NEXT: _llgo_0:
// CHECK-NEXT: ret ptr %0
// CHECK-NEXT: }

// CHECK-LABEL: define void @main.init(){{.*}} {
// CHECK-NEXT: _llgo_0:
// CHECK-NEXT: %0 = load i1, ptr @"main.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 @"main.init$guard", align 1
// CHECK-NEXT: call void @syscall.init()
// CHECK-NEXT: store ptr @_cgo_{{.*}}_Cfunc_free, ptr @main._cgo_{{.*}}_Cfunc_free, align 8
// CHECK-NEXT: store ptr @_cgo_{{.*}}_Cfunc__Cmalloc, ptr @main._cgo_{{.*}}_Cfunc__Cmalloc, align 8
// CHECK-NEXT: br label %_llgo_2
// CHECK-EMPTY:
// CHECK-NEXT: _llgo_2: ; preds = %_llgo_1, %_llgo_0
// CHECK-NEXT: ret void
// CHECK-NEXT: }

// CHECK-LABEL: define void @main.main(){{.*}} {
// CHECK-NEXT: _llgo_0:
// CHECK-NEXT: %0 = call ptr @"{{.*}}/runtime/internal/runtime.AllocZ"(i64 8)
Expand Down Expand Up @@ -45,7 +71,7 @@ import "C"
// CHECK-NEXT: %17 = getelementptr inbounds %"{{.*}}/runtime/internal/runtime.Defer", ptr %10, i32 0, i32 4
// CHECK-NEXT: %18 = getelementptr inbounds %"{{.*}}/runtime/internal/runtime.Defer", ptr %10, i32 0, i32 5
// CHECK-NEXT: store ptr null, ptr %18, align 8
// CHECK-NEXT: %19 = call i32 @{{.*}}sigsetjmp(ptr %9, i32 0)
// CHECK-NEXT: %19 = call i32 @{{(__)?}}sigsetjmp(ptr %9, i32 0)
// CHECK-NEXT: %20 = icmp eq i32 %19, 0
// CHECK-NEXT: br i1 %20, label %_llgo_4, label %_llgo_5
// CHECK-EMPTY:
Expand Down Expand Up @@ -91,44 +117,45 @@ import "C"
// CHECK-NEXT: store ptr %32, ptr %18, align 8
// CHECK-NEXT: %33 = extractvalue { ptr, i64, { ptr, ptr } } %31, 2
// CHECK-NEXT: call void @"{{.*}}/runtime/internal/runtime.FreeDeferNode"(ptr %30)
// CHECK-NEXT: %34 = extractvalue { ptr, ptr } %33, 1
// CHECK-NEXT: %35 = extractvalue { ptr, ptr } %33, 0
// CHECK-NEXT: %__llgo_funcval_code1 = call ptr asm "", "=r,0"(ptr %35)
// CHECK-NEXT: call void %__llgo_funcval_code1(ptr {{(nest|swiftself)}} %34)
// CHECK-NEXT: %34 = extractvalue { ptr, ptr } %33, 0
// CHECK-NEXT: %35 = call %"{{.*}}/runtime/internal/runtime.recoverState" @"{{.*}}/runtime/internal/runtime.StartRecoverFrame"(ptr %34)
// CHECK-NEXT: %36 = extractvalue { ptr, ptr } %33, 1
// CHECK-NEXT: %37 = extractvalue { ptr, ptr } %33, 0
// CHECK-NEXT: %__llgo_funcval_code1 = call ptr asm "", "=r,0"(ptr %37)
// CHECK-NEXT: call void %__llgo_funcval_code1(ptr {{(nest|swiftself)}} %36)
// CHECK-NEXT: call void @"{{.*}}/runtime/internal/runtime.EndRecoverFrame"(%"{{.*}}/runtime/internal/runtime.recoverState" %35)
// CHECK-NEXT: br label %_llgo_8
// CHECK-EMPTY:
// CHECK-NEXT: _llgo_8: ; preds = %_llgo_7, %_llgo_2
// CHECK-NEXT: %36 = load %"{{.*}}/runtime/internal/runtime.Defer", ptr %10, align 8
// CHECK-NEXT: %37 = extractvalue %"{{.*}}/runtime/internal/runtime.Defer" %36, 2
// CHECK-NEXT: call void @"{{.*}}/runtime/internal/runtime.SetThreadDefer"(ptr %37)
// CHECK-NEXT: %38 = load ptr, ptr %17, align 8
// CHECK-NEXT: indirectbr ptr %38, [label %_llgo_3, label %_llgo_6]
// CHECK-NEXT: %38 = load %"{{.*}}/runtime/internal/runtime.Defer", ptr %10, align 8
// CHECK-NEXT: %39 = extractvalue %"{{.*}}/runtime/internal/runtime.Defer" %38, 2
// CHECK-NEXT: call void @"{{.*}}/runtime/internal/runtime.SetThreadDefer"(ptr %39)
// CHECK-NEXT: %40 = load ptr, ptr %17, align 8
// CHECK-NEXT: indirectbr ptr %40, [label %_llgo_3, label %_llgo_6]
// CHECK-NEXT: }

// CHECK-LABEL: define { ptr, ptr } @"main.main$1"(ptr {{(nest|swiftself)}} %0){{.*}} {
// CHECK-NEXT: _llgo_0:
// CHECK-NEXT: %1 = call ptr @"{{.*}}/runtime/internal/runtime.AllocZ"(i64 8)
// CHECK-NEXT: %2 = load { ptr }, ptr %0, align 8
// CHECK-NEXT: %3 = extractvalue { ptr } %2, 0
// CHECK-NEXT: %4 = load ptr, ptr %3, align 8
// CHECK-NEXT: store ptr %4, ptr %1, align 8
// CHECK-NEXT: %5 = call ptr @"{{.*}}/runtime/internal/runtime.AllocU"(i64 8)
// CHECK-NEXT: %6 = getelementptr inbounds { ptr }, ptr %5, i32 0, i32 0
// CHECK-NEXT: store ptr %1, ptr %6, align 8
// CHECK-NEXT: %7 = insertvalue { ptr, ptr } { ptr @"main.main$1$1", ptr undef }, ptr %5, 1
// CHECK-NEXT: ret { ptr, ptr } %7
// CHECK-NEXT: }

// CHECK-LABEL: define void @"main.main$1$1"(ptr {{(nest|swiftself)}} %0){{.*}} {
// CHECK-NEXT: _llgo_0:
// CHECK-NEXT: %1 = load { ptr }, ptr %0, align 8
// CHECK-NEXT: %2 = extractvalue { ptr } %1, 0
// CHECK-NEXT: %3 = load ptr, ptr %2, align 8
// CHECK-NEXT: %4 = insertvalue %"{{.*}}/runtime/internal/runtime.eface" { ptr @_llgo_Pointer, ptr undef }, ptr %3, 1
// CHECK-NEXT: %5 = extractvalue { ptr } %1, 0
// CHECK-NEXT: %6 = load ptr, ptr %5, align 8
// CHECK-NEXT: %7 = call [0 x i8] @main._Cfunc_free(ptr %6)
// CHECK-NEXT: ret void
// CHECK-NEXT: }
func main() {
// CHECK-LABEL: define { ptr, ptr } @"main.main$1"(ptr {{(nest|swiftself)}} %0){{.*}} {
// CHECK-NEXT: _llgo_0:
// CHECK-NEXT: %1 = call ptr @"{{.*}}/runtime/internal/runtime.AllocZ"(i64 8)
// CHECK-NEXT: %2 = load { ptr }, ptr %0, align 8
// CHECK-NEXT: %3 = extractvalue { ptr } %2, 0
// CHECK-NEXT: %4 = load ptr, ptr %3, align 8
// CHECK-NEXT: store ptr %4, ptr %1, align 8
// CHECK-NEXT: %5 = call ptr @"{{.*}}/runtime/internal/runtime.AllocU"(i64 8)
// CHECK-NEXT: %6 = getelementptr inbounds { ptr }, ptr %5, i32 0, i32 0
// CHECK-NEXT: store ptr %1, ptr %6, align 8
// CHECK-NEXT: %7 = insertvalue { ptr, ptr } { ptr @"main.main$1$1", ptr undef }, ptr %5, 1
// CHECK-NEXT: ret { ptr, ptr } %7
// CHECK-NEXT: }
p := C.malloc(1024)
// CHECK-LABEL: define void @"main.main$1$1"(ptr {{(nest|swiftself)}} %0){{.*}} {
// CHECK-NEXT: _llgo_0:
// CHECK-NEXT: %1 = load { ptr }, ptr %0, align 8
// CHECK-NEXT: %2 = extractvalue { ptr } %1, 0
// CHECK-NEXT: %3 = load ptr, ptr %2, align 8
// CHECK-NEXT: %4 = insertvalue %"{{.*}}/runtime/internal/runtime.eface" { ptr @_llgo_Pointer, ptr undef }, ptr %3, 1
// CHECK-NEXT: %5 = extractvalue { ptr } %1, 0
// CHECK-NEXT: %6 = load ptr, ptr %5, align 8
// CHECK-NEXT: %7 = call [0 x i8] @main._Cfunc_free(ptr %6)
// CHECK-NEXT: ret void
// CHECK-NEXT: }
defer C.free(p)
}
Loading
Loading