From 24cef1fb1b98bf8205eb7b29f1ff95e7fef2d39e Mon Sep 17 00:00:00 2001 From: LonelyCat124 <3043914+LonelyCat124@users.noreply.github.com.> Date: Wed, 22 Apr 2026 10:41:31 +0100 Subject: [PATCH 1/4] Fixes #3406 --- setup.py | 2 +- src/psyclone/psyir/frontend/fparser2.py | 11 ++++++- .../fparser2_subroutine_handler_test.py | 30 +++++++++++++++++++ 3 files changed, 41 insertions(+), 2 deletions(-) diff --git a/setup.py b/setup.py index 80b0d34604..03b6e8c944 100644 --- a/setup.py +++ b/setup.py @@ -171,7 +171,7 @@ def get_files(directory, install_path, valid_suffixes): classifiers=CLASSIFIERS, packages=PACKAGES, package_dir={"": "src"}, - install_requires=['pyparsing', 'fparser==0.2.2', 'configparser', + install_requires=['pyparsing', 'fparser>=0.2.2', 'configparser', 'sympy', "Jinja2", 'termcolor', 'graphviz'], # Have to pin Sphinx to a pre-9.0 version because of # https://github.com/sphinx-doc/sphinx/issues/14223 diff --git a/src/psyclone/psyir/frontend/fparser2.py b/src/psyclone/psyir/frontend/fparser2.py index a7d2123cab..4b96214516 100644 --- a/src/psyclone/psyir/frontend/fparser2.py +++ b/src/psyclone/psyir/frontend/fparser2.py @@ -5717,7 +5717,16 @@ def _subroutine_handler(self, node, parent): try: x = _first_type_match(node.children, Fortran2003.Internal_Subprogram_Part) - name = str(x.parent.children[0].children[1]) + subroutine_stmt = None + for child in x.parent.children: + if isinstance(child, Fortran2003.Subroutine_Stmt): + subroutine_stmt = child + break + # Backup branch to maintain old functionality for edge cases + # and test suite. + if not subroutine_stmt: + subroutine_stmt = x.parent.children[0] + name = str(subroutine_stmt.children[1]) # If we will make a CodeBlock to represent this subroutine then # we still need to ensure the symbol is in the parent's symbol # table. For this case the best we can do is place the symbol diff --git a/src/psyclone/tests/psyir/frontend/fparser2_subroutine_handler_test.py b/src/psyclone/tests/psyir/frontend/fparser2_subroutine_handler_test.py index ddb5a971ac..c08f96316a 100644 --- a/src/psyclone/tests/psyir/frontend/fparser2_subroutine_handler_test.py +++ b/src/psyclone/tests/psyir/frontend/fparser2_subroutine_handler_test.py @@ -46,6 +46,7 @@ from psyclone.errors import InternalError from psyclone.psyir.frontend.fparser2 import ( Fparser2Reader, TYPE_MAP_FROM_FORTRAN) +from psyclone.psyir.frontend.fortran import FortranReader from psyclone.psyir.nodes import Container, Routine, CodeBlock, FileContainer from psyclone.psyir.symbols import ( DataSymbol, UnresolvedType, NoType, RoutineSymbol, ScalarType, @@ -622,3 +623,32 @@ def test_module_contains_subroutine_contains_subroutine( psyir.children[0].symbol_table.lookup("s") out = fortran_writer(psyir) assert "subroutine func_a" not in out + + +def test_module_contains_comment_before_subroutine( + fortran_writer +): + '''Test to check that subroutines contained in a module are + correctly handled when there are comments before the subroutine + statement after the contains.''' + code = """MODULE tsltde +CONTAINS +! Here is a comment + SUBROUTINE tsl_tde_osc() + END SUBROUTINE tsl_tde_osc +END MODULE tsltde""" + fortran_reader = FortranReader(ignore_comments=False) + psyir = fortran_reader.psyir_from_source(code) + out = fortran_writer(psyir) + assert """module tsltde + implicit none + public + + contains + ! Here is a comment + subroutine tsl_tde_osc() + + + end subroutine tsl_tde_osc + +end module tsltde""" in out From fe61f5c1f1895bcd0ca52ec13661f4b8c999d534 Mon Sep 17 00:00:00 2001 From: LonelyCat124 <3043914+LonelyCat124@users.noreply.github.com.> Date: Wed, 22 Apr 2026 13:20:51 +0100 Subject: [PATCH 2/4] Changes after review to cover functiosn properly and ensure we're testing the correct behaviour --- src/psyclone/psyir/frontend/fparser2.py | 15 +++--- .../fparser2_subroutine_handler_test.py | 54 ++++++++++++++----- 2 files changed, 48 insertions(+), 21 deletions(-) diff --git a/src/psyclone/psyir/frontend/fparser2.py b/src/psyclone/psyir/frontend/fparser2.py index 4b96214516..64aa7e8123 100644 --- a/src/psyclone/psyir/frontend/fparser2.py +++ b/src/psyclone/psyir/frontend/fparser2.py @@ -5717,15 +5717,12 @@ def _subroutine_handler(self, node, parent): try: x = _first_type_match(node.children, Fortran2003.Internal_Subprogram_Part) - subroutine_stmt = None - for child in x.parent.children: - if isinstance(child, Fortran2003.Subroutine_Stmt): - subroutine_stmt = child - break - # Backup branch to maintain old functionality for edge cases - # and test suite. - if not subroutine_stmt: - subroutine_stmt = x.parent.children[0] + # Find the Subroutine_Stmt or Function_Stmt to find the Name + # from. + subroutine_stmt = _first_type_match( + x.parent.children, + (Fortran2003.Subroutine_Stmt, Fortran2003.Function_Stmt) + ) name = str(subroutine_stmt.children[1]) # If we will make a CodeBlock to represent this subroutine then # we still need to ensure the symbol is in the parent's symbol diff --git a/src/psyclone/tests/psyir/frontend/fparser2_subroutine_handler_test.py b/src/psyclone/tests/psyir/frontend/fparser2_subroutine_handler_test.py index c08f96316a..a465952149 100644 --- a/src/psyclone/tests/psyir/frontend/fparser2_subroutine_handler_test.py +++ b/src/psyclone/tests/psyir/frontend/fparser2_subroutine_handler_test.py @@ -631,24 +631,54 @@ def test_module_contains_comment_before_subroutine( '''Test to check that subroutines contained in a module are correctly handled when there are comments before the subroutine statement after the contains.''' - code = """MODULE tsltde + code = """MODULE test_mod CONTAINS ! Here is a comment - SUBROUTINE tsl_tde_osc() - END SUBROUTINE tsl_tde_osc -END MODULE tsltde""" + SUBROUTINE test() + contains + Subroutine subsub() + end subroutine + END SUBROUTINE test +END MODULE test_mod""" fortran_reader = FortranReader(ignore_comments=False) psyir = fortran_reader.psyir_from_source(code) out = fortran_writer(psyir) - assert """module tsltde - implicit none - public - - contains + assert """ contains + ! PSyclone CodeBlock (unsupported code) reason: + ! - PSyclone doesn't yet support 'Contains' inside a Subroutine or Function ! Here is a comment - subroutine tsl_tde_osc() + SUBROUTINE test + CONTAINS + SUBROUTINE subsub + END SUBROUTINE + END SUBROUTINE test""" in out - end subroutine tsl_tde_osc +def test_module_contains_comment_before_function( + fortran_writer +): + '''Test to check that functions contained in a module are + correctly handled when there are comments before the function + statement after the contains.''' + code = """MODULE test_mod +CONTAINS +! Here is a comment + FUNCTION test() + contains + function subsub() + end function + END FUNCTION test +END MODULE test_mod""" -end module tsltde""" in out + fortran_reader = FortranReader(ignore_comments=False) + psyir = fortran_reader.psyir_from_source(code) + out = fortran_writer(psyir) + assert """ contains + ! PSyclone CodeBlock (unsupported code) reason: + ! - PSyclone doesn't yet support 'Contains' inside a Subroutine or Function + ! Here is a comment + FUNCTION test() + CONTAINS + FUNCTION subsub() + END FUNCTION + END FUNCTION test""" in out From 9c989396088b7a3348d4e4ff44b4e4a5e4587657 Mon Sep 17 00:00:00 2001 From: LonelyCat124 <3043914+LonelyCat124@users.noreply.github.com.> Date: Wed, 22 Apr 2026 15:16:34 +0100 Subject: [PATCH 3/4] Fixes for review --- setup.py | 2 +- .../tests/psyir/frontend/fparser2_subroutine_handler_test.py | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/setup.py b/setup.py index 03b6e8c944..80b0d34604 100644 --- a/setup.py +++ b/setup.py @@ -171,7 +171,7 @@ def get_files(directory, install_path, valid_suffixes): classifiers=CLASSIFIERS, packages=PACKAGES, package_dir={"": "src"}, - install_requires=['pyparsing', 'fparser>=0.2.2', 'configparser', + install_requires=['pyparsing', 'fparser==0.2.2', 'configparser', 'sympy', "Jinja2", 'termcolor', 'graphviz'], # Have to pin Sphinx to a pre-9.0 version because of # https://github.com/sphinx-doc/sphinx/issues/14223 diff --git a/src/psyclone/tests/psyir/frontend/fparser2_subroutine_handler_test.py b/src/psyclone/tests/psyir/frontend/fparser2_subroutine_handler_test.py index a465952149..819cf236d0 100644 --- a/src/psyclone/tests/psyir/frontend/fparser2_subroutine_handler_test.py +++ b/src/psyclone/tests/psyir/frontend/fparser2_subroutine_handler_test.py @@ -642,6 +642,8 @@ def test_module_contains_comment_before_subroutine( END MODULE test_mod""" fortran_reader = FortranReader(ignore_comments=False) psyir = fortran_reader.psyir_from_source(code) + assert "test" in psyir.children[0].symbol_table + assert "subsub" not in psyir.children[0].symbol_table out = fortran_writer(psyir) assert """ contains ! PSyclone CodeBlock (unsupported code) reason: @@ -672,6 +674,8 @@ def test_module_contains_comment_before_function( fortran_reader = FortranReader(ignore_comments=False) psyir = fortran_reader.psyir_from_source(code) + assert "test" in psyir.children[0].symbol_table + assert "subsub" not in psyir.children[0].symbol_table out = fortran_writer(psyir) assert """ contains ! PSyclone CodeBlock (unsupported code) reason: From 6a8fad8b2e660192d05bfdd90ef0588987b044f4 Mon Sep 17 00:00:00 2001 From: Sergi Siso Date: Thu, 23 Apr 2026 09:40:15 +0100 Subject: [PATCH 4/4] #3406 Update changelog --- changelog | 3 +++ 1 file changed, 3 insertions(+) diff --git a/changelog b/changelog index f6483e56d1..ec878bfe0f 100644 --- a/changelog +++ b/changelog @@ -1,3 +1,6 @@ + 9) PR #3406 for # 3406. Fix issue with comment before a subroutine that + turns into a CodeBlock. + 8) PR #3371 towards #3012. Add workaround to bypass psyclonefc fixed-from issues.