pyteal icon indicating copy to clipboard operation
pyteal copied to clipboard

ScratchVar load before store conflicting with Subroutines.

Open CiottiGiorgio opened this issue 2 years ago • 1 comments

Subject of the issue

Compiler checks for load before store do not work as expected when Subroutines that takes ScratchVar as arguments are used.

Steps to reproduce

from pyteal import *


def example():
    var = ScratchVar(TealType.uint64)

    @Subroutine(TealType.none)
    def sub(x: ScratchVar):
        return x.store(Int(0))

    return Seq([
        sub(var),
        Pop(var.load()),
        Approve()
    ])


if __name__ == '__main__':
    print(compileTeal(example(), mode=Mode.Application, version=6))

Expected behaviour

Contract can compile correctly

Actual behaviour

pyteal.TealCompileError: Scratch slot load occurs before store

CiottiGiorgio avatar May 04 '22 11:05 CiottiGiorgio

Thanks for reporting this issue, I've reproduced it on the current master branch.

The problem occurs on the Pop(var.load()) line. The issue here is that the compiler doesn't do enough analysis to make sure that line is safe. The sub subroutine happens to always stores a value in the subroutine argument slot, but the compiler isn't aware of that currently. For all it knows, that subroutine could only conditionally store something in the argument slot, or never store anything there.

With enhanced analysis in the compiler, we could detect across subroutine calls whether a scratch slot is safe to load.

jasonpaulos avatar May 10 '22 18:05 jasonpaulos