summaryrefslogtreecommitdiff
path: root/gcc/testsuite/ada/acats/tests/c9/c940010.a
blob: c4a670552d4ec09e0754fb7c6030717ddbe52e09 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
-- C940010.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 an exception is raised during the execution of an 
--      entry body it is propagated back to the caller
--
-- TEST DESCRIPTION:
--      Use a small fragment of code from the simulation of a freeway meter
--      used in c940007. Create three individual tasks which will be queued on
--      the entry as the barrier is set.  Release them one at a time.  A
--      procedure which is called within the entry has been modified for this
--      test to raise a different exception for each pass through.  Check that
--      all expected exceptions are raised and propagated.
--
--
-- CHANGE HISTORY:
--      06 Dec 94   SAIC    ACVC 2.0
--
--!


with Report;
with ImpDef;
                
procedure C940010 is

    TC_Failed_1 : Boolean := false; 

begin

   Report.Test ("C940010", "Check that an exception raised in an entry " &
                        "body is propagated back to the caller");

   declare  -- encapsulate the test

      TC_Defined_Error : Exception;    -- User defined exception
      TC_Expected_Passage_Total : constant integer := 669;
      TC_Int                    : constant integer := 5;

      -- Carrier tasks. One is created for each vehicle arriving at each ramp
      task type Vehicle_31;            -- For Ramp_31
      type acc_Vehicle_31 is access Vehicle_31;


      --================================================================
      protected Ramp_31 is

         function Meter_in_Use_State return Boolean;
         procedure Add_Meter_Queue;
         procedure Subtract_Meter_Queue;
         entry Wait_at_Meter;
         procedure Pulse;
         --
         procedure TC_Passage (Pass_Point : Integer);
         function TC_Get_Passage_Total return integer;
         function TC_Get_Current_Exception return integer;

      private

         Release_One_Vehicle : Boolean := false;
         Meter_in_Use        : Boolean := true;  -- TC: set true for this test
         --
         TC_Multiplier       : integer := 1;
         TC_Passage_Total    : integer := 0;
         -- Use this to cycle through the required exceptions
         TC_Current_Exception : integer range 0..3 := 0;

      end Ramp_31;  
      --================================================================
      protected body Ramp_31 is
               
   
         -- Trace the paths through the various routines by totaling the
         -- weighted call parameters
         procedure TC_Passage (Pass_Point : Integer) is
         begin
            TC_Passage_Total := TC_Passage_Total+(Pass_Point*TC_Multiplier);
         end TC_Passage;
   
         -- For the final check of the whole test
         function TC_Get_Passage_Total return integer is
         begin
            return TC_Passage_Total;
         end TC_Get_Passage_Total;

         function TC_Get_Current_Exception return integer is
         begin 
            return TC_Current_Exception;
         end TC_Get_Current_Exception;

   
         -----------------

         function Meter_in_Use_State return Boolean is
         begin
            return Meter_in_Use;
         end Meter_in_Use_State;
       
         -- Simulate the effects of the regular signal pulse 
         procedure Pulse is
         begin
            Release_one_Vehicle := true;
         end Pulse;

         -- Keep count of vehicles currently on meter queue - we can't use
         -- the 'count because we need the outcall trigger
         procedure Add_Meter_Queue is
         begin
            null;    --::: stub
         end Add_Meter_Queue;  

         -- TC: This routine has been modified to raise the required 
         --     exceptions
         procedure Subtract_Meter_Queue is
            TC_Pass_Point1 : constant integer := 10;
            TC_Pass_Point2 : constant integer := 20;
            TC_Pass_Point3 : constant integer := 30;
            TC_Pass_Point9 : constant integer := 1000;  -- error
         begin
            -- Cycle through the required exceptions, one per call
            TC_Current_Exception := TC_Current_Exception + 1;
            case TC_Current_Exception is
               when 1 => 
                     TC_Passage (TC_Pass_Point1);  -- note passage through here
                     raise Storage_Error;    -- PREDEFINED EXCEPTION
               when 2 => 
                     TC_Passage (TC_Pass_Point2);  -- note passage through here
                     raise TC_Defined_Error;    -- USER DEFINED EXCEPTION
               when 3 => 
                     TC_Passage (TC_Pass_Point3);  -- note passage through here
                     -- RUN TIME EXCEPTION (Constraint_Error)
                     -- Add the value 3 to 5 then try to assign it to an object
                     -- whose range is 0..3  - this causes the exception.
                     -- Disguise the values which cause the Constraint_Error
                     -- so that the optimizer will not eliminate this code
                     --    Note: the variable is checked at the end to ensure
                     --    that the actual assignment is attempted.  Also note
                     --    the value remains at 3 as the assignment does not
                     --    take place.  This is the value that is checked at
                     --    the end of the test.
                     -- Otherwise the optimizer could decide that the result 
                     -- of the assignment was not used so why bother to do it?
                     TC_Current_Exception := 
                               Report.Ident_Int (TC_Current_Exception) + 
                               Report.Ident_Int (TC_Int);
               when others =>
                     -- Set flag for Report.Failed which cannot be called from
                     -- within a Protected Object 
                     TC_Failed_1 := True;
            end case;

            TC_Passage ( TC_Pass_Point9 );  -- note passage through here
         end Subtract_Meter_Queue;  
   
         -- Here each Vehicle task queues itself awaiting release
         entry Wait_at_Meter when Release_One_Vehicle is
         -- Example of entry with barriers and persistent signal
            TC_Pass_Point : constant integer := 2;
         begin
            TC_Passage ( TC_Pass_Point );   -- note passage through here
            Release_One_Vehicle := false;   -- Consume the signal
            -- Decrement number of vehicles on ramp 
            Subtract_Meter_Queue;  -- Call procedure from within entry body
         end Wait_at_Meter;      
   
      end Ramp_31;  
      --================================================================
        
      -- Carrier task. One is created for each vehicle arriving at Ramp_31
      task body Vehicle_31 is
         TC_Pass_Point_1 : constant integer := 100;
         TC_Pass_Point_2 : constant integer := 200;
         TC_Pass_Point_3 : constant integer := 300;
      begin
         if Ramp_31.Meter_in_Use_State then  
            -- Increment count of number of vehicles on ramp 
            Ramp_31.Add_Meter_Queue;    -- Call a protected procedure
                                          -- which is also called from within
            -- enter the meter queue
            Ramp_31.Wait_at_Meter;      -- Call a protected entry   
            Report.Failed ("Exception not propagated back");
         end if;
         null;  --:::: call to the first in the series of the Ramp_Sensors
                --     this "passes" the vehicle from one sensor to the next
      exception
         when Storage_Error =>
               Ramp_31.TC_Passage ( TC_Pass_Point_1 );  -- note passage
         when TC_Defined_Error =>  
               Ramp_31.TC_Passage ( TC_Pass_Point_2 );  -- note passage
         when Constraint_Error =>
               Ramp_31.TC_Passage ( TC_Pass_Point_3 );  -- note passage
         when others => 
               Report.Failed ("Unexpected exception in Vehicle Task");
      end Vehicle_31;

      -- Simulate the arrival of a vehicle at the Ramp_Receiver of Ramp_31
      -- and the generation of an accompanying carrier task
      procedure New_Arrival_31 is
         Next_Vehicle_Task_31: acc_Vehicle_31 := new Vehicle_31;
         TC_Pass_Point : constant integer := 1; 
      begin
         Ramp_31.TC_Passage ( TC_Pass_Point );  -- Note passage through here
         null;  --::: stub
      end New_arrival_31;



   begin -- declare

      -- Test driver.  This is ALL test control code

      -- Create three independent tasks which will queue themselves on the
      -- entry.  Each task will get a different exception
      New_Arrival_31;
      New_Arrival_31;
      New_Arrival_31;

      delay ImpDef.Clear_Ready_Queue;

      -- Set the barrier condition of the entry true, releasing one task
      Ramp_31.Pulse; 
      delay ImpDef.Clear_Ready_Queue;
      
      Ramp_31.Pulse; 
      delay ImpDef.Clear_Ready_Queue;
      
      Ramp_31.Pulse; 
      delay ImpDef.Clear_Ready_Queue;

      if (TC_Expected_Passage_Total /= Ramp_31.TC_Get_Passage_Total)  or
         -- Note: We are not really interested in this next check.  It is 
         --       here to ensure the earlier statements which raised the 
         --       Constraint_Error are not optimized out
         (Ramp_31.TC_Get_Current_Exception /= 3) then
            Report.Failed ("Unexpected paths taken");
      end if;
      
   end; -- declare

   if TC_Failed_1 then 
      Report.Failed ("Bad path through Subtract_Meter_Queue");
   end if;

   Report.Result;

end C940010;