diff --git a/cl/_testrt/closure/in.go b/cl/_testrt/closure/in.go new file mode 100644 index 00000000..5b26c374 --- /dev/null +++ b/cl/_testrt/closure/in.go @@ -0,0 +1,15 @@ +package main + +import ( + "github.com/goplus/llgo/internal/runtime/c" +) + +func main() { + fn1 := func(n1, n2 int) { + c.Printf(c.Str("%d %d\n"), n1, n2) + } + fn2 := func() { + fn1(100, 200) + } + fn2() +} diff --git a/cl/_testrt/closure/out.ll b/cl/_testrt/closure/out.ll new file mode 100644 index 00000000..173c914a --- /dev/null +++ b/cl/_testrt/closure/out.ll @@ -0,0 +1,64 @@ +; ModuleID = 'main' +source_filename = "main" + +@"main.init$guard" = global ptr null +@0 = private unnamed_addr constant [7 x i8] c"%d %d\0A\00", align 1 + +define void @main.init() { +_llgo_0: + %0 = load i1, ptr @"main.init$guard", align 1 + br i1 %0, label %_llgo_2, label %_llgo_1 + +_llgo_1: ; preds = %_llgo_0 + store i1 true, ptr @"main.init$guard", align 1 + br label %_llgo_2 + +_llgo_2: ; preds = %_llgo_1, %_llgo_0 + ret void +} + +define void @main() { +_llgo_0: + call void @"github.com/goplus/llgo/internal/runtime.init"() + call void @main.init() + %0 = call ptr @"github.com/goplus/llgo/internal/runtime.AllocZ"(i64 16) + store ptr @"main.main$1", ptr %0, align 8 + %1 = call ptr @"github.com/goplus/llgo/internal/runtime.AllocU"(i64 8) + %2 = getelementptr inbounds { ptr }, ptr %1, i32 0, i32 0 + store ptr %0, ptr %2, align 8 + %3 = alloca { ptr, ptr }, align 8 + %4 = getelementptr inbounds { ptr, ptr }, ptr %3, i32 0, i32 0 + store ptr @"main.main$2", ptr %4, align 8 + %5 = getelementptr inbounds { ptr, ptr }, ptr %3, i32 0, i32 1 + store ptr %1, ptr %5, align 8 + %6 = load { ptr, ptr }, ptr %3, align 8 + %7 = extractvalue { ptr, ptr } %6, 1 + %8 = extractvalue { ptr, ptr } %6, 0 + call void %8(ptr %7) + ret void +} + +declare void @"github.com/goplus/llgo/internal/runtime.init"() + +declare ptr @"github.com/goplus/llgo/internal/runtime.AllocZ"(i64) + +define void @"main.main$1"(i64 %0, i64 %1) { +_llgo_0: + %2 = call i32 (ptr, ...) @printf(ptr @0, i64 %0, i64 %1) + ret void +} + +define void @"main.main$2"(ptr %0) { +_llgo_0: + %1 = load { ptr }, ptr %0, align 8 + %2 = extractvalue { ptr } %1, 0 + %3 = load { ptr, ptr }, ptr %2, align 8 + %4 = extractvalue { ptr, ptr } %3, 1 + %5 = extractvalue { ptr, ptr } %3, 0 + call void %5(ptr %4, i64 100, i64 200) + ret void +} + +declare ptr @"github.com/goplus/llgo/internal/runtime.AllocU"(i64) + +declare i32 @printf(ptr, ...) diff --git a/ssa/expr.go b/ssa/expr.go index 09657449..4fd644bd 100644 --- a/ssa/expr.go +++ b/ssa/expr.go @@ -494,9 +494,11 @@ func (b Builder) Load(ptr Expr) Expr { // Store stores val at the pointer ptr. func (b Builder) Store(ptr, val Expr) Builder { + raw := ptr.raw.Type if debugInstr { - log.Printf("Store %v, %v\n", ptr.impl, val.impl) + log.Printf("Store %v, %v, %v\n", raw, ptr.impl, val.impl) } + val = checkExpr(val, raw.(*types.Pointer).Elem(), b) b.impl.CreateStore(val.impl, ptr.impl) return b }