tact-lang / tact

Tact compiler main repository
https://tact-lang.org
MIT License
395 stars 111 forks source link

FunC codegen error for obvious cases of zero division in statements #716

Open anton-trunov opened 3 months ago

anton-trunov commented 3 months ago
contract Test {

    a: Int = 0;

    init() {
        self.a / self.a;
        // self. a / 0 would fail too
    }

    get fun foo(): Int {
        let x = 42 - 42;
        return 42 / x;   // this also fails
    }
}

Results in the following error message from FunC:

Func compilation error: cannot generate code for function `$Test$_contract_init`:
/dist/tact_Test.code.fc:15:14: error: division by zero
($self'a / $self'a)

As far as I understand this happens during code generation when going from FunC to Fift-asm.

To resolve this, we need to track variables whose values can be determined at compile-time.

jeshecdom commented 3 months ago

Mmmm... the main problem I see here is that const-eval (or the interpreter) is only called to simplify expressions. For example, inside function foo, it is called to simplify the argument of the return. const-eval will not execute function foo because there is no expression calling function foo. As such, it will treat variable x in the return statement as uninterpreted.

To solve this issue, we would need some form of code analysis outside of const-eval. Another possibility would be to attempt calling functions that do not have parameters, just to check if its execution generates an error. Probably, we will need an analysis/optimization pass after the typecheck pass, because currently, optimization and interpretation is only carried out on pieces of the code (in expressions, to be exact).

anton-trunov commented 3 months ago

To solve this issue, we would need some form of code analysis outside of const-eval.

To solve this issue you need to partially evaluate contracts (I almost always mean partial evaluation or constant evaluation by "const-eval", sorry if that's confusing)