J3/14-165 To: J3 Subject: Protected types work item proposal From: Van Snyder Date: 2014 May 30 Reference: 97-114, 03-258r1, 04-163, 04-167, 13-214, 13-348, 14-138r2, 14-139r1, 14-162r2 1. Introduction =============== LOCK_TYPE in 14-007r1 and EVENT_TYPE in TS 18508 each have three essentially identical constraints relating to protection, although the draft of TS 18508 neglected to specify one for EVENT_TYPE that is parallel to C438 in 14-007r1 (C433 in 10-007r1). This duplication is undesirable. The constraints and requirements on LOCK_TYPE and EVENT_TYPE implement most features necessary for general protected types. They are narrowly focused on the requirements of those two types. The difference between what's done for LOCK_TYPE and EVENT_TYPE, and what's necessary for general protected types, is that subobjects of general protected types are not protected by the existing constraints in 14-007r1, or the proposed ones in TS 18508 -- because all components of types LOCK_TYPE and EVENT_TYPE are private. It would be better to provide protected types, which would be useful for types defined anywhere within programs, not just the two types related to coarrays and that are defined within ISO_FORTRAN_ENV. There are four reasons to propose this work item at this time, rather than to wait for the next revision after 2015: 1. Protected types have been requested several times, by several people. They were part of the Ada Strawman requirements before Fortran 77 was published. Nobody has objected to them based on their merits. 2. It is counterproductive to embellish existing features with additional baggage, or to copy existing ones almost exactly, if more generally useful facilities could do the job. We should not develop duplicative, redundant, special, and narrowly-focused facilities, constraints, prohibitions, or requirements that contribute to the eternal bulk of the standard, textbooks, and processors, if they could be subsumed by more generally useful facilities. 3. To protect types LOCK_TYPE and EVENT_TYPE, processors need much of the machinery of general protected types, regardless whether it is provided as a general facility available for all types, or as a special facility applicable only to those two types (so far). 4. Although the size of the standard would be increased (by about one page) by this proposal, its size after integrating TS 18508 would be reduced. Without this facility, introducing further types that are effectively protected types would increase the size of the standard substantially more than would be the case if they were protected using the mechanism of this proposal, which requires only one word ("protected") for each type, and no functions to reference components. 2. Proposal for 2015 work plan ============================== Provide a PROTECTED attribute for a type definition. Define the effects of the attribute. Specify that the type LOCK_TYPE defined in subclause 13.8.2.16 is a protected type. Eliminate constraints C437, C438, C1303 and C1304. The effects of the PROTECTED attribute are o A protected type shall be extensible. o The PROTECTED attribute for a type shall be specified only in the specification part of a module. o Except within the module where a protected type is defined, or a descendant of that module, a variable of that type, or that has a subobject of that type, shall not appear in a variable definition context (16.6.7), except as -- the in a defined assignment, provided the subroutine that defines the assignment is defined in the module where the type is defined, or a descendant of that module, -- the in a statement specifier, provided the is required to be of a protected type that is defined in an intrinsic module, -- an actual argument corresponding to a dummy argument that has INTENT(INOUT), -- an in an ALLOCATE statement without a SOURCE= specifier, or in a DEALLOCATE statement, -- a in a , or -- a in a . {The last two exceptions are not needed if the revision of variable definition context proposed in 14-139r1 is adopted.} o Except within the module where a protected type is defined, or a descendant of that module, a nonpointer subobject of a variable of that type shall not appear -- in a variable definition context (16.6.7), -- as an actual argument corresponding to a dummy argument that does not explicitly have INTENT(IN). -- as the in a pointer assignment statement, -- as the corresponding to a component with the POINTER attribute in a , -- as an actual argument corresponding to a dummy argument with the POINTER attribute, or -- as an actual argument in a reference to the C_LOC function from the ISO_C_BINDING intrinsic module. {If the last four items were put into a new subclause 16.6.9 "Pointer targeting context" a reference thereto could be used here and in C1296.} o Except within the module where a protected type is defined, or a descendant of that module, a pointer subobject of a variable of that type shall not appear in a pointer association context (16.6.8), or as an actual argument corresponding to a pointer dummy argument that does not explicitly have INTENT(IN). {The definition of subobject in 6.4.2p5 excludes the targets of pointers. The above requirements prohibit changing the value of a nonpointer subobject of an object of protected type, or the association status of a pointer subobject of an object of protected type; they do not prohibit changing the value of the target of a pointer subobject of an object of protected type. Do we want to allow or prohibit that? Prohibiting it would be somewhat more complicated, and would make protected type objects look like things pure subprograms are not allowed to meddle with.} o If any in an ALLOCATE statement is unlimited polymorphic, shall not specify a protected type or a type that has a potential subobject component of protected type, and the declared type of shall not be a protected type or a type that has a potential subobject component of protected type. o If in a pointer assignment statement is unlimited polymorphic, the declared type of shall not be a protected type, and shall not have a potential subobject component of protected type. o The value of the actual argument associated with the CPTR argument of the C_F_POINTER subroutine from the ISO_C_BINDING intrinsic module shall not be the C address of an object of protected type, unless the object is type compatible with actual argument corresponding to the FPTR argument. o If a dummy argument is of a protected type, or has a component of protected type at any level of component selection, the procedure interface shall be explicit. o If an extension type has a potential subobject component of protected type, either its parent type shall be a protected type defined in the same module as the type of the protected component, or its parent type shall shall have a potential subobject component of a protected type defined in the same module as the protected component. This is to prevent subverting protection by using polymorphism. {It is unnecessary and undesirable to make this constraint stronger by requiring the same type instead of a protected type from the same module.} The ability to change the association status of a pointer of protected type, provided it is not a component of an object of protected type, allows using one to traverse a linked list of protected type, but not change any of the elements of the list. This proposal interacts with 14-138r2. Revisions proposed therein to C1303 and C1304 would not be necessary if this proposal were adopted, because this proposal deletes those constraints. This proposal interacts with 14-139r1. Revisions proposed therein to the definitions of variable definition context and pointer association context would simplify C441b in the Draft Edits section. 3. Draft Edits to 14-007r1 ========================== Draft edits are provided to 14-007r1, to estimate the scope of a project to provide protected types. There is a companion PDF showing the appearance of the new text -- a net increase of 32 lines in the standard. [6:19+] Define a new term "1.3.35.2a <> a nonpointer component, or a potential subobject component of a nonpointer component" {This definition is also proposed in 14-138r2 and 14-154r1.} [63:28+ R427] Insert an alternative to R427: "<> PROTECTED" [64:5 C435] After "ABSTRACT" insert "or PROTECTED". [64:9-11 C438] Delete constraint C438. [67:1- before subclause 4.5.3] Insert a subclause "4.5.2.5 PROTECTED attribute for types The PROTECTED attribute for types imposes restrictions on the contexts in which objects of those types may appear. A type with the PROTECTED attribute is a protected type. Except within a module where a protected type is defined, or a descendant of that module, a nonpointer variable of that type, the target of a pointer of that type, and a subobject of a variable of that type, are not definable. C441a (R427) The PROTECTED attribute for a type shall be specified only in the specification part of a module. {C441a might be redundant to C550; if so it need not be added.} C441b (R427) Except within the module where a protected type is defined, or a descendant of that module, a variable of that type, or that has a subobject of that type, shall not appear in a variable definition context (16.6.7), except as -- the in a defined assignment, provided the subroutine that defines the assignment is defined in the module where the type is defined, or a descendant of that module, -- the in a statement specifier, provided the is required to be of a protected type that is defined in an intrinsic module, -- an actual argument corresponding to a dummy argument that has INTENT(INOUT), -- an in an ALLOCATE statement without a SOURCE= specifier, or in a DEALLOCATE statement, -- a in a , or -- a in a . {The last two exceptions are not needed if the revision of variable definition context proposed in 14-139r1 is adopted.} C441c (R427) Except within the module where a protected type is defined, or a descendant of that module, a nonpointer subobject of a variable of that type shall not appear as -- in a variable definition context (16.6.7), -- as an actual argument corresponding to a dummy argument that does not explicitly have INTENT(IN), -- as the in a pointer assignment statement, -- as the corresponding to a component with the POINTER attribute in a , -- as an actual argument corresponding to a dummy argument with the POINTER attribute, or -- as an actual argument in a reference to the C_LOC function from the ISO_C_BINDING intrinsic module. {If the last four items were put into a new subclause 16.6.9 "Pointer targeting context" a reference thereto could be used here and in C1296.} C441d (R427) Except within the module where a protected type is defined, or a descendant of that module, a pointer subobject of a variable of that type shall not appear in a pointer association context (16.6.8), or as an actual argument corresponding to a pointer dummy argument that does not explicitly have INTENT(IN). {The definition of subobject in 6.4.2p5 excludes the targets of pointers. The above requirements prohibit changing the value of a nonpointer subobject of an object of protected type, or the association status of a pointer subobject of an object of protected type; they do not prohibit changing the value of the target of a pointer subobject of an object of protected type. Do we want to allow or prohibit that? Prohibiting it would be somewhat more complicated, and would make protected type objects look like things pure subprograms are not allowed to meddle with. (see note 4.22d below)} C441e (R425) If EXTENDS appears and the type being defined has a potential subobject component of protected type, its parent type shall either be a protected type, or shall have a potential subobject component of a protected type, and that type shall be defined in the same module as the type of the protected potential subobject component. {It is unnecessary and undesirable to make this constraint stronger by requiring the same type instead of a protected type from the same module.} The value of the actual argument associated with the CPTR argument of the C_F_POINTER subroutine from the ISO_C_BINDING intrinsic module shall not be the C address of an object of protected type, unless the object is type compatible with the actual argument corresponding to the FPTR argument. NOTE 4.22b One can use a pointer to examine objects of protected type, for example to traverse a list or tree, but not to change their values or the pointer associations of their subobjects. NOTE 4.22c Constraint C441e ensures that protection cannot be subverted using polymorphism. NOTE 4.22d The target of a pointer subobject is not a subobject (6.4.2). Therefore, although it is not possible to change the pointer association status of a pointer subobject of an object of protected type, it is possible to associate a pointer with the same target, or to change the value of its target. " [103:2 C555] Replace "procedure pointer or variable" with "derived type definition, procedure pointer, or variable". [129:11+ C644+] Insert a constraint: "C644a (R630) If any is unlimited polymorphic, shall not specify a protected type or a type that has a potential subobject component of protected type, and the declared type of shall not be a protected type or a type that has a potential subobject component of protected type." [160:10+ C716+] Insert a constraint: "C716a (R733) If is unlimited polymorphic, the declared type of shall not be a protected type, nor shall it have a potential subobject component of protected type." [279:29+ 12.5.2.2p1(2)(c)+] Insert a list item "(cc) is of a protected type, or has a subobject of a protected type," [402:15 13.8.2.16p1] Replace "derived type" with "protected derived type (4.5.2.5)". [402:16-17 13.8.2.16p1] Delete "Therefore it does not have the BIND attribute, and is not a sequence type." {Proposal in ballot on TS 18508 to add this was rejected; should we be consistent?} [403:24-29 C1303, C1304] Delete constraints C1303 and C1304. [436:4,6 C1501, C1503] Combine the constraints and add ABSTRACT and PROTECTED: "C1501 (R425) A derived type with the BIND attribute shall not have the ABSTRACT, EXTENDS, SEQUENCE or PROTECTED attribute." 4. Proposal for TS 18508 ======================== Specify that the type EVENT_TYPE described in subclause 6.2 of TS 18508 is a protected type. Eliminate constraints C602 and C603 in TS 18508. Specify that type EVENT_TYPE has a public COUNT component. Eliminate subclause 7.4.11 EVENT_QUERY from TS 18508. 5. Draft Edits to TS 18508 -- 14-130 ==================================== Draft edits to TS 18508 are provided, to estimate the scope of a project to provide protected types. These do not apply directly to TS 18508 if it is proposed as an amendment to Fortran 2008; rather, they would be incorporated during its integration into Fortran 2015 or a later revision. To accomodate future integration, the EVENT_QUERY intrinsic function should in any case be removed from TS 18508. EVENT_TYPE should instead be defined to have a public COUNT component, with constraints to protect that component. Those constraints could be removed when TS 18508 is incorporated into Fortran 2015 or a later revision that includes protected types. [15:6 6.2p1] Before "derived" insert "protected (4.5.2.5)". Before "private components" insert "one public component, named COUNT, of integer type and processor-dependent kind; it may have". Before "It is" insert "The value of HUGE with a COUNT component argument shall not be less than HUGE(0)." {An alternative is that EVENT_TYPE has a kind type parameter that specifies the kind of the COUNT component.} [15:8] Replace "An event variable has a count that" by "The COUNT component of an event variable" [15:9-10] Replace "The effect of each change ... change" with "The COUNT component of an event variable is updated as if by invoking the ATOMIC_ADD intrinsic subroutine". [15:12] Replace "event count" with "COUNT component". [15:13] Delete "The processor ... HUGE(0)." [15:16-24 C602, C603] Delete the constraints. [15:30] Replace "count" with "COUNT component". [16:10] Replace "count" with "COUNT component". [16:12] Replace "event count" with "COUNT component of the event variable". [16:13] Replace "count" with "COUNT component". [17:6] Delete "EVENT_QUERY,". [23:24-24:2+2] Delete subclause 7.4.11. [34:14+20] Eliminate the EVENT_QUERY row from the table revision. [36:29+] Add a list item: "o the kind of the COUNT component of the type EVENT_TYPE from the ISO_FORTRAN_ENV intrinsic module;" {An alternative is that EVENT_TYPE has a kind type parameter that specifies the kind of the COUNT component.} [43:6] Replace "EVENT_QUERY" with "Event count". [43:25] Delete "count," [43:40-47] Replace with " if ( confirm%event(i)%count > 0 ) then ! avoid blocking if processing ! on worker is incomplete "