-
Notifications
You must be signed in to change notification settings - Fork 12
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
problem with procedure pointers #393
Comments
Thanks for reporting this, I can reproduce the problem: from loki import Sourcefile
fcode = """
SUBROUTINE SPCMNEW
USE SPSI_MODNEW, ONLY : SPNSI
IMPLICIT NONE
PROCEDURE(SPNSI), POINTER :: SPNSIPTR
END SUBROUTINE SPCMNEW
"""
source = Sourcefile.from_source(fcode)
print(source.to_fortran()) This fails with an assertion in the
It works correctly if the type definition is provided to Loki, as in the following example: fcode_module = """
MODULE SPSI_MODNEW
IMPLICIT NONE
INTERFACE
SUBROUTINE SPNSI
END SUBROUTINE SPNSI
END INTERFACE
END MODULE SPSI_MODNEW
"""
fcode = "..."
module = Sourcefile.from_source(fcode_module)
source = Sourcefile.from_source(fcode, definitions=module.definitions)
print(source.to_fortran()) This produces the correct output:
The fix is to allow also deferred type information for the procedure interface, for which the following seems to suffice: diff --git a/loki/backend/fgen.py b/loki/backend/fgen.py
index 5ca129cf..090e3c3b 100644
--- a/loki/backend/fgen.py
+++ b/loki/backend/fgen.py
@@ -403,12 +403,15 @@ class FortranCodegen(Stringifier):
# TODO: We can't fully compare procedure types, yet, but we can make at least sure
# names match and other declared attributes are compatible
ignore = ['dtype', 'shape', 'dimensions', 'symbols', 'source', 'initial']
- assert all(isinstance(t.dtype, ProcedureType) for t in types)
+ assert all(isinstance(t.dtype, ProcedureType) or t.dtype == BasicType.DEFERRED for t in types)
assert all(t.compare(types[0], ignore=ignore) for t in types)
if isinstance(o.interface, DataType):
assert all(t.dtype.return_type.dtype == o.interface for t in types)
elif o.interface is not None:
- assert all(t.dtype.name == o.interface for t in types)
+ if types[0].dtype == BasicType.DEFERRED:
+ assert all(t.dtype == BasicType.DEFERRED for t in types)
+ else:
+ assert all(t.dtype.name == o.interface for t in types)
if o.external:
# This is an EXTERNAL statement (i.e., a kind of forward declaration) @npenigaud Can you please confirm that the fix works for you? Then I will file a PR with these changes later. |
Yes, the fix works for me, thanks.
Regards,
N. Penigaud
|
…nters Improve representation of procedure pointers (fix #393)
Procedure pointers are used in recent versions of the semi-implicit. However, the following leads to a bug in Loki :
spcmnew_pb.F90:
launch.py:
(SPNSI is an abstract interface for a subroutine, included in spsi_modnew.F90).
The text was updated successfully, but these errors were encountered: