Thanks to visit codestin.com
Credit goes to github.com

Skip to content

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

Closed
@emoise-gsi

Description

@emoise-gsi

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions