Skip to content

Bug in variable initialization #651

Open

Description

@certik

There are still some bugs in how variable initialization is handled.

from ltypes import i32

def g(x: i32):
    print(x)

x: i32 = 7

def f():
    a: i32 = 5
    x: i32 = 3
    x = 5
    b: i32 = x+1
    g(a*b+3)

f()

It prints:

$ lpython --new-parser a.py && ./a.out 
23
$ PYTHONPATH=src/runtime/ltypes python a.py
33

The solution: unless x is declared as x: Constant[i32] (we currently do not support it, but we could), then any initialization must be assigned to it using Assignment, not as "value" in the Variable_t, because then you can't assign to it later (we should check this in verify). Above x still has 3, not 5. For Constant[i32] you have to assign to it right away, and then you can't change it.

So the above code effectively becomes:

def f():
    a: i32
    x: i32
    b: i32
    a = 5
    x = 3
    x = 5
    b = x+1
    g(a*b+3)

And everything should work.

Activity

  1. czgdp1807 commented on Jun 20, 2022

    @czgdp1807
  2. czgdp1807 commented on Jun 20, 2022

    @czgdp1807
    Collaborator

    Well, first all the variables are declared. So declaration and initialisation of b happens before x = 5 is executed. This is not a bug I think. It is incorrect behaviour for Python. LLVM backend was initially written for Fortran (where you have to declare all the variables together before using them). To fix this, I think we can do an ASR pass where all the initialisations at declarations can be converted to assignments in the body. Then Fortran, Python would behave in the same way. Let me know what you think.

  3. certik commented on Jun 20, 2022

    @certik
    ContributorAuthor

    So the confusion stems from

            expr? symbolic_value, expr? value, storage_type storage, ttype type,
    

    The value is a compile time value, essentially implying the variable is a constant, so the value is assigned once and never changes.

    The symbolic_value is an initial value of the variable, that can change later.

  4. certik commented on Jun 20, 2022

    @certik
    ContributorAuthor

    I think the bug is in the frontend, assigning the initialization to value instead of symbolic_value.

  5. certik commented on Jun 20, 2022

    @certik
    ContributorAuthor

    Another condition: the runtime value of symbolic_value must be a compile time constant. 3+3, 3, and constants (we don't have those yet) and expressions using those, are all constants. Everything else is not a constant, and the frontend must generate an Assignment statement instead.

  6. Smit-create commented on Aug 31, 2022

    @Smit-create
    Collaborator

    This seems to be fixed now:

    % lpython expr.py && ./a.out
    33
    % lpython --new-parser expr.py && ./a.out
    33
    % PYTHONPATH=$PWD/src/runtime/ltypes python expr.py
    33
    
    
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

could closeIssues/PRs which can be closed.

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions