EXTERNAL (procedures) possibly trigger assertion in fgen backend
MichaelSt98 opened this issue · comments
Michael Staneker commented
e.g., bug.F90
SUBROUTINE DRIVER
real :: x
external x
END SUBROUTINE DRIVER
executing loki-transform.py convert -m idem --frontend fp --path bug --config bug/config.config -out out
with config file
[default]
mode = "idem"
role = "kernel"
[[routine]]
name = "driver"
role = "driver"
triggers assertion in the backend:
File "loki/loki/backend/fgen.py", line 411, in visit_ProcedureDeclaration
assert all(t.dtype.is_function for t in types) or all(not t.dtype.is_function for t in types)
File "loki/loki/backend/fgen.py", line 411, in <genexpr>
assert all(t.dtype.is_function for t in types) or all(not t.dtype.is_function for t in types)
changing
--- a/loki/backend/fgen.py
+++ b/loki/backend/fgen.py
@@ -398,14 +398,14 @@ 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) 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 o.external:
+ if o.external and not isinstance(types[0].dtype, BasicType):
# This is an EXTERNAL statement (i.e., a kind of forward declaration)
assert o.interface is None
assert all(t.dtype.is_function for t in types) or all(not t.dtype.is_function for t in types)
allows for successful transformation.
However, the generated output is not valid:
SUBROUTINE DRIVER ()
REAL, EXTERNAL :: x
PROCEDURE, REAL, EXTERNAL :: x
END SUBROUTINE DRIVER
as gfortran -c ...
gives
3 | PROCEDURE, REAL, EXTERNAL :: x
| 1
Error: Unclassifiable statement at (1)