!standard 4.3(6) 22-01-19 AI22-0007-1/03 !class binding interpretation 21-11-11 !status Corrigendum 1-2022 22-01-19 !status ARG Approved 11-0-0 21-11-18 !status work item 21-11-11 !status received 21-11-10 !priority Low !difficulty Easy !qualifier Omission !subject Discriminant checks for aggregates might need to be done early !summary Discriminant checks must be performed early enough to prevent bad objects. !issue If the ancestor subtype of a type extension is a constrained discriminated subtype, do we want to prevent the existence (however brief) of values of the descendant type that have the wrong discriminant value(s)? (Yes.) !recommendation (See Summary.) !wording Modify 4.3(6): If an aggregate is of a tagged type, a check is made that its value belongs to the first subtype of the type. Constraint_Error is raised if this check fails. {Any discriminant check is performed before the initialization of any nondiscriminant component of the aggregate object.} !discussion RM 4.3(6) says "If an aggregate is of a tagged type, a check is made that its value belongs to the first subtype of the type." This suggests that we first construct the object and then, after that is done, we perform the required discriminant check. The discriminant check needs to be performed earlier. Consider the following example: package Pkg2 is type T1 (D : Boolean) is tagged record case D is when False => null; when True => F1 : Some_Type; end case; end record; type T2 is new T1 (False) with record F2 : Another_Type; end record; function T2_Eq (X : T2) return Boolean is (X = (D => True, F1 => ..., F2 => ...)); end Pkg2; If the two component types require finalization and the compiler (reasonably) stores F1 and F2 at the same offset, then we could have a mess even after C_E is raised. Even apart from such representation issues, how would finalization work? When we finalize an object, we finalize its components. What are the components of this peculiar aggregate, and what type is it that has both an F1 and an F2 component? This seems like a definitional issue that we'd like to avoid having to deal with. All of these problems can be avoided if we require that the discriminant check be performed earlier (as opposed to after the aggregate value has been constructed). On the other hand, we do not want to change the point at which predicate checks are performed, they require the full object to be available. !corrigendum 4.3(6) @drepl If an @fa is of a tagged type, a check is made that its value belongs to the first subtype of the type. Constraint_Error is raised if this check fails. @dby If an @fa is of a tagged type, a check is made that its value belongs to the first subtype of the type. Constraint_Error is raised if this check fails. Any discriminant check is performed before the initialization of any nondiscriminant component of the aggregate object. !ACATS test An ACATS C-Test should be constructed to check that this case is checked in the correct order. This test is relatively important, as failing to make the check could result in erroneous execution (and trashed objects due to overwriting someone else's memory). !appendix ****************************************************************