CVS difference for ais/ai-00216.txt

Differences between 1.5 and version 1.6
Log of other versions for file ais/ai-00216.txt

--- ais/ai-00216.txt	2001/10/09 00:47:09	1.5
+++ ais/ai-00216.txt	2002/02/05 02:06:24	1.6
@@ -1,4 +1,4 @@
-!standard 03.08.01      (01)                        01-10-05  AI95-00216/05
+!standard 03.08.01      (01)                        02-02-04  AI95-00216/06
 !class amendment 99-03-23
 !status work item 99-03-23
 !status received 99-03-23
@@ -113,7 +113,89 @@
 
 !wording
 
+B.3.3 Pragma Unchecked_Union
 
+[A pragma Unchecked_Union specifies an interface correspondence
+between a given discriminated type and some C union. The pragma
+specifies that the associated type shall be given a representation
+that leaves no space for its discriminant(s).]
+
+                Syntax
+
+The form of pragma Unchecked_Union is as follows:
+
+    pragma Unchecked_Union (first_subtype_local_name);
+
+                Legality Rules
+
+Unchecked_Union is a representation pragma, specifying the unchecked
+union aspect of representation.
+
+The first_subtype_local_name of a pragma Unchecked_Union shall denote
+an unconstrained discriminated record subtype having a variant_part.
+
+The type is said to be an unchecked union type. A subtype of an
+unchecked union type is said to be an unchecked union subtype.
+An object of an unchecked union type is said to be an unchecked union
+object.
+
+All component subtypes of the type shall be C-compatible.
+
+If a component subtype of the type is subject to a per-object constraint,
+then the component subtype shall be an unchecked union subtype.
+
+The type shall not be a by-reference type.
+
+                Static Semantics
+
+An unchecked union type is eligible for conventions C and C_Pass_By_Copy,
+as is any subtype of the type.
+
+Discriminant_Check is suppressed for the type.
+
+All objects of the type shall have the same size.
+
+Discriminants of objects of the type shall be of size zero.
+
+Any name which denotes a discriminant of an Unchecked_Union type shall occur
+within the declarative region of the type, the component_choice_list of an
+aggregate, or the selector_name of a discriminant_constraint.
+
+An Unchecked_Union subtype shall not be passed as a generic actual parameter
+if the corresponding formal type has a known_discriminant_part or
+is a formal derived type which is not an unchecked union type.
+
+                Dynamic Semantics
+
+A view of an unchecked union object [(including a type conversion or
+function call)] is said to have "inferable discriminants" if it has a
+constrained nominal subtype, unless the object is a component of an
+enclosing unchecked union object which is subject to a per-object constraint
+and the enclosing object lacks inferable discriminants.
+
+An expression of an Unchecked_Union type is said to have "inferable
+discriminants" if it is either a name of an object with inferable discriminants
+or a qualified expression whose subtype_mark denotes a constrained subtype.
+
+The predefined equality operator for an Unchecked_Union type raises
+Program_Error if either of the operands lacks inferable discriminants. [This
+includes the case where the equality operator is invoked implicitly by the
+equality operator for an enclosing composite type - if the Unchecked_Union
+component is unconstrained, Program_Error is raised].
+
+Evaluation of a membership test raises Program_Error if the subtype_mark
+denotes a constrained Unchecked_Union subtype and the expression lacks
+inferable discriminants.
+
+Conversion from an Unchecked_Union type to an unconstrained non-Unchecked_Union
+type raises Program_Error if the operand of the conversion lacks inferable
+discriminants.
+
+Unless overridden by an attribute_definition_clause, execution of the Write or
+Read attribute of an Unchecked_Union type raises Program_Error. The same holds
+for the Output and Input attributes if the type lacks default discriminant
+values.
+
 !example
 
 Given the C type:
@@ -219,7 +301,7 @@
 *************************************************************
 
 From: Robert A Duff
-Sent: Friday, October 1, 1999 at 8:57 am.
+Sent: Friday, October 1, 1999 at 8:57 AM
 
 > It seems to me that completely forbidding the use of  'Read and 'Write is
 > too strict; there are certainly cases where you want to send such types over
@@ -248,6 +330,347 @@
 Good point.
 
 - Bob
+
+*************************************************************
+
+From: Steve Baird
+Sent: Monday, January 28, 2002 at  2:40 PM
+
+B.3.3 Pragma Unchecked_Union
+
+[A pragma Unchecked_Union specifies an interface correspondence
+between a given discriminated type and some C union. The pragma
+specifies that the associated type shall be given a representation
+that leaves no space for its discriminant(s).]
+
+                Syntax
+
+The form of pragma Unchecked_Union is as follows:
+
+    pragma Unchecked_Union (first_subtype_local_name);
+
+                Legality Rules
+
+Unchecked_Union is a representation pragma, specifying the unchecked
+union aspect of representation.
+
+The first_subtype_local_name of a pragma Unchecked_Union shall denote
+an unconstrained discriminated record subtype having a variant_part.
+
+The type is said to be an unchecked union type. A subtype of an
+unchecked union type is said to be an unchecked union subtype.
+An object of an unchecked union type is said to be an unchecked union
+object.
+
+All component subtypes of the type shall be C-compatible.
+
+If a component subtype of the type is subject to a per-object constraint,
+then the component subtype shall be an unchecked union subtype.
+
+The type shall not be a by-reference type.
+
+                Static Semantics
+
+An unchecked union type is eligible for conventions C and C_Pass_By_Copy,
+as is any subtype of the type.
+
+Discriminant_Check is suppressed for the type.
+
+All objects of the type shall have the same size.
+
+Discriminants of objects of the type shall be of size zero.
+
+Any name which denotes a discriminant of an object of an
+Unchecked_Union type shall occur within the declarative region of the type.
+
+An Unchecked_Union subtype shall not be passed as a generic actual parameter
+if the corresponding formal type has a known_discriminant_part or
+is a formal derived type which is not an unchecked union type.
+
+                Dynamic Semantics
+
+A view of an unchecked union object [(including a type conversion or
+function call)] is said to have "inferable discriminants" if it has a
+constrained nominal subtype, unless the object is a component of an
+enclosing unchecked union object which is subject to a per-object constraint
+and the enclosing object lacks inferable discriminants.
+
+An expression of an Unchecked_Union type is said to have "inferable
+discriminants" if it is either a name of an object with inferable
+discriminants
+or a qualified expression whose subtype_mark denotes a constrained subtype.
+
+The predefined equality operator for an Unchecked_Union type
+raises Program_Error if either of the operands lacks inferable
+discriminants. [This includes the case where the equality operator
+is invoked implicitly by the equality operator for an enclosing composite
+type - if the Unchecked_Union component is unconstrained, Program_Error
+is raised].
+
+Evaluation of a membership test raises Program_Error if the
+subtype_mark denotes a constrained Unchecked_Union subtype and the
+expression lacks inferable discriminants.
+
+Conversion from a derived Unchecked_Union type to an unconstrained
+non-Unchecked_Union ancestor type raises Program_Error if the operand
+of the conversion lacks inferable discriminants.
+
+Unless overridden by an attribute_definition_clause, execution of
+the Write or Read attribute of an Unchecked_Union type
+raises Program_Error. The same holds for the Output and Input attributes
+if the type lacks default discriminant values.
+
+
+-------- Discussion -------
+
+1) Consider the following example:
+
+     with Interfaces;
+     package Uu is
+       type Uu_32 (Is_Signed : Boolean) is
+          record
+            case Is_Signed is
+                when False =>
+                  Unsigned : Interfaces.Unsigned_32;
+                when True =>
+                  Signed : Interfaces.Integer_32;
+            end case;
+          end record;
+      pragma Unchecked_Union (Uu_32);
+
+       X : Uu_32 := (False, Interfaces.Unsigned_32'Last);
+       Y : Interfaces.Integer_32 := X.Signed;
+     end Uu;
+
+   Elaboration of this package results in erroneous execution. If it is
+   intended that this should behave as some sort of non-erroneous alternative
+   form of Unchecked_Conversion, then the definition needs to be changed.
+
+2) The various operations listed as raising Program_Error (i.e. certain
+   equality tests, membership tests, conversions, and streaming operations)
+   could be defined to be bounded errors, where the implementation would have
+   the option of either raising Program_Error or returning the correct
+   answer (typically, the latter alternative would only be selected
+   if the implementation was somehow able to infer discriminant values
+   for the object).
+
+   Consider the following example:
+
+     procedure Uu is
+       type Uu_32 is <as above> ;
+
+       subtype Signed_Uu is Uu_32 (Is_Signed => True);
+
+       generic
+         Unknown_Discrim : Uu_32;
+       package G is
+         Flag1 : constant Boolean := Unknown_Discrim in Signed_Uu;
+       end G;
+
+       package body G is
+         Flag2 : constant Boolean := Unknown_Discrim in Signed_Uu;
+       end G;
+
+       Known_Discrim : constant Signed_Uu := (True, 33);
+
+       package I is new G (Unknown_Discrim => Known_Discrim);
+     begin
+       null;
+     end;
+
+   An implementation (particularly one which does not share code for generics)
+   might have to go out of its way to ignore known information in order to
+   raise Program_Error instead of returning the correct answer for these
+   membership tests.
+
+3) It has been suggested that defining the dynamic semantics of Unchecked_Union
+   in terms of check suppression leads to definitional problems in the
+   cases of imported objects declared in C code, values created via unchecked
+   conversion, values created via streaming, etc. What is the "correct"
+   (albeit missing) discriminant value in these cases? What matters is that
+   some appropriate discriminant value exists (even if an oracular consultation
+   would be needed to ascertain its value) and, in particular, that
+   the assumption that it exists does not lead to a contradiction.
+
+4) Would the term "implied discriminants" be preferable to "inferable
+   discriminants"?
+
+5) Propagated discriminant constraints where both the enclosing type and
+   the component type are unchecked union types introduce definitional
+   complications. Some of the rules could be simpler if constructs such as
+       type Uu_32 is <as above> ;
+
+       type Another_Uu (Is_Signed : Boolean) is
+         record
+           F : Uu_32 (Is_Signed => Is_Signed);
+           ...
+         end record;
+       pragma Unchecked_Union (Another_Uu);
+   were illegal.
+
+6) Requiring that the type not be By_Reference is just a convenient
+   way of avoiding interactions with finalization, tags, view
+   conversions, and limited types. For most implementations, this is
+   already a consequence of the C-compatibility requirement.
+
+7) The requirement that constrained objects must have the same
+   size as unconstrained objects stems from C.
+
+8) Checking is suppressed when converting from a non-Unchecked_Union
+   ancestor type to a constrained Unchecked_Union derived subtype.
+   This is a logical consequence of suppressing Discriminant_Check
+   for the Unchecked_Union type, but contradicts the earlier AI.
+   Adding a rule of the form "discriminant checks are suppressed,
+   except that ... " does not seem like a good idea. Opening that can
+   of worms would lead to questions like "what about converting an
+   operand which has inferable discriminants? what about a variant
+   field access where the prefix has inferable discriminants?".
+
+9) If a mechanism is introduced for reinstating suppressed checks
+   (see AI-224), it must be made clear that the check suppression
+   implied by an Unchecked_Union pragma is irrevocable.
+
+*************************************************************
+
+From: Tucker Taft
+Sent: Monday, January 28, 2002 at  4:22 PM
+
+"Baird, Steve" wrote:
+
+> B.3.3 Pragma Unchecked_Union
+>
+> [A pragma Unchecked_Union specifies an interface correspondence
+> between a given discriminated type and some C union. The pragma
+> specifies that the associated type shall be given a representation
+> that leaves no space for its discriminant(s).]
+>
+>                 Syntax
+>
+> The form of pragma Unchecked_Union is as follows:
+>
+>     pragma Unchecked_Union (first_subtype_local_name);
+>
+>                 Legality Rules
+>
+> Unchecked_Union is a representation pragma, specifying the unchecked
+> union aspect of representation.
+>
+> The first_subtype_local_name of a pragma Unchecked_Union shall denote
+> an unconstrained discriminated record subtype having a variant_part.
+>
+> The type is said to be an unchecked union type. A subtype of an
+> unchecked union type is said to be an unchecked union subtype.
+> An object of an unchecked union type is said to be an unchecked union
+> object.
+>
+> All component subtypes of the type shall be C-compatible.
+>
+> If a component subtype of the type is subject to a per-object constraint,
+> then the component subtype shall be an unchecked union subtype.
+>
+> The type shall not be a by-reference type.
+
+This seems heavy handed.  Is there a clear reason why
+one shouldn't have an atomic or volatile component in an
+unchecked-union?
+
+>                 Static Semantics
+>
+> An unchecked union type is eligible for conventions C and C_Pass_By_Copy,
+> as is any subtype of the type.
+
+I thought the convention was by default "C" but that could be overridden.
+
+>
+> Discriminant_Check is suppressed for the type.
+>
+> All objects of the type shall have the same size.
+>
+> Discriminants of objects of the type shall be of size zero.
+>
+> Any name which denotes a discriminant of an object of an
+> Unchecked_Union type shall occur within the declarative region of the type.
+
+Discriminant names can also appear in named aggregates -- in fact they must.
+
+Given your concept of "inferrable" discriminants, why not allow
+referring to the discriminants of an object with inferrable discriminants?
+
+
+>
+> An Unchecked_Union subtype shall not be passed as a generic actual parameter
+> if the corresponding formal type has a known_discriminant_part or
+> is a formal derived type which is not an unchecked union type.
+>
+>                 Dynamic Semantics
+>
+> A view of an unchecked union object [(including a type conversion or
+> function call)] is said to have "inferable discriminants" if it has a
+> constrained nominal subtype, unless the object is a component of an
+> enclosing unchecked union object which is subject to a per-object constraint
+> and the enclosing object lacks inferable discriminants.
+>
+> An expression of an Unchecked_Union type is said to have "inferable
+> discriminants" if it is either a name of an object with inferable
+> discriminants or a qualified expression whose subtype_mark denotes a
+> constrained subtype.
+>
+> The predefined equality operator for an Unchecked_Union type
+> raises Program_Error if either of the operands lacks inferable
+> discriminants. [This includes the case where the equality operator
+> is invoked implicitly by the equality operator for an enclosing composite
+> type - if the Unchecked_Union component is unconstrained, Program_Error
+> is raised].
+>
+> Evaluation of a membership test raises Program_Error if the
+> subtype_mark denotes a constrained Unchecked_Union subtype and the
+> expression lacks inferable discriminants.
+>
+> Conversion from a derived Unchecked_Union type to an unconstrained
+> non-Unchecked_Union ancestor type raises Program_Error if the operand
+> of the conversion lacks inferable discriminants.
+
+Why does it matter whether the other type is an ancestor?  Presuming
+we are talking untagged types, all that is required is that they
+have a common ancestor for them to be convertible.
+
+I would drop the whole mention of "derived" and "ancestor" since that
+is better handled by the normal legality rules.
+
+*************************************************************
+
+From: Steve Baird
+Sent: Monday, January 28, 2002 at  6:33 PM
+
+> From: Tucker Taft
+> ...
+> This seems heavy handed.  Is there a clear reason why
+> one shouldn't have an atomic or volatile component in an
+> unchecked-union?
+
+Fair enough. I was just trying to avoid enumerating all the
+constructs mentioned in discussion point #6.
+
+> I thought the convention was by default "C" but that
+> could be overridden.
+
+This is a way of bypassing the C vs. C_Pass_By_Copy
+question.
+
+> Discriminant names can also appear in named aggregates
+
+Good point; I agree.
+
+> Given your concept of "inferrable" discriminants, why not
+> allow referring to the discriminants of an object with
+> inferrable discriminants?
+
+That's certainly an option. I had thought of this concept
+as only being part of the dynamic semantics of the language,
+not the static semantics, but your idea seems reasonable.
+
+> Why does it matter whether the other type is an ancestor?
+Good point. My mistake.
 
 *************************************************************
 

Questions? Ask the ACAA Technical Agent