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. diff --git a/src/psyclone/psyir/frontend/fparser2.py b/src/psyclone/psyir/frontend/fparser2.py index a7d2123cab..64aa7e8123 100644 --- a/src/psyclone/psyir/frontend/fparser2.py +++ b/src/psyclone/psyir/frontend/fparser2.py @@ -5717,7 +5717,13 @@ 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]) + # 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 # 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..819cf236d0 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,66 @@ 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 test_mod +CONTAINS +! Here is a comment + 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) + 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: + ! - PSyclone doesn't yet support 'Contains' inside a Subroutine or Function + ! Here is a comment + SUBROUTINE test + CONTAINS + SUBROUTINE subsub + END SUBROUTINE + END SUBROUTINE test""" in out + + +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""" + + 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: + ! - 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