Skip to content

[Flang] About using names with multiple declarations (intrinsic statement, interface block, derived type) in a program #138807

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

Closed
ohno-fj opened this issue May 7, 2025 · 3 comments · Fixed by #139169
Assignees

Comments

@ohno-fj
Copy link

ohno-fj commented May 7, 2025

Version of flang : 20.0.0(842e5915778a820c63cf38b75bec932a6ea8c18b)/AArch64

In the attached program, this program has three declarations using name (int):

  • intrinsic statement
    intrinsic-procedure-name-list is defined as intrinsic function (int).
  • generic-spec of interface block
    external procedure (ifunc01) is defined as generic specification (int).
  • derived-type definition
    type-name is defined as a derived type (int).

Is this confusing usage incorrect?
I checked Fortran standard 2023 and could not see if this program is incorrect.
Currently, Flang and Gfortran seem to recognize that intrinsic statement is valid and name (int) is an int intrinsic function.

The following are the test program, Flang, Gfortran and ifx compilation/execution result.

snf_fsstc_19_23.f90:

program main
  intrinsic :: int
  interface int
     function ifunc01(if01_arg01, if01_arg02) result(irst01)
       integer :: if01_arg01
       integer :: if01_arg02
       integer :: irst01
     end function ifunc01
  end interface int
  type int
     real :: ti1_r01
  end type int
  type (int) ::aaa
  aaa=int(1)
!  if (aaa%ti1_r01.ne.1) print *,'err'
!  if (int(2,1).ne.2) print *,'err'
  print *,'pass'
end program main

function ifunc01(if01_arg01, if01_arg02) result(irst01)
  integer :: if01_arg01
  integer :: if01_arg02
  integer :: irst01
  irst01 = int(if01_arg01) + int(if01_arg02)
end function ifunc01
$ flang snf_fsstc_19_23.f90
error: Semantic errors in snf_fsstc_19_23.f90
./snf_fsstc_19_23.f90:14:3: error: No intrinsic or user-defined ASSIGNMENT(=) matches operand types TYPE(int) and INTEGER(4)
    aaa=int(1)
    ^^^^^^^^^^
$
$ gfortran snf_fsstc_19_23.f90
snf_fsstc_19_23.f90:14:6:

   14 |   aaa=int(1)
      |      1
Error: Cannot convert INTEGER(4) to TYPE(int) at (1)
$
$ ifx snf_fsstc_19_23.f90; ./a.out
 pass
$
@llvmbot
Copy link
Member

llvmbot commented May 7, 2025

@llvm/issue-subscribers-flang-frontend

Author: None (ohno-fj)

``` Version of flang : 20.0.0(842e591)/AArch64 ```

In the attached program, this program has three declarations using name (int):

  • intrinsic statement
    intrinsic-procedure-name-list is defined as intrinsic function (int).
  • generic-spec of interface block
    external procedure (ifunc01) is defined as generic specification (int).
  • derived-type definition
    type-name is defined as a derived type (int).

Is this confusing usage incorrect?
I checked Fortran standard 2023 and could not see if this program is incorrect.
Currently, Flang and Gfortran seem to recognize that intrinsic statement is valid and name (int) is an int intrinsic function.

The following are the test program, Flang, Gfortran and ifx compilation/execution result.

snf_fsstc_19_23.f90:

program main
  intrinsic :: int
  interface int
     function ifunc01(if01_arg01, if01_arg02) result(irst01)
       integer :: if01_arg01
       integer :: if01_arg02
       integer :: irst01
     end function ifunc01
  end interface int
  type int
     real :: ti1_r01
  end type int
  type (int) ::aaa
  aaa=int(1)
!  if (aaa%ti1_r01.ne.1) print *,'err'
!  if (int(2,1).ne.2) print *,'err'
  print *,'pass'
end program main

function ifunc01(if01_arg01, if01_arg02) result(irst01)
  integer :: if01_arg01
  integer :: if01_arg02
  integer :: irst01
  irst01 = int(if01_arg01) + int(if01_arg02)
end function ifunc01
$ flang snf_fsstc_19_23.f90
error: Semantic errors in snf_fsstc_19_23.f90
./snf_fsstc_19_23.f90:14:3: error: No intrinsic or user-defined ASSIGNMENT(=) matches operand types TYPE(int) and INTEGER(4)
    aaa=int(1)
    ^^^^^^^^^^
$
$ gfortran snf_fsstc_19_23.f90
snf_fsstc_19_23.f90:14:6:

   14 |   aaa=int(1)
      |      1
Error: Cannot convert INTEGER(4) to TYPE(int) at (1)
$
$ ifx snf_fsstc_19_23.f90; ./a.out
 pass
$

@klausler
Copy link
Contributor

klausler commented May 7, 2025

The program is in error, and the compiler should catch it. F'2023 C7108 "(R756) If derived-type-spec is a type name that is the same as a generic name, the component-spec-list shall not be a valid actual-arg-spec-list for a function reference that is resolvable as a generic reference to that name (15.5.5.2)."

@klausler klausler self-assigned this May 7, 2025
klausler added a commit to klausler/llvm-project that referenced this issue May 8, 2025
Fortran 2023 constraint C7108 prohibits the use of a structure
constructor in a way that is ambiguous with a generic function
reference (intrinsic or user-defined).  Sadly, no Fortran
compiler implements this constraint, and the common portable
interpretation seems to be the generic resolution, not the
structure constructor.

Restructure the processing of structure constructors in expression
analysis so that it can be driven both from the parse tree as well
as from generic resolution, and then use it to detect ambigous
structure constructor / generic function cases, so that a portability
warning can be issued.  And document this as a new intentional
violation of the standard in Extensions.md.

Fixes llvm#138807.
klausler added a commit to klausler/llvm-project that referenced this issue May 9, 2025
Fortran 2023 constraint C7108 prohibits the use of a structure
constructor in a way that is ambiguous with a generic function
reference (intrinsic or user-defined).  Sadly, no Fortran
compiler implements this constraint, and the common portable
interpretation seems to be the generic resolution, not the
structure constructor.

Restructure the processing of structure constructors in expression
analysis so that it can be driven both from the parse tree as well
as from generic resolution, and then use it to detect ambigous
structure constructor / generic function cases, so that a portability
warning can be issued.  And document this as a new intentional
violation of the standard in Extensions.md.

Fixes llvm#138807.
klausler added a commit to klausler/llvm-project that referenced this issue May 10, 2025
Fortran 2023 constraint C7108 prohibits the use of a structure
constructor in a way that is ambiguous with a generic function
reference (intrinsic or user-defined).  Sadly, no Fortran
compiler implements this constraint, and the common portable
interpretation seems to be the generic resolution, not the
structure constructor.

Restructure the processing of structure constructors in expression
analysis so that it can be driven both from the parse tree as well
as from generic resolution, and then use it to detect ambigous
structure constructor / generic function cases, so that a portability
warning can be issued.  And document this as a new intentional
violation of the standard in Extensions.md.

Fixes llvm#138807.
klausler added a commit to klausler/llvm-project that referenced this issue May 12, 2025
Fortran 2023 constraint C7108 prohibits the use of a structure
constructor in a way that is ambiguous with a generic function
reference (intrinsic or user-defined).  Sadly, no Fortran
compiler implements this constraint, and the common portable
interpretation seems to be the generic resolution, not the
structure constructor.

Restructure the processing of structure constructors in expression
analysis so that it can be driven both from the parse tree as well
as from generic resolution, and then use it to detect ambigous
structure constructor / generic function cases, so that a portability
warning can be issued.  And document this as a new intentional
violation of the standard in Extensions.md.

Fixes llvm#138807.
klausler added a commit that referenced this issue May 13, 2025
Fortran 2023 constraint C7108 prohibits the use of a structure
constructor in a way that is ambiguous with a generic function reference
(intrinsic or user-defined). Sadly, no Fortran compiler implements this
constraint, and the common portable interpretation seems to be the
generic resolution, not the structure constructor.

Restructure the processing of structure constructors in expression
analysis so that it can be driven both from the parse tree as well as
from generic resolution, and then use it to detect ambigous structure
constructor / generic function cases, so that a portability warning can
be issued. And document this as a new intentional violation of the
standard in Extensions.md.

Fixes #138807.
llvm-sync bot pushed a commit to arm/arm-toolchain that referenced this issue May 13, 2025
Fortran 2023 constraint C7108 prohibits the use of a structure
constructor in a way that is ambiguous with a generic function reference
(intrinsic or user-defined). Sadly, no Fortran compiler implements this
constraint, and the common portable interpretation seems to be the
generic resolution, not the structure constructor.

Restructure the processing of structure constructors in expression
analysis so that it can be driven both from the parse tree as well as
from generic resolution, and then use it to detect ambigous structure
constructor / generic function cases, so that a portability warning can
be issued. And document this as a new intentional violation of the
standard in Extensions.md.

Fixes llvm/llvm-project#138807.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Development

Successfully merging a pull request may close this issue.

3 participants