Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.
28894 Discussions

Runtime crash with elemental procedure, optional and non-optional arguments

Harald1
New Contributor II
988 Views

The following code compiles with ifort/ifx, but crashes at runtime as indicated:

program main
  implicit none
  integer :: arr(1) = 42
  call sub (arg2=arr)
contains
  subroutine sub (arg1, arg2)
    integer, intent(in), optional :: arg1(:)
    integer, intent(in)           :: arg2(:)
    print *, fun (arg2=arg2)    ! This works
    print *, fun (arg1, arg2)   ! This crashes at runtime
  end subroutine
  elemental function fun (arg1, arg2)
    integer, intent(in), optional :: arg1
    integer, intent(in)           :: arg2
    integer                       :: fun
    fun = arg2
  end function
end program

 I get:

% ifort ifort-elemental-optional.f90 -g -what && ./a.out 
 Intel(R) Fortran 2021.11.0-1242.01
          42
forrtl: severe (174): SIGSEGV, segmentation fault occurred
Image              PC                Routine            Line        Source             
libpthread-2.31.s  000014D1CDCA7910  Unknown               Unknown  Unknown
a.out              00000000004039E9  Unknown               Unknown  Unknown
a.out              00000000004036E7  Unknown               Unknown  Unknown
a.out              000000000040365D  Unknown               Unknown  Unknown
libc-2.31.so       000014D1CDACF24D  __libc_start_main     Unknown  Unknown
a.out              000000000040358A  Unknown               Unknown  Unknown

It appears that passing the missing optional dummy argument arg1 to 'fun' fails.

 

9 Replies
David_Billinghurst
New Contributor III
961 Views

I believe your program conforms to the 2018 standard.

Section 15.5.2.12 Argument presence and restrictions on arguments not present ,  states

3 An optional dummy argument that is not present is subject to the following restrictions

[...]

4 Except as noted in the list above, it may be supplied as an actual argument corresponding to an optional dummy argument, which is then also considered not to be present.

 

The equivalent section 15.5.2.13 in Fortran 2023 appears identical.

Barbara_P_Intel
Employee
897 Views

@Harald1 and @David_Billinghurst, thank you for the report and the citation in the Fortran standards!

I filed a bug on your behalf, CMPLRLLVM-54890.

 

0 Kudos
Ron_Green
Moderator
770 Views

@Harald1 @David_Billinghurst we have a fix for this bug.  It's in the pipeline for the 2024 Update 2 release, 2024.2.  Roughly late June or July.  But don't hold me or Barbara to that. We only help get fixes and are not involved in validation and packaging. We can't control the release schedules.

0 Kudos
Frankcombe__Kim
Beginner
453 Views

@Ron_Green  This may have got fixed in 2024.2 but if we add another wrinkle (external interface) it fails. This code works fine with ifort 2020.x and 2021.x but fails on 2024.2 for both ifort and ifx. - tested on linux and windows

If we replace the interface block in dbase_inc with the LNULL function from dbase-utils.f90 it works as expected

 

If we break the compound IF statement up as below it works

IF (PRESENT(Z2)) then

 if (Z2 > ZNULLTST) LNULL=.TRUE.

end if

The issue appears to be that a compound if statement is being evaluated fully (as in debug mode) if used via an interface statement or that the optional statement in the interface block is being ignored.

A fix for this would be most welcome.:-)

Cheers

Kim

 

0 Kudos
andrew_4619
Honored Contributor III
416 Views
  IF (PRESENT(Z2) .AND. Z2 > ZNULLTST) LNULL=.TRUE.
  IF (PRESENT(Z3) .AND. Z3 > ZNULLTST) LNULL=.TRUE.
  IF (PRESENT(Z4) .AND. Z4 > ZNULLTST) LNULL=.TRUE.
  IF (PRESENT(Z5) .AND. Z5 > ZNULLTST) LNULL=.TRUE.

All of the above are bugs. There is no shortcut evaluation in Fortran so the Z? > ZNULLTST will be evaluated  even if present(Zi) is false.

The language standard requires it to be so. 

0 Kudos
Frankcombe__Kim
Beginner
397 Views

@andrew_4619just so I'm clear what you are saying. You believe that  for production code the whole of a compound if statement is evaluated rather than evaluated sequentially with the first failure causing future tests to be skipped?

That is certainly not what the ifort compiler has been doing until recently. In debug mode it will evaluate the whole expression but with -O2 or -O3 optimisation it will exit as soon as it reaches a point where the answer is obvious - in this case the PRESENT(Z2) part.

If it was an Intel extension rather than required by the standard then it was also an extension applied by Lahey which I used for many years prior to switching to Intel. If it was an extension it was a good one and one I'd like to see them maintain. It was in ifort last year (OneAPI 2023.x)  and has been part of the Parallel Studio package since at least 2016 when I switched from Lahey

Cheers

Kim

PS It also works if you don't use the interface module and instead directly use the function so the behavior is not consistent. 

0 Kudos
andrew_4619
Honored Contributor III
396 Views

There is no short-circuiting of logical expressions in Fortran, if you write code that relies on it it my or may not work as intended so do not do it. The standard defines the order of evaluation to be arbitrary so that compilers may reorder them as they see fit.  For example an unevaluated term that has a function in it might have consequences of being evaluated or not that break a program. 

Read also https://fortranwiki.org/fortran/show/short-circuiting

 

I should add that Fortran 2023 has some new syntax  that can allow shortcutting but I do not know if any compiler supports this yet, Intel does not. 

0 Kudos
Frankcombe__Kim
Beginner
389 Views

Looks like I have a lot of work in front of me to locate and re-write something I have relied on for 30 years and buried amongst hundreds of thousands of lines of production code. Sigh

0 Kudos
andrew_4619
Honored Contributor III
351 Views

Sorry! That one bit me about 25+ years ago when moving compiler. It would not help you with this one but all my code has /stand and /standard-semantics and a few diagnostic warning suppressions that can't be avoided (e.g. variables with dollar in the name Excel interfaces, attributes for std-call for windows interfaces on 32bit....). I also void/remove deprecated language features. I think that minimises the potential for future pain that always comes at a time when you don't have the time.....

0 Kudos
Reply