Skip to content

Optional argument used before checking present #201

@byornski

Description

@byornski

The NAG compiler fails to build the D4 library with the error message
Runtime Error: ../../../LibSource/dftd4-3.4.0/src/dftd4/param.f90, line 526: Reference to OPTIONAL argument S9 which is not PRESENT
This is the due to the use of merge on optional arguments in the following routine:

    523       real(wp), intent(in) :: s8, a1, a2
    524       real(wp), intent(in), optional :: s6, alp
    525       type(rational_damping_param) :: param
    526       param = rational_damping_param(&
    527          & s6=merge(s6, 1.0_wp, present(s6)), &
    528          & s8=s8, a1=a1, a2=a2, &
    529          & s9=merge(s9, 1.0_wp, present(s9)), &
    530          & alp=merge(alp, 16.0_wp, present(alp)))
    531    end function dftd_param

The nvidia compiler compiles this successfully, but crashes on a line using a similar construct:

0x00000000016ab37d in dftd4_param::get_rational_damping () at ../../../LibSource/dftd4-3.4.0/src/dftd4/param.f90:69
69         mbd = merge(s9 /= 0.0_wp, .true., present(s9))

According to this thread on the intel compiler forum, the merge statement may evaluate either or both of the source values and does not have to short circuit. This leads to the optional values being possibly evaluated, while being undefined and causing issues. The code should be replaced by a standard if else construct, eg

pure function dftd_param(s6, s8, a1, a2, alp) result(param)
  real(wp), intent(in) :: s8, a1, a2
  real(wp), intent(in), optional :: s6, alp
  type(rational_damping_param) :: param
  real(wp) :: s6_local, alp_local, s9_local

  s6_local = 1.0_wp
  if (present(s6)) s6_local = s6
  s9_local = 1.0_wp
  if (present(s9)) s9_local = s9
  alp_local = 16.0_wp
  if (present(alp)) alp_local = alp

  param = rational_damping_param(&
    & s6=s6_local &
    & s8=s8, a1=a1, a2=a2, &
    & s9=s9_local, &
    & alp=alp_local,
 end function dftd_param

and similarly for other cases where merge is used to check for "present"

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions