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

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

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
.   [R]
   function construct_t() result( r )
----------------------------------^
m.f90(16): remark #7712: This variable has not been used.   [R]
   function construct_t() result( r )
----------------------------------^

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

6 posts / 0 new
Last post
For more complete information about compiler optimizations, see our Optimization Notice.

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.

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.   [T]
   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.

Steve (aka "Doctor Fortran") - Retired from Intel

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

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.

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

Steve (aka "Doctor Fortran") - Retired from Intel

Leave a Comment

Please sign in to add a comment. Not a member? Join today