Skip to content

Commit 36a5e3b

Browse files
authored
Fix for Const[[:]] i.e., constant arrays (#1258)
1 parent 959a6f1 commit 36a5e3b

File tree

5 files changed

+78
-47
lines changed

5 files changed

+78
-47
lines changed

integration_tests/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,7 @@ RUN(NAME const_01 LABELS cpython llvm c)
158158
RUN(NAME const_02 LABELS cpython llvm c)
159159
RUN(NAME const_03 LABELS cpython llvm c
160160
EXTRAFILES const_03b.c)
161+
RUN(NAME const_04 LABELS cpython llvm c)
161162
RUN(NAME expr_01 LABELS cpython llvm c wasm)
162163
RUN(NAME expr_02 LABELS cpython llvm c wasm)
163164
RUN(NAME expr_03 LABELS cpython llvm c wasm)

integration_tests/const_04.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
from ltypes import i32, i16, Const
2+
from numpy import empty, int16
3+
4+
def sum_const_array(array: Const[i16[:]], size: i32) -> i16:
5+
i: i32
6+
array_sum: i16 = 0
7+
for i in range(size):
8+
array_sum += array[i]
9+
return array_sum
10+
11+
def test_const_array():
12+
arr: i16[4] = empty(4, dtype=int16)
13+
i: i32
14+
for i in range(4):
15+
arr[i] = i
16+
assert sum_const_array(arr, 4) == 6
17+
18+
test_const_array()

src/libasr/asr_utils.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1465,6 +1465,12 @@ static inline ASR::ttype_t* duplicate_type(Allocator& al, const ASR::ttype_t* t,
14651465
return ASRUtils::TYPE(ASR::make_Pointer_t(al, ptr->base.base.loc,
14661466
dup_type));
14671467
}
1468+
case ASR::ttypeType::Const: {
1469+
ASR::Const_t* c = ASR::down_cast<ASR::Const_t>(t);
1470+
ASR::ttype_t* dup_type = duplicate_type(al, c->m_type, dims);
1471+
return ASRUtils::TYPE(ASR::make_Const_t(al, c->base.base.loc,
1472+
dup_type));
1473+
}
14681474
case ASR::ttypeType::TypeParameter: {
14691475
ASR::TypeParameter_t* tp = ASR::down_cast<ASR::TypeParameter_t>(t);
14701476
ASR::dimension_t* dimsp = dims ? dims->p : tp->m_dims;

src/libasr/codegen/asr_to_c.cpp

Lines changed: 52 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -328,17 +328,23 @@ class ASRToCVisitor : public BaseCCPPVisitor<ASRToCVisitor>
328328
v.m_intent == LFortran::ASRUtils::intent_inout);
329329
bool is_array = ASRUtils::is_array(v.m_type);
330330
bool dummy = LFortran::ASRUtils::is_arg_dummy(v.m_intent);
331-
if (ASRUtils::is_pointer(v.m_type)) {
332-
ASR::ttype_t *t2 = ASR::down_cast<ASR::Pointer_t>(v.m_type)->m_type;
331+
ASR::ttype_t* v_m_type = v.m_type;
332+
if (ASR::is_a<ASR::Const_t>(*v_m_type)) {
333+
if( is_array ) {
334+
v_m_type = ASR::down_cast<ASR::Const_t>(v_m_type)->m_type;
335+
}
336+
}
337+
if (ASRUtils::is_pointer(v_m_type)) {
338+
ASR::ttype_t *t2 = ASR::down_cast<ASR::Pointer_t>(v_m_type)->m_type;
333339
if (ASRUtils::is_integer(*t2)) {
334340
ASR::Integer_t *t = ASR::down_cast<ASR::Integer_t>(t2);
335341
std::string type_name = "int" + std::to_string(t->m_kind * 8) + "_t";
336-
if( !ASRUtils::is_array(v.m_type) ) {
342+
if( !ASRUtils::is_array(v_m_type) ) {
337343
type_name.append(" *");
338344
}
339345
if( is_array ) {
340346
bool is_fixed_size = true;
341-
std::string dims = convert_dims_c(t->n_dims, t->m_dims, v.m_type, is_fixed_size, true);
347+
std::string dims = convert_dims_c(t->n_dims, t->m_dims, v_m_type, is_fixed_size, true);
342348
std::string encoded_type_name = "i" + std::to_string(t->m_kind * 8);
343349
generate_array_decl(sub, std::string(v.m_name), type_name, dims,
344350
encoded_type_name, t->m_dims, t->n_dims,
@@ -348,14 +354,14 @@ class ASRToCVisitor : public BaseCCPPVisitor<ASRToCVisitor>
348354
v.m_intent != ASRUtils::intent_out, is_fixed_size, true);
349355
} else {
350356
bool is_fixed_size = true;
351-
std::string dims = convert_dims_c(t->n_dims, t->m_dims, v.m_type, is_fixed_size);
357+
std::string dims = convert_dims_c(t->n_dims, t->m_dims, v_m_type, is_fixed_size);
352358
sub = format_type_c(dims, type_name, v.m_name, use_ref, dummy);
353359
}
354360
} else if(ASR::is_a<ASR::Struct_t>(*t2)) {
355361
ASR::Struct_t *t = ASR::down_cast<ASR::Struct_t>(t2);
356362
std::string der_type_name = ASRUtils::symbol_name(t->m_derived_type);
357363
bool is_fixed_size = true;
358-
std::string dims = convert_dims_c(t->n_dims, t->m_dims, v.m_type, is_fixed_size);
364+
std::string dims = convert_dims_c(t->n_dims, t->m_dims, v_m_type, is_fixed_size);
359365
std::string ptr_char = "*";
360366
if( !use_ptr_for_derived_type ) {
361367
ptr_char.clear();
@@ -366,20 +372,20 @@ class ASRToCVisitor : public BaseCCPPVisitor<ASRToCVisitor>
366372
sub = format_type_c("", "void**", v.m_name, false, false);
367373
} else {
368374
diag.codegen_error_label("Type number '"
369-
+ std::to_string(v.m_type->type)
375+
+ std::to_string(v_m_type->type)
370376
+ "' not supported", {v.base.base.loc}, "");
371377
throw Abort();
372378
}
373379
} else {
374380
std::string dims;
375381
use_ref = use_ref && !is_array;
376-
if (ASRUtils::is_integer(*v.m_type)) {
382+
if (ASRUtils::is_integer(*v_m_type)) {
377383
headers.insert("inttypes");
378-
ASR::Integer_t *t = ASR::down_cast<ASR::Integer_t>(v.m_type);
384+
ASR::Integer_t *t = ASR::down_cast<ASR::Integer_t>(v_m_type);
379385
std::string type_name = "int" + std::to_string(t->m_kind * 8) + "_t";
380386
if( is_array ) {
381387
bool is_fixed_size = true;
382-
dims = convert_dims_c(t->n_dims, t->m_dims, v.m_type, is_fixed_size, true);
388+
dims = convert_dims_c(t->n_dims, t->m_dims, v_m_type, is_fixed_size, true);
383389
std::string encoded_type_name = "i" + std::to_string(t->m_kind * 8);
384390
bool is_struct_type_member = ASR::is_a<ASR::StructType_t>(
385391
*ASR::down_cast<ASR::symbol_t>(v.m_parent_symtab->asr_owner));
@@ -392,16 +398,16 @@ class ASRToCVisitor : public BaseCCPPVisitor<ASRToCVisitor>
392398
!is_struct_type_member, is_fixed_size);
393399
} else {
394400
bool is_fixed_size = true;
395-
dims = convert_dims_c(t->n_dims, t->m_dims, v.m_type, is_fixed_size);
401+
dims = convert_dims_c(t->n_dims, t->m_dims, v_m_type, is_fixed_size);
396402
sub = format_type_c(dims, type_name, v.m_name, use_ref, dummy);
397403
}
398-
} else if (ASRUtils::is_real(*v.m_type)) {
399-
ASR::Real_t *t = ASR::down_cast<ASR::Real_t>(v.m_type);
404+
} else if (ASRUtils::is_real(*v_m_type)) {
405+
ASR::Real_t *t = ASR::down_cast<ASR::Real_t>(v_m_type);
400406
std::string type_name = "float";
401407
if (t->m_kind == 8) type_name = "double";
402408
if( is_array ) {
403409
bool is_fixed_size = true;
404-
dims = convert_dims_c(t->n_dims, t->m_dims, v.m_type, is_fixed_size, true);
410+
dims = convert_dims_c(t->n_dims, t->m_dims, v_m_type, is_fixed_size, true);
405411
std::string encoded_type_name = "r" + std::to_string(t->m_kind * 8);
406412
bool is_struct_type_member = ASR::is_a<ASR::StructType_t>(
407413
*ASR::down_cast<ASR::symbol_t>(v.m_parent_symtab->asr_owner));
@@ -414,17 +420,17 @@ class ASRToCVisitor : public BaseCCPPVisitor<ASRToCVisitor>
414420
!is_struct_type_member, is_fixed_size);
415421
} else {
416422
bool is_fixed_size = true;
417-
dims = convert_dims_c(t->n_dims, t->m_dims, v.m_type, is_fixed_size);
423+
dims = convert_dims_c(t->n_dims, t->m_dims, v_m_type, is_fixed_size);
418424
sub = format_type_c(dims, type_name, v.m_name, use_ref, dummy);
419425
}
420-
} else if (ASRUtils::is_complex(*v.m_type)) {
426+
} else if (ASRUtils::is_complex(*v_m_type)) {
421427
headers.insert("complex");
422-
ASR::Complex_t *t = ASR::down_cast<ASR::Complex_t>(v.m_type);
428+
ASR::Complex_t *t = ASR::down_cast<ASR::Complex_t>(v_m_type);
423429
std::string type_name = "float complex";
424430
if (t->m_kind == 8) type_name = "double complex";
425431
if( is_array ) {
426432
bool is_fixed_size = true;
427-
dims = convert_dims_c(t->n_dims, t->m_dims, v.m_type, is_fixed_size, true);
433+
dims = convert_dims_c(t->n_dims, t->m_dims, v_m_type, is_fixed_size, true);
428434
std::string encoded_type_name = "c" + std::to_string(t->m_kind * 8);
429435
generate_array_decl(sub, std::string(v.m_name), type_name, dims,
430436
encoded_type_name, t->m_dims, t->n_dims,
@@ -434,18 +440,18 @@ class ASRToCVisitor : public BaseCCPPVisitor<ASRToCVisitor>
434440
is_fixed_size);
435441
} else {
436442
bool is_fixed_size = true;
437-
dims = convert_dims_c(t->n_dims, t->m_dims, v.m_type, is_fixed_size);
443+
dims = convert_dims_c(t->n_dims, t->m_dims, v_m_type, is_fixed_size);
438444
sub = format_type_c(dims, type_name, v.m_name, use_ref, dummy);
439445
}
440-
} else if (ASRUtils::is_logical(*v.m_type)) {
441-
ASR::Logical_t *t = ASR::down_cast<ASR::Logical_t>(v.m_type);
446+
} else if (ASRUtils::is_logical(*v_m_type)) {
447+
ASR::Logical_t *t = ASR::down_cast<ASR::Logical_t>(v_m_type);
442448
bool is_fixed_size = true;
443-
dims = convert_dims_c(t->n_dims, t->m_dims, v.m_type, is_fixed_size);
449+
dims = convert_dims_c(t->n_dims, t->m_dims, v_m_type, is_fixed_size);
444450
sub = format_type_c(dims, "bool", v.m_name, use_ref, dummy);
445-
} else if (ASRUtils::is_character(*v.m_type)) {
446-
ASR::Character_t *t = ASR::down_cast<ASR::Character_t>(v.m_type);
451+
} else if (ASRUtils::is_character(*v_m_type)) {
452+
ASR::Character_t *t = ASR::down_cast<ASR::Character_t>(v_m_type);
447453
bool is_fixed_size = true;
448-
std::string dims = convert_dims_c(t->n_dims, t->m_dims, v.m_type, is_fixed_size);
454+
std::string dims = convert_dims_c(t->n_dims, t->m_dims, v_m_type, is_fixed_size);
449455
sub = format_type_c(dims, "char *", v.m_name, use_ref, dummy);
450456
if( v.m_intent == ASRUtils::intent_local &&
451457
!(ASR::is_a<ASR::symbol_t>(*v.m_parent_symtab->asr_owner) &&
@@ -454,13 +460,13 @@ class ASRToCVisitor : public BaseCCPPVisitor<ASRToCVisitor>
454460
sub += " = (char*) malloc(40 * sizeof(char))";
455461
return sub;
456462
}
457-
} else if (ASR::is_a<ASR::Struct_t>(*v.m_type)) {
463+
} else if (ASR::is_a<ASR::Struct_t>(*v_m_type)) {
458464
std::string indent(indentation_level*indentation_spaces, ' ');
459-
ASR::Struct_t *t = ASR::down_cast<ASR::Struct_t>(v.m_type);
465+
ASR::Struct_t *t = ASR::down_cast<ASR::Struct_t>(v_m_type);
460466
std::string der_type_name = ASRUtils::symbol_name(t->m_derived_type);
461467
if( is_array ) {
462468
bool is_fixed_size = true;
463-
dims = convert_dims_c(t->n_dims, t->m_dims, v.m_type, is_fixed_size, true);
469+
dims = convert_dims_c(t->n_dims, t->m_dims, v_m_type, is_fixed_size, true);
464470
std::string encoded_type_name = "x" + der_type_name;
465471
std::string type_name = std::string("struct ") + der_type_name;
466472
generate_array_decl(sub, std::string(v.m_name), type_name, dims,
@@ -471,7 +477,7 @@ class ASRToCVisitor : public BaseCCPPVisitor<ASRToCVisitor>
471477
is_fixed_size);
472478
} else if( v.m_intent == ASRUtils::intent_local && pre_initialise_derived_type) {
473479
bool is_fixed_size = true;
474-
dims = convert_dims_c(t->n_dims, t->m_dims, v.m_type, is_fixed_size);
480+
dims = convert_dims_c(t->n_dims, t->m_dims, v_m_type, is_fixed_size);
475481
std::string value_var_name = v.m_parent_symtab->get_unique_name(std::string(v.m_name) + "_value");
476482
sub = format_type_c(dims, "struct " + der_type_name,
477483
value_var_name, use_ref, dummy);
@@ -503,7 +509,7 @@ class ASRToCVisitor : public BaseCCPPVisitor<ASRToCVisitor>
503509
return sub;
504510
} else {
505511
bool is_fixed_size = true;
506-
dims = convert_dims_c(t->n_dims, t->m_dims, v.m_type, is_fixed_size);
512+
dims = convert_dims_c(t->n_dims, t->m_dims, v_m_type, is_fixed_size);
507513
if( v.m_intent == ASRUtils::intent_in ||
508514
v.m_intent == ASRUtils::intent_inout ) {
509515
use_ref = false;
@@ -516,13 +522,13 @@ class ASRToCVisitor : public BaseCCPPVisitor<ASRToCVisitor>
516522
sub = format_type_c(dims, "struct " + der_type_name + ptr_char,
517523
v.m_name, use_ref, dummy);
518524
}
519-
} else if (ASR::is_a<ASR::Union_t>(*v.m_type)) {
525+
} else if (ASR::is_a<ASR::Union_t>(*v_m_type)) {
520526
std::string indent(indentation_level*indentation_spaces, ' ');
521-
ASR::Union_t *t = ASR::down_cast<ASR::Union_t>(v.m_type);
527+
ASR::Union_t *t = ASR::down_cast<ASR::Union_t>(v_m_type);
522528
std::string der_type_name = ASRUtils::symbol_name(t->m_union_type);
523529
if( is_array ) {
524530
bool is_fixed_size = true;
525-
dims = convert_dims_c(t->n_dims, t->m_dims, v.m_type, is_fixed_size, true);
531+
dims = convert_dims_c(t->n_dims, t->m_dims, v_m_type, is_fixed_size, true);
526532
std::string encoded_type_name = "x" + der_type_name;
527533
std::string type_name = std::string("union ") + der_type_name;
528534
generate_array_decl(sub, std::string(v.m_name), type_name, dims,
@@ -532,7 +538,7 @@ class ASRToCVisitor : public BaseCCPPVisitor<ASRToCVisitor>
532538
v.m_intent != ASRUtils::intent_inout, is_fixed_size);
533539
} else {
534540
bool is_fixed_size = true;
535-
dims = convert_dims_c(t->n_dims, t->m_dims, v.m_type, is_fixed_size);
541+
dims = convert_dims_c(t->n_dims, t->m_dims, v_m_type, is_fixed_size);
536542
if( v.m_intent == ASRUtils::intent_in ||
537543
v.m_intent == ASRUtils::intent_inout ) {
538544
use_ref = false;
@@ -541,38 +547,38 @@ class ASRToCVisitor : public BaseCCPPVisitor<ASRToCVisitor>
541547
sub = format_type_c(dims, "union " + der_type_name,
542548
v.m_name, use_ref, dummy);
543549
}
544-
} else if (ASR::is_a<ASR::List_t>(*v.m_type)) {
545-
ASR::List_t* t = ASR::down_cast<ASR::List_t>(v.m_type);
550+
} else if (ASR::is_a<ASR::List_t>(*v_m_type)) {
551+
ASR::List_t* t = ASR::down_cast<ASR::List_t>(v_m_type);
546552
std::string list_element_type = CUtils::get_c_type_from_ttype_t(t->m_type);
547553
std::string list_type_c = list_api->get_list_type(t, list_element_type);
548554
sub = format_type_c("", list_type_c, v.m_name,
549555
false, false);
550-
} else if (ASR::is_a<ASR::Tuple_t>(*v.m_type)) {
551-
ASR::Tuple_t* t = ASR::down_cast<ASR::Tuple_t>(v.m_type);
556+
} else if (ASR::is_a<ASR::Tuple_t>(*v_m_type)) {
557+
ASR::Tuple_t* t = ASR::down_cast<ASR::Tuple_t>(v_m_type);
552558
std::string tuple_type_c = tuple_api->get_tuple_type(t);
553559
sub = format_type_c("", tuple_type_c, v.m_name,
554560
false, false);
555-
} else if (ASR::is_a<ASR::CPtr_t>(*v.m_type)) {
561+
} else if (ASR::is_a<ASR::CPtr_t>(*v_m_type)) {
556562
sub = format_type_c("", "void*", v.m_name, false, false);
557-
} else if (ASR::is_a<ASR::Const_t>(*v.m_type)) {
563+
} else if (ASR::is_a<ASR::Enum_t>(*v_m_type)) {
564+
ASR::Enum_t* enum_ = ASR::down_cast<ASR::Enum_t>(v_m_type);
565+
ASR::EnumType_t* enum_type = ASR::down_cast<ASR::EnumType_t>(enum_->m_enum_type);
566+
sub = format_type_c("", "enum " + std::string(enum_type->m_name), v.m_name, false, false);
567+
} else if (ASR::is_a<ASR::Const_t>(*v_m_type)) {
558568
if( v.m_intent == ASRUtils::intent_local ) {
559569
LFORTRAN_ASSERT(v.m_symbolic_value);
560570
visit_expr(*v.m_symbolic_value);
561571
sub = "#define " + std::string(v.m_name) + " " + src + "\n";
562572
return sub;
563573
} else {
564574
std::string const_underlying_type = CUtils::get_c_type_from_ttype_t(
565-
ASR::down_cast<ASR::Const_t>(v.m_type)->m_type);
575+
ASR::down_cast<ASR::Const_t>(v_m_type)->m_type);
566576
sub = format_type_c("", "const " + const_underlying_type + " ",
567577
v.m_name, false, false);
568578
}
569-
} else if (ASR::is_a<ASR::Enum_t>(*v.m_type)) {
570-
ASR::Enum_t* enum_ = ASR::down_cast<ASR::Enum_t>(v.m_type);
571-
ASR::EnumType_t* enum_type = ASR::down_cast<ASR::EnumType_t>(enum_->m_enum_type);
572-
sub = format_type_c("", "enum " + std::string(enum_type->m_name), v.m_name, false, false);
573579
} else {
574580
diag.codegen_error_label("Type number '"
575-
+ std::to_string(v.m_type->type)
581+
+ std::to_string(v_m_type->type)
576582
+ "' not supported", {v.base.base.loc}, "");
577583
throw Abort();
578584
}

src/libasr/codegen/asr_to_llvm.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2778,7 +2778,7 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor<ASRToLLVMVisitor>
27782778
ASR::ttype_t *t2 = ASRUtils::get_contained_type(asr_type);
27792779
type = get_arg_type_from_ttype_t(t2, m_abi, arg_m_abi,
27802780
m_storage, arg_m_value_attr, n_dims, a_kind,
2781-
is_array_type, arg_intent);
2781+
is_array_type, arg_intent, get_pointer);
27822782
break;
27832783
}
27842784
case (ASR::ttypeType::Real) : {

0 commit comments

Comments
 (0)