Version 1.1 of acs/ac-00252.txt

Unformatted version of acs/ac-00252.txt version 1.1
Other versions for file acs/ac-00252.txt

!standard 3.5.2(4/2)          13-10-24 AC95-00252/00
!class confirmation 13-10-24
!status received no action 13-10-24
!status received 13-08-07
!subject Possible hole with functions that require overriding
!summary
!appendix

!topic
!reference
!from Adam Beneschan 13-08-07
!discussion

This is illegal because Create needs to be overridden for T2, because
otherwise the inherited subprogram wouldn't initialize New_Field:

    package Pack1 is
        type T1 is tagged null record;
        function Create (N : Integer) return T1;
    end Pack1;

    with Pack1;
    package Pack2 is
        type T2 is new Pack1.T1 with record
            New_Field : Integer;
        end record;
    end Pack2;

But what makes this illegal?

    package Pack1 is
        type T1 is tagged null record;
        function Create (N : Integer) return T1;
    end Pack1;

    with Pack1;
    package Pack2 is
        type T2 is abstract new Pack1.T1 with record
            New_Field : Integer;
        end record;
    end Pack2;

    with Pack2;
    package Pack3 is
        type T3 is new Pack2.T2 with null record;
    end Pack3;

For T2, it's legal to define the derived type without overriding
Create, because the type is abstract (3.9.3(5)).  And for T3, it's
legal to define the derived type without overriding Create, because T3
is a nonabstract null extension (3.9.3(4)).  But New_Field still
doesn't get initialized.

***************************************************************

From: Randy Brukardt
Sent: Wednesday, August  7, 2013   8:57 PM

> !topic

Cool! The empty topic! :-)

...
> But what makes this illegal?
>
>     package Pack1 is
>         type T1 is tagged null record;
>         function Create (N : Integer) return T1;
>     end Pack1;
>
>     with Pack1;
>     package Pack2 is
>         type T2 is abstract new Pack1.T1 with record
>             New_Field : Integer;
>         end record;
>     end Pack2;
>
>     with Pack2;
>     package Pack3 is
>         type T3 is new Pack2.T2 with null record;
>     end Pack3;
>
> For T2, it's legal to define the derived type without overriding
> Create, because the type is abstract (3.9.3(5)).
> And for T3, it's legal to define the derived type without overriding
> Create, because T3 is a nonabstract null extension (3.9.3(4)).  But
> New_Field still doesn't get initialized.

T3 is not legal, according to my reading of 3.9.3(4-6).

T2 is an abstract type, and Create triggers 3.9.3(4) because it is a function
with a controlling result. Since T2 is abstract, 3.9.3(5) is triggered, and "the
implicitly declared subprogram is abstract".

For T3, 3.9.3(4) is also triggered, because "the corresponding primitive
subprogram of the parent type is abstract". We don't care about the part about
non-null extensions of functions with controlling results; that fact that it is
false isn't relevant since another part of the rule is true (and this is an
"or"). Since neither 3.9.3(5) nor 3.9.3(6) apply, the declaration is illegal.

Thank goodness, too, because I don't want to have to try to reword this mess
again! Note that the key here is that a function can both have a controlling
result and be abstract, and those things are separate tests.

The wording isn't as clear as it could be, because of the need to talk about
"ancestor types" so this rule can be applied to interfaces and generic derived
types (which don't have parent types per-se). The intent is that you only look
at the closest ancestor for this purpose - the parent for a derived type; in
particular T1's Create has no bearing on this test. I could see adding an AARM
note to clarify that, but I don't think it's practical to actually clarify the
wording (each time we change it, it gets messier! Most of those changes were
necessary to fix actual bugs, so we couldn't avoid them, but this one is more
obvious).

***************************************************************

From: Tucker Taft
Sent: Wednesday, August  7, 2013   9:41 PM

I agree with Randy.  The corresponding (Create) subprogram in the parent type is
abstract, so it must be overridden in the derived type.

***************************************************************

From: Adam Beneschan
Sent: Thursday, August  8, 2013  10:32 AM

> > !topic
>
> Cool! The empty topic! :-)

I guess the topic name is an accurate reflection of the contents of my brain at
the time I asked my question.  Of *course* an abstract subprogram has to be
overridden.  Don't know how I completely missed that.

Thanks for pointing that out.

***************************************************************


Questions? Ask the ACAA Technical Agent