3 -- Grant of Unlimited Rights
5 -- Under contracts F33600-87-D-0337, F33600-84-D-0280, MDA903-79-C-0687,
6 -- F08630-91-C-0015, and DCA100-97-D-0025, the U.S. Government obtained
7 -- unlimited rights in the software and documentation contained herein.
8 -- Unlimited rights are defined in DFAR 252.227-7013(a)(19). By making
9 -- this public release, the Government intends to confer upon all
10 -- recipients unlimited rights equal to those held by the Government.
11 -- These rights include rights to use, duplicate, release or disclose the
12 -- released technical data and computer software in whole or in part, in
13 -- any manner and for any purpose whatsoever, and to have or permit others
18 -- ALL MATERIALS OR INFORMATION HEREIN RELEASED, MADE AVAILABLE OR
19 -- DISCLOSED ARE AS IS. THE GOVERNMENT MAKES NO EXPRESS OR IMPLIED
20 -- WARRANTY AS TO ANY MATTER WHATSOEVER, INCLUDING THE CONDITIONS OF THE
21 -- SOFTWARE, DOCUMENTATION OR OTHER INFORMATION RELEASED, MADE AVAILABLE
22 -- OR DISCLOSED, OR THE OWNERSHIP, MERCHANTABILITY, OR FITNESS FOR A
23 -- PARTICULAR PURPOSE OF SAID MATERIAL.
27 -- Check that the tag of an object of a tagged type is preserved by
28 -- type conversion and parameter passing.
31 -- The fact that the tag of an object is not changed is verified by
32 -- making dispatching calls to primitive operations, and confirming that
33 -- the proper body is executed. Objects of both specific and class-wide
36 -- The dispatching calls are made in two contexts. The first is a
37 -- straightforward dispatching call made from within a class-wide
38 -- operation. The second is a redispatch from within a primitive
41 -- For the parameter passing case, the initial class-wide and specific
42 -- objects are passed directly in calls to the class-wide and primitive
43 -- operations. The redispatch is accomplished by initializing a local
44 -- class-wide object in the primitive operation to the value of the
45 -- formal parameter, and using the local object as the actual in the
46 -- (re)dispatching call.
48 -- For the type conversion case, the initial class-wide object is assigned
49 -- a view conversion of an object of a specific type:
51 -- type T is tagged ...
52 -- type DT is new T with ...
55 -- B : T'Class := T(A); -- Despite conversion, tag of B is that of DT.
57 -- The class-wide object is then passed directly in calls to the
58 -- class-wide and primitive operations. For the initial object of a
59 -- specific type, however, a view conversion of the object is passed,
60 -- forcing a non-dispatching call in the primitive operation case. Within
61 -- the primitive operation, a view conversion of the formal parameter to
62 -- a class-wide type is then used to force a (re)dispatching call.
64 -- For the type conversion and parameter passing case, a combining of
65 -- view conversion and parameter passing of initial specific objects are
66 -- called directly to the class-wide and primitive operations.
70 -- 28 Jun 95 SAIC Initial prerelease version.
71 -- 23 Apr 96 SAIC Added use C390007_0 in the main.
77 type Call_ID_Kind
is (None
, Parent_Outer
, Parent_Inner
,
78 Derived_Outer
, Derived_Inner
);
80 type Root_Type
is abstract tagged null record;
82 procedure Outer_Proc
(X
: in out Root_Type
) is abstract;
83 procedure Inner_Proc
(X
: in out Root_Type
) is abstract;
85 procedure ClassWide_Proc
(X
: in out Root_Type
'Class);
90 --==================================================================--
93 package body C390007_0
is
95 procedure ClassWide_Proc
(X
: in out Root_Type
'Class) is
103 --==================================================================--
106 package C390007_0
.C390007_1
is
108 type Param_Parent_Type
is new Root_Type
with record
109 Last_Call
: Call_ID_Kind
:= None
;
112 procedure Outer_Proc
(X
: in out Param_Parent_Type
);
113 procedure Inner_Proc
(X
: in out Param_Parent_Type
);
115 end C390007_0
.C390007_1
;
118 --==================================================================--
121 package body C390007_0
.C390007_1
is
123 procedure Outer_Proc
(X
: in out Param_Parent_Type
) is
125 X
.Last_Call
:= Parent_Outer
;
128 procedure Inner_Proc
(X
: in out Param_Parent_Type
) is
130 X
.Last_Call
:= Parent_Inner
;
133 end C390007_0
.C390007_1
;
136 --==================================================================--
139 package C390007_0
.C390007_1
.C390007_2
is
141 type Param_Derived_Type
is new Param_Parent_Type
with null record;
143 procedure Outer_Proc
(X
: in out Param_Derived_Type
);
144 procedure Inner_Proc
(X
: in out Param_Derived_Type
);
146 end C390007_0
.C390007_1
.C390007_2
;
149 --==================================================================--
152 package body C390007_0
.C390007_1
.C390007_2
is
154 procedure Outer_Proc
(X
: in out Param_Derived_Type
) is
155 Y
: Root_Type
'Class := X
;
157 Inner_Proc
(Y
); -- Redispatch.
158 Root_Type
'Class (X
) := Y
;
161 procedure Inner_Proc
(X
: in out Param_Derived_Type
) is
163 X
.Last_Call
:= Derived_Inner
;
166 end C390007_0
.C390007_1
.C390007_2
;
169 --==================================================================--
172 package C390007_0
.C390007_3
is
174 type Convert_Parent_Type
is new Root_Type
with record
175 First_Call
: Call_ID_Kind
:= None
;
176 Second_Call
: Call_ID_Kind
:= None
;
179 procedure Outer_Proc
(X
: in out Convert_Parent_Type
);
180 procedure Inner_Proc
(X
: in out Convert_Parent_Type
);
182 end C390007_0
.C390007_3
;
185 --==================================================================--
188 package body C390007_0
.C390007_3
is
190 procedure Outer_Proc
(X
: in out Convert_Parent_Type
) is
192 X
.First_Call
:= Parent_Outer
;
193 Inner_Proc
(Root_Type
'Class(X
)); -- Redispatch.
196 procedure Inner_Proc
(X
: in out Convert_Parent_Type
) is
198 X
.Second_Call
:= Parent_Inner
;
201 end C390007_0
.C390007_3
;
204 --==================================================================--
207 package C390007_0
.C390007_3
.C390007_4
is
209 type Convert_Derived_Type
is new Convert_Parent_Type
with null record;
211 procedure Outer_Proc
(X
: in out Convert_Derived_Type
);
212 procedure Inner_Proc
(X
: in out Convert_Derived_Type
);
214 end C390007_0
.C390007_3
.C390007_4
;
217 --==================================================================--
220 package body C390007_0
.C390007_3
.C390007_4
is
222 procedure Outer_Proc
(X
: in out Convert_Derived_Type
) is
224 X
.First_Call
:= Derived_Outer
;
225 Inner_Proc
(Root_Type
'Class(X
)); -- Redispatch.
228 procedure Inner_Proc
(X
: in out Convert_Derived_Type
) is
230 X
.Second_Call
:= Derived_Inner
;
233 end C390007_0
.C390007_3
.C390007_4
;
236 --==================================================================--
239 with C390007_0
.C390007_1
.C390007_2
;
240 with C390007_0
.C390007_3
.C390007_4
;
246 Report
.Test
("C390007", "Check that the tag of an object of a tagged " &
247 "type is preserved by type conversion and parameter passing");
251 -- Check that tags are preserved by parameter passing:
254 Parameter_Passing_Subtest
:
256 Specific_A
: C390007_0
.C390007_1
.C390007_2
.Param_Derived_Type
;
257 Specific_B
: C390007_0
.C390007_1
.C390007_2
.Param_Derived_Type
;
259 ClassWide_A
: C390007_0
.C390007_1
.Param_Parent_Type
'Class := Specific_A
;
260 ClassWide_B
: C390007_0
.C390007_1
.Param_Parent_Type
'Class := Specific_B
;
262 use C390007_0
.C390007_1
;
263 use C390007_0
.C390007_1
.C390007_2
;
266 Outer_Proc
(Specific_A
);
267 if Specific_A
.Last_Call
/= Derived_Inner
then
268 Report
.Failed
("Parameter passing: tag not preserved in call to " &
269 "primitive operation with specific operand");
272 C390007_0
.ClassWide_Proc
(Specific_B
);
273 if Specific_B
.Last_Call
/= Derived_Inner
then
274 Report
.Failed
("Parameter passing: tag not preserved in call to " &
275 "class-wide operation with specific operand");
278 Outer_Proc
(ClassWide_A
);
279 if ClassWide_A
.Last_Call
/= Derived_Inner
then
280 Report
.Failed
("Parameter passing: tag not preserved in call to " &
281 "primitive operation with class-wide operand");
284 C390007_0
.ClassWide_Proc
(ClassWide_B
);
285 if ClassWide_B
.Last_Call
/= Derived_Inner
then
286 Report
.Failed
("Parameter passing: tag not preserved in call to " &
287 "class-wide operation with class-wide operand");
290 end Parameter_Passing_Subtest
;
294 -- Check that tags are preserved by type conversion:
297 Type_Conversion_Subtest
:
299 Specific_A
: C390007_0
.C390007_3
.C390007_4
.Convert_Derived_Type
;
300 Specific_B
: C390007_0
.C390007_3
.C390007_4
.Convert_Derived_Type
;
302 ClassWide_A
: C390007_0
.C390007_3
.Convert_Parent_Type
'Class :=
303 C390007_0
.C390007_3
.Convert_Parent_Type
(Specific_A
);
304 ClassWide_B
: C390007_0
.C390007_3
.Convert_Parent_Type
'Class :=
305 C390007_0
.C390007_3
.Convert_Parent_Type
(Specific_B
);
307 use C390007_0
.C390007_3
;
308 use C390007_0
.C390007_3
.C390007_4
;
311 Outer_Proc
(Convert_Parent_Type
(Specific_A
));
312 if (Specific_A
.First_Call
/= Parent_Outer
) or
313 (Specific_A
.Second_Call
/= Derived_Inner
)
315 Report
.Failed
("Type conversion: tag not preserved in call to " &
316 "primitive operation with specific operand");
319 Outer_Proc
(ClassWide_A
);
320 if (ClassWide_A
.First_Call
/= Derived_Outer
) or
321 (ClassWide_A
.Second_Call
/= Derived_Inner
)
323 Report
.Failed
("Type conversion: tag not preserved in call to " &
324 "primitive operation with class-wide operand");
327 C390007_0
.ClassWide_Proc
(Convert_Parent_Type
(Specific_B
));
328 if (Specific_B
.Second_Call
/= Derived_Inner
) then
329 Report
.Failed
("Type conversion: tag not preserved in call to " &
330 "class-wide operation with specific operand");
333 C390007_0
.ClassWide_Proc
(ClassWide_B
);
334 if (ClassWide_A
.Second_Call
/= Derived_Inner
) then
335 Report
.Failed
("Type conversion: tag not preserved in call to " &
336 "class-wide operation with class-wide operand");
339 end Type_Conversion_Subtest
;
343 -- Check that tags are preserved by type conversion and parameter passing:
346 Type_Conversion_And_Parameter_Passing_Subtest
:
348 Specific_A
: C390007_0
.C390007_1
.C390007_2
.Param_Derived_Type
;
349 Specific_B
: C390007_0
.C390007_1
.C390007_2
.Param_Derived_Type
;
351 use C390007_0
.C390007_1
;
352 use C390007_0
.C390007_1
.C390007_2
;
355 Outer_Proc
(Param_Parent_Type
(Specific_A
));
356 if Specific_A
.Last_Call
/= Parent_Outer
then
357 Report
.Failed
("Type conversion and parameter passing: tag not " &
358 "preserved in call to primitive operation with " &
362 C390007_0
.ClassWide_Proc
(Param_Parent_Type
(Specific_B
));
363 if Specific_B
.Last_Call
/= Derived_Inner
then
364 Report
.Failed
("Type conversion and parameter passing: tag not " &
365 "preserved in call to class-wide operation with " &
369 end Type_Conversion_And_Parameter_Passing_Subtest
;