!standard 3.9.3(4/3) 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. ***************************************************************