gfortran: OOP features [Fortran 2003/2008]
OOP here refers to "Object-Oriented Programming", which was introduced to Fortran in the 2003 standard. The purpose of this page is to document which features have been implemented in gfortran so far, what is still missing and which problems can be expected.
Summary:
gfortran 4.5: some experimental support for polymorphic CLASS entities and object oriented features
gfortran 4.6: almost complete implementation of scalar polymorphism (GSoC 2010 project of Janus Weil)
gfortran 4.7: polymophic arrays, constructors, bug fixes and minor enhancements
Contents
Implemented features
The following features are available in gfortran 4.5:
- basic CLASS declarations
- polymorphic pointer assignments
- polymorphic dummy arguments
- polymorphic allocation
- SELECT TYPE statements
- intrinsic functions SAME_TYPE_AS and EXTENDS_TYPE_OF
- dynamic dispatch, polymorphic type-bound procedures (only partially working)
- Allocatable scalars with allocatable components (partially working, fully in 4.6)
These additional features are available in 4.6:
- improved handling of TBPs to make polymorphism work between libraries/programs and complicated inheritance patterns
- ALLOCATE with MOLD
- STORAGE_SIZE intrinsic function
- proper handling of generic TBPs
- ASSOCIATE construct (except some special cases)
- (Re)allocate on assignment (non-polymorphic)
- allocatable character length scalar variables (deferred-length type parameter)
These additional features are available in 4.7:
- Polymophic arrays
- Generic procedures with same name as a type ("constructor")
- lots of bug fixes
- enhanced diagnostics
- performance improvements
Unimplemented features
- unlimited polymorphism: CLASS(*)
FINALizing subroutines ("destructor", PR37336)
ASSOCIATE construct (some fine points, cf. PR38936)
derived type I/O (PR48298), early draft patch
allocatable character length arrays and as derived-type components (PR45170)
Open Problems
[Here is a list of all OOP-related bugs.]
PRs related to CLASS arrays (8):
Re-enable polymorphic array test cases (i.e. undo the patch), which disabled them)
Issues listed in the patch submission email for polymorphic arrays
PR41600: SELECT TYPE with associate-name => exp: Arrays not supported
PR43412: BT_CLASS does not does not set array spec
PR46991: polymorphic assumed-size actual arguments
PR47506: [Fortran 90+] Assumed-size array checks (polymorphic and component)
PR47680: ICE with polymorphic array elements as dummy
PR51610: Class container does not properly handle POINTER and TARGET
PR51632: Bogus argument checking for generated _def_init parameter and _copy procedure with CAF
PR50981: Issues with polymorphism and ELEMENTAL
Also the implementation of SELECT TYPE still has a few bugs (1):
PR41599: SELECT TYPE with associate-name => exp: Use (sometimes) a restricted pointer
Bugs concerning type-bound operators (3):
PR41951: Not diagnosing ambiguous operators (TB vs. INTERFACE)
PR49591: Multiple identical specific procedures in type-bound operator not detected
PR49074: Ambiguous generics not diagnosed (Defined assignment w/ CLASS arrays: Incomplete error message)
Miscellaneous (compile-time) bugs (14):
PR42769: ICE in resolve_typebound_procedure
PR45076: gfortran.dg/dynamic_dispatch_6.f03 ICEs with -fprofile-use
PR45836: Type Bound Procedure Error - Type Mismatch
PR45900: Static TBP resolved incorrectly
PR46952: Spurious "recursive call" error with type bound procedure
PR47399: ICE with TBP of a PARAMETER
PR47805: Overridding hidden (private) TPB is rejected
PR48786: Generic ambiguity check too strict for polymorphic dummies
PR49213: gfortran rejects structure constructor expression
PR49592: Non-polymorphic ALLOCATE with polymorphic SOURCE= rejected
PR49630: ICE on obsolescent deferred-length type bound character function
PR51864: ALLOCATE with polymorphic array constructor as SOURCE=
PR51961: ALLOCATE with MOLD= rejects if source-expr has a different rank
PR52010: Intrinsic assignment of a CLASS to a TYPE
Accepts-invalid, ICE-on-invalid and diagnostic bugs (6):
PR37222: Checks when overriding type-bound procedures are incomplete
PR42188: F03:C612. The leftmost part-name shall be the name of a data object.
PR43207: invalid pointer assignment => type%parent
PR47710: Improve ambiguity check for GENERIC TBP w/ PASS and NOPASS
PR50252: Error message on "call x%y" (x not declared) can be more informative
PR51208: ALLOCATE with SOURCE= or MOLD=: Diagnose if variable occurs twice
Runtime problems (wrong code, missed optimization) (9):
PR46321: Polymorphic deallocation
PR46783: TRANSFER with polymorphic MOLD=
PR46897: type-bound defined ASSIGNMENT(=) not used for derived type component in intrinsic assign
PR47505: Intrinsics which should operate on polymorphic objects (BT_CLASS)
PR49475: [debugging] Add DWARF info for Fortran's OOP features (extension, member functions)
PR51160: Memory leak with abstract type
PR51284: CLASS and VALUE attribute: No copy to temporary done
PR51514: Wrong code when passing a CLASS to a TYPE
PR52143: ICE with polymorphic function result in gfc_class_vptr_get
Extended features of Fortran 2008 (3):
PR43366: [F2008] Intrinsic assign to polymorphic variable
PR46371: [Coarray] SELECT TYPE: scalar coarray variable is rejected
PR51947: Polymorphic coarrays: Bogus errors for dummy arguments
Internal Representation
The current implementation is such that each class(t) variable consists of a class container (named __class_X) with two fields:
_data: a pointer to a struct of the declared type t
_vptr: a pointer to a vtab entity (see below)
For each derived type t we then construct a vtab entity (called __vtab_X), which is of a type __vtype_X and contains the following fields:
_hash: a unique hash identifier for this type
_size: the storage size of the type t (in bytes)
_extends: a pointer to the vtab of the parent type (or NULL if the type is not an extension)
_def_init: a pointer to a default-initialized variable of type t
_copy: Deep copy function used for ALLOCATE with polymorphic SOURCE=
_free: Deep free function used when deallocating a polymorphic variable (will be implemented for PR46321)
- a number of procedure pointer components for the implementation of polymorphic type-bound procedure calls.
In the naming of class containers, vtabs and vtypes, the X is usually being replaced by a combination of module name and type name. However, if the resulting string is too long, we insert a hashed string instead, which is a hex representation of the type's _hash value.
Fixed Bugs
Fixed in 4.5 (34)
PR41556: Errors in applying operator/assignment to an abstract type
PR41579: Nesting of SELECT TYPE
PR41581: Allocation of a CLASS with SOURCE=<class> does not work
PR41582: Allocation of abstract types requires a type spec or a SOURCE
PR41583: TYPE IS rejected because of way vtable index is implemented
PR41585: Reject CLASS(T) as component of TYPE T
PR41586: Allocatable _scalar_ TYPE/CLASS leak memory
PR41587: ICE with ALLOCATABLE CLASS components
PR41608: ICE with CLASS and invalid code
PR41618: accepts-invalid with CLASS pointer component
PR41629: gimplification error on valid code
PR41631: Support CLASS IS () in SELECT TYPE
PR41648: Type-bound procedures refused
PR41656: Unresolved GENERIC
PR41685: ICE: verify_flow_info failed
PR41706: Calling one TBP as an actual argument of another TBP
PR41714: ALLOCATE SOURCE= does not properly copy the value from SOURCE
PR41719: invalid: Intrinsic assignment involving polymorphic variables
PR41766: SELECT TYPE selector as actual argument with INTENT(INOUT)
PR41781: bogus undefined label error with SELECT TYPE
PR41784: ICE in load_derived_extensions
PR41800: ICE in fold_convert_loc, at fold-const.c:2789
PR41873: Bogus Error: ABSTRACT INTERFACE must not be referenced...
PR41937: Error in allocating derived type allocatable components
PR42053: SELECT TYPE: reject duplicate CLASS IS blocks
PR42144: deferred TBPs do not work
PR42167: SELECT TYPE with function return value
PR42257: Compiler segmentation fault due missing public statement
PR42335: ICE on CLASS IS (bad_identifier)
PR42353: Bogus Error: Name 'vtype$...' at (1) is an ambiguous reference ...
PR43169: gfortran rejects pure procedure with select type construct
PR43199: ICE when reading module file: find_array_spec(): Component not found
PR43256: TBP with missing optional arg
PR43291: [4.5 regression] Type mismatch in argument; passed CLASS(t1) to CLASS(t2)
Fixed in 4.6 (84)
PR40117: [F2008] Type-bound procedure: allow list after PROCEDURE
PR41580: SAME_TYPE_AS and EXTENDS_TYPE_OF - add compile-time simplifcation
PR41753: segfault with -O2 using methods as actual arguments
PR41829: Runtime error with dynamic dispatching
PR42051: ICE on array-valued function with CLASS formal argument
PR42207: Compile-time errors on typed allocation and pointer function result
PR42385: poylmorphic operators do not work
PR43388: [F2008] ALLOCATE with MOLD=
PR43696: Bogus error: Passed-object dummy argument must not be POINTER
PR43895: internal compiler error: verify_ssa failed
PR43896: ICE in gfc_conv_variable, at fortran/trans-expr.c:551
PR43986: gfortran.dg/dynamic_dispatch_4.f03 doesn't work on Linux/ia64
PR43945: Derived type with GENERIC: resolved to the wrong specific TBP
PR43990: ICE in output_constructor_regular_field, at varasm.c:49
PR44044: SELECT TYPE with class-valued function
PR44047: SELECT TYPE with associate-name and allocatable selector
PR44064: ICE with file containing two modules and one program
PR44065: Undefined reference to vtab$...
PR44211: ICE with TBP of pointer component of derived type array
PR44212: ICE when defining a pointer component before defining the class and calling a TBP then
PR44434: ICE in in gfc_add_component_ref
PR44541: wrong code for polymorphic variable with INTENT(OUT)/Alloc w/ MOLD
PR44549: [F2008] Type-bound procedure: bogus error from list after PROCEDURE
PR44558: ICE on invalid code: called TBP subroutine as TBP function
PR44565: [4.6 Regression] ICE in gimplify_expr with array-valued generic TBP
PR44596: Dynamic dispatch uses broken types
PR44614: Wrongly importing a symbol into an interface without IMPORT
PR44616: ICE if CLASS(foo) is used before its definition
PR44649: F2008: storage_size intrinsic (also working for polymorphic types)
PR44696: ASSOCIATED fails on polymorphic variables
PR44868: Error recovery: ICE after invalid TBP call
PR44869: generic TBPs not initialized properly
PR44912: Segmentation fault on TBP
PR44917: Detect ambiguous specifics in a generic TBP interface
PR44925: C_LOC with CLASS pointer
PR44926: Ambiguous interface not detected
PR44936: Generic TBP not resolved correctly at compile time
PR44962: ICE with specification expression SIZE(<CLASS>)
PR45004: Segfault with allocatable scalars and move_alloc
PR45271: Polymorphic code breaks when changing order of USE statements
PR45384: double free with SELECT TYPE
PR45420: poylmorphic TBP calls in a CLASS DEFAULT clause
PR45438: [4.6 Regression] ICE with -fcheck=pointer
PR45439: SELECT TYPE bogus complaint about INTENT
PR45451: Inconsistent status of ALLOCATABLE components inside CLASS variables
PR45456: [4.6 Regression] Bogus pointer initialization error on pointer-valued TBP
PR45494: Wrong dummy argument not rejected
PR45674: Undefined references for extended types
PR45746: ICE in fold_convert_loc: pointer to allocatable array with select type
PR45827: [4.6 Regression] mio_component_ref(): Component not found
PR45848: ICE on invalid code in fortran/symbol.c:2410
PR45933: [4.6 regression] ICE in gfc_add_component_ref, at fortran/class.c:77
PR45961: [4.6 Regression] Problem with polymorphic type-bound operators
PR46161: Invalid: Passing non-polymorphic to allocatable polymorphic dummy
PR46174: ALLOCATE with SOURCE: Deep copy missing
PR46196: gfortran compiles invalid generic TBP: dummy arguments are type compatible
PR46313: class container naming collisions
PR46330: [4.6 Regression] ICE after revision 166368
PR46344: [4.6 Regression] ICE with allocatable CLASS components
PR46370: [Coarray] ALLOCATE: Error allocating CLASS coarrays
PR46408: Segfault when running gfortran.dg/class_allocate_6.f03
PR46413: ICE when printing a polymorphic type
PR46448: [4.6 Regression] symbol '__copy_...' is already defined
PR46581: [4.6 Regression] segfault in SELECT TYPE with associate-name
PR46809: ICE with -fcheck=pointer for CLASS IS
PR46838: Initialization of polymorphic allocatable components
PR46849: MODULE PROCEDURE resolution does not work in BLOCK or SELECT TYPE
PR46971: [4.6 Regression] ICE on long class names
PR47024: STORAGE_SIZE (for polymorphic types): Segfault at run time
PR47082: [4.6 Regression] ICE in gfc_conv_component_ref
PR47180: EXTENDS_TYPE_OF returns the wrong result for disassociated polymorphic pointers
PR47189: calling STORAGE_SIZE on a NULL-initialized class pointer
PR47194: EXTENDS_TYPE_OF still returns the wrong result if the polymorphic variable is unallocated
PR47204: [4.6 Regression] ICE: SIGSEGV in gfc_free_namespace (symbol.c:3323) on invalid code
PR47455: [4.6 Regression] internal compiler error: in fold_convert_loc, at fold-const.c:2028
PR47463: ICE in gfc_add_component_ref
PR47565: [4.6 Regression] Segfault with TBP
PR47572: Invalid: Allocatable polymorphic with init expression
PR47637: Memory leak involving INTENT(OUT) CLASS argument w/ allocatable components
PR47728: ICE on invalid CLASS declaration
PR47730: ICE on invalid source in connection with SELECT TYPE
PR47745: Segfault with CLASS(*) and derived type dummy arguments
PR47767: SELECT TYPE fails to execute correct TYPE IS block
PR48059: [4.6 Regression] ICE in in gfc_conv_component_ref: character function of extended type
Fixed in 4.7 (54)
PR41539: Calling function which takes CLASS: Rank comparison does not work
PR43214: TBP with non-scalar PASS
PR43969: ALLOCATED() with polymorphic arrays
PR44568: ICE with TBP of polymorphic derived type array
PR46262: tree check: expected function_type or method_type, have pointer_type
PR46328: type-bound operator call with non-trivial polymorphic operand
PR46356: Erroneous procedure/intent error and ICE for class dummy argument
PR46990: gfortran rejects passing a CLASS variable to TYPE
PR47546: Internal error - free_pi_tree(): Unresolved fixup
PR47601: Internal Error: mio_component_ref(): Component not found
PR47978: Invalid INTENT in overriding TBP not detected
PR48095: Invalid assignment to procedure pointer component not rejected
PR48291: [4.6/4.7 Regression] internal compiler error, new_symbol(): Symbol name too long
PR48351: Realloc on assignment fails if parent component is CLASS
PR48699: [4.6/4.7 Regression] MOVE_ALLOC inside SELECT TYPE
PR48705: ICE with generic TBP
PR48810: [4.6/4.7 Regression] TPB rejected because module procedure is private
PR48887: SELECT TYPE: Associate name shall not be a pointer/allocatable
PR48946: Deferred Overloaded Assignment
PR49074: Defined assignment w/ CLASS arrays: Incomplete error message
PR49112: [4.6/4.7 Regression] Missing type-bound procedure, "duplicate save" warnings and internal compiler error
PR49417: [4.6/4.7 Regression] ICE on invalid CLASS component declaration
PR49562: [4.6/4.7 Regression] ICE-on-invalid: assigning value to type-bound function
PR49638: length parameter is ignored when overriding type bound character functions with constant length
PR50225: The allocation status for polymorphic allocatable function results is not set properly
PR50227: [4.7 Regression] ICE-on-valid with allocatable class variable
PR50625: [4.6/4.7 Regression] ALLOCATABLE attribute lost for module CLASS variables
PR50640: [4.7 Regression] FAIL: gfortran.dg/select_type_12.f03 -O (internal compiler error)
PR50919: Don't use vtable for NON_OVERRIDABLE TBP
PR50960: vtables not marked as constant
PR51052: Internal compiler error in gfc_conv_component
PR51056: [4.7 Regression] Bogus "Unused module variable '__vtab_domain_Domain_container'"
PR51293: ICE on ANY with overloaded == operator
PR51334: ICE with type-bound operator: tree check: expected record_type or union_type or qual_union_type, have function_type in gfc_conv_component_ref, at fortran/trans-expr.c:556
PR51378: Structure constructor wrongly rejects parent components if only child has PRIVATE comps
PR51383: arrays of extended types break when associated
PR51529: gfortran.dg/class_to_type_1.f03 is miscompiled: Uninitialized variable used
PR51605: SELECT TYPE with TARGET (internal compiler error gfc_trans_block_construct, at fortran/trans-stmt.c:984)
PR51634: ICE with polymorphic operators
PR51809: [4.7 Regression] ICE (segfault) depending on USE statements order
PR51733: No allocate on assign for class objects with allocatable components
PR51754: ICE on valid with class arrays
PR51870: ICE with ALLOCATE and SOURCE-expr function returning BT_CLASS (cf. also PR51943 and PR51946)
PR51913: [4.6/4.7 Regression] bug when submitting a class pointer to a subroutine
PR51948: [4.6/4.7 Regression] Rejects valid: Function result value in MOVE_ALLOC, nested in SELECT TYPE
PR51970: gimplification failed for polymorphic MOVE_ALLOC
PR51972: ALLOCATE misses memset/calloc, causing segfault
PR51977: MOVE_ALLOC: Bogus "must have the same rank 0/1" for same-rank arrays
PR52013: Polymorphism and coarrays: Support as class container
PR52016: Polymorphism and elemental: missing diagnostic
PR52024: GENERIC operator cannot be resolved
PR52029: _copy should be PURE
PR52102: Wrong result with ALLOCATE w/ SOURCE= and nonpoly. array constructor source-expr
PR52044: Invalid memory access with ALLOCATE, default initializer and polymorphic array components