Closed cpunion closed 1 week ago
A simpler case without generic function also crashed:
package main
func main() {
func(resolve func(error)) {
func(err error) {
if err != nil {
resolve(err)
return
}
resolve(nil)
}(nil)
}(func(err error) {
})
}
Generates wrong LLVM-IR code:
define void @"main.main$1$1"(ptr %0, %"github.com/goplus/llgo/internal/runtime.iface" %1) {
_llgo_0:
%2 = call ptr @"github.com/goplus/llgo/internal/runtime.IfaceType"(%"github.com/goplus/llgo/internal/runtime.iface" %1)
%3 = extractvalue %"github.com/goplus/llgo/internal/runtime.iface" %1, 1
%4 = alloca %"github.com/goplus/llgo/internal/runtime.eface", align 8
%5 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %4, i32 0, i32 0
store ptr %2, ptr %5, align 8
%6 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %4, i32 0, i32 1
store ptr %3, ptr %6, align 8
%7 = load %"github.com/goplus/llgo/internal/runtime.eface", ptr %4, align 8
%8 = call ptr @"github.com/goplus/llgo/internal/runtime.IfaceType"(%"github.com/goplus/llgo/internal/runtime.iface" zeroinitializer)
%9 = alloca %"github.com/goplus/llgo/internal/runtime.eface", align 8
%10 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %9, i32 0, i32 0
store ptr %8, ptr %10, align 8
%11 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %9, i32 0, i32 1
store ptr null, ptr %11, align 8
%12 = load %"github.com/goplus/llgo/internal/runtime.eface", ptr %9, align 8
%13 = call i1 @"github.com/goplus/llgo/internal/runtime.EfaceEqual"(%"github.com/goplus/llgo/internal/runtime.eface" %7, %"github.com/goplus/llgo/internal/runtime.eface" %12)
%14 = xor i1 %13, true
br i1 %14, label %_llgo_1, label %_llgo_2
_llgo_1: ; preds = %_llgo_0
%15 = load { ptr }, ptr %0, align 8
%16 = extractvalue { ptr } %15, 0
%17 = load { ptr, ptr }, ptr %16, align 8
%18 = extractvalue { ptr, ptr } %17, 1
%19 = extractvalue { ptr, ptr } %17, 0
call void %19(ptr %18, %"github.com/goplus/llgo/internal/runtime.iface" zeroinitializer)
ret void
_llgo_2: ; preds = %_llgo_0
%20 = extractvalue { ptr } %15, 0
%21 = load { ptr, ptr }, ptr %20, align 8
%22 = extractvalue { ptr, ptr } %21, 1
%23 = extractvalue { ptr, ptr } %21, 0
call void %23(ptr %22, %"github.com/goplus/llgo/internal/runtime.iface" zeroinitializer)
ret void
}
%15
is initialized in _llgo_1
(if then branch), but used in _llgo_2
(else branch).
When enable
DEBUG 1
, it run success and print same address. But when disableDEBUG 1
, printed addresses changed and it crashed.