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

Compiler bug: target array can not be passed for pointer argument via generic interface

BalintAradi
New Contributor I
1,281 Views

I have encountered a problem, when trying to pass an array with the target attribute as an actual argument to a procedure with a pointer, intent(in) dummy argument via a generic interface. The minimal working example below demonstrates the problem. Calling subptr_int1 directly works, but via the `subptr` interface does not, the compiler complains about not being to able to find a matching interface for the call.  Also, it seems, that for scalars it works  with the interface.  As far as I can judge, the code is standard conforming, two other compilers have no problems to compile it.

module test_target
implicit none

interface subptr
module procedure subptr_int1
end interface subptr

contains

subroutine subptr_int1(val)
integer, pointer, intent(in) :: val(:)

print *, "INTEGER1 PTR obtained", val(1)

end subroutine subptr_int1

end module test_target


program test_target_program
use test_target
implicit none

integer, target :: int1val(1)

int1val(1) = 42
call subptr(int1val)

end program test_target_program

 

0 Kudos
11 Replies
jimdempseyatthecove
Black Belt
1,262 Views

An array descriptor is not a pointer. Your subroutine requires a reference to a pointer be passed.

Note, should you flip the arguments about (call with pointer to subroutine with array), the actual argument is that which the pointer points to and not the pointer itself.

module test_target
  implicit none
  interface subptr
    module procedure subptr_int1
  end interface subptr
contains
  subroutine subptr_int1(val)
    integer, pointer, intent(in) :: val(:)
    print *, "INTEGER1 PTR obtained", val(1)
  end subroutine subptr_int1
end module test_target

program test_target_program
 use test_target
 implicit none
 integer, target :: int1val(1)
 integer, pointer :: p(:)


 int1val(1) = 42
 p => int1val
 call subptr(p)
end program test_target_program

Jim Dempsey

0 Kudos
BalintAradi
New Contributor I
1,258 Views

The array in question (int1val) has the "target" attribute, therefore, according to the standard, it should be allowed to be an actual argument for a dummy argument with the 'pointer, intent(in)' argument. Consequently, the example above is correct and standard conforming.

Note, that if I directly call the routine with "call subptr_int1(int1val)", the code compiles and works as supposed without any further changes.  It is only the generic interface, which confuses the Intel compiler. And, if I turn int1val and val into a scalar, the code again compiles and works without further changes. It is only the combination of using an array and the generic interface, where the compiler misbehaves.

0 Kudos
Steve_Lionel
Black Belt
1,247 Views

I'm inclined to agree with @BalintAradi that the code should be accepted. Generic resolution isn't quite the same as argument association, but I think this cases passes the test. It's a fairly new thing in the language to allow passing a non-pointer to an INTENT(IN) pointer, and it's likely that the ifort developers overlooked adding a check for this in generic resolution.

jimdempseyatthecove
Black Belt
1,225 Views

>>I'm inclined to agree with @BalintAradi that the code should be accepted.

I disagree for this reason:

The interface has been declared. In this specific example, then subroutine dummy argument for the pointer had intent(in) ...

However, consider if the intent were instead intent(inout)

In this case, had the call passed a pointer into the subroutine, the caller's pointer could be modified with => as well as have the pointer's target altered with =.

Orthogonality should not be broken dependent upon INTENT(IN) verses INTENT(INOUT) IMHO

 

Jim Dempsey

 

0 Kudos
FortranFan
Honored Contributor II
1,215 Views

For whatever it's worth, I too think the program conforms and that Intel Fortran compiler should process the code ok.

BalintAradi
New Contributor I
1,207 Views

@jimdempseyatthecove I think, if a module procedure can be called directly with a given actual argument, one should be also able to call it with the same actual argument via the generic interface, if it is listed in that generic interface. The direct call works if the pointer dummy argument of the called subroutine is intent(in), and it does not work, if the pointer dummy argument is intent(inout) (as dictated by the standard). I'd expect the call via the generic interface to behave the same way.

 

Also, as I mentioned above the posted example can be compiled and is working perfectly even with the Intel compiler if the dummy and the formal arguments are changed to scalars. So, I'd guess, the array case was just simply overseen.

0 Kudos
Steve_Lionel
Black Belt
1,203 Views

Jim, the standard already carves out an exception for this case:


If the dummy argument does not have INTENT (IN), the actual argument shall be a pointer. Otherwise, the actual argument shall be a pointer or a valid target for the dummy pointer in a pointer assignment statement. If the actual argument is not a pointer, the dummy pointer becomes pointer associated with the actual argument. (15.5.2.7p2)

0 Kudos
jimdempseyatthecove
Black Belt
1,198 Views

If I read that correctly (correct me if I am wrong)...

"If the dummy argument does not have INTENT (IN), the actual argument shall be a pointer. " would apply to INTENT(OUT), INTENT(INOUT) and INTENT not specified.

The above is ambiguous (or maybe not). Is this a copy of the pointer of the caller or is this a reference to the caller's pointer?

My preference as to the decision made by the Fortran committee would be that this be a reference to the caller's pointer else how could you have a subroutine returning a pointer? Or, as an extension, a function returning a pointer?

Jim Dempsey

0 Kudos
Steve_Lionel
Black Belt
1,186 Views

Yes, any INTENT not (IN), including unspecified, requires that the actual argument be a pointer if the dummy is a pointer. I don't think it is ambiguous.

Subroutines don't "return" anything, and I don't see the connection with functions returning pointers. This feature allows you to pass a non-pointer to a pointer under conditions that disallow changes to the pointer (INTENT(IN)).  The dummy pointer becomes associated with the actual argument (rather than the target of a pointer actual argument).

0 Kudos
Barbara_P_Intel
Moderator
1,108 Views

I filed a bug report, CMPLRIL0-34402, and referenced this discussion. Let's see what our Intel Fortran compiler developers have to say.



0 Kudos
Devorah_H_Intel
Moderator
548 Views

The fix will be available in the next oneAPI release. 

0 Kudos
Reply