Skip to content
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

EXTERNAL (procedures) possibly trigger assertion in fgen backend #57

Closed
MichaelSt98 opened this issue Mar 31, 2023 · 0 comments · Fixed by #404
Closed

EXTERNAL (procedures) possibly trigger assertion in fgen backend #57

MichaelSt98 opened this issue Mar 31, 2023 · 0 comments · Fixed by #404
Labels
bug Something isn't working

Comments

@MichaelSt98
Copy link
Collaborator

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)
@MichaelSt98 MichaelSt98 added the bug Something isn't working label Mar 31, 2023
reuterbal added a commit that referenced this issue Oct 17, 2024
…y-trigger-assertion-in-fgen-backend

Remove duplicate declarations for external statements (fix #57)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant