!standard 12.7 (06) 98-11-23 AI95-00213/00 !standard D.4 (11) !class confirmation 98-11-23 !status work item 98-11-23 !priority High !difficulty Easy !subject Formal object matching for formal packages. !summary 98-11-23 For a generic formal object of mode in, the rule in clause 12.7(6) is applied to the actual parameter of the actual instance, and the actual parameter for the formal package. The copy of the actual created for the instance plays no part in the matching. !question 98-11-23 For a generic formal object of mode in, the rule in clause 12.7(6) defines a matching rule for actuals of generic formal packages. If the type of such an object is a type which cannot have static expressions (such as a tagged type), can the actuals ever match? (Yes.) An actual for an instance denotes a new-stand alone constant initialized by the actual to the instantiation, as described in 12.4(10). Therefore, the actuals for a formal package can never statically denote the same constant. Is this correct? (No.) Here is an example: package Pack is type Count_Type is tagged record; Count : Integer := 0; end record; TC_Default_Count : constant Count_Type := (Count => 0); end Pack; generic type Item (<>) is tagged private; TC_Default_Value : Item; package Test_0 is ... end Test_0; with Test_0; generic type Item_Type (<>) is tagged private; Default : Item_Type; with package Stacker is new Test_0 (Item_Type, Default); procedure Test_1 (S : in out Stacker.Stack; I : in Item_Type); with Pack; with Test_0; pragma Elaborate (Test_0); package Test_2 is new Test_0 (Pack.Count_Type, Pack.TC_Default_Count); procedure Test is package Count_Stacks renames Test_2; procedure TC_Count_Test is new Test_1 (Pack.Count_Type, Pack.TC_Default_Count,Count_Stacks); -- Legal? (Yes.) ... end Test; Note that Test_2.Default denotes a constant initialized by Pack.TC_Default_Count, while TC_Count_Test.TC_Default_Value denotes Pack.TC_Default_Count. Do these match by the rule of 12.7(6)? (Yes.) !response 98-11-23 The wording in paragraphs in 12.7(5) and 12.7(6) was carefully constructed to insure that the actuals to the instantiations are used when applying 12.7(6), and not the copy defined by 12.4(10). The lengthy wording "the actual parameter of the actual instance" was used to insure that the meaning was unambiguous. If the alternative meaning suggested by the question was used, none of the matching rules defined in 12.7(6) would be meaningful. The "stand-alone constant object" of 12.4(10) cannot be a static expression or the literal null anymore than it "denotes the same constant". Therefore, adopting the alternative meaning makes 12.7(6) completely useless, and would make it impossible to use formal packages with formal object of mode in. Such a result is clearly nonsense, and could not have been intended by the language designers. !appendix 98-11-23 From: Randy Brukardt[SMTP:Randy@rrsoftware.com] Sent: Saturday, November 21, 1998 7:47 PM Subject: Generic formal package matching. Here is a petition against an ACATS test: CC50A01 When a generic unit declares, in its generic formal part, a formal package with a generic_actual_part (as opposed to "(<>)"), the rules governing which instances are legal as an actual parameter (RM 12.7(6)) are quite strict when the generic_package_name mentioned in the formal package has formal objects. In particular, if the formal object is of mode IN, then the actual in the formal package and the actual in its matching actual package must be static expressions with the same value, or statically denote the same constant, or both be the literal null. The generic package CC50A01_0 has a formal object of mode IN in its generic formal part. This generic package is used as the generic_package_name in the formal package Stacker in generic CC50A01_1. The generic package CC50A01_1 is then instantiated twice as CC50A01.TC_Count_Test and as CC5 0A01.TC_Person_Test. Included is an abbreviated version of the test: package FC50A00 is type Count_Type is tagged record; Count : Integer := 0; end record; type Person_Type (Stat : Status; NameLen, AddrLen : Str_Len) is tagged record ... end record; TC_Default_Count : constant Count_Type := (Count => 0); TC_Default_Person : constant Person_Type := ...; end FC50A00; generic type Item (<>) is tagged private; TC_Default_Value : Item; package CC50A01_0 is ... end CC50A01_0; with CC50A01_0; generic type Item_Type (<>) is tagged private; Default : Item_Type; with package Stacker is new CC50A01_0 (Item_Type, Default); procedure CC50A01_1 (S : in out Stacker.Stack; I : in Item_Type); with FC50A00; with CC50A01_0; pragma Elaborate (CC50A01_0); package CC50A01_2 is new CC50A01_0 (FC50A00.Count_Type, FC50A00.TC_Default_Count); with FC50A00; with CC50A01_0; pragma Elaborate (CC50A01_0); package CC50A01_3 is new CC50A01_0 (FC50A00.Person_Type, FC50A00.TC_Default_Person); procedure CC50A01 is package Count_Stacks renames CC50A01_2; package Person_Stacks renames CC50A01_3; procedure TC_Count_Test is new CC50A01_1 (FC50A00.Count_Type, FC50A00.TC_Default_Count,Count_Stacks); procedure TC_Person_Test is new CC50A01_1 (FC50A00.Person_Type, FC50A00.TC_Default_Person,Person_Stacks); ... end CC50A01; For TC_Count_Test, the value FC50A00.TC_Default_Count is specified for Default. Therefore Default becomes a stand-alone constant initialized to the value of FC50A00.TC_Default_Count by RM 12.4(10). Default is the actual for the formal object TC_Default_Value in the formal package Stacker. The actual for the formal package Stacker is Count_Stacks, which is a rename of CC50A01_2. Its actual for the formal object TC_Default_Value is FC50A00.TC_Default_Count. For Count_Stacks to be a legal actual for the formal package Stacker, then the actuals corresponding to each of their formal objects TC_Default_Count must be static expressions with the same value, or they must statically denote the same constant, or they must both be the literal null. Obviously, neither is the literal null. Also, neither is a static expression because they are both of tagged record types, and RM 4.9(24) in conjunction with 4.9(5) considers only those constants initialized with static scalar or string expressions to be static expressions. Finally, they do not statically denote the same constant. The actual for Count_Stacks denotes the object FC50A00.TC_Default_Count, whereas the actual for Stacker denotes Default, which is a new stand-alone constant merely initialized to the value of FC50A00.TC_Default_Count. Because of this, the following diagnostic is issued: 289: procedure TC_Count_Test is new CC50A01_1 (FC50A00.Count_Type, 290: FC50A00.TC_Default_Count, 291: Count_Stacks); A ---------------------------------------------^ A:error: RM 12.7(6): formal package actual mismatch for formal "in" object tc_default_value An analogous argument holds for CC50A01.TC_Person_Test. The value FC50A00.TC_Default_Person is specified for Default. Therefore Default becomes a stand-alone constant initialized to the value of FC50A00.TC_Default_Person by RM 12.4(10). Default is the actual for the formal object TC_Default_Value in the formal package Stacker. The actual for the formal package Stacker is Person_Stacks, which is a rename of CC50A01_3. Its actual for the formal object TC_Default_Value is FC50A00.TC_Default_Person. For Person_Stacks to be a legal actual for the formal package Stacker, then the actuals corresponding to each of their formal objects TC_Default_Person must be static expressions with the same value, or they must statically denote the same constant, or they must both be the literal null. Obviously, neither is the literal null. Also, neither is a static expression because they are both of tagged record types, and RM 4.9(24) in conjunction with RM 4.9(5) considers only those constants initialized with static scalar or string expressions to be static expressions. Finally, they do not statically denote the same constant. The actual for Person_Stacks denotes the object FC50A00.TC_Default_Person, whereas the actual for Stacker denotes Default, which is a new stand-alone constant merely initialized to the value of FC50A00.TC_Default_Person. Because of this, the following diagnostic is issued: 295: procedure TC_Person_Test is new CC50A01_1 (FC50A00.Person_Type, 296: FC50A00.TC_Default_Person, 297: Person_Stacks); A ----------------------------------------------^ A:error: RM 12.7(6): formal package actual mismatch for formal "in" object tc_default_value We request that this test be withdrawn. ACAA analysis: My first reaction to this petition is ugh - if the petition is correct, the use of formal packages is greatly restricted Once getting past this, I found that the operative part is: "Finally, they do not statically denote the same constant. The actual for Count_Stacks denotes the object FC50A00.TC_Default_Count, whereas the actual for Stacker denotes Default, which is a new stand-alone constant merely initialized to the value of FC50A00.TC_Default_Count." Since the TC_Default_Count IS a constant, the only question is whether this interpretation that IN formals never denote their argument is correct. Certainly, none of the previous 46 conformity assessments using ACATS 2.1 (or ACVC 2.1) has found a problem here. In addition, such an interpretation is tantamount to claiming that formal IN parameters of composite types can never be used in generic formal packages. That's clearly silly. I would prefer to reject this petition for the above reasons, but I can't find a reason in the standard to do so. The implementors description of the meaning of an IN generic object is completely accurate. Clearly, this is an issue very much like the old Ada 83 issue of type A is new Integer range 1 .. 10; not being a static type. Randy. *************************************************************