view gcc/testsuite/ada/acats/tests/cb/cb41003.a @ 111:04ced10e8804

gcc 7
author kono
date Fri, 27 Oct 2017 22:46:09 +0900
parents
children
line wrap: on
line source

-- CB41003.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 an exception occurrence can be saved into an object of
--      type Exception_Occurrence using the procedure Save_Occurrence.
--      Check that a saved exception occurrence can be used to reraise 
--      another occurrence of the same exception using the procedure
--      Reraise_Occurrence.  Check that the function Save_Occurrence will
--      allocate a new object of type Exception_Occurrence_Access, and saves
--      the source exception to the new object which is returned as the 
--      function result.
--
-- TEST DESCRIPTION:
--      This test verifies that an occurrence of an exception can be saved,
--      using either of two overloaded versions of Save_Occurrence.  The
--      procedure version of Save_Occurrence is used to save an occurrence
--      of a user defined exception into an object of type 
--      Exception_Occurrence.  This object is then used as an input 
--      parameter to procedure Reraise_Occurrence, the expected exception is
--      handled, and the exception id of the handled exception is compared
--      to the id of the originally raised exception.
--      The function version of Save_Occurrence returns a result of 
--      Exception_Occurrence_Access, and is used to store the value of another
--      occurrence of the user defined exception.  The resulting access value
--      is dereferenced and used as an input to Reraise_Occurrence.  The
--      resulting exception is handled, and the exception id of the handled 
--      exception is compared to the id of the originally raised exception.
--
--
-- CHANGE HISTORY:
--      06 Dec 94   SAIC    ACVC 2.0
--
--!

with Report;
with Ada.Exceptions;

procedure CB41003 is

begin

   Report.Test ("CB41003", "Check that an exception occurrence can "   &
                           "be saved into an object of type "          &
                           "Exception_Occurrence using the procedure " &
                           "Save_Occurrence");

   Test_Block:
   declare

      use Ada.Exceptions;

      User_Exception_1,
      User_Exception_2   : Exception;

      Saved_Occurrence   : Exception_Occurrence;
      Occurrence_Ptr     : Exception_Occurrence_Access;

      User_Message       : constant String :=   -- 200 character string.
        "The string returned by Exception_Message may be tr" &
        "uncated (to no less then 200 characters) by the Sa" &
        "ve_Occurrence procedure (not the function), the Re" &
        "raise_Occurrence proc, and the re-raise statement.";

   begin

      Raise_And_Save_Block_1 :
      begin

         -- This nested exception structure is designed to ensure that the
         -- appropriate exception occurrence is saved using the 
         -- Save_Occurrence procedure.

         raise Program_Error;
         Report.Failed("Program_Error not raised");

      exception
         when Program_Error => 

            begin
               -- Use the procedure Raise_Exception, along with the 'Identity
               -- attribute to raise the first user defined exception.  Note
               -- that a 200 character message is included in the call.

               Raise_Exception(User_Exception_1'Identity, User_Message);
               Report.Failed("User_Exception_1 not raised");

            exception
               when Exc : User_Exception_1 => 

                  -- This exception occurrence is saved into a variable using
                  -- procedure Save_Occurrence.  This saved occurrence should
                  -- not be confused with the raised occurrence of 
                  -- Program_Error above.

                  Save_Occurrence(Target => Saved_Occurrence, Source => Exc);

               when others => 
                  Report.Failed("Unexpected exception handled, expecting " &
                                "User_Exception_1");
            end;

         when others => 
            Report.Failed("Incorrect exception generated by raise statement");

      end Raise_And_Save_Block_1;


      Reraise_And_Handle_Saved_Exception_1 :
      begin
         -- Reraise the exception that was saved in the previous block.

         Reraise_Occurrence(X => Saved_Occurrence);

      exception
         when Exc : User_Exception_1 => -- Expected exception.
            -- Check the exception id of the handled id by using the 
            -- Exception_Identity function, and compare with the id of the
            -- originally raised exception.

            if User_Exception_1'Identity /= Exception_Identity(Exc) then
               Report.Failed("Exception_Ids do not match - 1");
            end if;

            -- Check that the message associated with this exception occurrence
            -- has not been truncated (it was originally 200 characters).

            if User_Message /= Exception_Message(Exc) then
               Report.Failed("Exception messages do not match - 1");
            end if;

         when others => 
            Report.Failed
              ("Incorrect exception raised by Reraise_Occurrence - 1");
      end Reraise_And_Handle_Saved_Exception_1;


      Raise_And_Save_Block_2 :
      begin

         Raise_Exception(User_Exception_2'Identity, User_Message);
         Report.Failed("User_Exception_2 not raised");

      exception
         when Exc : User_Exception_2 => 

            -- This exception occurrence is saved into an access object 
            -- using function Save_Occurrence.

            Occurrence_Ptr := Save_Occurrence(Source => Exc);

         when others => 
            Report.Failed("Unexpected exception handled, expecting " &
                          "User_Exception_2");
      end Raise_And_Save_Block_2;


      Reraise_And_Handle_Saved_Exception_2 :
      begin
         -- Reraise the exception that was saved in the previous block.
         -- Dereference the access object for use as input parameter.

         Reraise_Occurrence(X => Occurrence_Ptr.all);

      exception
         when Exc : User_Exception_2 => -- Expected exception.
            -- Check the exception id of the handled id by using the 
            -- Exception_Identity function, and compare with the id of the
            -- originally raised exception.

            if User_Exception_2'Identity /= Exception_Identity(Exc) then
               Report.Failed("Exception_Ids do not match - 2");
            end if;

            -- Check that the message associated with this exception occurrence
            -- has not been truncated (it was originally 200 characters).

            if User_Message /= Exception_Message(Exc) then
               Report.Failed("Exception messages do not match - 2");
            end if;

         when others => 
            Report.Failed
              ("Incorrect exception raised by Reraise_Occurrence - 2");
       end Reraise_And_Handle_Saved_Exception_2;


       -- Another example of the use of saving an exception occurrence
       -- is demonstrated in the following block, where the ability to 
       -- save an occurrence into a data structure, for later processing,
       -- is modeled.

       Store_And_Handle_Block:
       declare
          
          Exc_Number  : constant := 3;
          Exception_1, 
          Exception_2, 
          Exception_3 : exception;

          Exception_Storage : array (1..Exc_Number) of Exception_Occurrence;
          Messages          : array (1..Exc_Number) of String(1..9) :=
                                ("Message 1", "Message 2", "Message 3");

       begin

          Outer_Block:
          begin

             Inner_Block:
             begin

                for i in 1..Exc_Number loop
                   begin

                      begin
                         -- Exceptions all raised in a deep scope.
                         if i = 1 then
                            Raise_Exception(Exception_1'Identity, Messages(i));
                         elsif i = 2 then
                            Raise_Exception(Exception_2'Identity, Messages(i));
                         elsif i = 3 then
                            Raise_Exception(Exception_3'Identity, Messages(i));
                         end if;
                         Report.Failed("Exception not raised on loop #" &
                                       Integer'Image(i));
                      end;
                      Report.Failed("Exception not propagated on loop #" &
                                    Integer'Image(i));
                   exception
                      when Exc : others =>

                         -- Save each occurrence into a storage array for 
                         -- later processing.

                         Save_Occurrence(Exception_Storage(i), Exc);
                   end;
                end loop;

             end Inner_Block;
          end Outer_Block;

          -- Raise the exceptions from the stored occurrences, and handle.

          for i in 1..Exc_Number loop
             begin
                Reraise_Occurrence(Exception_Storage(i));
                Report.Failed("No exception reraised for " &
                              "exception #" & Integer'Image(i));
             exception
                when Exc   : others =>
                   -- The following sequence of checks ensures that the 
                   -- correct occurrence was stored, and the associated
                   -- exception was raised and handled in the proper order.
                   if i = 1 then
                      if Exception_1'Identity /= Exception_Identity(Exc) then
                         Report.Failed("Exception_1 not raised");
                      end if;
                   elsif i = 2 then
                      if Exception_2'Identity /= Exception_Identity(Exc) then
                         Report.Failed("Exception_2 not raised");
                      end if;
                   elsif i = 3 then
                      if Exception_3'Identity /= Exception_Identity(Exc) then
                         Report.Failed("Exception_3 not raised");
                      end if;
                   end if;

                   if Exception_Message(Exc) /= Messages(i) then
                      Report.Failed("Incorrect message associated with " &
                                    "exception #" & Integer'Image(i));
                   end if;
             end;
          end loop;
       exception
          when others => 
            Report.Failed("Unexpected exception in Store_And_Handle_Block");
       end Store_And_Handle_Block;


      Reraise_Out_Of_Scope:
      declare

         TC_Value      : constant := 5;
         The_Exception : exception;
         Saved_Exc_Occ : Exception_Occurrence;

         procedure Handle_It (Exc_Occ : in Exception_Occurrence) is
            Must_Be_Raised : exception;
         begin
            if Exception_Identity(Exc_Occ) = The_Exception'Identity then
               raise Must_Be_Raised;
               Report.Failed("Exception Must_Be_Raised was not raised");
            else
               Report.Failed("Incorrect exception handled in " &
                             "Procedure Handle_It");
            end if;
         end Handle_It;

      begin

         if Report.Ident_Int(5) = TC_Value then
            raise The_Exception;
         end if;

      exception
         when Exc : others => 
            Save_Occurrence (Saved_Exc_Occ, Exc);
            begin
               Handle_It(Saved_Exc_Occ);   -- Raise another exception, in a
            exception                      -- different scope.
               when others =>              -- Handle this new exception.
                  begin
                     Reraise_Occurrence (Saved_Exc_Occ);  -- Reraise the
                                                          -- original excptn.
                     Report.Failed("Saved Exception was not raised");
                  exception                               
                     when Exc_2 : others =>
                        if Exception_Identity (Exc_2) /= 
                           The_Exception'Identity 
                        then
                           Report.Failed
                             ("Incorrect exception occurrence reraised");
                        end if;
                  end;
            end;
      end Reraise_Out_Of_Scope;


   exception
      when others => Report.Failed ("Exception raised in Test_Block");
   end Test_Block;

   Report.Result;

end CB41003;