Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

lpython emits invalid c code when passing an object to a function #2179

Closed
emoise-gsi opened this issue Jul 18, 2023 · 1 comment · Fixed by #2180
Closed

lpython emits invalid c code when passing an object to a function #2179

emoise-gsi opened this issue Jul 18, 2023 · 1 comment · Fixed by #2180

Comments

@emoise-gsi
Copy link

lpython version: 18.2

This a variation of a bug I opened in the past (#2059). The bug was fixed but it has morphed into something else.

Consider the code, pass_address_bug.py:

from lpython import packed, dataclass, ccallable, i32, ccallback

@ccallable
@packed
@dataclass
class struct_0:
    val_0 : i32 = 613

@ccallable
@packed
@dataclass
class struct_1:
    val_1 : struct_0 = struct_0()

def print_val_0_in_struct_0(struct_0_instance : struct_0) -> i32:
    print(struct_0_instance.val_0)
    return 0

@ccallback
def entry_point() -> i32:
    struct_1_instance : struct_1 = struct_1()  
    return print_val_0_in_struct_0(struct_1_instance.val_1)

compiling with lpython,
$ lpython pass_address_bug.py --show-c > bug.c

produces the following code, bug.c:

#include <inttypes.h>

#include <stdlib.h>
#include <stdbool.h>
#include <stdio.h>
#include <string.h>
#include <lfortran_intrinsics.h>

struct dimension_descriptor
{
    int32_t lower_bound, length;
};
struct __attribute__((packed)) struct_0 {
 int32_t val_0;
};

struct __attribute__((packed)) struct_1 {
 struct struct_0 val_1;
};


// Implementations
int32_t print_val_0_in_struct_0(struct struct_0* struct_0_instance)
{
    int32_t _lpython_return_variable;
    printf("%d\n", struct_0_instance->val_0);
    _lpython_return_variable = 0;
    return _lpython_return_variable;
}

int32_t entry_point()
{
    int32_t _lpython_return_variable;
    struct struct_1 struct_1_instance_value;
    struct struct_1* struct_1_instance = &struct_1_instance_value;
    struct_1_instance->val_1.val_0 = 613;
    _lpython_return_variable = print_val_0_in_struct_0(struct_1_instance->val_1);
    return _lpython_return_variable;
}

int main(int argc, char* argv[])
{
    _lpython_set_argv(argc, argv);
    return 0;
}

The problem is in the line:
_lpython_return_variable = print_val_0_in_struct_0(struct_1_instance->val_1);
It should be
_lpython_return_variable = print_val_0_in_struct_0(&struct_1_instance->val_1);

Note that the following code, pass_address_works.py, is compiled correctly:

from lpython import packed, dataclass, ccallable, i32, ccallback

@ccallable
@packed
@dataclass
class struct_0:
    val_0 : i32 = 613

@ccallable
@packed
@dataclass
class struct_1:
    val_1 : struct_0 = struct_0()

def print_val_0_in_struct_0(struct_0_instance : struct_0) -> None:
    print(struct_0_instance.val_0)

@ccallback
def entry_point() -> i32:
    struct_1_instance : struct_1 = struct_1()  
    print_val_0_in_struct_0(struct_1_instance.val_1)
    return 0
@Shaikh-Ubaid
Copy link
Collaborator

The last time we fixed it for a subroutine (struct passed to subroutine). This time it seems we have a struct passed to a function. I fixed it here #2180.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants