| -- C460A01.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 if the target type of a type conversion is a general |
| -- access type, Program_Error is raised if the accessibility level of |
| -- the operand type is deeper than that of the target type. Check for |
| -- cases where the type conversion occurs in an instance body, and |
| -- the operand type is passed as an actual during instantiation. |
| -- |
| -- TEST DESCRIPTION: |
| -- In order to satisfy accessibility requirements, the operand type must |
| -- be at the same or a less deep nesting level than the target type -- the |
| -- operand type must "live" as long as the target type. Nesting levels |
| -- are the run-time nestings of masters: block statements; subprogram, |
| -- task, and entry bodies; and accept statements. Packages are invisible |
| -- to accessibility rules. |
| -- |
| -- This test checks for cases where the operand is a subprogram formal |
| -- parameter. |
| -- |
| -- The test declares three generic packages, each containing an access |
| -- type conversion in which the operand type is a formal type: |
| -- |
| -- (1) One in which the target type is declared within the |
| -- specification, and the conversion occurs within a nested |
| -- function. |
| -- |
| -- (2) One in which the target type is also a formal type, and |
| -- the conversion occurs within a nested function. |
| -- |
| -- (3) One in which the target type is declared outside the |
| -- generic, and the conversion occurs within a nested |
| -- procedure. |
| -- |
| -- The test verifies the following: |
| -- |
| -- For (1), Program_Error is not raised when the nested function is |
| -- called. Since the actual corresponding to the formal operand type |
| -- must always have the same or a less deep level than the target |
| -- type declared within the instance, the access type conversion is |
| -- always safe. |
| -- |
| -- For (2), Program_Error is raised when the nested function is |
| -- called if the operand type passed as an actual during instantiation |
| -- has an accessibility level deeper than that of the target type |
| -- passed as an actual, and that no exception is raised otherwise. |
| -- The exception is propagated to the innermost enclosing master. |
| -- |
| -- For (3), Program_Error is raised when the nested procedure is |
| -- called if the operand type passed as an actual during instantiation |
| -- has an accessibility level deeper than that of the target type. |
| -- The exception is handled within the nested procedure. |
| -- |
| -- TEST FILES: |
| -- The following files comprise this test: |
| -- |
| -- F460A00.A |
| -- => C460A01.A |
| -- |
| -- |
| -- CHANGE HISTORY: |
| -- 09 May 95 SAIC Initial prerelease version. |
| -- 24 Apr 96 SAIC Added code to avoid dead variable optimization. |
| -- 13 Feb 97 PWB.CTA Removed 'Class from qual expression at line 342. |
| --! |
| |
| generic |
| type Designated_Type is tagged private; |
| type Operand_Type is access Designated_Type; |
| package C460A01_0 is |
| type Target_Type is access all Designated_Type; |
| function Convert (P : Operand_Type) return Target_Type; |
| end C460A01_0; |
| |
| |
| --==================================================================-- |
| |
| |
| package body C460A01_0 is |
| function Convert (P : Operand_Type) return Target_Type is |
| begin |
| return Target_Type(P); -- Never fails. |
| end Convert; |
| end C460A01_0; |
| |
| |
| --==================================================================-- |
| |
| |
| generic |
| type Designated_Type is tagged private; |
| type Operand_Type is access all Designated_Type; |
| type Target_Type is access all Designated_Type; |
| package C460A01_1 is |
| function Convert (P : Operand_Type) return Target_Type; |
| end C460A01_1; |
| |
| |
| --==================================================================-- |
| |
| |
| package body C460A01_1 is |
| function Convert (P : Operand_Type) return Target_Type is |
| begin |
| return Target_Type(P); |
| end Convert; |
| end C460A01_1; |
| |
| |
| --==================================================================-- |
| |
| |
| with F460A00; |
| generic |
| type Designated_Type (<>) is new F460A00.Tagged_Type with private; |
| type Operand_Type is access Designated_Type; |
| package C460A01_2 is |
| procedure Proc (P : Operand_Type; |
| Res : out F460A00.TC_Result_Kind); |
| end C460A01_2; |
| |
| |
| --==================================================================-- |
| |
| with Report; |
| package body C460A01_2 is |
| procedure Proc (P : Operand_Type; |
| Res : out F460A00.TC_Result_Kind) is |
| Ptr : F460A00.AccTag_L0; |
| begin |
| Ptr := F460A00.AccTag_L0(P); |
| |
| -- Avoid optimization (dead variable removal of Ptr): |
| if not Report.Equal (Ptr.C, Ptr.C) then -- Always false. |
| Report.Failed ("Unexpected error in C460A01_2 instance"); |
| end if; |
| |
| Res := F460A00.OK; |
| exception |
| when Program_Error => Res := F460A00.PE_Exception; |
| when others => Res := F460A00.Others_Exception; |
| end Proc; |
| end C460A01_2; |
| |
| |
| --==================================================================-- |
| |
| |
| with F460A00; |
| with C460A01_0; |
| with C460A01_1; |
| with C460A01_2; |
| |
| with Report; |
| procedure C460A01 is |
| begin -- C460A01. -- [ Level = 1 ] |
| |
| Report.Test ("C460A01", "Run-time accessibility checks: instance " & |
| "bodies. Operand type of access type conversion is " & |
| "passed as actual to instance"); |
| |
| |
| SUBTEST1: |
| declare -- [ Level = 2 ] |
| type AccTag_L2 is access all F460A00.Tagged_Type; |
| Operand: AccTag_L2 := new F460A00.Tagged_Type; |
| |
| Result : F460A00.TC_Result_Kind := F460A00.UN_Init; |
| begin -- SUBTEST1. |
| |
| declare -- [ Level = 3 ] |
| -- The instantiation of C460A01_0 should NOT result in any |
| -- exceptions. |
| |
| package Pack_OK is new C460A01_0 (F460A00.Tagged_Type, AccTag_L2); |
| Target : Pack_OK.Target_Type; |
| begin |
| -- The accessibility level of Pack_OK.Target_Type will always be at |
| -- least as deep as the operand type passed as an actual. Thus, |
| -- a call to Pack_OK.Convert does not propagate an exception: |
| |
| Target := Pack_OK.Convert(Operand); |
| |
| -- Avoid optimization (dead variable removal of Target): |
| if not Report.Equal (Target.C, Target.C) then -- Always false. |
| Report.Failed ("Unexpected error in SUBTEST #1"); |
| end if; |
| |
| Result := F460A00.OK; -- Expected result. |
| exception |
| when Program_Error => Result := F460A00.PE_Exception; |
| when others => Result := F460A00.Others_Exception; |
| end; |
| |
| F460A00.TC_Check_Results (Result, F460A00.OK, "SUBTEST #1"); |
| |
| exception |
| when Program_Error => |
| Report.Failed ("SUBTEST #1: Program_Error incorrectly raised"); |
| when others => |
| Report.Failed ("SUBTEST #1: Unexpected exception raised"); |
| end SUBTEST1; |
| |
| |
| |
| SUBTEST2: |
| declare -- [ Level = 2 ] |
| type AccTag_L2 is access all F460A00.Tagged_Type; |
| Operand : AccTag_L2 := new F460A00.Tagged_Type; |
| |
| Result : F460A00.TC_Result_Kind := F460A00.UN_Init; |
| begin -- SUBTEST2. |
| |
| declare -- [ Level = 3 ] |
| |
| type AccTag_L3 is access all F460A00.Tagged_Type; |
| Target : AccTag_L3; |
| |
| -- The instantiation of C460A01_1 should NOT result in any |
| -- exceptions. |
| |
| package Pack_OK is new C460A01_1 |
| (Designated_Type => F460A00.Tagged_Type, |
| Operand_Type => AccTag_L2, |
| Target_Type => AccTag_L3); |
| begin |
| -- The accessibility level of the actual passed as the operand type |
| -- in Pack_OK is 2. The accessibility level of the actual passed as |
| -- the target type is 3. Therefore, the access type conversion in |
| -- Pack_OK.Convert does not raise an exception when the subprogram is |
| -- called. If an exception is (incorrectly) raised, it is propagated |
| -- to the innermost enclosing master: |
| |
| Target := Pack_OK.Convert(Operand); |
| |
| -- Avoid optimization (dead variable removal of Target): |
| if not Report.Equal (Target.C, Target.C) then -- Always false. |
| Report.Failed ("Unexpected error in SUBTEST #2"); |
| end if; |
| |
| Result := F460A00.OK; -- Expected result. |
| exception |
| when Program_Error => Result := F460A00.PE_Exception; |
| when others => Result := F460A00.Others_Exception; |
| end; |
| |
| F460A00.TC_Check_Results (Result, F460A00.OK, "SUBTEST #2"); |
| |
| exception |
| when Program_Error => |
| Report.Failed ("SUBTEST #2: Program_Error incorrectly raised"); |
| when others => |
| Report.Failed ("SUBTEST #2: Unexpected exception raised"); |
| end SUBTEST2; |
| |
| |
| |
| SUBTEST3: |
| declare -- [ Level = 2 ] |
| type AccTag_L2 is access all F460A00.Tagged_Type; |
| Target : AccTag_L2; |
| |
| Result : F460A00.TC_Result_Kind := F460A00.UN_Init; |
| begin -- SUBTEST3. |
| |
| declare -- [ Level = 3 ] |
| |
| type AccTag_L3 is access all F460A00.Tagged_Type; |
| Operand : AccTag_L3 := new F460A00.Tagged_Type; |
| |
| -- The instantiation of C460A01_1 should NOT result in any |
| -- exceptions. |
| |
| package Pack_PE is new C460A01_1 |
| (Designated_Type => F460A00.Tagged_Type, |
| Operand_Type => AccTag_L3, |
| Target_Type => AccTag_L2); |
| begin |
| -- The accessibility level of the actual passed as the operand type |
| -- in Pack_PE is 3. The accessibility level of the actual passed as |
| -- the target type is 2. Therefore, the access type conversion in |
| -- Pack_PE.Convert raises Program_Error when the subprogram is |
| -- called. The exception is propagated to the innermost enclosing |
| -- master: |
| |
| Target := Pack_PE.Convert(Operand); |
| |
| -- Avoid optimization (dead variable removal of Target): |
| if not Report.Equal (Target.C, Target.C) then -- Always false. |
| Report.Failed ("Unexpected error in SUBTEST #3"); |
| end if; |
| |
| Result := F460A00.OK; |
| exception |
| when Program_Error => Result := F460A00.PE_Exception; |
| -- Expected result. |
| when others => Result := F460A00.Others_Exception; |
| end; |
| |
| F460A00.TC_Check_Results (Result, F460A00.PE_Exception, "SUBTEST #3"); |
| |
| exception |
| when Program_Error => |
| Report.Failed ("SUBTEST #3: Program_Error incorrectly raised"); |
| when others => |
| Report.Failed ("SUBTEST #3: Unexpected exception raised"); |
| end SUBTEST3; |
| |
| |
| |
| SUBTEST4: |
| declare -- [ Level = 2 ] |
| Result : F460A00.TC_Result_Kind := F460A00.UN_Init; |
| begin -- SUBTEST4. |
| |
| declare -- [ Level = 3 ] |
| |
| TType : F460A00.Tagged_Type; |
| Operand : F460A00.AccTagClass_L0 |
| := new F460A00.Tagged_Type'(TType); |
| |
| -- The instantiation of C460A01_2 should NOT result in any |
| -- exceptions. |
| |
| package Pack_OK is new C460A01_2 (F460A00.Tagged_Type'Class, |
| F460A00.AccTagClass_L0); |
| begin |
| -- The accessibility level of the actual passed as the operand type |
| -- in Pack_OK is 0. The accessibility level of the target type |
| -- (F460A00.AccTag_L0) is also 0. Therefore, the access type |
| -- conversion in Pack_OK.Proc does not raise an exception when the |
| -- subprogram is called. If an exception is (incorrectly) raised, |
| -- it is handled within the subprogram: |
| |
| Pack_OK.Proc(Operand, Result); |
| end; |
| |
| F460A00.TC_Check_Results (Result, F460A00.OK, "SUBTEST #4"); |
| |
| exception |
| when Program_Error => |
| Report.Failed ("SUBTEST #4: Program_Error incorrectly raised"); |
| when others => |
| Report.Failed ("SUBTEST #4: Unexpected exception raised"); |
| end SUBTEST4; |
| |
| |
| |
| SUBTEST5: |
| declare -- [ Level = 2 ] |
| Result : F460A00.TC_Result_Kind := F460A00.UN_Init; |
| begin -- SUBTEST5. |
| |
| declare -- [ Level = 3 ] |
| |
| type AccDerTag_L3 is access all F460A00.Derived_Tagged_Type; |
| Operand : AccDerTag_L3 := new F460A00.Derived_Tagged_Type; |
| |
| -- The instantiation of C460A01_2 should NOT result in any |
| -- exceptions. |
| |
| package Pack_PE is new C460A01_2 (F460A00.Derived_Tagged_Type, |
| AccDerTag_L3); |
| begin |
| -- The accessibility level of the actual passed as the operand type |
| -- in Pack_PE is 3. The accessibility level of the target type |
| -- (F460A00.AccTag_L0) is 0. Therefore, the access type conversion |
| -- in Pack_PE.Proc raises Program_Error when the subprogram is |
| -- called. The exception is handled within the subprogram: |
| |
| Pack_PE.Proc(Operand, Result); |
| end; |
| |
| F460A00.TC_Check_Results (Result, F460A00.PE_Exception, "SUBTEST #5"); |
| |
| exception |
| when Program_Error => |
| Report.Failed ("SUBTEST #5: Program_Error incorrectly raised"); |
| when others => |
| Report.Failed ("SUBTEST #5: Unexpected exception raised"); |
| end SUBTEST5; |
| |
| Report.Result; |
| |
| end C460A01; |