The existing (SPARK-based) implementation of Default_Initial_Condition aspects only applies DIC checks based on a type's own DIC (or only one DIC from an ancestor if the type doesn't specify one, but not from further up the ancestor chain), but Ada 202x (AI12-0265) specifies that all DICs of parent types apply to the descendant type (so they're basically "additive"). This is similar to what's already done for types that have Type_Invariant'Class aspects, and the implementation is modeled on what's done for Type_Invariant, which generates "partial" checking procedures to apply checks for any DIC specified directly on the partial (private) view of a type. The "full" DIC procedure calls the type's partial DIC procedure if any, and applies any DIC checks inherited from parent types. Calls to DIC procedures are suppressed in various cases when the procedure body is null (such as when assertions are not enabled).
Also, checks of Default_Initial_Conditions were missing in a number of
cases where such checks are required, and these changes address those
gaps. Specifically, checks are now done for record and array components
where the components are default initialized, for default-initialized
allocators, for ancestor parts of extension aggregates, and for
components that are default-initialized by aggregate component
associations specified with a box. Note that components whose
declarations specify an initialization expression are not defined to be
"initialized by default".
For the case of box associations, it was necessary to add a flag to
N_Component_Association nodes (Was_Default_Init_Box_Association),
to mark such associations as having come from a box association that
requires default initialization, because new associations are created
in the analyzer and the original associations are no longer available
at the point where aggregate expansion occurs (Original_Node doesn't
apply).
Note that these changes do not complete the work for implementing
Default_Initial_Condition, which also requires support for DIC aspects
on generic formal types (part of AI12-0265), and resolution of DIC
expressions as specified in AI12-0397.
Tested on x86_64-pc-linux-gnu, committed on trunk
gcc/ada/
* einfo.ads (Is_Partial_DIC_Procedure): New function.
(Partial_DIC_Procedure): New procedure.
* einfo.adb (Is_Partial_DIC_Procedure): New function to return
whether a subprogram is a partial Default_Initial_Condition
procedure by checking the name (to avoid adding a new field).
(DIC_Procedure): Add a test that excludes partial DIC procedures
from being returned.
(Partial_DIC_Procedure): New procedure to return the partial DIC
procedure of a type, if it has one (otherwise returns Empty).
(Set_DIC_Procedure): Remove check for duplicate DIC procedures.
* exp_aggr.adb (Gen_Assign): Generate a call to the type's DIC
procedure in the case where an array component is default
initialized (due to an association with a box).
(Build_Record_Aggr_Code): For an extension aggregate, generate a
call to the ancestor type's DIC procedure (if any) when the
ancestor part is a subtype mark. For a record component
association that was specified with a box (tested for by
checking the new flag Was_Default_Init_Box_Association),
generate a call to the component type's DIC procedure (if it has
one).
* exp_ch4.adb (Expand_N_Allocator): When the allocated object is
default initialized and the designated type has a DIC aspect,
generate a call to the DIC procedure.
* exp_util.ads (Build_DIC_Call): Change the formal Obj_Id to
name Obj_Name, and change its type from Entity_Id to Node_Id
(and update comment).
(Build_DIC_Procedure_Body): Add formal Partial_DIC, remove
formal For_Freeze, and update comment accordingly.
(Build_DIC_Procedure_Declaration): Add formal Partial_DIC and
update comment.
* exp_util.adb
(Build_DIC_Call): Revised to use its Obj_Name (formerly Obj_Id)
formal directly rather than calling New_Occurrence_Of on it, to
allow arbitrary names to be passed rather than being limited to
Entity_Ids.
(Build_DIC_Procedure_Body): Call Add_Parent_DICs to generate
checks for DICs associated with any parent types, implementing
the required "additive" semantics for DICs. When building a DIC
procedure body for a partial view (when Partial_DIC is True),
call Add_Own_DIC when the type has its own DIC. In the case of
"full" DIC procedures, a call is generated to any partial DIC
procedure of the type (unless the procedure has a null body),
along with checks for any DICs inherited by the full view.
(Build_DIC_Procedure_Declaration): Add handling for partial DIC
procedures. For the suffix of a regular DIC procedure's name,
use "DIC" (instead of "Default_Initial_Condition"), and for the
suffix of a partial DIC procedure's name, use "Partial_DIC".
(Add_DIC_Check): Add the DIC pragma to the list of seen pragmas
(Pragmas_Seen).
(Add_Inherited_Tagged_DIC): Remove the formals Par_Typ,
Deriv_Typ, and Obj_Id, and add formal Expr, which denotes DIC's
expression. Remove the call to Replace_References (which is now
done in Add_Inherited_DICs).
(Add_Inherited_DICs): New procedure to locate a DIC pragma
associated with a parent type, replace its references
appropriately (such as any current instance references), and add
a check for the DIC.
(Add_Own_DIC): Add an Obj_Id formal to allow caller to pass the
_init formal of the generated DIC procedure.
(Add_Parent_DICs): New procedure to traverse a type's parents,
looking for DICs associated with those and calling
Add_Inherited_DICs to apply the appropriate DIC checks.
(Is_Verifiable_DIC_Pragma): Treat pragmas that have an Empty
first argument the same as a pragma without any arguments
(returning False for that case).
* exp_ch3.adb (Init_One_Dimension): Generate calls to the
component's DIC procedure when needed.
(Possible_DIC_Call): New function nested in Init_One_Dimension
to build a call to the array component type's DIC-checking
function when appropriate.
(Build_Array_Init_Proc): The presence of a DIC on the component
type is an additional condition for generating an init proc for
an array type.
(Build_Init_Statements): When the record component's type has a
DIC, and the component declaration does not have an
initialization expression, generate a call to the component
type's DIC procedure.
(Expand_N_Object_Declaration): Modify the call to Build_DIC_Call
to pass a new occurrence of the object's defining id rather than
the id itself.
(Freeze_Type): Only build a type's DIC procedure (if it has one)
for types that are not interfaces.
* exp_spark.adb (Expand_SPARK_N_Freeze_Type): Remove From_Freeze
actual and add a ??? comment.
(Expand_SPARK_N_Object_Declaration): Modify call to
Build_DIC_Call to pass a new occurrence of the object id rather
than the object id itself.
* sem_aggr.adb (Resolve_Record_Aggregate): Declare local flag
Is_Box_Init_By_Default and set it in cases where the component
association has a box and the component is being initialized by
default (as opposed to initialized by an initialization
expression associated with the component's declaration).
(Add_Association): If the association has a box for a component
initialized by default, the flag
Was_Default_Init_Box_Association is set on the new component
association (for later testing during expansion).
(Get_Value): Reset Is_Box_Init_By_Default to False.
* sem_ch3.adb (Build_Assertion_Bodies_For_Type): Rearrange code
to build DIC procedure bodies for a (noninterface) type that
Has_Own_DIC (for partial type views) or Has_DIC (for full type
views) as appropriate.
* sem_ch13.adb (Analyze_Aspect_Specifications,
Aspect_Default_Initial_Condition): Add an extra argument to the
DIC pragma to denote the type associated with the pragma (for
use in Build_DIC_Procedure_Body).
* sem_prag.adb (Analyze_Pragma): Allow two arguments for pragma
Default_Initial_Condition. If not already present, add an extra
argument denoting the type that the pragma is associated with.
* sem_util.adb (Propagate_DIC_Attributes): Retrieve any partial
DIC procedure associated with the type and add it to the type's
list of subprograms (Subprograms_For_Type).
* sinfo.ads (Was_Default_Init_Box_Association): New flag on
N_Component_Association nodes. Add subprograms to get and set
flag, as well as updating the documentation.
* sinfo.adb (Was_Default_Init_Box_Association): New function to
retrieve the corresponding flag (Flag14).
(Set_Was_Default_Init_Box_Association): New procedure to set the
corresponding flag (Flag14).
patch.diff.gz
Description: application/gzip
