anza-xyz / move

Move compiler targeting llvm supported backends
https://discord.gg/wFgfjG9J
Apache License 2.0
108 stars 33 forks source link

[Bug] Compiler stack overflow on long sequence of struct field access #317

Open dmakarov opened 1 year ago

dmakarov commented 1 year ago

🐛 Bug

To reproduce

target/debug/move build --arch solana -p struct-nested

Where struct-nested contain the following module

Code snippet to reproduce

module main::struct_nested {
    struct Box<T> has copy, drop, store { a: T }
    struct Box3<T> has copy, drop, store { b: Box<Box<T>> }
    struct Box7<T> has copy, drop, store { c: Box3<Box3<T>> }
    struct Box15<T> has copy, drop, store { d: Box7<Box7<T>> }
    struct Box31<T> has copy, drop, store { e: Box15<Box15<T>> }
    struct Box63<T> has copy, drop, store { f: Box31<Box31<T>> }
    struct Box127<T> has copy, drop, store { g: Box63<Box63<T>> }

    fun box3<T>(x: T): Box3<T> {
        Box3 { b: Box { a: Box { a: x } } }
    }

    fun box7<T>(x: T): Box7<T> {
        Box7 { c: box3(box3(x)) }
    }

    fun box15<T>(x: T): Box15<T> {
        Box15 { d: box7(box7(x)) }
    }

    fun box31<T>(x: T): Box31<T> {
        Box31 { e: box15(box15(x)) }
    }

    fun box63<T>(x: T): Box63<T> {
        Box63 { f: box31(box31(x)) }
    }

    fun box127<T>(x: T): Box127<T> {
        Box127 { g: box63(box63(x)) }
    }

    public entry fun bar() {
        let x = box127(true);
        assert!(x.g.f.e.d.c.b.a.a.b.a.a.c.b.a.a.b.a.a.d.c.b.a.a.b.a.a.c.b.a.a.b.a.a.e.d.c.b.a.a.b.a.a.c.b.a.a.b.a.a.d.c.b.a.a.b.a.a.c.b.a.a.b.a.a.f.e.d.c.b.a.a.b.a.a.c.b.a.a.b.a.a.d.c.b.a.a.b.a.a.c.b.a.a.b.a.a.e.d.c.b.a.a.b.a.a.c.b.a.a.b.a.a.d.c.b.a.a.b.a.a.c.b.a.a.b.a.a, 0);
    }
}

Stack trace/error message

thread 'main' has overflowed its stack
fatal runtime error: stack overflow
Aborted (core dumped)
dmakarov commented 1 year ago

A smaller module also crashes

module main::struct_nested {
    struct Box<T> has copy, drop, store { a: T }
    struct Box3<T> has copy, drop, store { b: Box<Box<T>> }

    fun box3<T>(x: T): Box3<T> {
        Box3 { b: Box { a: Box { a: x } } }
    }

    public entry fun bar() {
        let x = box3(true);
        assert!(x.b.a.a, 0);
    }
}
[DEBUG language/solana/move-to-solana/src/stackless/module_context.rs:454] Declare Move function struct_nested__bar
[DEBUG language/solana/move-to-solana/src/stackless/module_context.rs:454] Declare Move function struct_nested__box3_bool
[DEBUG language/solana/move-to-solana/src/stackless/module_context.rs:645] instance struct_nested::Box3<bool>
[DEBUG language/solana/move-to-solana/src/stackless/module_context.rs:645] instance struct_nested::Box3
[DEBUG language/solana/move-to-solana/src/stackless/module_context.rs:645] instance struct_nested::Box3
[DEBUG language/solana/move-to-solana/src/stackless/module_context.rs:645] instance struct_nested::Box<bool>
[DEBUG language/solana/move-to-solana/src/stackless/module_context.rs:645] instance struct_nested::Box<bool>
[DEBUG language/solana/move-to-solana/src/stackless/module_context.rs:645] instance struct_nested::Box3<bool>
Segmentation fault (core dumped)
dmakarov commented 1 year ago

A smaller module also crashes

module main::struct_nested {
    struct Box<T> has copy, drop, store { a: T }
    struct Box3<T> has copy, drop, store { b: Box<Box<T>> }

    fun box3<T>(x: T): Box3<T> {
        Box3 { b: Box { a: Box { a: x } } }
    }

    public entry fun bar() {
        let x = box3(true);
        assert!(x.b.a.a, 0);
    }
}
[DEBUG language/solana/move-to-solana/src/stackless/module_context.rs:454] Declare Move function struct_nested__bar
[DEBUG language/solana/move-to-solana/src/stackless/module_context.rs:454] Declare Move function struct_nested__box3_bool
[DEBUG language/solana/move-to-solana/src/stackless/module_context.rs:645] instance struct_nested::Box3<bool>
[DEBUG language/solana/move-to-solana/src/stackless/module_context.rs:645] instance struct_nested::Box3
[DEBUG language/solana/move-to-solana/src/stackless/module_context.rs:645] instance struct_nested::Box3
[DEBUG language/solana/move-to-solana/src/stackless/module_context.rs:645] instance struct_nested::Box<bool>
[DEBUG language/solana/move-to-solana/src/stackless/module_context.rs:645] instance struct_nested::Box<bool>
[DEBUG language/solana/move-to-solana/src/stackless/module_context.rs:645] instance struct_nested::Box3<bool>
Segmentation fault (core dumped)

This error was triggered by compiling entry function returning no value. Fixed by #319