Skip to content

Commit 6ebd4b8

Browse files
authored
Merge pull request #1629 from czgdp1807/var_init
Fix double initialisation of variables in ASR
2 parents 57699a9 + 095494a commit 6ebd4b8

File tree

75 files changed

+333
-130
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

75 files changed

+333
-130
lines changed

integration_tests/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -210,6 +210,7 @@ RUN(NAME array_02_decl LABELS cpython llvm c)
210210
RUN(NAME array_03_decl LABELS cpython llvm c)
211211
RUN(NAME variable_decl_01 LABELS cpython llvm c)
212212
RUN(NAME variable_decl_02 LABELS cpython llvm c)
213+
RUN(NAME variable_decl_03 LABELS cpython llvm c)
213214
RUN(NAME array_expr_01 LABELS cpython llvm c)
214215
RUN(NAME array_expr_02 LABELS cpython llvm c)
215216
RUN(NAME array_01 LABELS cpython llvm wasm c)

integration_tests/nrp/nr.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
from ltypes import i32, f64
1+
from lpython import i32, f64
22

33

44
def func(x: f64, c: f64) -> f64:

integration_tests/test_global_decl.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
1-
from lpython import i32
1+
from lpython import i32, Const
22
from numpy import empty, int32
33

44
# issue-1368
55

6-
SIZE: i32 = i32(3)
6+
SIZE: Const[i32] = i32(3)
77

88
def main() -> None:
99
xs: i32[SIZE] = empty(SIZE, dtype=int32)

integration_tests/test_package_01.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
from nrp import newton_raphson
2-
from ltypes import f64, i32
2+
from lpython import f64, i32
33

44

55
def check():

integration_tests/variable_decl_01.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
from lpython import i32, i64
1+
from lpython import i32, i64, Const
22
from numpy import empty, int64
33

44
def f(n: i32, m: i32):
5-
l: i32 = 2
5+
l: Const[i32] = 2
66
a: i64[n, m, l] = empty((n, m, l), dtype=int64)
77
i: i32; j: i32; k: i32;
88
for i in range(n):

integration_tests/variable_decl_03.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
from lpython import f64
2+
3+
def f() -> f64:
4+
return 5.5
5+
6+
def main():
7+
t1: f64 = f() * 1e6
8+
print(t1)
9+
assert abs(t1 - 5.5 * 1e6) <= 1e-6
10+
11+
main()

src/libasr/asdl_cpp.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2419,6 +2419,10 @@ def make_visitor(self, name, fields):
24192419
LCOMPILERS_ASSERT(!ASR::is_a<ASR::ExternalSymbol_t>(*e->m_external));
24202420
s = e->m_external;
24212421
}
2422+
if( ASR::down_cast<ASR::Variable_t>(s)->m_storage !=
2423+
ASR::storage_typeType::Parameter ) {
2424+
return nullptr;
2425+
}
24222426
return ASR::down_cast<ASR::Variable_t>(s)->m_value;
24232427
}""" \
24242428
% (name, name), 2, new_line=False)

src/libasr/asr_utils.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -963,8 +963,8 @@ ASR::asr_t* make_Cast_t_value(Allocator &al, const Location &a_loc,
963963
double_value, 0, a_type));
964964
} else if (a_kind == ASR::cast_kindType::IntegerToReal) {
965965
// TODO: Clashes with the pow functions
966-
// int64_t value = ASR::down_cast<ASR::ConstantInteger_t>(ASRUtils::expr_value(a_arg))->m_n;
967-
// value = ASR::down_cast<ASR::expr_t>(ASR::make_ConstantReal_t(al, a_loc, (double)v, a_type));
966+
int64_t int_value = ASR::down_cast<ASR::IntegerConstant_t>(ASRUtils::expr_value(a_arg))->m_n;
967+
value = ASR::down_cast<ASR::expr_t>(ASR::make_RealConstant_t(al, a_loc, (double)int_value, a_type));
968968
} else if (a_kind == ASR::cast_kindType::IntegerToComplex) {
969969
int64_t int_value = ASR::down_cast<ASR::IntegerConstant_t>(
970970
ASRUtils::expr_value(a_arg))->m_n;

src/libasr/asr_utils.h

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -611,6 +611,35 @@ static inline bool is_value_constant(ASR::expr_t *a_value) {
611611
// OK
612612
} else if (ASR::is_a<ASR::StringConstant_t>(*a_value)) {
613613
// OK
614+
} else if(ASR::is_a<ASR::ArrayConstant_t>(*a_value)) {
615+
// OK
616+
// TODO: Check for each value of array constant
617+
// and make sure each one is a constant.
618+
} else if(ASR::is_a<ASR::ImpliedDoLoop_t>(*a_value)) {
619+
// OK
620+
} else if(ASR::is_a<ASR::Cast_t>(*a_value)) {
621+
ASR::Cast_t* cast_t = ASR::down_cast<ASR::Cast_t>(a_value);
622+
return is_value_constant(cast_t->m_arg);
623+
} else if(ASR::is_a<ASR::PointerNullConstant_t>(*a_value)) {
624+
// OK
625+
} else if(ASR::is_a<ASR::ArrayReshape_t>(*a_value)) {
626+
ASR::ArrayReshape_t* array_reshape = ASR::down_cast<ASR::ArrayReshape_t>(a_value);
627+
return is_value_constant(array_reshape->m_array) && is_value_constant(array_reshape->m_shape);
628+
} else if( ASR::is_a<ASR::StructTypeConstructor_t>(*a_value) ) {
629+
ASR::StructTypeConstructor_t* struct_type_constructor =
630+
ASR::down_cast<ASR::StructTypeConstructor_t>(a_value);
631+
bool is_constant = true;
632+
for( size_t i = 0; i < struct_type_constructor->n_args; i++ ) {
633+
if( struct_type_constructor->m_args[i].m_value ) {
634+
is_constant = is_constant &&
635+
(is_value_constant(
636+
struct_type_constructor->m_args[i].m_value) ||
637+
is_value_constant(
638+
ASRUtils::expr_value(
639+
struct_type_constructor->m_args[i].m_value)));
640+
}
641+
}
642+
return is_constant;
614643
} else {
615644
return false;
616645
}

src/libasr/asr_verify.cpp

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -516,6 +516,24 @@ class VerifyVisitor : public BaseWalkVisitor<VerifyVisitor>
516516
"Variable::m_parent_symtab must be present in the ASR ("
517517
+ std::string(x.m_name) + ")");
518518

519+
ASR::asr_t* asr_owner = symtab->asr_owner;
520+
bool is_module = false;
521+
if( ASR::is_a<ASR::symbol_t>(*asr_owner) &&
522+
ASR::is_a<ASR::Module_t>(
523+
*ASR::down_cast<ASR::symbol_t>(asr_owner)) ) {
524+
is_module = true;
525+
}
526+
if( symtab->parent != nullptr &&
527+
!is_module) {
528+
// For now restrict this check only to variables which are present
529+
// inside symbols which have a body.
530+
require( (x.m_symbolic_value == nullptr && x.m_value == nullptr) ||
531+
(x.m_symbolic_value != nullptr && x.m_value != nullptr) ||
532+
(x.m_symbolic_value != nullptr && ASRUtils::is_value_constant(x.m_symbolic_value)),
533+
"Initialisation of " + std::string(x.m_name) +
534+
" must reduce to a compile time constant.");
535+
}
536+
519537
if (x.m_symbolic_value)
520538
visit_expr(*x.m_symbolic_value);
521539
visit_ttype(*x.m_type);

src/libasr/codegen/asr_to_llvm.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2154,7 +2154,7 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor<ASRToLLVMVisitor>
21542154
}
21552155

21562156
void visit_Variable(const ASR::Variable_t &x) {
2157-
if (x.m_value) {
2157+
if (x.m_value && x.m_storage == ASR::storage_typeType::Parameter) {
21582158
this->visit_expr_wrapper(x.m_value, true);
21592159
return;
21602160
}
@@ -5534,7 +5534,8 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor<ASRToLLVMVisitor>
55345534
}
55355535

55365536
inline void fetch_var(ASR::Variable_t* x) {
5537-
if (x->m_value) {
5537+
// Only do for constant variables
5538+
if (x->m_value && x->m_storage == ASR::storage_typeType::Parameter) {
55385539
this->visit_expr_wrapper(x->m_value, true);
55395540
return;
55405541
}

src/libasr/pass/inline_function_calls.cpp

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -294,18 +294,22 @@ class InlineFunctionCallVisitor : public PassUtils::PassVisitor<InlineFunctionCa
294294
break;
295295
}
296296
ASR::ttype_t* local_var_type = func_var->m_type;
297+
if( ASR::is_a<ASR::Const_t>(*local_var_type) ) {
298+
local_var_type = ASR::down_cast<ASR::Const_t>(local_var_type)->m_type;
299+
}
300+
LCOMPILERS_ASSERT(!ASR::is_a<ASR::Const_t>(*local_var_type));
297301
ASR::symbol_t* local_var = (ASR::symbol_t*) ASR::make_Variable_t(
298-
al, func_var->base.base.loc, current_scope,
299-
s2c(al, local_var_name), nullptr, 0, ASR::intentType::Local,
300-
nullptr, nullptr, ASR::storage_typeType::Default,
301-
local_var_type, ASR::abiType::Source, ASR::accessType::Public,
302-
ASR::presenceType::Required, false);
302+
al, func_var->base.base.loc, current_scope,
303+
s2c(al, local_var_name), nullptr, 0, ASR::intentType::Local,
304+
nullptr, nullptr, ASR::storage_typeType::Default,
305+
local_var_type, ASR::abiType::Source, ASR::accessType::Public,
306+
ASR::presenceType::Required, false);
303307
current_scope->add_symbol(local_var_name, local_var);
304308
arg2value[func_var_name] = local_var;
305-
if( m_symbolic_value && !ASR::is_a<ASR::Const_t>(*local_var_type) ) {
309+
if( m_symbolic_value ) {
306310
exprs_to_be_visited.push_back(std::make_pair(m_symbolic_value, local_var));
307311
}
308-
if( m_value && !ASR::is_a<ASR::Const_t>(*local_var_type) ) {
312+
if( m_value ) {
309313
exprs_to_be_visited.push_back(std::make_pair(m_value, local_var));
310314
}
311315
}

0 commit comments

Comments
 (0)