| -- C760002.A |
| -- |
| -- Grant of Unlimited Rights |
| -- |
| -- Under contracts F33600-87-D-0337, F33600-84-D-0280, MDA903-79-C-0687, |
| -- F08630-91-C-0015, and DCA100-97-D-0025, the U.S. Government obtained |
| -- unlimited rights in the software and documentation contained herein. |
| -- Unlimited rights are defined in DFAR 252.227-7013(a)(19). By making |
| -- this public release, the Government intends to confer upon all |
| -- recipients unlimited rights equal to those held by the Government. |
| -- These rights include rights to use, duplicate, release or disclose the |
| -- released technical data and computer software in whole or in part, in |
| -- any manner and for any purpose whatsoever, and to have or permit others |
| -- to do so. |
| -- |
| -- DISCLAIMER |
| -- |
| -- ALL MATERIALS OR INFORMATION HEREIN RELEASED, MADE AVAILABLE OR |
| -- DISCLOSED ARE AS IS. THE GOVERNMENT MAKES NO EXPRESS OR IMPLIED |
| -- WARRANTY AS TO ANY MATTER WHATSOEVER, INCLUDING THE CONDITIONS OF THE |
| -- SOFTWARE, DOCUMENTATION OR OTHER INFORMATION RELEASED, MADE AVAILABLE |
| -- OR DISCLOSED, OR THE OWNERSHIP, MERCHANTABILITY, OR FITNESS FOR A |
| -- PARTICULAR PURPOSE OF SAID MATERIAL. |
| --* |
| -- |
| -- OBJECTIVE: |
| -- Check that assignment to an object of a (non-limited) controlled |
| -- type causes the Adjust operation of the type to be called. |
| -- Check that Adjust is called after copying the value of the |
| -- source expression to the target object. |
| -- |
| -- Check that Adjust is called for all controlled components when |
| -- the containing object is assigned. (Test this for the cases |
| -- where the type of the containing object is controlled and |
| -- noncontrolled; test this for initialization as well as |
| -- assignment statements.) |
| -- |
| -- Check that for an object of a controlled type with controlled |
| -- components, Adjust for each of the components is called before |
| -- the containing object is adjusted. |
| -- |
| -- Check that an Adjust procedure for a Limited_Controlled type is |
| -- not called by the implementation. |
| -- |
| -- TEST DESCRIPTION: |
| -- This test is loosely "derived" from C760001. |
| -- |
| -- Visit Tags: |
| -- D - Default value at declaration |
| -- d - Default value at declaration, limited root |
| -- I - initialize at root controlled |
| -- i - initialize at root limited controlled |
| -- A - adjust at root controlled |
| -- X,Y,Z,x,y,z - used in test body |
| -- |
| -- |
| -- CHANGE HISTORY: |
| -- 06 Dec 94 SAIC ACVC 2.0 |
| -- 19 Dec 94 SAIC Correct test assertion logic for Sinister case |
| -- |
| --! |
| |
| ---------------------------------------------------------------- C760002_0 |
| |
| with Ada.Finalization; |
| package C760002_0 is |
| subtype Unique_ID is Natural; |
| function Unique_Value return Unique_ID; |
| -- increments each time it's called |
| |
| function Most_Recent_Unique_Value return Unique_ID; |
| -- returns the same value as the most recent call to Unique_Value |
| |
| type Root is tagged record |
| My_ID : Unique_ID := Unique_Value; |
| Visit_Tag : Character := 'D'; -- Default |
| end record; |
| |
| procedure Initialize( R: in out Root ); |
| procedure Adjust ( R: in out Root ); |
| |
| type Root_Controlled is new Ada.Finalization.Controlled with record |
| My_ID : Unique_ID := Unique_Value; |
| Visit_Tag : Character := 'D'; ---------------------------------------- D |
| end record; |
| |
| procedure Initialize( R: in out Root_Controlled ); |
| procedure Adjust ( R: in out Root_Controlled ); |
| |
| type Root_Limited_Controlled is |
| new Ada.Finalization.Limited_Controlled with record |
| My_ID : Unique_ID := Unique_Value; |
| Visit_Tag : Character := 'd'; ---------------------------------------- d |
| end record; |
| |
| procedure Initialize( R: in out Root_Limited_Controlled ); |
| procedure Adjust ( R: in out Root_Limited_Controlled ); |
| |
| end C760002_0; |
| |
| with Report; |
| package body C760002_0 is |
| |
| Global_Unique_Counter : Unique_ID := 0; |
| |
| function Unique_Value return Unique_ID is |
| begin |
| Global_Unique_Counter := Global_Unique_Counter +1; |
| return Global_Unique_Counter; |
| end Unique_Value; |
| |
| function Most_Recent_Unique_Value return Unique_ID is |
| begin |
| return Global_Unique_Counter; |
| end Most_Recent_Unique_Value; |
| |
| procedure Initialize( R: in out Root ) is |
| begin |
| Report.Failed("Initialize called for Non_Controlled type"); |
| end Initialize; |
| |
| procedure Adjust ( R: in out Root ) is |
| begin |
| Report.Failed("Adjust called for Non_Controlled type"); |
| end Adjust; |
| |
| procedure Initialize( R: in out Root_Controlled ) is |
| begin |
| R.Visit_Tag := 'I'; --------------------------------------------------- I |
| end Initialize; |
| |
| procedure Adjust( R: in out Root_Controlled ) is |
| begin |
| R.Visit_Tag := 'A'; --------------------------------------------------- A |
| end Adjust; |
| |
| procedure Initialize( R: in out Root_Limited_Controlled ) is |
| begin |
| R.Visit_Tag := 'i'; --------------------------------------------------- i |
| end Initialize; |
| |
| procedure Adjust( R: in out Root_Limited_Controlled ) is |
| begin |
| Report.Failed("Adjust called for Limited_Controlled type"); |
| end Adjust; |
| |
| end C760002_0; |
| |
| ---------------------------------------------------------------- C760002_1 |
| |
| with Ada.Finalization; |
| with C760002_0; |
| package C760002_1 is |
| |
| type Proc_ID is (None, Init, Adj, Fin); |
| |
| type Test_Controlled is new C760002_0.Root_Controlled with record |
| Last_Proc_Called: Proc_ID := None; |
| end record; |
| |
| procedure Initialize( TC: in out Test_Controlled ); |
| procedure Adjust ( TC: in out Test_Controlled ); |
| procedure Finalize ( TC: in out Test_Controlled ); |
| |
| type Nested_Controlled is new C760002_0.Root_Controlled with record |
| Nested : C760002_0.Root_Controlled; |
| Last_Proc_Called: Proc_ID := None; |
| end record; |
| |
| procedure Initialize( TC: in out Nested_Controlled ); |
| procedure Adjust ( TC: in out Nested_Controlled ); |
| procedure Finalize ( TC: in out Nested_Controlled ); |
| |
| type Test_Limited_Controlled is |
| new C760002_0.Root_Limited_Controlled with record |
| Last_Proc_Called: Proc_ID := None; |
| end record; |
| |
| procedure Initialize( TC: in out Test_Limited_Controlled ); |
| procedure Adjust ( TC: in out Test_Limited_Controlled ); |
| procedure Finalize ( TC: in out Test_Limited_Controlled ); |
| |
| type Nested_Limited_Controlled is |
| new C760002_0.Root_Limited_Controlled with record |
| Nested : C760002_0.Root_Limited_Controlled; |
| Last_Proc_Called: Proc_ID := None; |
| end record; |
| |
| procedure Initialize( TC: in out Nested_Limited_Controlled ); |
| procedure Adjust ( TC: in out Nested_Limited_Controlled ); |
| procedure Finalize ( TC: in out Nested_Limited_Controlled ); |
| |
| end C760002_1; |
| |
| with Report; |
| package body C760002_1 is |
| |
| procedure Initialize( TC: in out Test_Controlled ) is |
| begin |
| TC.Last_Proc_Called := Init; |
| C760002_0.Initialize(C760002_0.Root_Controlled(TC)); |
| end Initialize; |
| |
| procedure Adjust ( TC: in out Test_Controlled ) is |
| begin |
| TC.Last_Proc_Called := Adj; |
| C760002_0.Adjust(C760002_0.Root_Controlled(TC)); |
| end Adjust; |
| |
| procedure Finalize ( TC: in out Test_Controlled ) is |
| begin |
| TC.Last_Proc_Called := Fin; |
| end Finalize; |
| |
| procedure Initialize( TC: in out Nested_Controlled ) is |
| begin |
| TC.Last_Proc_Called := Init; |
| C760002_0.Initialize(C760002_0.Root_Controlled(TC)); |
| end Initialize; |
| |
| procedure Adjust ( TC: in out Nested_Controlled ) is |
| begin |
| TC.Last_Proc_Called := Adj; |
| C760002_0.Adjust(C760002_0.Root_Controlled(TC)); |
| end Adjust; |
| |
| procedure Finalize ( TC: in out Nested_Controlled ) is |
| begin |
| TC.Last_Proc_Called := Fin; |
| end Finalize; |
| |
| procedure Initialize( TC: in out Test_Limited_Controlled ) is |
| begin |
| TC.Last_Proc_Called := Init; |
| C760002_0.Initialize(C760002_0.Root_Limited_Controlled(TC)); |
| end Initialize; |
| |
| procedure Adjust ( TC: in out Test_Limited_Controlled ) is |
| begin |
| Report.Failed("Adjust called for Test_Limited_Controlled"); |
| end Adjust; |
| |
| procedure Finalize ( TC: in out Test_Limited_Controlled ) is |
| begin |
| TC.Last_Proc_Called := Fin; |
| end Finalize; |
| |
| procedure Initialize( TC: in out Nested_Limited_Controlled ) is |
| begin |
| TC.Last_Proc_Called := Init; |
| C760002_0.Initialize(C760002_0.Root_Limited_Controlled(TC)); |
| end Initialize; |
| |
| procedure Adjust ( TC: in out Nested_Limited_Controlled ) is |
| begin |
| Report.Failed("Adjust called for Nested_Limited_Controlled"); |
| end Adjust; |
| |
| procedure Finalize ( TC: in out Nested_Limited_Controlled ) is |
| begin |
| TC.Last_Proc_Called := Fin; |
| end Finalize; |
| |
| end C760002_1; |
| |
| ---------------------------------------------------------------- C760002 |
| |
| with Report; |
| with TCTouch; |
| with C760002_0; |
| with C760002_1; |
| with Ada.Finalization; |
| procedure C760002 is |
| |
| use type C760002_1.Proc_ID; |
| |
| -- in the first test, test the simple cases. |
| -- Also check that assignment causes a call to Adjust for a controlled |
| -- object. Check that assignment of a non-controlled object does not call |
| -- an Adjust procedure. |
| |
| procedure Check_Simple_Objects is |
| |
| A,B : C760002_0.Root; |
| S,T : C760002_1.Test_Controlled; |
| Q : C760002_1.Test_Limited_Controlled; -- Adjust call shouldn't happen |
| begin |
| |
| S := T; |
| |
| TCTouch.Assert((S.Last_Proc_Called = C760002_1.Adj), |
| "Adjust for simple object"); |
| TCTouch.Assert((S.My_ID = T.My_ID), |
| "Assignment failed for simple object"); |
| |
| -- Check that adjust was called |
| TCTouch.Assert((S.Visit_Tag = 'A'), "Adjust timing incorrect"); |
| |
| -- Check that Adjust has not been called |
| TCTouch.Assert_Not((T.Visit_Tag = 'A'), "Adjust incorrectly called"); |
| |
| -- Check that Adjust does not get called |
| A.My_ID := A.My_ID +1; |
| B := A; -- see: Adjust: Report.Failed |
| |
| end Check_Simple_Objects; |
| |
| -- in the second test, test a more complex case, check that a controlled |
| -- component of a controlled object gets processed correctly |
| |
| procedure Check_Nested_Objects is |
| NO1 : C760002_1.Nested_Controlled; |
| NO2 : C760002_1.Nested_Controlled := NO1; |
| |
| begin |
| |
| -- NO2 should be flagged with adjust markers |
| TCTouch.Assert((NO2.Last_Proc_Called = C760002_1.Adj), |
| "Adjust not called for NO2 enclosure declaration"); |
| TCTouch.Assert((NO2.Nested.Visit_Tag = 'A'), |
| "Adjust not called for NO2 enclosed declaration"); |
| |
| NO2.Visit_Tag := 'x'; |
| NO2.Nested.Visit_Tag := 'y'; |
| |
| NO1 := NO2; |
| |
| -- NO1 should be flagged with adjust markers |
| TCTouch.Assert((NO1.Visit_Tag = 'A'), |
| "Adjust not called for NO1 enclosure declaration"); |
| TCTouch.Assert((NO1.Nested.Visit_Tag = 'A'), |
| "Adjust not called for NO1 enclosed declaration"); |
| |
| end Check_Nested_Objects; |
| |
| procedure Check_Array_Case is |
| type Array_Simple is array(1..4) of C760002_1.Test_Controlled; |
| type Array_Nested is array(1..4) of C760002_1.Nested_Controlled; |
| |
| Left,Right : Array_Simple; |
| Overlap : Array_Simple := Left; |
| |
| Sinister,Dexter : Array_Nested; |
| Underlap : Array_Nested := Sinister; |
| |
| Now : Natural; |
| |
| begin |
| |
| -- get a current unique value since initializations |
| Now := C760002_0.Unique_Value; |
| |
| -- check results of declarations |
| for N in 1..4 loop |
| TCTouch.Assert(Left(N).My_Id < Now, |
| "Initialize for array initial value"); |
| TCTouch.Assert(Overlap(N).My_Id < Now, |
| "Adjust for nested array (outer) initial value"); |
| TCTouch.Assert(Sinister(N).Nested.My_Id < Now, |
| "Initialize for nested array (inner) initial value"); |
| TCTouch.Assert(Sinister(N).My_Id < Sinister(N).Nested.My_Id, |
| "Initialize for enclosure should be after enclosed"); |
| TCTouch.Assert(Overlap(N).Visit_Tag = 'A',"Adjust at declaration"); |
| TCTouch.Assert(Underlap(N).Nested.Visit_Tag = 'A', |
| "Adjust at declaration, nested object"); |
| end loop; |
| |
| -- set visit tags |
| for O in 1..4 loop |
| Overlap(O).Visit_Tag := 'X'; |
| Underlap(O).Visit_Tag := 'Y'; |
| Underlap(O).Nested.Visit_Tag := 'y'; |
| end loop; |
| |
| -- check that overlapping assignments don't cause odd grief |
| Overlap(1..3) := Overlap(2..4); |
| Underlap(2..4) := Underlap(1..3); |
| |
| for M in 2..3 loop |
| TCTouch.Assert(Overlap(M).Last_Proc_Called = C760002_1.Adj, |
| "Adjust for overlap"); |
| TCTouch.Assert(Overlap(M).Visit_Tag = 'A', |
| "Adjust for overlap ID"); |
| TCTouch.Assert(Underlap(M).Last_Proc_Called = C760002_1.Adj, |
| "Adjust for Underlap"); |
| TCTouch.Assert(Underlap(M).Nested.Visit_Tag = 'A', |
| "Adjust for Underlaps nested ID"); |
| end loop; |
| |
| end Check_Array_Case; |
| |
| procedure Check_Access_Case is |
| type TC_Ref is access C760002_1.Test_Controlled; |
| type NC_Ref is access C760002_1.Nested_Controlled; |
| type TL_Ref is access C760002_1.Test_Limited_Controlled; |
| type NL_Ref is access C760002_1.Nested_Limited_Controlled; |
| |
| A,B : TC_Ref; |
| C,D : NC_Ref; |
| E : TL_Ref; |
| F : NL_Ref; |
| |
| begin |
| |
| A := new C760002_1.Test_Controlled; |
| B := new C760002_1.Test_Controlled'( A.all ); |
| |
| C := new C760002_1.Nested_Controlled; |
| D := new C760002_1.Nested_Controlled'( C.all ); |
| |
| E := new C760002_1.Test_Limited_Controlled; |
| F := new C760002_1.Nested_Limited_Controlled; |
| |
| TCTouch.Assert(A.Visit_Tag = 'I',"TC Allocation"); |
| TCTouch.Assert(B.Visit_Tag = 'A',"TC Allocation, with value"); |
| |
| TCTouch.Assert(C.Visit_Tag = 'I',"NC Allocation"); |
| TCTouch.Assert(C.Nested.Visit_Tag = 'I',"NC Allocation, Nested"); |
| TCTouch.Assert(D.Visit_Tag = 'A',"NC Allocation, with value"); |
| TCTouch.Assert(D.Nested.Visit_Tag = 'A', |
| "NC Allocation, Nested, with value"); |
| |
| TCTouch.Assert(E.Visit_Tag = 'i',"TL Allocation"); |
| TCTouch.Assert(F.Visit_Tag = 'i',"NL Allocation"); |
| |
| A.all := B.all; |
| C.all := D.all; |
| |
| TCTouch.Assert(A.Visit_Tag = 'A',"TC Assignment"); |
| TCTouch.Assert(C.Visit_Tag = 'A',"NC Assignment"); |
| TCTouch.Assert(C.Nested.Visit_Tag = 'A',"NC Assignment, Nested"); |
| |
| end Check_Access_Case; |
| |
| procedure Check_Access_Limited_Array_Case is |
| type Array_Simple is array(1..4) of C760002_1.Test_Limited_Controlled; |
| type AS_Ref is access Array_Simple; |
| type Array_Nested is array(1..4) of C760002_1.Nested_Limited_Controlled; |
| type AN_Ref is access Array_Nested; |
| |
| Simple_Array_Limited : AS_Ref; |
| |
| Nested_Array_Limited : AN_Ref; |
| |
| begin |
| |
| Simple_Array_Limited := new Array_Simple; |
| |
| Nested_Array_Limited := new Array_Nested; |
| |
| for N in 1..4 loop |
| TCTouch.Assert(Simple_Array_Limited(N).Last_Proc_Called |
| = C760002_1.Init, |
| "Initialize for array initial value"); |
| TCTouch.Assert(Nested_Array_Limited(N).Last_Proc_Called |
| = C760002_1.Init, |
| "Initialize for nested array (outer) initial value"); |
| TCTouch.Assert(Nested_Array_Limited(N).Nested.Visit_Tag = 'i', |
| "Initialize for nested array (inner) initial value"); |
| end loop; |
| end Check_Access_Limited_Array_Case; |
| |
| begin -- Main test procedure. |
| |
| Report.Test ("C760002", "Check that assignment causes the Adjust " & |
| "operation of the type to be called. Check " & |
| "that Adjust is called after copying the " & |
| "value of the source expression to the target " & |
| "object. Check that Adjust is called for all " & |
| "controlled components when the containing " & |
| "object is assigned. Check that Adjust is " & |
| "called for components before the containing " & |
| "object is adjusted. Check that Adjust is not " & |
| "called for a Limited_Controlled type by the " & |
| "implementation" ); |
| |
| Check_Simple_Objects; |
| |
| Check_Nested_Objects; |
| |
| Check_Array_Case; |
| |
| Check_Access_Case; |
| |
| Check_Access_Limited_Array_Case; |
| |
| Report.Result; |
| |
| end C760002; |