@@ -1376,6 +1376,20 @@ class CommonVisitor : public AST::BaseVisitor<Struct> {
1376
1376
return t;
1377
1377
}
1378
1378
1379
+ bool contains_local_variable (ASR::expr_t * value) {
1380
+ if ( ASR::is_a<ASR::Var_t>(*value) ) {
1381
+ ASR::Var_t* var_value = ASR::down_cast<ASR::Var_t>(value);
1382
+ ASR::symbol_t * var_value_sym = var_value->m_v ;
1383
+ ASR::Variable_t* var_value_variable = ASR::down_cast<ASR::Variable_t>(
1384
+ ASRUtils::symbol_get_past_external (var_value_sym));
1385
+ return var_value_variable->m_intent == ASR::intentType::Local;
1386
+ }
1387
+
1388
+ // TODO: Let any other expression pass through
1389
+ // Will be handled later
1390
+ return false ;
1391
+ }
1392
+
1379
1393
void fill_dims_for_asr_type (Vec<ASR::dimension_t >& dims,
1380
1394
ASR::expr_t * value, const Location& loc) {
1381
1395
ASR::dimension_t dim;
@@ -1388,8 +1402,13 @@ class CommonVisitor : public AST::BaseVisitor<Struct> {
1388
1402
ASR::expr_t * zero = ASRUtils::EXPR (ASR::make_IntegerConstant_t (al, loc, 0 , itype));
1389
1403
ASR::expr_t * comptime_val = nullptr ;
1390
1404
int64_t value_int = -1 ;
1391
- ASRUtils::extract_value (ASRUtils::expr_value (value), value_int);
1392
- if ( value_int != -1 ) {
1405
+ if ( !ASRUtils::extract_value (ASRUtils::expr_value (value), value_int) &&
1406
+ contains_local_variable (value) ) {
1407
+ throw SemanticError (" Only those local variables which can be reduced to compile "
1408
+ " time constant should be used in dimensions of an array." ,
1409
+ value->base .loc );
1410
+ }
1411
+ if (value_int != -1 ) {
1393
1412
comptime_val = ASRUtils::EXPR (ASR::make_IntegerConstant_t (al, loc, value_int - 1 , itype));
1394
1413
}
1395
1414
dim.m_start = zero;
@@ -2184,12 +2203,20 @@ class CommonVisitor : public AST::BaseVisitor<Struct> {
2184
2203
}
2185
2204
2186
2205
void create_add_variable_to_scope (std::string& var_name, ASR::expr_t * init_expr,
2187
- ASR::expr_t * value, ASR::ttype_t * type,
2188
- const Location& loc, ASR::abiType abi) {
2189
- if ( ASR::is_a<ASR::Const_t>(*type) && !init_expr ) {
2206
+ ASR::ttype_t * type, const Location& loc, ASR::abiType abi) {
2207
+
2208
+ ASR::expr_t * value = nullptr ;
2209
+ if ( init_expr ) {
2210
+ value = ASRUtils::expr_value (init_expr);
2211
+ }
2212
+ bool is_runtime_expression = !ASRUtils::is_value_constant (value);
2213
+ bool is_variable_const = ASR::is_a<ASR::Const_t>(*type);
2214
+
2215
+ if ( is_variable_const && !init_expr ) {
2190
2216
throw SemanticError (" Constant variable " + var_name +
2191
2217
" is not initialised at declaration." , loc);
2192
2218
}
2219
+
2193
2220
ASR::intentType s_intent = ASRUtils::intent_local;
2194
2221
ASR::storage_typeType storage_type =
2195
2222
ASR::storage_typeType::Default;
@@ -2210,24 +2237,30 @@ class CommonVisitor : public AST::BaseVisitor<Struct> {
2210
2237
current_procedure_abi_type, s_access, s_presence,
2211
2238
value_attr);
2212
2239
ASR::symbol_t * v_sym = ASR::down_cast<ASR::symbol_t >(v);
2240
+ ASR::Variable_t* v_variable = ASR::down_cast<ASR::Variable_t>(v_sym);
2213
2241
2214
- if ( init_expr && current_body) {
2242
+ if ( init_expr && current_body &&
2243
+ (is_runtime_expression || !is_variable_const)) {
2215
2244
ASR::expr_t * v_expr = ASRUtils::EXPR (ASR::make_Var_t (al, loc, v_sym));
2216
2245
cast_helper (v_expr, init_expr, true );
2217
2246
ASR::asr_t * assign = ASR::make_Assignment_t (al, loc, v_expr,
2218
2247
init_expr, nullptr );
2219
2248
current_body->push_back (al, ASRUtils::STMT (assign));
2220
- ASR::Variable_t* v_variable = ASR::down_cast<ASR::Variable_t>(v_sym);
2221
- if ( !ASR::is_a<ASR::Const_t>(*type) &&
2222
- ASRUtils::is_aggregate_type (type) ) {
2223
- v_variable->m_symbolic_value = nullptr ;
2224
- v_variable->m_value = nullptr ;
2225
- Vec<char *> variable_dependencies_vec;
2226
- variable_dependencies_vec.reserve (al, 1 );
2227
- ASRUtils::collect_variable_dependencies (al, variable_dependencies_vec, type);
2228
- v_variable->m_dependencies = variable_dependencies_vec.p ;
2229
- v_variable->n_dependencies = variable_dependencies_vec.size ();
2230
- }
2249
+
2250
+ v_variable->m_symbolic_value = nullptr ;
2251
+ v_variable->m_value = nullptr ;
2252
+ Vec<char *> variable_dependencies_vec;
2253
+ variable_dependencies_vec.reserve (al, 1 );
2254
+ ASRUtils::collect_variable_dependencies (al, variable_dependencies_vec, type);
2255
+ v_variable->m_dependencies = variable_dependencies_vec.p ;
2256
+ v_variable->n_dependencies = variable_dependencies_vec.size ();
2257
+ }
2258
+
2259
+ // Restrict this check only to symbols which have a body.
2260
+ if ( !((v_variable->m_symbolic_value == nullptr && v_variable->m_value == nullptr ) ||
2261
+ (v_variable->m_symbolic_value != nullptr && v_variable->m_value != nullptr )) &&
2262
+ current_body ) {
2263
+ throw SemanticError (" Initialisation of " + var_name + " must reduce to a compile time constant." , loc);
2231
2264
}
2232
2265
current_scope->add_symbol (var_name, v_sym);
2233
2266
}
@@ -2275,7 +2308,7 @@ class CommonVisitor : public AST::BaseVisitor<Struct> {
2275
2308
this ->visit_expr (*x.m_value );
2276
2309
}
2277
2310
if ( is_c_p_pointer_call ) {
2278
- create_add_variable_to_scope (var_name, nullptr , nullptr , type,
2311
+ create_add_variable_to_scope (var_name, nullptr , type,
2279
2312
x.base .base .loc , abi);
2280
2313
AST::Call_t* c_p_pointer_call = AST::down_cast<AST::Call_t>(x.m_value );
2281
2314
AST::expr_t * cptr = c_p_pointer_call->m_args [0 ];
@@ -2305,17 +2338,13 @@ class CommonVisitor : public AST::BaseVisitor<Struct> {
2305
2338
throw SemanticAbort ();
2306
2339
}
2307
2340
init_expr = value;
2308
- value = nullptr ;
2309
- if ( ASR::is_a<ASR::Const_t>(*type) ) {
2310
- value = ASRUtils::expr_value (init_expr);
2311
- }
2312
2341
}
2313
2342
} else {
2314
2343
cast_helper (type, init_expr, init_expr->base .loc );
2315
2344
}
2316
2345
2317
2346
if ( !is_c_p_pointer_call ) {
2318
- create_add_variable_to_scope (var_name, init_expr, value, type,
2347
+ create_add_variable_to_scope (var_name, init_expr, type,
2319
2348
x.base .base .loc , abi);
2320
2349
}
2321
2350
@@ -5685,7 +5714,7 @@ class BodyVisitor : public CommonVisitor<BodyVisitor> {
5685
5714
fn_args.push_back (al, sub);
5686
5715
} else if (attr_name == " endswith" ) {
5687
5716
/*
5688
- str.endswith(suffix) ---->
5717
+ str.endswith(suffix) ---->
5689
5718
Return True if the string ends with the specified suffix, otherwise return False.
5690
5719
5691
5720
arg_sub: Substring argument provided inside endswith() function
@@ -5907,8 +5936,8 @@ class BodyVisitor : public CommonVisitor<BodyVisitor> {
5907
5936
}
5908
5937
return ;
5909
5938
} else if (attr_name == " endswith" ) {
5910
- /*
5911
- str.endswith(suffix) ---->
5939
+ /*
5940
+ str.endswith(suffix) ---->
5912
5941
Return True if the string ends with the specified suffix, otherwise return False.
5913
5942
*/
5914
5943
@@ -5921,23 +5950,23 @@ class BodyVisitor : public CommonVisitor<BodyVisitor> {
5921
5950
if (!ASRUtils::is_character (*arg_suffix_type)) {
5922
5951
throw SemanticError (" str.endswith() takes one arguments of type: str" , arg_suffix->base .loc );
5923
5952
}
5924
-
5953
+
5925
5954
if (ASRUtils::expr_value (arg_suffix) != nullptr ) {
5926
5955
/*
5927
5956
Invoked when Suffix argument is provided as a constant string
5928
5957
*/
5929
5958
ASR::StringConstant_t* suffix_constant = ASR::down_cast<ASR::StringConstant_t>(arg_suffix);
5930
5959
std::string suffix = suffix_constant->m_s ;
5931
-
5960
+
5932
5961
bool res = true ;
5933
- if (suffix.size () > s_var.size ())
5962
+ if (suffix.size () > s_var.size ())
5934
5963
res = false ;
5935
- else
5964
+ else
5936
5965
res = std::equal (suffix.rbegin (), suffix.rend (), s_var.rbegin ());
5937
-
5938
- tmp = ASR::make_LogicalConstant_t (al, loc, res,
5966
+
5967
+ tmp = ASR::make_LogicalConstant_t (al, loc, res,
5939
5968
ASRUtils::TYPE (ASR::make_Logical_t (al, loc, 4 , nullptr , 0 )));
5940
-
5969
+
5941
5970
} else {
5942
5971
/*
5943
5972
Invoked when Suffix argument is provided as a variable
0 commit comments