Skip to content

Commit e17007a

Browse files
authored
Test for tuple return and fixes in CPtrToPointer node in C backend (#1351)
1 parent bdc218a commit e17007a

File tree

6 files changed

+79
-16
lines changed

6 files changed

+79
-16
lines changed

integration_tests/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -189,6 +189,7 @@ RUN(NAME array_expr_02 LABELS cpython llvm)
189189
RUN(NAME bindc_01 LABELS cpython llvm c)
190190
RUN(NAME bindc_02 LABELS cpython llvm c)
191191
RUN(NAME bindc_04 LABELS llvm c)
192+
RUN(NAME bindc_07 LABELS llvm c)
192193
RUN(NAME exit_01 LABELS cpython llvm c)
193194
RUN(NAME exit_02 FAIL LABELS cpython llvm c)
194195
RUN(NAME exit_01b LABELS cpython llvm c wasm wasm_x86)

integration_tests/bindc_07.py

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
from ltypes import CPtr, i64, sizeof, i32, ccall, c_p_pointer, empty_c_void_p, Pointer, pointer
2+
from numpy import empty, int64
3+
4+
@ccall
5+
def _lfortran_malloc(size: i32) -> CPtr:
6+
pass
7+
8+
def allocate_memory(size: i32) -> tuple[CPtr, CPtr, CPtr, CPtr]:
9+
array1: CPtr = _lfortran_malloc(size * i32(sizeof(i64)))
10+
array2: CPtr = _lfortran_malloc(size * i32(sizeof(i64)))
11+
array3: CPtr = _lfortran_malloc(size * i32(sizeof(i64)))
12+
array4: CPtr = _lfortran_malloc(size * i32(sizeof(i64)))
13+
return array1, array2, array3, array4
14+
15+
def sum_arrays(array1: CPtr, array2: CPtr, array3: CPtr, array4: CPtr, size: i32):
16+
iarray1: Pointer[i64[size]] = c_p_pointer(array1, i64[size])
17+
iarray2: Pointer[i64[size]] = c_p_pointer(array2, i64[size])
18+
iarray3: Pointer[i64[size]] = c_p_pointer(array3, i64[size])
19+
iarray4: Pointer[i64[size]] = c_p_pointer(array4, i64[size])
20+
sum_array_cptr: CPtr = _lfortran_malloc(size * i32(sizeof(i64)))
21+
sum_array: Pointer[i64[size]] = c_p_pointer(sum_array_cptr, i64[size])
22+
i: i32
23+
24+
for i in range(size):
25+
iarray1[i] = i64(i)
26+
iarray2[i] = i64(2 * i)
27+
iarray3[i] = i64(3 * i)
28+
iarray4[i] = i64(4 * i)
29+
30+
for i in range(size):
31+
sum_array[i] = iarray1[i] + iarray2[i] + iarray3[i] + iarray4[i]
32+
33+
for i in range(size):
34+
print(i, sum_array[i])
35+
assert sum_array[i] == i64(10 * i)
36+
37+
def test_tuple_return():
38+
a: CPtr = empty_c_void_p()
39+
b: CPtr = empty_c_void_p()
40+
c: CPtr = empty_c_void_p()
41+
d: CPtr = empty_c_void_p()
42+
a, b, c, d = allocate_memory(50)
43+
sum_arrays(a, b, c, d, 50)
44+
45+
test_tuple_return()

src/libasr/codegen/asr_to_c.cpp

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,8 +93,9 @@ class ASRToCVisitor : public BaseCCPPVisitor<ASRToCVisitor>
9393
std::string variable_name = std::string(v_m_name) + "_value";
9494
sub = format_type_c("", type_name_without_ptr, variable_name, use_ref, dummy) + ";\n";
9595
sub += indent + format_type_c("", type_name, v_m_name, use_ref, dummy);
96-
sub += " = &" + variable_name + ";\n";
96+
sub += " = &" + variable_name;
9797
if( !is_pointer ) {
98+
sub += ";\n";
9899
if( !is_fixed_size ) {
99100
sub += indent + format_type_c("*", type_name_copy, std::string(v_m_name) + "_data",
100101
use_ref, dummy);
@@ -919,6 +920,36 @@ R"(
919920
}
920921
}
921922

923+
void visit_CPtrToPointer(const ASR::CPtrToPointer_t& x) {
924+
visit_expr(*x.m_cptr);
925+
std::string source_src = std::move(src);
926+
visit_expr(*x.m_ptr);
927+
std::string dest_src = std::move(src);
928+
src = "";
929+
std::string indent(indentation_level*indentation_spaces, ' ');
930+
if( ASRUtils::is_array(ASRUtils::expr_type(x.m_ptr)) ) {
931+
std::string dim_set_code = "";
932+
ASR::dimension_t* m_dims = nullptr;
933+
int n_dims = ASRUtils::extract_dimensions_from_ttype(ASRUtils::expr_type(x.m_ptr), m_dims);
934+
dim_set_code = indent + dest_src + "->n_dims = " + std::to_string(n_dims) + ";\n";
935+
for( int i = 0; i < n_dims; i++ ) {
936+
if( m_dims[i].m_start ) {
937+
visit_expr(*m_dims[i].m_start);
938+
dim_set_code += indent + dest_src + "->dims[" + std::to_string(i) + "].lower_bound = " + src + ";\n";
939+
}
940+
if( m_dims[i].m_length ) {
941+
visit_expr(*m_dims[i].m_length);
942+
dim_set_code += indent + dest_src + "->dims[" + std::to_string(i) + "].length = " + src + ";\n";
943+
}
944+
}
945+
src.clear();
946+
src += dim_set_code;
947+
dest_src += "->data";
948+
}
949+
std::string type_src = CUtils::get_c_type_from_ttype_t(ASRUtils::expr_type(x.m_ptr));
950+
src += indent + dest_src + " = (" + type_src + ") " + source_src + ";\n";
951+
}
952+
922953
void visit_Print(const ASR::Print_t &x) {
923954
std::string indent(indentation_level*indentation_spaces, ' ');
924955
std::string out = indent + "printf(\"";

src/libasr/codegen/asr_to_c_cpp.h

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1360,19 +1360,6 @@ R"(#include <stdio.h>
13601360
src = "(" + type_src + ") " + arg_src;
13611361
}
13621362

1363-
void visit_CPtrToPointer(const ASR::CPtrToPointer_t& x) {
1364-
self().visit_expr(*x.m_cptr);
1365-
std::string source_src = std::move(src);
1366-
self().visit_expr(*x.m_ptr);
1367-
std::string dest_src = std::move(src);
1368-
if( ASRUtils::is_array(ASRUtils::expr_type(x.m_ptr)) ) {
1369-
dest_src += "->data";
1370-
}
1371-
std::string type_src = CUtils::get_c_type_from_ttype_t(ASRUtils::expr_type(x.m_ptr));
1372-
std::string indent(indentation_level*indentation_spaces, ' ');
1373-
src = indent + dest_src + " = (" + type_src + ") " + source_src + ";\n";
1374-
}
1375-
13761363
void visit_IntegerBinOp(const ASR::IntegerBinOp_t &x) {
13771364
handle_BinOp(x);
13781365
}

tests/reference/c-expr_12-93c7780.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
"outfile": null,
77
"outfile_hash": null,
88
"stdout": "c-expr_12-93c7780.stdout",
9-
"stdout_hash": "1127059fc2c4c1c983f076379c82dc361f4b19498555e14f4442c179",
9+
"stdout_hash": "eb08879462b433e55fbbfe330788bea1af316edb842fde0b772f6716",
1010
"stderr": null,
1111
"stderr_hash": null,
1212
"returncode": 0

tests/reference/c-expr_12-93c7780.stdout

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,6 @@ void f()
7070
y->dims[0].length = 2;
7171
struct i16 yptr1_value;
7272
struct i16* yptr1 = &yptr1_value;
73-
;
7473
g(&yptr1, y);
7574
check(&yptr1);
7675
}

0 commit comments

Comments
 (0)