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

There is no matching specific subroutine for this type bound generic subroutine call

Jauch
Beginner
2,431 Views

I have a type with two bound procedures (GetAsScalar & GetAsList) under a generic procedure (GetValue):

type, extends(TObject)  ::  TKeyword
    character(len=:), allocatable               ::  fValue

contains
    procedure, private                          ::  GetAsScalar
    procedure, private                          ::  GetAsList        

    generic                                     ::  GetValue    =>  &
                                                    GetAsScalar,    &
                                                    GetAsList
end type TKeyword

The routines signatures are these:

subroutine GetAsScalar (this, value, status)
    !Arguments-------------------------------------------------------------
    class(TKeyword)                                 ::  this
    class(*), target                                ::  value
    logical, optional                               ::  status

    !...
end subroutine GetAsScalar

subroutine GetAsList (this, value, status)
    !Arguments-------------------------------------------------------------
    class(TKeyword)                                 ::  this
    class(*), pointer                               ::  value(:)
    logical, optional                               ::  status

    !...
end subroutine GetAsList

Internally, the TKeyword object stores a string.

If I try to use it in the following way (bellow), I get a compilation error: "There is no matching specific subroutine for this type bound generic subroutine call"

class(TKeyword), pointer :: key
class(*), pointer :: p(:)
allocate (integer::p(3))

!Code to read instantiate the TKeyword object

call key%GetValue(p, status)

select type (p)
type is (integer)
    write (*,*) p
end select

If I remove the GetAsScalar from the generic association and make it public, the following code works as expected:

class(TKeyword), pointer :: key
class(*), pointer :: p(:)
allocate (integer::p(3))

!Code to read instantiate the TKeyword object

call key%GetAsList(p, status)

select type (p)
type is (integer)
    write (*,*) p
end select

When passing a scalar (integer, real, character, etc), the GetAsScalar routine is called without problems.

I would like to know why this is happening. What am I missing in this "generic thing" that makes the compiler unable to recognize my subroutine under the generic? There is a way to make this work? Would be something related with the routine signature?

I'm using Intel Fortran 15.0.1.148

0 Kudos
11 Replies
IanH
Honored Contributor III
2,431 Views

Looks like a compiler bug associated with resolution of procedures with CLASS(*) dummy arguments.

MODULE m
  IMPLICIT NONE
  
  TYPE :: TKeyword
  CONTAINS
    PROCEDURE :: GetAsList
    GENERIC :: GetValue => GetAsList
  END TYPE TKeyword
  INTERFACE StandaloneGeneric
    MODULE PROCEDURE GetAsList
  END INTERFACE StandaloneGeneric
CONTAINS
  SUBROUTINE GetAsList (this, value)
    CLASS(TKeyword) ::  this
    CLASS(*), POINTER ::  value(:)
  END SUBROUTINE GetAsList  
END MODULE m

PROGRAM program
  USE m
  IMPLICIT NONE
  
  TYPE(TKeyword) :: key
  CLASS(*), POINTER :: p(:)
  
  ALLOCATE (INTEGER::p(3))
  CALL key%GetAsList(p)           ! Type bound specific - ok.
  CALL key%GetValue(p)            ! Type bound generic - not ok.
  CALL GetAsList(key, p)          ! Stand-alone specific - ok.
  CALL StandaloneGeneric(key, p)  ! Stand-alone generic - not ok.
END PROGRAM program

 

>ifort /check:all /warn:all /standard-semantics /stand "2014-12-31 TObject.f90"
Intel(R) Visual Fortran Compiler XE for applications running on IA-32, Version 15.0.1.148 Build 20141023
Copyright (C) 1985-2014 Intel Corporation.  All rights reserved.

2014-12-31 TObject.f90(13): remark #7712: This variable has not been used.   [VALUE]
  SUBROUTINE GetAsList (this, value)
------------------------------^
2014-12-31 TObject.f90(13): remark #7712: This variable has not been used.   [THIS]
  SUBROUTINE GetAsList (this, value)
------------------------^
2014-12-31 TObject.f90(28): error #8486: There is no matching specific subroutine for this type bound generic subroutine call.   [GETVALUE]
  CALL key%GetValue(p)            ! Type bound generic - not ok.
-----------^
2014-12-31 TObject.f90(30): error #6285: There is no matching specific subroutine for this generic subroutine call.   [STANDALONEGENERIC]
  CALL StandaloneGeneric(key, p)  ! Stand-alone generic - not ok.
-------^
compilation aborted for 2014-12-31 TObject.f90 (code 1)

 

0 Kudos
Steven_L_Intel1
Employee
2,431 Views

Thanks, we'll look into it.

0 Kudos
Steven_L_Intel1
Employee
2,431 Views

Escalated as issue DPD200364904. I have this vague memory of having looked at this issue before, but my research suggests it was a somewhat different problem. I will let you know what we find.

0 Kudos
Jauch
Beginner
2,431 Views

Hello Steve,

Thanks.
I have just a question. So, in fact, there is nothing wrong from the point of view of the "language standard", right?
I'm assuming the code simply should compile whithout the message error, and that is a problem with the compiler?

Cheers,

Eduardo

0 Kudos
Steven_L_Intel1
Employee
2,431 Views

I believe that the code is valid and should compile without error. I'll let you know what we find.

0 Kudos
Jauch
Beginner
2,431 Views

Thanks Steve :)

0 Kudos
Steven_L_Intel1
Employee
2,431 Views

I expect the fix for this to appear in Update 2, scheduled for February.

0 Kudos
Jauch
Beginner
2,431 Views

Hi,

I don't know if this will be useful, but I get the same errors on any type bound generic that includes a procedure with one or more arguments of type polymorphic pointer to an array.

So, while the compiler compiles without problems the module where there is a type bound generic with one or more procedures that have one or more arguments like this: "class(*), pointer  ::  array(:)" (where array can be 2D, 3D, etc), when you try to use it in the same or another module, the error shows up.

This seems to happen only for procedures with polymorphic arrays arguments.

Cheers,

Eduardo

0 Kudos
Steven_L_Intel1
Employee
2,431 Views

Examples of problems would be most useful.

0 Kudos
Jauch
Beginner
2,431 Views

I attached an example (GenericError.zip) that causes the following errors:

Error    1     error #8485: There is no matching specific function for this type bound generic function reference.   [COPY]    Console.f90    21
Error    2     error #8497: Illegal use of a procedure name in an expression, possibly a function call missing parenthesis.   [COPY]    console.f90    21

If I remove the generic "Copy" from ModuleArrayTools and make the Copy1D, Copy2D and Copy3D procedures public, calling Copy1D instead of Copy in the main program compiles as expected.

Even if I change the types and number of arguments in the type routines (Copy1D, Copy2D and Copy3D), the presence of a dummy argument that is an array of type "class(*), pointer" makes the compiler unable to identify the right routine.

If no binding routine for the generics have a dummy argument that is an array of type "class(*), pointer", or if the routine that have it is not necessary, the code compiles without errors.

0 Kudos
Steven_L_Intel1
Employee
2,431 Views

Thanks - that's the same bug as Ian's and should be fixed in update 2.

0 Kudos
Reply