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

Skip to content

LPython generates invalid C code when deep copying user defined objects #2125

Closed
@emoise-gsi

Description

@emoise-gsi

Source code:
bug.py

from lpython import packed, dataclass, i32, ccallback, CPtr, ccall

@packed
@dataclass
class inner_struct:
    inner_field: i32 = 0

@packed
@dataclass
class outer_struct:
    inner_s : inner_struct = inner_struct()

@ccall
def outer_struct_instance_from_ptr(p : CPtr) -> outer_struct:
    pass

@ccallback
def print_outer_struct(p : CPtr) -> None:
    outer_struct_instance : outer_struct = outer_struct_instance_from_ptr(p)
    inner_struct_instance : inner_struct = outer_struct_instance.inner_s
    print(inner_struct_instance.inner_field)

compiled with lpython v0.18.0:
lpython -I $CONDA_PREFIX/lib/python3.10/ bug.py --show-c > bug.c

generates 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)) inner_struct {
 int32_t inner_field;
};

struct __attribute__((packed)) outer_struct {
 struct inner_struct inner_s;
};


inline void struct_deepcopy_outer_struct(struct outer_struct* src, struct outer_struct* dest);
inline void struct_deepcopy_inner_struct(struct inner_struct* src, struct inner_struct* dest);


// Implementations
void outer_struct_instance_from_ptr(void* p, struct outer_struct* _lpython_return_variable);

void print_outer_struct(void* p)
{
    struct outer_struct __libasr__created__var__0__libasr_created_return_var__value;
    struct outer_struct* __libasr__created__var__0__libasr_created_return_var_ = &__libasr__created__var__0__libasr_created_return_var__value;
    struct inner_struct inner_struct_instance_value;
    struct inner_struct* inner_struct_instance = &inner_struct_instance_value;
    struct outer_struct outer_struct_instance_value;
    struct outer_struct* outer_struct_instance = &outer_struct_instance_value;
    outer_struct_instance_from_ptr(p, __libasr__created__var__0__libasr_created_return_var_);
    struct_deepcopy_outer_struct(__libasr__created__var__0__libasr_created_return_var_, outer_struct_instance);
    struct_deepcopy_inner_struct(&outer_struct_instance->inner_s, inner_struct_instance);
    printf("%d\n", inner_struct_instance->inner_field);
}

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

void struct_deepcopy_outer_struct(struct outer_struct* src, struct outer_struct* dest) {
void struct_deepcopy_inner_struct(struct inner_struct* src, struct inner_struct* dest) {
    dest->inner_field =  src->inner_field;
}

    struct_deepcopy_inner_struct(&(src->inner_s), &(dest->inner_s));;
}

The problem is in the last lines:

void struct_deepcopy_outer_struct(struct outer_struct* src, struct outer_struct* dest) {
void struct_deepcopy_inner_struct(struct inner_struct* src, struct inner_struct* dest) {
    dest->inner_field =  src->inner_field;
}

    struct_deepcopy_inner_struct(&(src->inner_s), &(dest->inner_s));;
}

I presume the intended output is supposed to be

void struct_deepcopy_outer_struct(struct outer_struct* src, struct outer_struct* dest) {
    struct_deepcopy_inner_struct(&(src->inner_s), &(dest->inner_s));;
}

void struct_deepcopy_inner_struct(struct inner_struct* src, struct inner_struct* dest) {
    dest->inner_field =  src->inner_field;
}

Metadata

Metadata

Assignees

Labels

bugSomething isn't working

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions