Using polymorphism with TBPs in fortran 2003

Using polymorphism with TBPs in fortran 2003

Hi,

I am trying out ifort 11.1 on x86_64. When I tried to use some fortran 2003 features, namely polymorphic pointer / objects, extended types and TBPs, I ran into a lot of problems. (I put it in product defect, but not sure if it actually is a bug).

I have one base type and 2 extended types, both an extension of the base type.:

=========base_type.f03=========
module base
type:: base_type
contains
procedure :: pro_foo => base_pro_foo
end type base_type

contains
function base_pro_foo (this,str1)
class(base_type) :: this
character :: str1*(*)
...
end function base_pro_foo
..
end module base
=======extended_type1.f03========
module extension1
type, extends (base_type):: extended_type1
contains
procedure :: pro_foo => extend1_pro_foo ! override base_type procedure
end type extended_type1

function extend1_pro_foo (this,str1)
class(extended_type1) :: this
character :: str1*(*)
...
end function extend1_pro_foo
..
end module extension1

=======extended_type2.f03========
module extension2
type, extends(base_type) :: extended_type2
contains
procedure :: pro_foo => extend2_pro_foo ! override base_type procedure
end type extended_type2
.. [similar to extension 1]
end module extension2
================================

I compiled all the modules and built one static library file libmods.a.

Then, in my main program, I had:

============main.f03=============
use base
use extension1
use extension2

class(base_type), pointer :: myPointer
class(base_type), allocatable :: myObject
allocate(extension_type1 :: myObject)
! this doesn't work either: type(extension_type1) :: myObject
..
[some initialization of the object]
..
myPointer => myObject

myPointer% pro_foo('string_bar')

============================================================

When I compiled the code, I got this error:
--------------------------------------------------
ifort main.o -L/my_library_dir -lmods -lstdc++ -Imodule_source_directory \
-o mainBin

my_library_dir/libmods.a(extended_type1.o):(.rodata+0x0): multiple definition of `DYNTYPE_PACK_0.0.2'
my_library_dir/libmods.a(extended_type2.o):(.rodata+0x0): first defined here
my_library_dir/libmods.a(extended_type1.o):(.rodata+0x10): multiple definition of `DYNTYPE_PACK_1.0.2'
my_library_dir/libmods.a(extended_type2.o):(.rodata+0x10): first defined here
my_library_dir/libmods.a(extended_type1.o):(.rodata+0x20): multiple definition of `TBPLIST_PACK_0.0.2'
my_library_dir/libmods.a(extended_type2.o):(.rodata+0x20): first defined here
make[2]: *** [tempInput] Error 1
make[2]: Leaving directory `my_src_dir'
make[1]: *** [default] Error 2
make[1]: Leaving directory `my_src_dir'
make: *** [default] Error 1
=============================================================

"select type" resolution did not seem to help either. Does anyone know what the problem is?

Thank very much in advance!!

Best regards,
Ned

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

We received a similar report involving these compiler generated symbols that is reportedly fixed in the upcoming 11.1 update due out in a few days.

I was unable to create a reproducing case with the code snippets you provided, so if you can offer a complete reproducer then I would be happy to see if the upcoming update resolves the issue and if not then report this to development.

Quoting - Kevin Davis (Intel)

We received a similar report involving these compiler generated symbols that is reportedly fixed in the upcoming 11.1 update due out in a few days.

I was unable to create a reproducing case with the code snippets you provided, so if you can offer a complete reproducer then I would be happy to see if the upcoming update resolves the issue and if not then report this to development.

I think that was the problem that I reported a while back here in the forum.

Compiling all code within a single source file does prevent this error in the current compiler.

Therefore, I made a single source file including all my other source files and I am compiling this now instead of the seperate files.

This works so far, but I really hope the fix will be available soon.

regards,
Thomas

The instance I referred to was submitted via Intel Premier not in the forum.If you have a link to your previous related post we can check on the availability of a fix in the next 11.1 update which should be available in a few days.

Quoting - Kevin Davis (Intel)
if you can offer a complete reproducer then I would be happy to see if the upcoming update resolves the issue and if not then report this to development.

Thanks Kevin, I will try to do that -- might not get around to it till after a couple days.

Btw, any info on when TB-generics and parametrized derived types will be supported?

So for some reasons I could not reproduce the error message after extracting the relevant portions of the code, but now I ran into another problem after modifying the code:

=========================

catastrophic error: **Internal compiler error: internal abort** Please report this error along with the circumstances in which it occurred in a Software Problem Report. Note: File and line given may not be explicit cause of this error.
this% type2Ptr => extended2A_new()
----------------------------^

=========================

The attached source is a complete reproducer. Any idea if I did anything wrong? Also, if I do something like

deallocate (this%type2Ptr)

in main.f90 (f03), what actually happens? Any memory leak?

Thanks very much!!!

Regards,
Ned

Attachments: 

AttachmentSize
Downloadapplication/octet-stream ifortPointer.tar.gz3.67 KB

The error is reproducible even with our newest Development compilers so I'll forward this to Development. The catalyst is unclear, but I'll post again with more info when I have it.

Thanks Kevin.

Also, I bypassed the previous mentioned problematic statement. But in the main program, if I do not use the associate construct, but refer to the pointer when calling its TBP directly, I get another catasrophic error:

main.f90(37): catastrophic error: **Internal compiler error: internal abort** Please report this error along with the circumstances in which it occurred in a Software Problem Report.  Note: File and line given may not be explicit cause of this error.
 write(*,*) thisType1%type2Ptr% coeff("coeff1")
------------^
compilation aborted for main.f90 (code 3)

Please see the attached updated reproducer. Thanks!

Attachments: 

AttachmentSize
Downloadapplication/octet-stream ifortPointerNew.tar.gz3.72 KB

Sorry for the delay Ned. Regarding your last posts:

Both ICEs were submitted to Development along with a separate inquiry about a possible memory leak and what happens for deallocate (this%type2ptr).

My testing seems to show this only deallocates memory associated with the allocation from the statement (from your main.f90):

iErr = thisType1%initProc()

I'm finding twodeallocates are required to free all associated memory:

deallocate (thisType1%type2Ptr)
deallocate (thisType1)

All that I am able to say about the availability of TB-generics and parameterized derived types is that these will be available in a future release. Additional guidance I received was thatparameterized derived types is likely among the last F2003 features that we'll provide. Sorry I can't be more specific than that.

I'll keep the thread updated with information I receive from Development regarding the issues you reported as I learn it. Thank you also for the convenient reproducers. Those were very helpful.

(Internal tracking id: DPD200139961 - internal error in type1_type.f90)
(Internal tracking id: DPD200139975 - internal error in main.f90)
(Internal tracking id: DPD200139983 - memory leak)

Quoting - Kevin Davis (Intel)

I'll keep the thread updated with information I receive from Development regarding the issues you reported as I learn it. Thank you also for the convenient reproducers. Those were very helpful.

(Internal tracking id: DPD200139961 - internal error in type1_type.f90)
(Internal tracking id: DPD200139975 - internal error in main.f90)
(Internal tracking id: DPD200139983 - memory leak)

Updates on internal tracking ids.

DPD200139983 - (memory leak) - Development reports there is no memory leak and the required de-allocations I noted are expected. In regard to the specific interest about deallocate (this%type2Ptr), this deallocates the specific field type2Ptr only. They added that deallocating a record (thisType1) should never deallocate
pointer fields within the record. That this is just part of the Fortran language.

DPD200139975 - (internal error in main.f90) - This is fixed the upcoming 11.1 Update 3 scheduled for later this month.

DPD200139961 - (internal error in type1_type.f90) - Fix is being targeted to the 11.1 update *after* Update 3. I will update this post when I know.

(Resolution Update on 12/23/2009): Defect DPD200139961 is fixed in the Intel Fortran Compiler Professional Edition 11.1 Update 4 (11.1.064 - Linux).

It is correct that deallocation of a derived type with POINTER fields does not deallocate the POINTERs. However, if they are ALLOCATABLE components, they do get deallocated.

Steve - Intel Developer Support

Ran into, what I believe, appears to be a bug using ifort (IFORT) 11.1 20090827 (linux ia32), which is what I was directed to download about an hour or so ago via the intel website.

I create a polymorphic variable to a base class.
I then allocate the polymorphic variable as a derived class.
SELECT TYPE works as expected (in identifying that the variable is a derived class)
Within the TYPE IS-block, I can use the polymorphic variable as an argument to a subroutine expecting a variable of the derived class.
BUT
Compiler does not allow the polymorphic variable to be used as an argument to the subroutine when called outside of the SELECT TYPE-switch.

I would expect the polymorphic variable to be used as a variable to a subroutine expecting a class of the same class that the polymorphic variable was allocated as...

It's a pretty simple code to reproduce this. I'll inline it here.

MODULE TestMod

  IMPLICIT NONE

  TYPE ATYPE
     REAL,POINTER :: ADATA(:) => NULL()
   CONTAINS
     PROCEDURE,PASS :: Destroy_ATYPE
     PROCEDURE,PASS :: Destroy => Destroy_ATYPE
 !    FINAL :: Destroy_ATYPE
  END TYPE ATYPE

  TYPE, EXTENDS(ATYPE) :: BTYPE
     REAL,POINTER :: BDATA(:) => NULL()
   CONTAINS
     PROCEDURE,PASS :: Destroy_BTYPE
     PROCEDURE,PASS :: Destroy => Destroy_BTYPE
 !    FINAL :: Destroy_BTYPE
  END TYPE BTYPE

CONTAINS

  SUBROUTINE Destroy_ATYPE(this)
    IMPLICIT NONE

    CLASS(ATYPE) :: this

    WRITE(6,*)"Destroy_ATYPE"

    IF ( ASSOCIATED( this%ADATA ) ) THEN
       WRITE(6,*)"DEALLOCATING this%ADATA"
       DEALLOCATE( this%ADATA )
    END IF

  END SUBROUTINE Destroy_ATYPE


  SUBROUTINE Destroy_BTYPE(this)
    IMPLICIT NONE

    CLASS(BTYPE) :: this

    WRITE(6,*)"Destroy_BTYPE"

    IF ( ASSOCIATED( this%BDATA ) ) THEN
       WRITE(6,*)"DEALLOCATING this%BDATA"
       DEALLOCATE( this%BDATA )
    END IF

    ! MUST DESTROY INHERITED TYPES BY HAND WITH IFORT V11.1
    CALL this%Destroy_ATYPE()

  END SUBROUTINE Destroy_BTYPE


END MODULE TestMod


PROGRAM TestProg

  USE TestMod, ONLY : ATYPE, BTYPE
  IMPLICIT NONE

  TYPE(BTYPE) :: b
  CLASS(ATYPE),ALLOCATABLE :: polym

  CALL INIT_BTYPE(b)
  CALL b%Destroy()

  ALLOCATE( BTYPE :: polym )
 
  SELECT TYPE ( polym )

  TYPE IS (ATYPE)
     WRITE(6,*)"polym is ATYPE"

  TYPE IS (BTYPE)
     WRITE(6,*)"polym is BTYPE"

     ! THIS CALL IS OK.  COMPILES AND RUNS FINE
     CALL INIT_BTYPE(polym)

  END SELECT
 
  ! THIS CALL CAUSES A ifort (IFORT) 11.1 20090827
  ! COMPILE ERROR:
  ! Main.f90(91): error #6633: The type of the actual argument differs from the type of the dummy argument.   [POLYM]
  !  CALL INIT_BTYPE(polym)
  !------------------^

  CALL INIT_BTYPE(polym)

  CALL polym%Destroy()

CONTAINS

  SUBROUTINE INIT_BTYPE(b)
    USE TestMod, ONLY : ATYPE,BTYPE
    IMPLICIT NONE

    CLASS(BTYPE) :: b

    WRITE(6,*)"WITHIN INIT_BTYPE"

    IF ( .NOT. ASSOCIATED( b%ADATA ) ) ALLOCATE( b%ADATA(3) )
    IF ( .NOT. ASSOCIATED( b%BDATA ) ) ALLOCATE( b%BDATA(3) )

    b%ADATA = 0.0
    b%BDATA = 0.0

  END SUBROUTINE INIT_BTYPE

END PROGRAM TestProg

Thanks - we'll take a look.

Steve - Intel Developer Support

I will be the first to admit that I get a blinding headache anytime the word "polymorphism" appears, but I think I understand what should happen here.

The words from the standard are:

"A polymorphic entity that is not an unlimited polymorphic entity is type compatible with entities of the same declared type or any of its extensions." [F2003, p76, lines 1-3]

Note that it says "declared type" and not "dynamic type" - so it does not matter that polym was allocated with type BTYPE.

However, I believe that the compiler is in error here. The declared type of polym is ATYPE and the declared type of the dummy argument is BTYPE (the declared type of a polymorphic entity is "the specified type if the CLASS type specifier contains a class name." BTYPE is an extension of ATYPE and thus the two are type compatible.

I will report this to the developers. I know that we recently fixed a similar issue, but it isn't exactly the same. Issue ID is DPD200141034.

Steve - Intel Developer Support


Quoting - Steve Lionel (Intel)
"A polymorphic entity that is not an unlimited polymorphic entity is type compatible with entities of the same declared type or any of its extensions." [F2003, p76, lines 1-3]

Note that it says "declared type" and not "dynamic type" - so it does not matter that polym was allocated with type BTYPE.

However, I believe that the compiler is in error here. The declared type of polym is ATYPE and the declared type of the dummy argument is BTYPE (the declared type of a polymorphic entity is "the specified type if the CLASS type specifier contains a class name." BTYPE is an extension of ATYPE and thus the two are type compatible.

I'm not trying to be nit-picky here (I'm not even a computer scientist, so let me apologize first)... but, well, let me explain my point of view instead of trying to quote the standard... hopefully this will make my thoughts more clear.
When I talk about type-compatability here, I'm talking about polymorphic entities and their type-compatability.
The type compatibility of nonpolymorphic entities is straight forward and not an issue.

The "common-sense-logic-in-my-brain" says that
A dummy argument in a subroutine containing CLASS(X) means that the actual argument must AT LEAST provide all of the data and method components of TYPE X because this routine will ONLY be using the data and methods defined by TYPE X (and everything it extended).

So, to me, I would consider it an error to pass to a subroutine (as an actual argument) a variable of type ATYPE when the subroutines dummy argument is BTYPE (polymorphic), because ATYPE does not provide at least all of the functionality of BTYPE.

...that's not coming from the standard, that's just coming from "the-common-sense-in-my-brain".
However, your reading of the standard suggests that an actual ATYPE argument can be passed to a subroutine accepting a BTYPE (polymorphic) because BTYPE is type compatible with ATYPE (or more precisely, your interpretation was that they were type compatible with each other); however, I will now argue from the standard that ATYPE is not type compatible with BTYPE even though BTYPE is type compatible with ATYPE (because BTYPE is an extension of ATYPE and thus provides all of the functionality that an ATYPE would have).

Now, with that point of view, when I read the standard and it says "A polymorphic entity that is not an unlimited polymorphic entity is type compatible with entities of the same declared type or any of its extensions."

BTYPE is type compatible to ATYPE because it is an extension of ATYPE.
ATYPE is not type compatible with BTYPE because ATYPE is not a BTYPE nor an extension of BTYPE.

I think that when a polymorphic object is passed as an actul argument to a subroutine, the subroutine has NO KNOWLEDGE of how
that polymorphic object was declared so it treats that object as if its declared type was its current dynamic type.

I'm not trying to be argumentative, it's just a tricky issue that perhaps just isn't clear to me because I'm a newbie.

-Tim

Quoting - tjgiese

I think that when a polymorphic object is passed as an actul argument to a subroutine, the subroutine has NO KNOWLEDGE of how
that polymorphic object was declared so it treats that object as if its declared type was its current dynamic type.

INDEED. From the standard:

"The dynamic type of a nonallocatable nonpointer polymorphic dummy argument is the dynamic type of its associated actual argument."

Lines 14-16 in "Sec 5.1.1.2 CLASS" pg 76 from Working Draft May 10, 2004 11:07.

-Tim

My colleagues and I had a lively conversation about this over lunch. I was convinced that the compiler is correct, largely along the lines suggested by Tim.

First, let me say again that dynamic type does not enter into this, at least directly. It's the declared type that is the issue.

My error was not reading elsewhere in the standard where it says:

"If a dummy argument is neither allocatable nor a pointer, it shall be type compatible (5.1.1.2) with the associated actual argument."

5.1.1.2 is the text I cited earlier. The key here is the "direction" of compatibility - type compatibility is not symmetric. In my earlier post, I took the position that the actual argument was type compatible with the dummy, but the standard requires that the test go the other way - the dummy has to be compatible with the actual. Given this, CLASS(BTYPE) is not type compatible with CLASS(ATYPE) since, as Tim says, BTYPE is bigger than ATYPE. This is the only thing that makes sense - otherwise you could pass a variable containing only ATYPE components to something that tries to access extended components from BTYPE.

In your source, you have a call to INIT_BTYPE within a TYPE IS(BTYPE), and the compiler correctly allows that since within that TYPE IS, polym is a variable whose declared type is BTYPE. (It is curious to note that this is not really the same polym - it is a "selector", similar to an associate name, a new variable that happens to have the same storage as the original polym.

So in conclusion, the compiler is correct and your source is not.

Steve - Intel Developer Support

Quoting - Steve Lionel (Intel)
My colleagues and I had a lively conversation about this over lunch. I was convinced that the compiler is correct, largely along the lines suggested by Tim.

First, let me say again that dynamic type does not enter into this, at least directly. It's the declared type that is the issue.

My error was not reading elsewhere in the standard where it says:

"If a dummy argument is neither allocatable nor a pointer, it shall be type compatible (5.1.1.2) with the associated actual argument."

5.1.1.2 is the text I cited earlier. The key here is the "direction" of compatibility - type compatibility is not symmetric. In my earlier post, I took the position that the actual argument was type compatible with the dummy, but the standard requires that the test go the other way - the dummy has to be compatible with the actual. Given this, CLASS(BTYPE) is not type compatible with CLASS(ATYPE) since, as Tim says, BTYPE is bigger than ATYPE. This is the only thing that makes sense - otherwise you could pass a variable containing only ATYPE components to something that tries to access extended components from BTYPE.

In your source, you have a call to INIT_BTYPE within a TYPE IS(BTYPE), and the compiler correctly allows that since within that TYPE IS, polym is a variable whose declared type is BTYPE. (It is curious to note that this is not really the same polym - it is a "selector", similar to an associate name, a new variable that happens to have the same storage as the original polym.

So in conclusion, the compiler is correct and your source is not.

Yikes, if your conclusion is correct, then that almost makes the usage polymorphic entities completely moot.
I would think that they would be most useful by declaring them to the most basic type (for the problem considered) and then dynamically make them specific to a more specific type based on user input.
However, if you wanted to pass objects to routines, then they'd have to be declared as the most specific case (which
you probably don't know a priori - the whole point of having dynamic types, afterall), or else you have to nest all your subroutines
like such

PROGRAM FOO

  CLASS(ATYPE),ALLOCATABLE :: c
  CLASS(ATYPE),ALLOCATABLE :: d

  ALLOCATE( BTYPE :: c )
  ALLOCATE( BTYPE :: d )

  SELECT TYPE ( c )  
  TYPE IS (BTYPE)  
     SELECT TYPE ( d )
     TYPE IS (BTYPE)
        CALL Sub(c,d)
     END SELECT
  END SELECT

CONTAINS

  SUBROUTINE Sub(c,d)
    CLASS(BTYPE) :: c,d
  END SUBROUTINE

END PROGRAM FOO

"If a dummy argument is neither allocatable nor a pointer, it shall be type compatible (5.1.1.2) with the associated actual argument."

I would have reworded that to read
If a nonpolymorphic dummy argument is neither allocatable nor a pointer, it shall be type compatible with the dynamic-type of the associated actual argument.

which would make it consistent (and logical, on many levels) with Sec 5.1.1.2, which reads:
The dynamic type of a nonallocatable nonpointer polymorphic dummy argument is the dynamic type of its associated actual argument.

You can dynamically allocate to any extended type. But if you're passing an actual argument, the declared type has to be at least "as big" as that of the dummy.

The standard has a note on this as follows:

NOTE 12.21 The dynamic type of a polymorphic allocatable or pointer dummy argument may change as a result of execution of an allocate statement or pointer assignment in the subprogram. Because of this the corresponding actual argument needs to be polymorphic and have a declared type that is the same as the declared type of the dummy argument or an extension of that type. However, type compatibility requires that the declared type of the dummy argument be the same as, or an extension of, the type of the actual argument. Therefore, the dummy and actual arguments need to have the same declared type.

Dynamic type information is not maintained for a nonpolymorphic allocatable or pointer dummy argument. However, allocating or pointer assigning such a dummy argument would require maintenance of this information if the corresponding actual argument is polymorphic. Therefore, the corresponding actual argument needs to be nonpolymorphic.

Steve - Intel Developer Support
PROGRAM TestProg

  USE TestMod, ONLY : ATYPE, BTYPE
  IMPLICIT NONE

  CLASS(ATYPE),ALLOCATABLE,TARGET :: polym1
  CLASS(ATYPE),ALLOCATABLE,TARGET :: polym2

  TYPE(ATYPE),POINTER :: pArg1 => NULL()
  TYPE(BTYPE),POINTER :: pArg2 => NULL()

  ALLOCATE( BTYPE :: polym1 )
  ALLOCATE( BTYPE :: polym2 )


  !=============================================================================
  ! PASS POLYMORPHIC ENTITIES AS ACTUAL ARGUMENTS TO
  ! A SUBROUTINE WHICH EXPECTS ACCESS TO (AT MOST)
  ! A BTYPE TYPE.  IN PRACTICE,  polym1 AND polym2
  ! MAY BE COMPONENTS OF DIFFERENT OBJECTS (OR THE SAME OBJECT);
  ! THEIR EXACT TYPE MAY BE DYNAMIC (BASED ON USER INPUT)
  ! BUT WE MAY ONLY CARE ABOUT THE MEMBER DATA AND METHODS
  ! PROVIDED BY THEM.  BEFORE WE CAN PASS THEM TO A SUBROUTINE
  ! (WHICH MAY CAUSE THEM TO INTERACT SOMEHOW AND PRODUCE SOME RESULT)
  ! WE FIRST NEED TO VERIFY THAT THEY, INDEED, HAVE THE APPROPRIATE
  ! DATA AND METHODS THAT THE SUBROUTINE WILL BE USING
  !
  ! Personally, I'd find it a lot more convienent if the called routine
  ! could ask these sort of questions and hide it from the programmer,
  ! but that's just me... Hell, I'd probably make some other changes
  ! about fortran 2003 standard to make these sort of questions part of the compiler.

  ! VERIFY THAT THE FIRST ARGUMENT IS AT LEAST AN "ATYPE"
  SELECT TYPE ( polym1 )
  CLASS IS (ATYPE) ! OR ANY EXTENSION OF ATYPE
     pArg1 => polym1
  CLASS DEFAULT
     WRITE(6,*)"Runtime error: can't call BB_Example: Incompatible class (ARG1)"
  END SELECT

  ! VERIFY THAT THE SECOND ARGUMENT IS AT LEAST A "BTYPE"
  SELECT TYPE ( polym2 )
  CLASS IS (BTYPE) ! OR ANY EXTENSION OF BTYPE
     pArg2 => polym2
  CLASS DEFAULT
     WRITE(6,*)"Runtime error: can't call BB_Example: Incompatible class (ARG2)"
  END SELECT

  CALL BB_Example(pArg1,pArg2)

  NULLIFY(pArg1)
  NULLIFY(pArg2)

  !=============================================================================

  CALL polym1%Destroy()
  CALL polym2%Destroy()

  IF ( ALLOCATED( polym1 ) ) DEALLOCATE( polym1 )
  IF ( ALLOCATED( polym2 ) ) DEALLOCATE( polym2 )

CONTAINS

  SUBROUTINE BB_Example(a,b)
    USE TestMod, ONLY : ATYPE,BTYPE
    IMPLICIT NONE

    CLASS(ATYPE),INTENT(IN) :: a
    CLASS(BTYPE),INTENT(IN) :: b

    WRITE(6,*)"WITHIN BB_Example"

  END SUBROUTINE BB_EXAMPLE

END PROGRAM TestProg

I included a simple example that gets around the problem while still remaining within the standard... just in case someone google's this page with a similar problem.

I've been thinking about this for a while now and I am no longer finding this part of the standard as objectionable as I initially did.

By saying:

CLASS(x) :: a

I'm really saying: I'm making a promise to you, the programmer reading my source code, that I will make every best effort to only use the variable "a" in a manner that conforms with data/method of an object of TYPE(x). I am making "a" a polymorphic variable, because you, the programmer reading my source code, may have extended the tyoe "x" to override its methods. Therefore, my code will not break your new code.

If I tried to pass "a" to a subroutine accepting it as a CLASS(y) (where y extended x), then I've broken that promise, even if at runtime "a" had a dynamic type that provided the capabilities of "y" - it doesn't matter - *I* broke the promise, and the only way to know if the intention of the promise was preserved at runtime is to manually check if "a" indeed has the functionality of y. Well, the compiler COULD do runtime checks too, but perhaps programming the manual check is the punishment for breaking the promise.

Quoting - Kevin Davis (Intel)

Updates on internal tracking ids.

DPD200139983 - (memory leak) - Development reports there is no memory leak and the required de-allocations I noted are expected. In regard to the specific interest about deallocate (this%type2Ptr), this deallocates the specific field type2Ptr only. They added that deallocating a record (thisType1) should never deallocate
pointer fields within the record. That this is just part of the Fortran language.

DPD200139975 - (internal error in main.f90) - This is fixed the upcoming 11.1 Update 3 scheduled for later this month.

DPD200139961 - (internal error in type1_type.f90) - Fix is being targeted to the 11.1 update *after* Update 3. I will update this post when I know.

The last remaining defect DPD200139961 is fixed in the Intel Fortran Compiler Professional Edition 11.1 Update 4 (11.1.064 - Linux).

Leave a Comment

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