This is an archive of the discontinued LLVM Phabricator instance.

[flang] Support check for BIND statement entity
ClosedPublic

Authored by peixin on Jun 6 2022, 8:45 AM.

Details

Summary

As Fortran 2018 8.6.4(1), the BIND statement specifies the BIND attribute
for a list of variables and common blocks.

Diff Detail

Event Timeline

peixin created this revision.Jun 6 2022, 8:45 AM
Herald added a project: Restricted Project. · View Herald Transcript
Herald added a subscriber: jdoerfert. · View Herald Transcript
peixin requested review of this revision.Jun 6 2022, 8:45 AM
klausler added inline comments.Jun 6 2022, 12:32 PM
flang/lib/Semantics/resolve-names.cpp
3890

What happens if this symbol turns out later to be a procedure?

I think this sort of check should be done later in check-declarations, after name resolution has been done as the symbol table is complete.

peixin added inline comments.Jun 6 2022, 6:20 PM
flang/lib/Semantics/resolve-names.cpp
3890

What happens if this symbol turns out later to be a procedure?

This works for this case. Check the following case (modfile16.f90 in this patch):

real :: d
external :: d
bind(c, name='dd') :: d
real :: e
bind(c, name='ee') :: e
external :: e
bind(c, name='ff') :: f
real :: f
external :: f

You will get errors for d, e, and f. The reason is that it walks the parse-tree for DeclTypeSpecVisitor before parser::BindEntity. (https://github.com/llvm/llvm-project/blob/576b8245c838e822f709d8450f537c7909d45411/flang/lib/Semantics/resolve-names.cpp#L132-L144) For procedures, the symbol has EntityDetails, but GetType is empty.

I think this sort of check should be done later in check-declarations, after name resolution has been done as the symbol table is complete.

I tried to look at check-declarations, but I didn't figure out how to do it there since it is unknown if the BIND(C) attribute for procedure is from bind statement or procedure declaration statement. Let me dig some more again to see if it can be done in check-declarations.

peixin added inline comments.Jun 8 2022, 7:37 PM
flang/lib/Semantics/resolve-names.cpp
3890

@klausler It seems that this must be done here.

  1. The derived type and module subroutine in bind statement will get fatal internal error: bind name not allowed on this kind of symbol in SetBindNameOn. (Check bind(c) :: sub and bind(c) :: my_type in the following test case bind-c02.f90).
  1. It is unknown if the BIND(C) attribute for procedure is from bind statement or procedure declaration statement.

Will this error be incorrectly triggered if a BIND(C) :: x declaration appears before any other declaration for a variable or COMMON block 'x'? What if a BIND(C) :: j declaration appears as the only declaration for an implicitly-typed variable "j"?

peixin updated this revision to Diff 437506.Jun 16 2022, 4:54 AM

Will this error be incorrectly triggered if a BIND(C) :: x declaration appears before any other declaration for a variable or COMMON block 'x'? What if a BIND(C) :: j declaration appears as the only declaration for an implicitly-typed variable "j"?

Thanks for this. The previous fix is not correct for this. It should not check if there is the type for the entity. The bind statement is one declaration statement, so it is actually declaring one new entity. The real error is multiple declaration of one name. This is consistent with the errors in ifort.

klausler added inline comments.Jun 21 2022, 9:05 AM
flang/lib/Semantics/check-declarations.cpp
1887 ↗(On Diff #437506)

First, you can compare symbol names without converting them to strings. But I don't see why this test is needed here in BIND(C) checking in the first place; it does not seem to be specific to BIND(C). If a check like this is needed, wouldn't it be necessary for non-BIND(C) symbols as well?

peixin updated this revision to Diff 438893.Jun 21 2022, 7:42 PM

Remove the unnecessary check.

peixin added inline comments.Jun 21 2022, 7:45 PM
flang/lib/Semantics/check-declarations.cpp
1887 ↗(On Diff #437506)

I take a look at non-bind(C) symbols, and find out that LLVM Flang can support this. Check the following case:

module m
  integer :: m
end

LLVM Flang codegen supports this since the name mangling makes the module name and variable name unique. gfortran and ifort do not support this.

For BIND(C) symbols, it's the same issue. So, there is no necessary for the previous check.

klausler accepted this revision.Jun 28 2022, 8:47 AM
klausler added inline comments.
flang/lib/Semantics/resolve-names.cpp
3889

"named" constant

This revision is now accepted and ready to land.Jun 28 2022, 8:47 AM
peixin updated this revision to Diff 440823.Jun 28 2022, 7:02 PM

Fix the typo.

This revision was automatically updated to reflect the committed changes.