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

Failure to detect the standard prohibition on the use of a non-intrinsic procedure in an initialization/constant expression

FortranFan
Honored Contributor II
429 Views

A support incident # 02999251 has been submitted at the Online Service Center to resolve a failure by the Intel Fortran compiler to raise an error when a non-intrinsic procedure is used in an initialization expression.

Shown below is an example of this problem where the named constant declaration on line 12 uses a non-intrinsic procedure, construct_t, via the generic interface that has the same as the type t that is involved in the declaration.  This is, unfortunately, not allowed per the current Fortran standard.

module m

   implicit none

   type :: t
   end type

   interface t
      module procedure construct_t
   end interface

   type(t), parameter :: foo = t()

contains

   function construct_t() result( r )
      type(t) :: r
   end function

end module m

Upon compilation using Intel Fortran compiler 18.0 Beta Update 1,

C:\..>ifort /c /standard-semantics /stand /warn:all m.f90
Intel(R) Visual Fortran Intel(R) 64 Compiler for applications running on Intel(R) 64,
Version 18.0.0.083 Beta Build 20170510
Copyright (C) 1985-2017 Intel Corporation.  All rights reserved.

ifort: NOTE: The Beta evaluation period for this product ends on 12-oct-2017 UTC
.
m.f90(16): warning #6178: The return value of this FUNCTION has not been defined
.   
   function construct_t() result( r )
----------------------------------^
m.f90(16): remark #7712: This variable has not been used.   
   function construct_t() result( r )
----------------------------------^

The issue is noticed with Intel Fortran compiler 17.0 update 4 as well.

0 Kudos
5 Replies
IanH
Honored Contributor II
429 Views

The code violates the ordering requirement on procedures referenced via generic identifiers in constant (or specification) expressions.  That requirement isn't a constraint.

Because of that ordering violation, the compiler thinks that t() is the structure constructor.  Structure constructors are permitted in constant expressions.

0 Kudos
Steve_Lionel
Honored Contributor III
429 Views

Your program is nonconforming in a different way than you describe.

C496 (R455) 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 (12.5.5.2).

This is really what the compiler should be catching. In other words, you have created ambiguous declarations.

If we modify the source as follows:

module m

   implicit none

   type :: t
   end type

   interface t
      module procedure construct_t
   end interface

   type(t), parameter :: foo = t(3)

contains

   function construct_t(i) result( r )
   integer i
      type(t) :: r
      
      r = t()
   end function

end module m

The compiler complains:

t.f90(12): error #6593: The number of expressions in a structure constructor differs from the number of components of the derived type.   
   type(t), parameter :: foo = t(3)
-------------------------------^

So here it is not even considering the generic function reference. I do see:

NOTE 7.57
The form ’name(...)’ is interpreted as a generic function-reference if possible; it is interpreted as a structure-constructor
only if it cannot be interpreted as a generic function-reference.

This suggests to me that the compiler indeed should instead be interpreting (in my example) t(3) as a generic reference and then griping that the function reference isn't valid in a constant expression, which is your original complaint. Please add this to your problem report.

0 Kudos
FortranFan
Honored Contributor II
429 Views

Good point, Steve, about C496 (R455).  Your comments have been added to the incident

0 Kudos
IanH
Honored Contributor II
429 Views

The code in #3 also violates the ordering restrictions (f2008 7.1.12p3).  The compiler is quite justified in assuming that the reference to t is not a reference to the generic.

0 Kudos
Steve_Lionel
Honored Contributor III
429 Views

Good catch, Ian! That makes my version also invalid. But my original point about FortranFan's version still holds.

0 Kudos
Reply