From 75497b780090656fdbf4c1dc49204497f03a5b2e Mon Sep 17 00:00:00 2001 From: Pranavchiku Date: Sun, 28 Jul 2024 23:22:31 +0530 Subject: [PATCH 1/2] enh: declare a global save variable and throw warning only when it is not enabled --- src/lfortran/semantics/ast_common_visitor.h | 34 ++++++++++++++++--- .../semantics/ast_symboltable_visitor.cpp | 11 ++++++ 2 files changed, 40 insertions(+), 5 deletions(-) diff --git a/src/lfortran/semantics/ast_common_visitor.h b/src/lfortran/semantics/ast_common_visitor.h index 90a6992e66..f21b17d887 100644 --- a/src/lfortran/semantics/ast_common_visitor.h +++ b/src/lfortran/semantics/ast_common_visitor.h @@ -1021,6 +1021,9 @@ class CommonVisitor : public AST::BaseVisitor { std::map> &instantiate_symbols; std::vector &data_structure; + // global save variable + bool is_global_save_enabled = false; + // implied do loop nesting int idl_nesting_level = 0; @@ -1999,6 +2002,25 @@ class CommonVisitor : public AST::BaseVisitor { } } + + template + void check_if_global_save_is_enabled(T &x) { + for ( size_t i = 0; i < x.n_decl; i++ ) { + if ( AST::is_a(*x.m_decl[i]) ) { + AST::Declaration_t* decl = AST::down_cast(x.m_decl[i]); + if ( decl->n_attributes > 0 && decl->n_syms == 0 && + decl->m_trivia == nullptr && + AST::is_a(*decl->m_attributes[0]) ) { + AST::SimpleAttribute_t* attr = AST::down_cast(decl->m_attributes[0]); + if ( attr->m_attr == AST::simple_attributeType::AttrSave ) { + is_global_save_enabled = true; + break; + } + } + } + } + } + void create_external_function(std::string sym, Location loc, ASR::ttype_t* determined_type = nullptr) { if (compiler_options.implicit_interface) { bool is_subroutine = false; @@ -3205,11 +3227,13 @@ class CommonVisitor : public AST::BaseVisitor { } if (is_Function && implicit_save && !is_save) { // throw warning to that particular variable - diag.semantic_warning_label( - "Assuming implicit save attribute for variable declaration", - {x.m_syms[i].loc}, - "help: add explicit save attribute or parameter attribute or initialize in a separate statement" - ); + if ( !is_global_save_enabled ) { + diag.semantic_warning_label( + "Assuming implicit save attribute for variable declaration", + {x.m_syms[i].loc}, + "help: add explicit save attribute or parameter attribute or initialize in a separate statement" + ); + } } if( std::find(excluded_from_symtab.begin(), excluded_from_symtab.end(), sym) == excluded_from_symtab.end() ) { if ( !is_implicitly_declared && !is_external) { diff --git a/src/lfortran/semantics/ast_symboltable_visitor.cpp b/src/lfortran/semantics/ast_symboltable_visitor.cpp index 87377f970f..0dd6594680 100644 --- a/src/lfortran/semantics/ast_symboltable_visitor.cpp +++ b/src/lfortran/semantics/ast_symboltable_visitor.cpp @@ -514,6 +514,8 @@ class SymbolTableVisitor : public CommonVisitor { } } simd_variables.clear(); + bool is_global_save_enabled_copy = is_global_save_enabled; + check_if_global_save_is_enabled( x ); for (size_t i=0; i { fix_type_info(ASR::down_cast2(tmp)); mark_common_blocks_as_declared(); + is_global_save_enabled = is_global_save_enabled_copy; } bool subroutine_contains_entry_function(std::string subroutine_name, AST::stmt_t** body, size_t n_body) { @@ -939,6 +942,9 @@ class SymbolTableVisitor : public CommonVisitor { char *bindc_name=nullptr; extract_bind(x, current_procedure_abi_type, bindc_name); + // iterate over declarations and check if global save is present + bool is_global_save_enabled_copy = is_global_save_enabled; + check_if_global_save_is_enabled( x ); for (size_t i=0; i { in_Subroutine = false; is_template = false; mark_common_blocks_as_declared(); + is_global_save_enabled = is_global_save_enabled_copy; } AST::AttrType_t* find_return_type(AST::decl_attribute_t** attributes, @@ -1268,6 +1275,9 @@ class SymbolTableVisitor : public CommonVisitor { char *bindc_name=nullptr; extract_bind(x, current_procedure_abi_type, bindc_name); + // iterate over declarations and check if global save is present + bool is_global_save_enabled_copy = is_global_save_enabled; + check_if_global_save_is_enabled( x ); for (size_t i=0; i { current_function_dependencies = current_function_dependencies_copy; in_Subroutine = false; mark_common_blocks_as_declared(); + is_global_save_enabled = is_global_save_enabled_copy; } void visit_Declaration(const AST::Declaration_t& x) { From 69fbb09681a0b4820e5673cc4c9623dd5798eb65 Mon Sep 17 00:00:00 2001 From: Pranavchiku Date: Sun, 28 Jul 2024 23:24:18 +0530 Subject: [PATCH 2/2] test: add register and update references --- tests/reference/asr-save3-025da43.json | 13 ++++++ tests/reference/asr-save3-025da43.stdout | 59 ++++++++++++++++++++++++ tests/save3.f90 | 4 ++ tests/tests.toml | 6 ++- 4 files changed, 81 insertions(+), 1 deletion(-) create mode 100644 tests/reference/asr-save3-025da43.json create mode 100644 tests/reference/asr-save3-025da43.stdout create mode 100644 tests/save3.f90 diff --git a/tests/reference/asr-save3-025da43.json b/tests/reference/asr-save3-025da43.json new file mode 100644 index 0000000000..88d9b01e87 --- /dev/null +++ b/tests/reference/asr-save3-025da43.json @@ -0,0 +1,13 @@ +{ + "basename": "asr-save3-025da43", + "cmd": "lfortran --show-asr --no-color {infile} -o {outfile}", + "infile": "tests/save3.f90", + "infile_hash": "73a25f7c7513eff87c70b3f4e4d291178ff58078c3f57c81f356d77f", + "outfile": null, + "outfile_hash": null, + "stdout": "asr-save3-025da43.stdout", + "stdout_hash": "7b1b85844dc907929fc93c75f7d95194967a2bd2c7fbb458fb2fbac4", + "stderr": null, + "stderr_hash": null, + "returncode": 0 +} \ No newline at end of file diff --git a/tests/reference/asr-save3-025da43.stdout b/tests/reference/asr-save3-025da43.stdout new file mode 100644 index 0000000000..1afa7a32ab --- /dev/null +++ b/tests/reference/asr-save3-025da43.stdout @@ -0,0 +1,59 @@ +(TranslationUnit + (SymbolTable + 1 + { + f: + (Function + (SymbolTable + 2 + { + var: + (Variable + 2 + var + [] + Local + (RealConstant + 0.000000 + (Real 4) + ) + (RealConstant + 0.000000 + (Real 4) + ) + Save + (Real 4) + () + Source + Public + Required + .false. + ) + }) + f + (FunctionType + [] + () + Source + Implementation + () + .false. + .false. + .false. + .false. + .false. + [] + .false. + ) + [] + [] + [] + () + Public + .false. + .false. + () + ) + }) + [] +) diff --git a/tests/save3.f90 b/tests/save3.f90 new file mode 100644 index 0000000000..9a50a17b1e --- /dev/null +++ b/tests/save3.f90 @@ -0,0 +1,4 @@ +subroutine f() +real :: var = 0.0 +save +end subroutine diff --git a/tests/tests.toml b/tests/tests.toml index 4310298bc1..cefb29f14f 100644 --- a/tests/tests.toml +++ b/tests/tests.toml @@ -3403,6 +3403,10 @@ asr = true filename = "save2.f90" asr = true +[[test]] +filename = "save3.f90" +asr = true + [[test]] filename = "../integration_tests/c_ptr_02.f90" asr = true @@ -4072,4 +4076,4 @@ asr = true [[test]] filename = "errors/intrinsics11.f90" -asr = true \ No newline at end of file +asr = true