diff options
author | Giuliano Belinassi <giuliano.belinassi@usp.br> | 2020-08-22 17:43:43 -0300 |
---|---|---|
committer | Giuliano Belinassi <giuliano.belinassi@usp.br> | 2020-08-22 17:43:43 -0300 |
commit | a926878ddbd5a98b272c22171ce58663fc04c3e0 (patch) | |
tree | 86af256e5d9a9c06263c00adc90e5fe348008c43 /gcc/ada/sem_ch3.adb | |
parent | 542730f087133690b47e036dfd43eb0db8a650ce (diff) | |
parent | 07cbaed8ba7d1b6e4ab3a9f44175502a4e1ecdb1 (diff) | |
download | gcc-devel/autopar_devel.zip gcc-devel/autopar_devel.tar.gz gcc-devel/autopar_devel.tar.bz2 |
Merge branch 'autopar_rebase2' into autopar_develdevel/autopar_devel
Quickly commit changes in the rebase branch.
Diffstat (limited to 'gcc/ada/sem_ch3.adb')
-rw-r--r-- | gcc/ada/sem_ch3.adb | 1760 |
1 files changed, 809 insertions, 951 deletions
diff --git a/gcc/ada/sem_ch3.adb b/gcc/ada/sem_ch3.adb index 956c92d..a5690d6 100644 --- a/gcc/ada/sem_ch3.adb +++ b/gcc/ada/sem_ch3.adb @@ -6,7 +6,7 @@ -- -- -- B o d y -- -- -- --- Copyright (C) 1992-2019, Free Software Foundation, Inc. -- +-- Copyright (C) 1992-2020, Free Software Foundation, Inc. -- -- -- -- GNAT is free software; you can redistribute it and/or modify it under -- -- terms of the GNU General Public License as published by the Free Soft- -- @@ -45,6 +45,7 @@ with Layout; use Layout; with Lib; use Lib; with Lib.Xref; use Lib.Xref; with Namet; use Namet; +with Nlists; use Nlists; with Nmake; use Nmake; with Opt; use Opt; with Restrict; use Restrict; @@ -91,6 +92,11 @@ package body Sem_Ch3 is -- abstract interface types implemented by a record type or a derived -- record type. + procedure Build_Access_Subprogram_Wrapper (Decl : Node_Id); + -- When an access-to-subprogram type has pre/postconditions, we build a + -- subprogram that includes these contracts and is invoked by an indirect + -- call through the corresponding access type. + procedure Build_Derived_Type (N : Node_Id; Parent_Type : Entity_Id; @@ -253,6 +259,11 @@ package body Sem_Ch3 is -- circularity issues in Gigi. We create an incomplete type for the record -- declaration, which is the designated type of the anonymous access. + procedure Check_Constraining_Discriminant (New_Disc, Old_Disc : Entity_Id); + -- Check that, if a new discriminant is used in a constraint defining the + -- parent subtype of a derivation, its subtype is statically compatible + -- with the subtype of the corresponding parent discriminant (RM 3.7(15)). + procedure Check_Delta_Expression (E : Node_Id); -- Check that the expression represented by E is suitable for use as a -- delta expression, i.e. it is of real type and is static. @@ -562,16 +573,18 @@ package body Sem_Ch3 is -- copying the record declaration for the derived base. In the tagged case -- the value returned is irrelevant. - procedure Inherit_Predicate_Flags (Subt, Par : Entity_Id); - -- Propagate static and dynamic predicate flags from a parent to the - -- subtype in a subtype declaration with and without constraints. - function Is_EVF_Procedure (Subp : Entity_Id) return Boolean; -- Subsidiary to Check_Abstract_Overriding and Derive_Subprogram. -- Determine whether subprogram Subp is a procedure subject to pragma -- Extensions_Visible with value False and has at least one controlling -- parameter of mode OUT. + function Is_Private_Primitive (Prim : Entity_Id) return Boolean; + -- Subsidiary to Check_Abstract_Overriding and Derive_Subprogram. + -- When applied to a primitive subprogram Prim, returns True if Prim is + -- declared as a private operation within a package or generic package, + -- and returns False otherwise. + function Is_Valid_Constraint_Kind (T_Kind : Type_Kind; Constraint_Kind : Node_Kind) return Boolean; @@ -657,14 +670,22 @@ package body Sem_Ch3 is -- declaration, Prev_T is the original incomplete type, whose full view is -- the record type. - procedure Replace_Components (Typ : Entity_Id; Decl : Node_Id); - -- Subsidiary to Build_Derived_Record_Type. For untagged records, we - -- build a copy of the declaration tree of the parent, and we create - -- independently the list of components for the derived type. Semantic - -- information uses the component entities, but record representation - -- clauses are validated on the declaration tree. This procedure replaces - -- discriminants and components in the declaration with those that have - -- been created by Inherit_Components. + procedure Replace_Discriminants (Typ : Entity_Id; Decl : Node_Id); + -- Subsidiary to Build_Derived_Record_Type. For untagged record types, we + -- first create the list of components for the derived type from that of + -- the parent by means of Inherit_Components and then build a copy of the + -- declaration tree of the parent with the help of the mapping returned by + -- Inherit_Components, which will for example be used to validate record + -- representation clauses given for the derived type. If the parent type + -- is private and has discriminants, the ancestor discriminants used in the + -- inheritance are that of the private declaration, whereas the ancestor + -- discriminants present in the declaration tree of the parent are that of + -- the full declaration; as a consequence, the remapping done during the + -- copy will leave the references to the ancestor discriminants unchanged + -- in the declaration tree and they need to be fixed up. If the derived + -- type has a known discriminant part, then the remapping done during the + -- copy will only create references to the girder discriminants and they + -- need to be replaced with references to the non-girder discriminants. procedure Set_Fixed_Range (E : Entity_Id; @@ -716,8 +737,6 @@ package body Sem_Ch3 is Enclosing_Prot_Type : Entity_Id := Empty; begin - Check_SPARK_05_Restriction ("access type is not allowed", N); - if Is_Entry (Current_Scope) and then Is_Task_Type (Etype (Scope (Current_Scope))) then @@ -732,8 +751,8 @@ package body Sem_Ch3 is -- function, scope is the current one, because it is the one of the -- current type declaration, except for the pathological case below. - if Nkind_In (Related_Nod, N_Object_Declaration, - N_Access_Function_Definition) + if Nkind (Related_Nod) in + N_Object_Declaration | N_Access_Function_Definition then Anon_Scope := Current_Scope; @@ -746,8 +765,8 @@ package body Sem_Ch3 is begin Par := Related_Nod; - while Nkind_In (Par, N_Access_Function_Definition, - N_Access_Definition) + while Nkind (Par) in + N_Access_Function_Definition | N_Access_Definition loop Par := Parent (Par); end loop; @@ -773,7 +792,7 @@ package body Sem_Ch3 is -- be available in the scope that encloses the protected declaration. -- Otherwise the type is in the scope enclosing the subprogram. - -- If the function has formals, The return type of a subprogram + -- If the function has formals, the return type of a subprogram -- declaration is analyzed in the scope of the subprogram (see -- Process_Formals) and thus the protected type, if present, is -- the scope of the current function scope. @@ -921,7 +940,6 @@ package body Sem_Ch3 is then if Is_Limited_Record (Desig_Type) and then Is_Class_Wide_Type (Desig_Type) - and then Tasking_Allowed then Build_Class_Wide_Master (Anon_Type); @@ -1029,7 +1047,7 @@ package body Sem_Ch3 is Param := First (Parameter_Specifications (Def)); while Present (Param) loop Check_For_Premature_Usage (Parameter_Type (Param)); - Param := Next (Param); + Next (Param); end loop; end if; @@ -1050,8 +1068,6 @@ package body Sem_Ch3 is -- Start of processing for Access_Subprogram_Declaration begin - Check_SPARK_05_Restriction ("access type is not allowed", T_Def); - -- Associate the Itype node with the inner full-type declaration or -- subprogram spec or entry body. This is required to handle nested -- anonymous declarations. For example: @@ -1062,20 +1078,18 @@ package body Sem_Ch3 is -- (Z : access T))) D_Ityp := Associated_Node_For_Itype (Desig_Type); - while not (Nkind_In (D_Ityp, N_Full_Type_Declaration, - N_Private_Type_Declaration, - N_Private_Extension_Declaration, - N_Procedure_Specification, - N_Function_Specification, - N_Entry_Body) - - or else - Nkind_In (D_Ityp, N_Object_Declaration, - N_Object_Renaming_Declaration, - N_Formal_Object_Declaration, - N_Formal_Type_Declaration, - N_Task_Type_Declaration, - N_Protected_Type_Declaration)) + while Nkind (D_Ityp) not in N_Full_Type_Declaration + | N_Private_Type_Declaration + | N_Private_Extension_Declaration + | N_Procedure_Specification + | N_Function_Specification + | N_Entry_Body + | N_Object_Declaration + | N_Object_Renaming_Declaration + | N_Formal_Object_Declaration + | N_Formal_Type_Declaration + | N_Task_Type_Declaration + | N_Protected_Type_Declaration loop D_Ityp := Parent (D_Ityp); pragma Assert (D_Ityp /= Empty); @@ -1083,15 +1097,14 @@ package body Sem_Ch3 is Set_Associated_Node_For_Itype (Desig_Type, D_Ityp); - if Nkind_In (D_Ityp, N_Procedure_Specification, - N_Function_Specification) + if Nkind (D_Ityp) in N_Procedure_Specification | N_Function_Specification then Set_Scope (Desig_Type, Scope (Defining_Entity (D_Ityp))); - elsif Nkind_In (D_Ityp, N_Full_Type_Declaration, - N_Object_Declaration, - N_Object_Renaming_Declaration, - N_Formal_Type_Declaration) + elsif Nkind (D_Ityp) in N_Full_Type_Declaration + | N_Object_Declaration + | N_Object_Renaming_Declaration + | N_Formal_Type_Declaration then Set_Scope (Desig_Type, Scope (Defining_Identifier (D_Ityp))); end if; @@ -1198,22 +1211,6 @@ package body Sem_Ch3 is begin F := First (Formals); - -- In ASIS mode, the access_to_subprogram may be analyzed twice, - -- when it is part of an unconstrained type and subtype expansion - -- is disabled. To avoid back-end problems with shared profiles, - -- use previous subprogram type as the designated type, and then - -- remove scope added above. - - if ASIS_Mode and then Present (Scope (Defining_Identifier (F))) - then - Set_Etype (T_Name, T_Name); - Init_Size_Align (T_Name); - Set_Directly_Designated_Type (T_Name, - Scope (Defining_Identifier (F))); - End_Scope; - return; - end if; - while Present (F) loop if No (Parent (Defining_Identifier (F))) then Set_Parent (Defining_Identifier (F), F); @@ -1327,8 +1324,6 @@ package body Sem_Ch3 is Full_Desig : Entity_Id; begin - Check_SPARK_05_Restriction ("access type is not allowed", Def); - -- Check for permissible use of incomplete type if Nkind (S) /= N_Subtype_Indication then @@ -1415,6 +1410,26 @@ package body Sem_Ch3 is Set_Is_Tagged_Type (T, False); end if; + -- For SPARK, check that the designated type is compatible with + -- respect to volatility with the access type. + + if SPARK_Mode /= Off + and then Comes_From_Source (T) + then + -- ??? UNIMPLEMENTED + -- In the case where the designated type is incomplete at this point, + -- performing this check here is harmless but the check will need to + -- be repeated when the designated type is complete. + + -- The preceding call to Comes_From_Source is needed because the + -- FE sometimes introduces implicitly declared access types. See, + -- for example, the expansion of nested_po.ads in OA28-015. + + Check_Volatility_Compatibility + (Full_Desig, T, "designated type", "access type", + Srcpos_Bearer => T); + end if; + Set_Etype (T, T); -- If the type has appeared already in a with_type clause, it is frozen @@ -1800,13 +1815,9 @@ package body Sem_Ch3 is -- of locally defined tagged types (or compiling with static -- dispatch tables generation disabled) the corresponding -- entry of the secondary dispatch table is filled when such - -- an entity is frozen. This is an expansion activity that must - -- be suppressed for ASIS because it leads to gigi elaboration - -- issues in annotate mode. + -- an entity is frozen. - if not ASIS_Mode then - Set_Has_Delayed_Freeze (New_Subp); - end if; + Set_Has_Delayed_Freeze (New_Subp); end if; <<Continue>> @@ -1943,10 +1954,6 @@ package body Sem_Ch3 is T := Find_Type_Of_Object (Subtype_Indication (Component_Definition (N)), N); - if not Nkind_In (Typ, N_Identifier, N_Expanded_Name) then - Check_SPARK_05_Restriction ("subtype mark required", Typ); - end if; - -- Ada 2005 (AI-230): Access Definition case else @@ -1997,7 +2004,6 @@ package body Sem_Ch3 is -- package Sem). if Present (E) then - Check_SPARK_05_Restriction ("default expression is not allowed", E); Preanalyze_Default_Expression (E, T); Check_Initialization (T, E); @@ -2340,9 +2346,9 @@ package body Sem_Ch3 is -- because they have already been resolved. elsif Decls = Visible_Declarations (Context) - and then Ekind_In (Typ, E_Limited_Private_Type, - E_Private_Type, - E_Record_Type_With_Private) + and then Ekind (Typ) in E_Limited_Private_Type + | E_Private_Type + | E_Record_Type_With_Private and then Has_Own_Invariants (Typ) then Build_Invariant_Procedure_Body @@ -2354,7 +2360,8 @@ package body Sem_Ch3 is -- potential errors. elsif Decls = Private_Declarations (Context) - and then not Is_Private_Type (Typ) + and then (not Is_Private_Type (Typ) + or else Present (Underlying_Full_View (Typ))) and then Has_Private_Declaration (Typ) and then Has_Invariants (Typ) then @@ -2460,7 +2467,7 @@ package body Sem_Ch3 is end if; exit when Last_Entity (Current_Scope) = Curr; - Curr := Next_Entity (Curr); + Next_Entity (Curr); end loop; end if; @@ -2486,9 +2493,9 @@ package body Sem_Ch3 is -- controlled primitives. if Nkind (Body_Spec) /= N_Procedure_Specification - or else not Nam_In (Chars (Body_Id), Name_Adjust, - Name_Finalize, - Name_Initialize) + or else Chars (Body_Id) not in Name_Adjust + | Name_Finalize + | Name_Initialize then return; @@ -2523,7 +2530,7 @@ package body Sem_Ch3 is Spec_Id := Current_Entity (Body_Id); while Present (Spec_Id) loop - if Ekind_In (Spec_Id, E_Procedure, E_Generic_Procedure) + if Ekind (Spec_Id) in E_Procedure | E_Generic_Procedure and then Scope (Spec_Id) = Current_Scope and then Present (First_Formal (Spec_Id)) and then No (Next_Formal (First_Formal (Spec_Id))) @@ -2613,32 +2620,16 @@ package body Sem_Ch3 is -- Local variables Context : Node_Id := Empty; + Ctrl_Typ : Entity_Id := Empty; Freeze_From : Entity_Id := Empty; Next_Decl : Node_Id; - Body_Seen : Boolean := False; - -- Flag set when the first body [stub] is encountered - -- Start of processing for Analyze_Declarations begin - if Restriction_Check_Required (SPARK_05) then - Check_Later_Vs_Basic_Declarations (L, During_Parsing => False); - end if; - Decl := First (L); while Present (Decl) loop - -- Package spec cannot contain a package declaration in SPARK - - if Nkind (Decl) = N_Package_Declaration - and then Nkind (Parent (L)) = N_Package_Specification - then - Check_SPARK_05_Restriction - ("package specification cannot contain a package declaration", - Decl); - end if; - -- Complete analysis of declaration Analyze (Decl); @@ -2648,6 +2639,16 @@ package body Sem_Ch3 is Freeze_From := First_Entity (Current_Scope); end if; + -- Remember if the declaration we just processed is the full type + -- declaration of a controlled type (to handle late overriding of + -- initialize, adjust or finalize). + + if Nkind (Decl) = N_Full_Type_Declaration + and then Is_Controlled (Defining_Identifier (Decl)) + then + Ctrl_Typ := Defining_Identifier (Decl); + end if; + -- At the end of a declarative part, freeze remaining entities -- declared in it. The end of the visible declarations of package -- specification is not the end of a declarative part if private @@ -2668,8 +2669,8 @@ package body Sem_Ch3 is if Nkind (Parent (L)) = N_Component_List then null; - elsif Nkind_In (Parent (L), N_Protected_Definition, - N_Task_Definition) + elsif Nkind (Parent (L)) in + N_Protected_Definition | N_Task_Definition then Check_Entry_Contracts; @@ -2695,7 +2696,7 @@ package body Sem_Ch3 is and then Present (First_Entity (Current_Scope)) then while Is_Generic_Formal (Freeze_From) loop - Freeze_From := Next_Entity (Freeze_From); + Next_Entity (Freeze_From); end loop; Freeze_All (Freeze_From, Decl); @@ -2703,14 +2704,7 @@ package body Sem_Ch3 is else -- For declarations in a subprogram body there is no issue - -- with name resolution in aspect specifications, but in - -- ASIS mode we need to preanalyze aspect specifications - -- that may otherwise only be analyzed during expansion - -- (e.g. during generation of a related subprogram). - - if ASIS_Mode then - Resolve_Aspects; - end if; + -- with name resolution in aspect specifications. Freeze_All (First_Entity (Current_Scope), Decl); Freeze_From := Last_Entity (Current_Scope); @@ -2736,16 +2730,6 @@ package body Sem_Ch3 is -- End of a package declaration - -- In compilation mode the expansion of freeze node takes care - -- of resolving expressions of all aspects in the list. In ASIS - -- mode this must be done explicitly. - - if ASIS_Mode - and then Scope (Current_Scope) = Standard_Standard - then - Resolve_Aspects; - end if; - -- This is a freeze point because it is the end of a -- compilation unit. @@ -2807,29 +2791,20 @@ package body Sem_Ch3 is -- to examine Next_Decl as the late primitive idiom can only apply -- to the first encountered body. - -- The spec of the late primitive is not generated in ASIS mode to - -- ensure a consistent list of primitives that indicates the true - -- semantic structure of the program (which is not relevant when - -- generating executable code). - -- ??? A cleaner approach may be possible and/or this solution -- could be extended to general-purpose late primitives, TBD. - if not ASIS_Mode - and then not Body_Seen - and then not Is_Body (Decl) - then - Body_Seen := True; + if Present (Ctrl_Typ) then - if Nkind (Next_Decl) = N_Subprogram_Body then - Handle_Late_Controlled_Primitive (Next_Decl); - end if; + -- No need to continue searching for late body overriding if + -- the controlled type is already frozen. - else - -- In ASIS mode, if the next declaration is a body, complete - -- the analysis of declarations so far. + if Is_Frozen (Ctrl_Typ) then + Ctrl_Typ := Empty; - Resolve_Aspects; + elsif Nkind (Next_Decl) = N_Subprogram_Body then + Handle_Late_Controlled_Primitive (Next_Decl); + end if; end if; Adjust_Decl; @@ -2851,7 +2826,7 @@ package body Sem_Ch3 is if Present (L) then Context := Parent (L); - -- Certain contract annocations have forward visibility semantics and + -- Certain contract annotations have forward visibility semantics and -- must be analyzed after all declarative items have been processed. -- This timing ensures that entities referenced by such contracts are -- visible. @@ -3126,16 +3101,10 @@ package body Sem_Ch3 is when N_Derived_Type_Definition => null; - -- For record types, discriminants are allowed, unless we are in - -- SPARK. + -- For record types, discriminants are allowed. when N_Record_Definition => - if Present (Discriminant_Specifications (N)) then - Check_SPARK_05_Restriction - ("discriminant type is not allowed", - Defining_Identifier - (First (Discriminant_Specifications (N)))); - end if; + null; when others => if Present (Discriminant_Specifications (N)) then @@ -3175,6 +3144,17 @@ package body Sem_Ch3 is Validate_Access_Type_Declaration (T, N); + -- If the type has contracts, we create the corresponding + -- wrapper at once, before analyzing the aspect specifications, + -- so that pre/postconditions can be handled directly on the + -- generated wrapper. + + if Ada_Version >= Ada_2020 + and then Present (Aspect_Specifications (N)) + then + Build_Access_Subprogram_Wrapper (N); + end if; + when N_Access_To_Object_Definition => Access_Type_Declaration (T, Def); @@ -3246,12 +3226,6 @@ package body Sem_Ch3 is return; end if; - -- Controlled type is not allowed in SPARK - - if Is_Visibly_Controlled (T) then - Check_SPARK_05_Restriction ("controlled type is not allowed", N); - end if; - -- Some common processing for all types Set_Depends_On_Private (T, Has_Private_Component (T)); @@ -3393,8 +3367,6 @@ package body Sem_Ch3 is T : Entity_Id; begin - Check_SPARK_05_Restriction ("incomplete type is not allowed", N); - Generate_Definition (Defining_Identifier (N)); -- Process an incomplete declaration. The identifier must not have been @@ -3638,7 +3610,7 @@ package body Sem_Ch3 is return; end if; - if Nkind_In (E, N_Integer_Literal, N_Real_Literal) then + if Nkind (E) in N_Integer_Literal | N_Real_Literal then Set_Etype (E, Etype (Id)); end if; @@ -3699,7 +3671,7 @@ package body Sem_Ch3 is -- has aspects that require delayed analysis, the resolution of the -- aggregate must be deferred to the freeze point of the object. This -- special processing was created for address clauses, but it must - -- also apply to Alignment. This must be done before the aspect + -- also apply to address aspects. This must be done before the aspect -- specifications are analyzed because we must handle the aggregate -- before the analysis of the object declaration is complete. @@ -3847,7 +3819,7 @@ package body Sem_Ch3 is while Present (Comp) loop Check_Component (Etype (Comp), Parent (Comp)); - Comp := Next_Component (Comp); + Next_Component (Comp); end loop; end if; end Check_Component; @@ -3922,10 +3894,12 @@ package body Sem_Ch3 is begin if Present (Aspect_Specifications (N)) then - A := First (Aspect_Specifications (N)); - A_Id := Get_Aspect_Id (Chars (Identifier (A))); + A := First (Aspect_Specifications (N)); + while Present (A) loop - if A_Id = Aspect_Alignment or else A_Id = Aspect_Address then + A_Id := Get_Aspect_Id (Chars (Identifier (A))); + + if A_Id = Aspect_Address then -- Set flag on object entity, for later processing at -- the freeze point. @@ -4078,7 +4052,7 @@ package body Sem_Ch3 is then null; - else + elsif Comes_From_Source (Id) then declare Save_Typ : constant Entity_Id := Etype (Id); begin @@ -4205,38 +4179,10 @@ package body Sem_Ch3 is Act_T := T; - -- These checks should be performed before the initialization expression - -- is considered, so that the Object_Definition node is still the same - -- as in source code. - - -- In SPARK, the nominal subtype is always given by a subtype mark - -- and must not be unconstrained. (The only exception to this is the - -- acceptance of declarations of constants of type String.) - - if not Nkind_In (Object_Definition (N), N_Expanded_Name, N_Identifier) - then - Check_SPARK_05_Restriction - ("subtype mark required", Object_Definition (N)); - - elsif Is_Array_Type (T) - and then not Is_Constrained (T) - and then T /= Standard_String - then - Check_SPARK_05_Restriction - ("subtype mark of constrained type expected", - Object_Definition (N)); - end if; - if Is_Library_Level_Entity (Id) then Check_Dynamic_Object (T); end if; - -- There are no aliased objects in SPARK - - if Aliased_Present (N) then - Check_SPARK_05_Restriction ("aliased object is not allowed", N); - end if; - -- Process initialization expression if present and not in error if Present (E) and then E /= Error then @@ -4263,7 +4209,7 @@ package body Sem_Ch3 is Analyze (E); -- In case of errors detected in the analysis of the expression, - -- decorate it with the expected type to avoid cascaded errors + -- decorate it with the expected type to avoid cascaded errors. if No (Etype (E)) then Set_Etype (E, T); @@ -4310,7 +4256,11 @@ package body Sem_Ch3 is -- If the aggregate is limited it will be built in place, and its -- expansion is deferred until the object declaration is expanded. - if Is_Limited_Type (T) then + -- This is also required when generating C code to ensure that an + -- object with an alignment or address clause can be initialized + -- by means of component by component assignments. + + if Is_Limited_Type (T) or else Modify_Tree_For_C then Set_Expansion_Delayed (E); end if; @@ -4427,18 +4377,6 @@ package body Sem_Ch3 is Apply_Scalar_Range_Check (E, T); Apply_Static_Length_Check (E, T); - if Nkind (Original_Node (N)) = N_Object_Declaration - and then Comes_From_Source (Original_Node (N)) - - -- Only call test if needed - - and then Restriction_Check_Required (SPARK_05) - and then not Is_SPARK_05_Initialization_Expr (Original_Node (E)) - then - Check_SPARK_05_Restriction - ("initialization expression is not appropriate", E); - end if; - -- A formal parameter of a specific tagged type whose related -- subprogram is subject to pragma Extensions_Visible with value -- "False" cannot be implicitly converted to a class-wide type by @@ -4476,15 +4414,16 @@ package body Sem_Ch3 is -- We need a predicate check if the type has predicates that are not -- ignored, and if either there is an initializing expression, or for -- default initialization when we have at least one case of an explicit - -- default initial value and then this is not an internal declaration - -- whose initialization comes later (as for an aggregate expansion). + -- default initial value (including via a Default_Value or + -- Default_Component_Value aspect, see AI12-0301) and then this is not + -- an internal declaration whose initialization comes later (as for an + -- aggregate expansion). -- If expression is an aggregate it may be expanded into assignments -- and the declaration itself is marked with No_Initialization, but -- the predicate still applies. if not Suppress_Assignment_Checks (N) - and then Present (Predicate_Function (T)) - and then not Predicates_Ignored (T) + and then Predicate_Enabled (T) and then (not No_Initialization (N) or else (Present (E) and then Nkind (E) = N_Aggregate)) @@ -4536,14 +4475,6 @@ package body Sem_Ch3 is if not Is_Definite_Subtype (T) then - -- In SPARK, a declaration of unconstrained type is allowed - -- only for constants of type string. - - if Is_String_Type (T) and then not Constant_Present (N) then - Check_SPARK_05_Restriction - ("declaration of object of unconstrained type not allowed", N); - end if; - -- Nothing to do in deferred constant case if Constant_Present (N) and then No (E) then @@ -4637,16 +4568,26 @@ package body Sem_Ch3 is Set_Ekind (Id, E_Variable); end if; - Rewrite (N, - Make_Object_Renaming_Declaration (Loc, - Defining_Identifier => Id, - Subtype_Mark => New_Occurrence_Of (T, Loc), - Name => E)); + -- If the expression is an aggregate it contains the required + -- discriminant values but it has not been resolved yet, so do + -- it now, and treat it as the initial expression of an object + -- declaration, rather than a renaming. - Set_Renamed_Object (Id, E); - Freeze_Before (N, T); - Set_Is_Frozen (Id); - goto Leave; + if Nkind (E) = N_Aggregate then + Analyze_And_Resolve (E, T); + + else + Rewrite (N, + Make_Object_Renaming_Declaration (Loc, + Defining_Identifier => Id, + Subtype_Mark => New_Occurrence_Of (T, Loc), + Name => E)); + + Set_Renamed_Object (Id, E); + Freeze_Before (N, T); + Set_Is_Frozen (Id); + goto Leave; + end if; else -- Ensure that the generated subtype has a unique external name @@ -5142,7 +5083,7 @@ package body Sem_Ch3 is ("parent of type extension must be a tagged type ", Indic); goto Leave; - elsif Ekind_In (Parent_Type, E_Void, E_Incomplete_Type) then + elsif Ekind (Parent_Type) in E_Void | E_Incomplete_Type then Error_Msg_N ("premature derivation of incomplete type", Indic); goto Leave; @@ -5339,7 +5280,6 @@ package body Sem_Ch3 is Skip : Boolean := False) is Id : constant Entity_Id := Defining_Identifier (N); - R_Checks : Check_Result; T : Entity_Id; begin @@ -5441,58 +5381,6 @@ package body Sem_Ch3 is end if; end if; - -- Subtype of Boolean cannot have a constraint in SPARK - - if Is_Boolean_Type (T) - and then Nkind (Subtype_Indication (N)) = N_Subtype_Indication - then - Check_SPARK_05_Restriction - ("subtype of Boolean cannot have constraint", N); - end if; - - if Nkind (Subtype_Indication (N)) = N_Subtype_Indication then - declare - Cstr : constant Node_Id := Constraint (Subtype_Indication (N)); - One_Cstr : Node_Id; - Low : Node_Id; - High : Node_Id; - - begin - if Nkind (Cstr) = N_Index_Or_Discriminant_Constraint then - One_Cstr := First (Constraints (Cstr)); - while Present (One_Cstr) loop - - -- Index or discriminant constraint in SPARK must be a - -- subtype mark. - - if not - Nkind_In (One_Cstr, N_Identifier, N_Expanded_Name) - then - Check_SPARK_05_Restriction - ("subtype mark required", One_Cstr); - - -- String subtype must have a lower bound of 1 in SPARK. - -- Note that we do not need to test for the nonstatic case - -- here, since that was already taken care of in - -- Process_Range_Expr_In_Decl. - - elsif Base_Type (T) = Standard_String then - Get_Index_Bounds (One_Cstr, Low, High); - - if Is_OK_Static_Expression (Low) - and then Expr_Value (Low) /= 1 - then - Check_SPARK_05_Restriction - ("String subtype must have lower bound of 1", N); - end if; - end if; - - Next (One_Cstr); - end loop; - end if; - end; - end if; - -- In the case where there is no constraint given in the subtype -- indication, Process_Subtype just returns the Subtype_Mark, so its -- semantic attributes must be established here. @@ -5500,14 +5388,6 @@ package body Sem_Ch3 is if Nkind (Subtype_Indication (N)) /= N_Subtype_Indication then Set_Etype (Id, Base_Type (T)); - -- Subtype of unconstrained array without constraint is not allowed - -- in SPARK. - - if Is_Array_Type (T) and then not Is_Constrained (T) then - Check_SPARK_05_Restriction - ("subtype of unconstrained array must have constraint", N); - end if; - case Ekind (T) is when Array_Kind => Set_Ekind (Id, E_Array_Subtype); @@ -5571,6 +5451,7 @@ package body Sem_Ch3 is Set_Class_Wide_Type (Id, Class_Wide_Type (T)); Set_Cloned_Subtype (Id, T); Set_Is_Tagged_Type (Id, True); + Set_Is_Limited_Record (Id, Is_Limited_Record (T)); Set_Has_Unknown_Discriminants (Id, True); Set_No_Tagged_Streams_Pragma @@ -5835,6 +5716,17 @@ package body Sem_Ch3 is end if; end if; + -- If the base type is a scalar type, or else if there is no + -- constraint, the atomic flag is inherited by the subtype. + -- Ditto for the Independent aspect. + + if Is_Scalar_Type (Id) + or else Is_Entity_Name (Subtype_Indication (N)) + then + Set_Is_Atomic (Id, Is_Atomic (T)); + Set_Is_Independent (Id, Is_Independent (T)); + end if; + -- Remaining processing depends on characteristics of base type T := Etype (Id); @@ -5845,6 +5737,7 @@ package body Sem_Ch3 is if Is_Interface (T) then Set_Is_Interface (Id); + Set_Is_Limited_Interface (Id, Is_Limited_Interface (T)); end if; if Present (Generic_Parent_Type (N)) @@ -5913,33 +5806,28 @@ package body Sem_Ch3 is -- Check that Constraint_Error is raised for a scalar subtype indication -- when the lower or upper bound of a non-null range lies outside the - -- range of the type mark. + -- range of the type mark. Likewise for an array subtype, but check the + -- compatibility for each index. if Nkind (Subtype_Indication (N)) = N_Subtype_Indication then - if Is_Scalar_Type (Etype (Id)) - and then Scalar_Range (Id) /= - Scalar_Range - (Etype (Subtype_Mark (Subtype_Indication (N)))) - then - Apply_Range_Check - (Scalar_Range (Id), - Etype (Subtype_Mark (Subtype_Indication (N)))); - - -- In the array case, check compatibility for each index + declare + Indic_Typ : constant Entity_Id := + Etype (Subtype_Mark (Subtype_Indication (N))); + Subt_Index : Node_Id; + Target_Index : Node_Id; - elsif Is_Array_Type (Etype (Id)) and then Present (First_Index (Id)) - then - -- This really should be a subprogram that finds the indications - -- to check??? + begin + if Is_Scalar_Type (Etype (Id)) + and then Scalar_Range (Id) /= Scalar_Range (Indic_Typ) + then + Apply_Range_Check (Scalar_Range (Id), Indic_Typ); - declare - Subt_Index : Node_Id := First_Index (Id); - Target_Index : Node_Id := - First_Index (Etype - (Subtype_Mark (Subtype_Indication (N)))); - Has_Dyn_Chk : Boolean := Has_Dynamic_Range_Check (N); + elsif Is_Array_Type (Etype (Id)) + and then Present (First_Index (Id)) + then + Subt_Index := First_Index (Id); + Target_Index := First_Index (Indic_Typ); - begin while Present (Subt_Index) loop if ((Nkind (Subt_Index) = N_Identifier and then Ekind (Entity (Subt_Index)) in Scalar_Kind) @@ -5947,47 +5835,17 @@ package body Sem_Ch3 is and then Nkind (Scalar_Range (Etype (Subt_Index))) = N_Range then - declare - Target_Typ : constant Entity_Id := - Etype (Target_Index); - begin - R_Checks := - Get_Range_Checks - (Scalar_Range (Etype (Subt_Index)), - Target_Typ, - Etype (Subt_Index), - Defining_Identifier (N)); - - -- Reset Has_Dynamic_Range_Check on the subtype to - -- prevent elision of the index check due to a dynamic - -- check generated for a preceding index (needed since - -- Insert_Range_Checks tries to avoid generating - -- redundant checks on a given declaration). - - Set_Has_Dynamic_Range_Check (N, False); - - Insert_Range_Checks - (R_Checks, - N, - Target_Typ, - Sloc (Defining_Identifier (N))); - - -- Record whether this index involved a dynamic check - - Has_Dyn_Chk := - Has_Dyn_Chk or else Has_Dynamic_Range_Check (N); - end; + Apply_Range_Check + (Scalar_Range (Etype (Subt_Index)), + Etype (Target_Index), + Insert_Node => N); end if; Next_Index (Subt_Index); Next_Index (Target_Index); end loop; - - -- Finally, mark whether the subtype involves dynamic checks - - Set_Has_Dynamic_Range_Check (N, Has_Dyn_Chk); - end; - end if; + end if; + end; end if; Set_Optimize_Alignment_Flags (Id); @@ -6162,14 +6020,8 @@ package body Sem_Ch3 is Set_Etype (Index, Standard_Boolean); end if; - -- Check SPARK restriction requiring a subtype mark - - if not Nkind_In (Index, N_Identifier, N_Expanded_Name) then - Check_SPARK_05_Restriction ("subtype mark required", Index); - end if; - -- Add a subtype declaration for each index of private array type - -- declaration whose etype is also private. For example: + -- declaration whose type is also private. For example: -- package Pkg is -- type Index is private; @@ -6179,11 +6031,14 @@ package body Sem_Ch3 is -- This is currently required by the expander for the internally -- generated equality subprogram of records with variant parts in - -- which the etype of some component is such private type. + -- which the type of some component is such a private type. And it + -- also helps semantic analysis in peculiar cases where the array + -- type is referenced from an instance but not the index directly. - if Ekind (Current_Scope) = E_Package + if Is_Package_Or_Generic_Package (Current_Scope) and then In_Private_Part (Current_Scope) and then Has_Private_Declaration (Etype (Index)) + and then Scope (Etype (Index)) = Current_Scope then declare Loc : constant Source_Ptr := Sloc (Def); @@ -6240,14 +6095,8 @@ package body Sem_Ch3 is if Present (Component_Typ) then Element_Type := Process_Subtype (Component_Typ, P, Related_Id, 'C'); - Set_Etype (Component_Typ, Element_Type); - if not Nkind_In (Component_Typ, N_Identifier, N_Expanded_Name) then - Check_SPARK_05_Restriction - ("subtype mark required", Component_Typ); - end if; - -- Ada 2005 (AI-230): Access Definition case else pragma Assert (Present (Access_Definition (Component_Def))); @@ -6358,8 +6207,6 @@ package body Sem_Ch3 is Set_Packed_Array_Impl_Type (T, Empty); if Aliased_Present (Component_Definition (Def)) then - Check_SPARK_05_Restriction - ("aliased is not allowed", Component_Definition (Def)); Set_Has_Aliased_Components (Etype (T)); -- AI12-001: All aliased objects are considered to be specified as @@ -6529,61 +6376,6 @@ package body Sem_Ch3 is Mark_Rewrite_Insertion (Decl); - -- In ASIS mode, analyze the profile on the original node, because - -- the separate copy does not provide enough links to recover the - -- original tree. Analysis is limited to type annotations, within - -- a temporary scope that serves as an anonymous subprogram to collect - -- otherwise useless temporaries and itypes. - - if ASIS_Mode then - declare - Typ : constant Entity_Id := Make_Temporary (Loc, 'S'); - - begin - if Nkind (Spec) = N_Access_Function_Definition then - Set_Ekind (Typ, E_Function); - else - Set_Ekind (Typ, E_Procedure); - end if; - - Set_Parent (Typ, N); - Set_Scope (Typ, Current_Scope); - Push_Scope (Typ); - - -- Nothing to do if procedure is parameterless - - if Present (Parameter_Specifications (Spec)) then - Process_Formals (Parameter_Specifications (Spec), Spec); - end if; - - if Nkind (Spec) = N_Access_Function_Definition then - declare - Def : constant Node_Id := Result_Definition (Spec); - - begin - -- The result might itself be an anonymous access type, so - -- have to recurse. - - if Nkind (Def) = N_Access_Definition then - if Present (Access_To_Subprogram_Definition (Def)) then - Set_Etype - (Def, - Replace_Anonymous_Access_To_Protected_Subprogram - (Spec)); - else - Find_Type (Subtype_Mark (Def)); - end if; - - else - Find_Type (Def); - end if; - end; - end if; - - End_Scope; - end; - end if; - -- Insert the new declaration in the nearest enclosing scope. If the -- parent is a body and N is its return type, the declaration belongs -- in the enclosing scope. Likewise if N is the type of a parameter. @@ -6643,7 +6435,7 @@ package body Sem_Ch3 is Mark_Rewrite_Insertion (Comp); - if Nkind_In (N, N_Object_Declaration, N_Access_Function_Definition) + if Nkind (N) in N_Object_Declaration | N_Access_Function_Definition or else (Nkind (Parent (N)) = N_Full_Type_Declaration and then not Is_Type (Current_Scope)) then @@ -6669,6 +6461,144 @@ package body Sem_Ch3 is return Anon; end Replace_Anonymous_Access_To_Protected_Subprogram; + ------------------------------------- + -- Build_Access_Subprogram_Wrapper -- + ------------------------------------- + + procedure Build_Access_Subprogram_Wrapper (Decl : Node_Id) is + Loc : constant Source_Ptr := Sloc (Decl); + Id : constant Entity_Id := Defining_Identifier (Decl); + Type_Def : constant Node_Id := Type_Definition (Decl); + Specs : constant List_Id := + Parameter_Specifications (Type_Def); + Profile : constant List_Id := New_List; + Subp : constant Entity_Id := Make_Temporary (Loc, 'A'); + + Contracts : constant List_Id := New_List; + Form_P : Node_Id; + New_P : Node_Id; + New_Decl : Node_Id; + Spec : Node_Id; + + procedure Replace_Type_Name (Expr : Node_Id); + -- In the expressions for contract aspects, replace occurrences of the + -- access type with the name of the subprogram entity, as needed, e.g. + -- for 'Result. Aspects that are not contracts, e.g. Size or Alignment) + -- remain on the original access type declaration. What about expanded + -- names denoting formals, whose prefix in source is the type name ??? + + ----------------------- + -- Replace_Type_Name -- + ----------------------- + + procedure Replace_Type_Name (Expr : Node_Id) is + function Process (N : Node_Id) return Traverse_Result; + function Process (N : Node_Id) return Traverse_Result is + begin + if Nkind (N) = N_Attribute_Reference + and then Is_Entity_Name (Prefix (N)) + and then Chars (Prefix (N)) = Chars (Id) + then + Set_Prefix (N, Make_Identifier (Sloc (N), Chars (Subp))); + end if; + + return OK; + end Process; + + procedure Traverse is new Traverse_Proc (Process); + begin + Traverse (Expr); + end Replace_Type_Name; + + begin + if Ekind (Id) in E_Access_Subprogram_Type + | E_Access_Protected_Subprogram_Type + | E_Anonymous_Access_Protected_Subprogram_Type + | E_Anonymous_Access_Subprogram_Type + then + null; + + else + Error_Msg_N + ("illegal pre/postcondition on access type", Decl); + return; + end if; + + declare + Asp : Node_Id; + A_Id : Aspect_Id; + Cond : Node_Id; + Expr : Node_Id; + + begin + Asp := First (Aspect_Specifications (Decl)); + while Present (Asp) loop + A_Id := Get_Aspect_Id (Chars (Identifier (Asp))); + if A_Id = Aspect_Pre or else A_Id = Aspect_Post then + Cond := Asp; + Expr := Expression (Cond); + Replace_Type_Name (Expr); + Next (Asp); + + Remove (Cond); + Append (Cond, Contracts); + + else + Next (Asp); + end if; + end loop; + end; + + -- If there are no contract aspects, no need for a wrapper. + + if Is_Empty_List (Contracts) then + return; + end if; + + Form_P := First (Specs); + + while Present (Form_P) loop + New_P := New_Copy_Tree (Form_P); + Set_Defining_Identifier (New_P, + Make_Defining_Identifier + (Loc, Chars (Defining_Identifier (Form_P)))); + Append (New_P, Profile); + Next (Form_P); + end loop; + + -- Add to parameter specifications the access parameter that is passed + -- in from an indirect call. + + Append ( + Make_Parameter_Specification (Loc, + Defining_Identifier => Make_Temporary (Loc, 'P'), + Parameter_Type => New_Occurrence_Of (Id, Loc)), + Profile); + + if Nkind (Type_Def) = N_Access_Procedure_Definition then + Spec := + Make_Procedure_Specification (Loc, + Defining_Unit_Name => Subp, + Parameter_Specifications => Profile); + else + Spec := + Make_Function_Specification (Loc, + Defining_Unit_Name => Subp, + Parameter_Specifications => Profile, + Result_Definition => + New_Copy_Tree + (Result_Definition (Type_Definition (Decl)))); + end if; + + New_Decl := + Make_Subprogram_Declaration (Loc, Specification => Spec); + Set_Aspect_Specifications (New_Decl, Contracts); + + Insert_After (Decl, New_Decl); + Set_Access_Subprogram_Wrapper (Designated_Type (Id), Subp); + Build_Access_Subprogram_Wrapper_Body (Decl, New_Decl); + end Build_Access_Subprogram_Wrapper; + ------------------------------- -- Build_Derived_Access_Type -- ------------------------------- @@ -7133,14 +7063,13 @@ package body Sem_Ch3 is Error_Msg_NE ("new discriminant& must constrain old one", N, New_Disc); - elsif not - Subtypes_Statically_Compatible - (Etype (New_Disc), - Etype (Corresponding_Discriminant (New_Disc))) - then - Error_Msg_NE - ("& not statically compatible with parent discriminant", - N, New_Disc); + -- If a new discriminant is used in the constraint, then its + -- subtype must be statically compatible with the subtype of + -- the parent discriminant (RM 3.7(15)). + + else + Check_Constraining_Discriminant + (New_Disc, Corresponding_Discriminant (New_Disc)); end if; Next_Discriminant (New_Disc); @@ -7513,6 +7442,7 @@ package body Sem_Ch3 is Set_First_Rep_Item (Implicit_Base, First_Rep_Item (Parent_Base)); Set_Parent (Implicit_Base, Parent (Derived_Type)); Set_Is_Known_Valid (Implicit_Base, Is_Known_Valid (Parent_Base)); + Set_Is_Volatile (Implicit_Base, Is_Volatile (Parent_Base)); -- Set RM Size for discrete type or decimal fixed-point type -- Ordinary fixed-point is excluded, why??? @@ -7696,6 +7626,10 @@ package body Sem_Ch3 is Full_Der : Entity_Id := New_Copy (Derived_Type); Full_P : Entity_Id; + function Available_Full_View (Typ : Entity_Id) return Entity_Id; + -- Return the Full_View or Underlying_Full_View of Typ, whichever is + -- present (they cannot be both present for the same type), or Empty. + procedure Build_Full_Derivation; -- Build full derivation, i.e. derive from the full view @@ -7703,6 +7637,32 @@ package body Sem_Ch3 is -- Copy derived type declaration, replace parent with its full view, -- and build derivation + ------------------------- + -- Available_Full_View -- + ------------------------- + + function Available_Full_View (Typ : Entity_Id) return Entity_Id is + begin + if Present (Full_View (Typ)) then + return Full_View (Typ); + + elsif Present (Underlying_Full_View (Typ)) then + + -- We should be called on a type with an underlying full view + -- only by means of the recursive call made in Copy_And_Build + -- through the first call to Build_Derived_Type, or else if + -- the parent scope is being analyzed because we are deriving + -- a completion. + + pragma Assert (Is_Completion or else In_Private_Part (Par_Scope)); + + return Underlying_Full_View (Typ); + + else + return Empty; + end if; + end Available_Full_View; + --------------------------- -- Build_Full_Derivation -- --------------------------- @@ -7722,7 +7682,9 @@ package body Sem_Ch3 is -- part of a child unit. In that case retrieve the full view of -- the parent momentarily. - elsif not In_Same_Source_Unit (N, Parent_Type) then + elsif not In_Same_Source_Unit (N, Parent_Type) + and then Present (Full_View (Parent_Type)) + then Full_P := Full_View (Parent_Type); Exchange_Declarations (Parent_Type); Copy_And_Build; @@ -7753,19 +7715,28 @@ package body Sem_Ch3 is Full_Parent := Full_View (Full_Parent); end if; - -- And its underlying full view if necessary + -- If the full view is itself derived from another private type + -- and has got an underlying full view, and this is done for a + -- completion, i.e. to build the underlying full view of the type, + -- then use this underlying full view. We cannot do that if this + -- is not a completion, i.e. to build the full view of the type, + -- because this would break the privacy of the parent type, except + -- if the parent scope is being analyzed because we are deriving a + -- completion. if Is_Private_Type (Full_Parent) and then Present (Underlying_Full_View (Full_Parent)) + and then (Is_Completion or else In_Private_Part (Par_Scope)) then Full_Parent := Underlying_Full_View (Full_Parent); end if; - -- For record, concurrent, access and most enumeration types, the - -- derivation from full view requires a fully-fledged declaration. - -- In the other cases, just use an itype. + -- For private, record, concurrent, access and almost all enumeration + -- types, the derivation from the full view requires a fully-fledged + -- declaration. In the other cases, just use an itype. - if Is_Record_Type (Full_Parent) + if Is_Private_Type (Full_Parent) + or else Is_Record_Type (Full_Parent) or else Is_Concurrent_Type (Full_Parent) or else Is_Access_Type (Full_Parent) or else @@ -7812,9 +7783,13 @@ package body Sem_Ch3 is end if; else + -- If the parent type is private, this is not a completion and + -- we build the full derivation recursively as a completion. + Build_Derived_Type (Full_N, Full_Parent, Full_Der, - Is_Completion => False, Derive_Subps => False); + Is_Completion => Is_Private_Type (Full_Parent), + Derive_Subps => False); end if; -- The full declaration has been introduced into the tree and @@ -8002,7 +7977,7 @@ package body Sem_Ch3 is -- case (see point 5. of its head comment) since we build it for the -- derived subtype. - if Present (Full_View (Parent_Type)) + if Present (Available_Full_View (Parent_Type)) and then not Is_Itype (Derived_Type) then declare @@ -8054,8 +8029,8 @@ package body Sem_Ch3 is end; end if; - elsif Present (Full_View (Parent_Type)) - and then Has_Discriminants (Full_View (Parent_Type)) + elsif Present (Available_Full_View (Parent_Type)) + and then Has_Discriminants (Available_Full_View (Parent_Type)) then if Has_Unknown_Discriminants (Parent_Type) and then Nkind (Subtype_Indication (Type_Definition (N))) = @@ -8092,7 +8067,7 @@ package body Sem_Ch3 is Set_Stored_Constraint (Derived_Type, No_Elist); Set_Is_Constrained - (Derived_Type, Is_Constrained (Full_View (Parent_Type))); + (Derived_Type, Is_Constrained (Available_Full_View (Parent_Type))); else -- Untagged type, No discriminants on either view @@ -8105,8 +8080,8 @@ package body Sem_Ch3 is end if; if Present (Discriminant_Specifications (N)) - and then Present (Full_View (Parent_Type)) - and then not Is_Tagged_Type (Full_View (Parent_Type)) + and then Present (Available_Full_View (Parent_Type)) + and then not Is_Tagged_Type (Available_Full_View (Parent_Type)) then Error_Msg_N ("cannot add discriminants to untagged type", N); end if; @@ -8131,18 +8106,26 @@ package body Sem_Ch3 is end if; -- If this is not a completion, construct the implicit full view by - -- deriving from the full view of the parent type. + -- deriving from the full view of the parent type. But if this is a + -- completion, the derived private type being built is a full view + -- and the full derivation can only be its underlying full view. - -- ??? If the parent is untagged private and its completion is + -- ??? If the parent type is untagged private and its completion is -- tagged, this mechanism will not work because we cannot derive from -- the tagged full view unless we have an extension. - if Present (Full_View (Parent_Type)) - and then not Is_Tagged_Type (Full_View (Parent_Type)) - and then not Is_Completion + if Present (Available_Full_View (Parent_Type)) + and then not Is_Tagged_Type (Available_Full_View (Parent_Type)) + and then not Error_Posted (N) then Build_Full_Derivation; - Set_Full_View (Derived_Type, Full_Der); + + if not Is_Completion then + Set_Full_View (Derived_Type, Full_Der); + else + Set_Underlying_Full_View (Derived_Type, Full_Der); + Set_Is_Underlying_Full_View (Full_Der); + end if; end if; end if; @@ -9260,41 +9243,13 @@ package body Sem_Ch3 is end if; -- If a new discriminant is used in the constraint, then its - -- subtype must be statically compatible with the parent - -- discriminant's subtype (3.7(15)). - - -- However, if the record contains an array constrained by - -- the discriminant but with some different bound, the compiler - -- tries to create a smaller range for the discriminant type. - -- (See exp_ch3.Adjust_Discriminants). In this case, where - -- the discriminant type is a scalar type, the check must use - -- the original discriminant type in the parent declaration. - - declare - Corr_Disc : constant Entity_Id := - Corresponding_Discriminant (Discrim); - Disc_Type : constant Entity_Id := Etype (Discrim); - Corr_Type : Entity_Id; - - begin - if Present (Corr_Disc) then - if Is_Scalar_Type (Disc_Type) then - Corr_Type := - Entity (Discriminant_Type (Parent (Corr_Disc))); - else - Corr_Type := Etype (Corr_Disc); - end if; + -- subtype must be statically compatible with the subtype of + -- the parent discriminant (RM 3.7(15)). - if not - Subtypes_Statically_Compatible (Disc_Type, Corr_Type) - then - Error_Msg_N - ("subtype must be compatible " - & "with parent discriminant", - Discrim); - end if; - end if; - end; + if Present (Corresponding_Discriminant (Discrim)) then + Check_Constraining_Discriminant + (Discrim, Corresponding_Discriminant (Discrim)); + end if; Next_Discriminant (Discrim); end loop; @@ -9628,7 +9583,7 @@ package body Sem_Ch3 is Set_Stored_Constraint (Derived_Type, Expand_To_Stored_Constraint (Parent_Type, Discs)); - Replace_Components (Derived_Type, New_Decl); + Replace_Discriminants (Derived_Type, New_Decl); end if; -- Insert the new derived type declaration @@ -9650,10 +9605,6 @@ package body Sem_Ch3 is elsif not Private_Extension then Expand_Record_Extension (Derived_Type, Type_Def); - -- Note : previously in ASIS mode we set the Parent_Subtype of the - -- derived type to propagate some semantic information. This led - -- to other ASIS failures and has been removed. - -- Ada 2005 (AI-251): Addition of the Tag corresponding to all the -- implemented interfaces if we are in expansion mode @@ -10526,9 +10477,9 @@ package body Sem_Ch3 is -- build-in-place library function, child unit or not. if (Nkind (Nod) in N_Entity and then Is_Compilation_Unit (Nod)) - or else (Nkind_In (Nod, N_Defining_Program_Unit_Name, - N_Subprogram_Declaration) - and then Is_Compilation_Unit (Defining_Entity (Nod))) + or else (Nkind (Nod) in + N_Defining_Program_Unit_Name | N_Subprogram_Declaration + and then Is_Compilation_Unit (Defining_Entity (Nod))) then Add_Global_Declaration (IR); else @@ -10558,7 +10509,7 @@ package body Sem_Ch3 is Analyze_And_Resolve (Bound, Base_Type (Par_T)); - if Nkind_In (Bound, N_Integer_Literal, N_Real_Literal) then + if Nkind (Bound) in N_Integer_Literal | N_Real_Literal then New_Bound := New_Copy (Bound); Set_Etype (New_Bound, Der_T); Set_Analyzed (New_Bound); @@ -10808,6 +10759,26 @@ package body Sem_Ch3 is elsif Present (Interface_Alias (Subp)) then null; + -- AI12-0042: Test for rule in 7.3.2(6.1/4), that requires overriding + -- of a visible private primitive inherited from an ancestor with + -- the aspect Type_Invariant'Class, unless the inherited primitive + -- is abstract. + + elsif not Is_Abstract_Subprogram (Subp) + and then not Comes_From_Source (Subp) -- An inherited subprogram + and then Requires_Overriding (Subp) + and then Present (Alias_Subp) + and then Has_Invariants (Etype (T)) + and then Present (Get_Pragma (Etype (T), Pragma_Invariant)) + and then Class_Present (Get_Pragma (Etype (T), Pragma_Invariant)) + and then Is_Private_Primitive (Alias_Subp) + then + Error_Msg_NE + ("inherited private primitive & must be overridden", T, Subp); + Error_Msg_N + ("\because ancestor type has 'Type_'Invariant''Class " & + "(RM 7.3.2(6.1))", T); + elsif (Is_Abstract_Subprogram (Subp) or else Requires_Overriding (Subp) or else @@ -11046,6 +11017,20 @@ package body Sem_Ch3 is end if; end if; + -- Ada 2005 (AI95-0414) and Ada 2020 (AI12-0269): Diagnose failure to + -- match No_Return in parent, but do it unconditionally in Ada 95 too + -- for procedures, since this is our pragma. + + if Present (Overridden_Operation (Subp)) + and then No_Return (Overridden_Operation (Subp)) + and then not No_Return (Subp) + then + Error_Msg_N ("overriding subprogram & must be No_Return", Subp); + Error_Msg_N + ("\since overridden subprogram is No_Return (RM 6.5.1(6/2))", + Subp); + end if; + -- If the operation is a wrapper for a synchronized primitive, it -- may be called indirectly through a dispatching select. We assume -- that it will be referenced elsewhere indirectly, and suppress @@ -11482,28 +11467,6 @@ package body Sem_Ch3 is if Present (Acc_Def) then Create_Extra_Formals (Designated_Type (Anon_Access)); - - -- If an access to object, preserve entity of designated type, - -- for ASIS use, before rewriting the component definition. - - else - declare - Desig : Entity_Id; - - begin - Desig := Entity (Subtype_Indication (Type_Def)); - - -- If the access definition is to the current record, - -- the visible entity at this point is an incomplete - -- type. Retrieve the full view to simplify ASIS queries - - if Ekind (Desig) = E_Incomplete_Type then - Desig := Full_View (Desig); - end if; - - Set_Entity - (Subtype_Mark (Access_Definition (Comp_Def)), Desig); - end; end if; Rewrite (Comp_Def, @@ -11577,7 +11540,7 @@ package body Sem_Ch3 is begin if not Comes_From_Source (E) then - if Ekind_In (E, E_Task_Type, E_Protected_Type) then + if Ekind (E) in E_Task_Type | E_Protected_Type then -- It may be an anonymous protected type created for a -- single variable. Post error on variable, if present. @@ -11707,10 +11670,10 @@ package body Sem_Ch3 is -- this kind is reserved for predefined operators, that are -- intrinsic and do not need completion. - elsif Ekind_In (E, E_Function, - E_Procedure, - E_Generic_Function, - E_Generic_Procedure) + elsif Ekind (E) in E_Function + | E_Procedure + | E_Generic_Function + | E_Generic_Procedure then if Has_Completion (E) then null; @@ -11740,9 +11703,8 @@ package body Sem_Ch3 is end if; elsif Is_Entry (E) then - if not Has_Completion (E) and then - (Ekind (Scope (E)) = E_Protected_Object - or else Ekind (Scope (E)) = E_Protected_Type) + if not Has_Completion (E) + and then Ekind (Scope (E)) = E_Protected_Type then Post_Error; end if; @@ -11763,33 +11725,30 @@ package body Sem_Ch3 is -- A formal incomplete type (Ada 2012) does not require a completion; -- other incomplete type declarations do. - elsif Ekind (E) = E_Incomplete_Type - and then No (Underlying_Type (E)) - and then not Is_Generic_Type (E) - then - Post_Error; + elsif Ekind (E) = E_Incomplete_Type then + if No (Underlying_Type (E)) + and then not Is_Generic_Type (E) + then + Post_Error; + end if; - elsif Ekind_In (E, E_Task_Type, E_Protected_Type) - and then not Has_Completion (E) - then - Post_Error; + elsif Ekind (E) in E_Task_Type | E_Protected_Type then + if not Has_Completion (E) then + Post_Error; + end if; -- A single task declared in the current scope is a constant, verify -- that the body of its anonymous type is in the same scope. If the -- task is defined elsewhere, this may be a renaming declaration for -- which no completion is needed. - elsif Ekind (E) = E_Constant - and then Ekind (Etype (E)) = E_Task_Type - and then not Has_Completion (Etype (E)) - and then Scope (Etype (E)) = Current_Scope - then - Post_Error; - - elsif Ekind (E) = E_Protected_Object - and then not Has_Completion (Etype (E)) - then - Post_Error; + elsif Ekind (E) = E_Constant then + if Ekind (Etype (E)) = E_Task_Type + and then not Has_Completion (Etype (E)) + and then Scope (Etype (E)) = Current_Scope + then + Post_Error; + end if; elsif Ekind (E) = E_Record_Type then if Is_Tagged_Type (E) then @@ -11808,6 +11767,41 @@ package body Sem_Ch3 is end loop; end Check_Completion; + ------------------------------------- + -- Check_Constraining_Discriminant -- + ------------------------------------- + + procedure Check_Constraining_Discriminant (New_Disc, Old_Disc : Entity_Id) + is + New_Type : constant Entity_Id := Etype (New_Disc); + Old_Type : Entity_Id; + + begin + -- If the record type contains an array constrained by the discriminant + -- but with some different bound, the compiler tries to create a smaller + -- range for the discriminant type (see exp_ch3.Adjust_Discriminants). + -- In this case, where the discriminant type is a scalar type, the check + -- must use the original discriminant type in the parent declaration. + + if Is_Scalar_Type (New_Type) then + Old_Type := Entity (Discriminant_Type (Parent (Old_Disc))); + else + Old_Type := Etype (Old_Disc); + end if; + + if not Subtypes_Statically_Compatible (New_Type, Old_Type) then + Error_Msg_N + ("subtype must be statically compatible with parent discriminant", + New_Disc); + + if not Predicates_Compatible (New_Type, Old_Type) then + Error_Msg_N + ("\subtype predicate is not compatible with parent discriminant", + New_Disc); + end if; + end if; + end Check_Constraining_Discriminant; + ------------------------------------ -- Check_CPP_Type_Has_No_Defaults -- ------------------------------------ @@ -11978,7 +11972,7 @@ package body Sem_Ch3 is -- In gnatc or gnatprove mode, make sure set Do_Range_Check flag gets -- set unless we can be sure that no range check is required. - if (GNATprove_Mode or not Expander_Active) + if not Expander_Active and then Is_Scalar_Type (T) and then not Is_In_Range (Exp, T, Assume_Valid => True) then @@ -12544,18 +12538,11 @@ package body Sem_Ch3 is -- Show Full is simply a renaming of Full_Base Set_Cloned_Subtype (Full, Full_Base); + Set_Is_Limited_Record (Full, Is_Limited_Record (Full_Base)); -- Propagate predicates - if Has_Predicates (Full_Base) then - Set_Has_Predicates (Full); - - if Present (Predicate_Function (Full_Base)) - and then No (Predicate_Function (Full)) - then - Set_Predicate_Function (Full, Predicate_Function (Full_Base)); - end if; - end if; + Propagate_Predicate_Attributes (Full, Full_Base); end if; -- It is unsafe to share the bounds of a scalar type, because the Itype @@ -12587,11 +12574,18 @@ package body Sem_Ch3 is if Is_Tagged_Type (Full_Base) then Set_Is_Tagged_Type (Full); + Set_Is_Limited_Record (Full, Is_Limited_Record (Full_Base)); + Set_Direct_Primitive_Operations (Full, Direct_Primitive_Operations (Full_Base)); Set_No_Tagged_Streams_Pragma (Full, No_Tagged_Streams_Pragma (Full_Base)); + if Is_Interface (Full_Base) then + Set_Is_Interface (Full); + Set_Is_Limited_Interface (Full, Is_Limited_Interface (Full_Base)); + end if; + -- Inherit class_wide type of full_base in case the partial view was -- not tagged. Otherwise it has already been created when the private -- subtype was analyzed. @@ -12700,15 +12694,7 @@ package body Sem_Ch3 is -- of the type or at the end of the visible part, and we must avoid -- generating them twice. - if Has_Predicates (Priv) then - Set_Has_Predicates (Full); - - if Present (Predicate_Function (Priv)) - and then No (Predicate_Function (Full)) - then - Set_Predicate_Function (Full, Predicate_Function (Priv)); - end if; - end if; + Propagate_Predicate_Attributes (Full, Priv); if Has_Delayed_Aspects (Priv) then Set_Has_Delayed_Aspects (Full); @@ -13311,15 +13297,11 @@ package body Sem_Ch3 is -- Ditto for access types. Makes use of previous two functions, to -- constrain designated type. - function Build_Subtype (T : Entity_Id; C : List_Id) return Entity_Id; - -- T is an array or discriminated type, C is a list of constraints - -- that apply to T. This routine builds the constrained subtype. - function Is_Discriminant (Expr : Node_Id) return Boolean; -- Returns True if Expr is a discriminant - function Get_Discr_Value (Discrim : Entity_Id) return Node_Id; - -- Find the value of discriminant Discrim in Constraint + function Get_Discr_Value (Discr_Expr : Node_Id) return Node_Id; + -- Find the value of a discriminant named by Discr_Expr in Constraints ----------------------------------- -- Build_Constrained_Access_Type -- @@ -13334,7 +13316,7 @@ package body Sem_Ch3 is Scop : Entity_Id; begin - -- if the original access type was not embedded in the enclosing + -- If the original access type was not embedded in the enclosing -- type definition, there is no need to produce a new access -- subtype. In fact every access type with an explicit constraint -- generates an itype whose scope is the enclosing record. @@ -13433,6 +13415,7 @@ package body Sem_Ch3 is Is_Discriminant (Hi_Expr) then Need_To_Create_Itype := True; + exit; end if; Next_Index (Old_Index); @@ -13462,7 +13445,7 @@ package body Sem_Ch3 is Next_Index (Old_Index); end loop; - return Build_Subtype (Old_Type, Constr_List); + return Build_Subtype (Related_Node, Loc, Old_Type, Constr_List); else return Old_Type; @@ -13489,6 +13472,7 @@ package body Sem_Ch3 is if Is_Discriminant (Expr) then Need_To_Create_Itype := True; + exit; -- After expansion of discriminated task types, the value -- of the discriminant may be converted to a run-time type @@ -13500,6 +13484,7 @@ package body Sem_Ch3 is and then Is_Discriminant (Expression (Expr)) then Need_To_Create_Itype := True; + exit; end if; Next_Elmt (Old_Constraint); @@ -13527,86 +13512,22 @@ package body Sem_Ch3 is Next_Elmt (Old_Constraint); end loop; - return Build_Subtype (Old_Type, Constr_List); + return Build_Subtype (Related_Node, Loc, Old_Type, Constr_List); else return Old_Type; end if; end Build_Constrained_Discriminated_Type; - ------------------- - -- Build_Subtype -- - ------------------- - - function Build_Subtype (T : Entity_Id; C : List_Id) return Entity_Id is - Indic : Node_Id; - Subtyp_Decl : Node_Id; - Def_Id : Entity_Id; - Btyp : Entity_Id := Base_Type (T); - - begin - -- The Related_Node better be here or else we won't be able to - -- attach new itypes to a node in the tree. - - pragma Assert (Present (Related_Node)); - - -- If the view of the component's type is incomplete or private - -- with unknown discriminants, then the constraint must be applied - -- to the full type. - - if Has_Unknown_Discriminants (Btyp) - and then Present (Underlying_Type (Btyp)) - then - Btyp := Underlying_Type (Btyp); - end if; - - Indic := - Make_Subtype_Indication (Loc, - Subtype_Mark => New_Occurrence_Of (Btyp, Loc), - Constraint => Make_Index_Or_Discriminant_Constraint (Loc, C)); - - Def_Id := Create_Itype (Ekind (T), Related_Node); - - Subtyp_Decl := - Make_Subtype_Declaration (Loc, - Defining_Identifier => Def_Id, - Subtype_Indication => Indic); - - Set_Parent (Subtyp_Decl, Parent (Related_Node)); - - -- Itypes must be analyzed with checks off (see package Itypes) - - Analyze (Subtyp_Decl, Suppress => All_Checks); - - if Is_Itype (Def_Id) and then Has_Predicates (T) then - Inherit_Predicate_Flags (Def_Id, T); - - -- Indicate where the predicate function may be found - - if Is_Itype (T) then - if Present (Predicate_Function (Def_Id)) then - null; - - elsif Present (Predicate_Function (T)) then - Set_Predicate_Function (Def_Id, Predicate_Function (T)); - - else - Set_Predicated_Parent (Def_Id, Predicated_Parent (T)); - end if; - - elsif No (Predicate_Function (Def_Id)) then - Set_Predicated_Parent (Def_Id, T); - end if; - end if; - - return Def_Id; - end Build_Subtype; - --------------------- -- Get_Discr_Value -- --------------------- - function Get_Discr_Value (Discrim : Entity_Id) return Node_Id is + function Get_Discr_Value (Discr_Expr : Node_Id) return Node_Id is + Discr_Id : constant Entity_Id := Entity (Discr_Expr); + -- Entity of a discriminant that appear as a standalone expression in + -- the constraint of a component. + D : Entity_Id; E : Elmt_Id; @@ -13622,9 +13543,9 @@ package body Sem_Ch3 is E := First_Elmt (Constraints); while Present (D) loop - if D = Entity (Discrim) - or else D = CR_Discriminant (Entity (Discrim)) - or else Corresponding_Discriminant (D) = Entity (Discrim) + if D = Discr_Id + or else D = CR_Discriminant (Discr_Id) + or else Corresponding_Discriminant (D) = Discr_Id then return Node (E); end if; @@ -13644,12 +13565,12 @@ package body Sem_Ch3 is -- be present when the component is a discriminated task type? if Is_Derived_Type (Typ) - and then Scope (Entity (Discrim)) = Etype (Typ) + and then Scope (Discr_Id) = Etype (Typ) then D := First_Discriminant (Etype (Typ)); E := First_Elmt (Constraints); while Present (D) loop - if D = Entity (Discrim) then + if D = Discr_Id then return Node (E); end if; @@ -13879,8 +13800,6 @@ package body Sem_Ch3 is else pragma Assert (Nkind (C) = N_Digits_Constraint); - Check_SPARK_05_Restriction ("digits constraint is not allowed", S); - Digits_Expr := Digits_Expression (C); Analyze_And_Resolve (Digits_Expr, Any_Integer); @@ -14122,8 +14041,6 @@ package body Sem_Ch3 is -- Digits constraint present if Nkind (C) = N_Digits_Constraint then - - Check_SPARK_05_Restriction ("digits constraint is not allowed", S); Check_Restriction (No_Obsolescent_Features, C); if Warn_On_Obsolescent_Feature then @@ -14356,8 +14273,6 @@ package body Sem_Ch3 is -- Delta constraint present if Nkind (C) = N_Delta_Constraint then - - Check_SPARK_05_Restriction ("delta constraint is not allowed", S); Check_Restriction (No_Obsolescent_Features, C); if Warn_On_Obsolescent_Feature then @@ -14699,7 +14614,7 @@ package body Sem_Ch3 is if Is_Tagged_Type (Typ) or else Has_Controlled_Component (Typ) then Old_C := First_Component (Typ); while Present (Old_C) loop - if Nam_In (Chars (Old_C), Name_uTag, Name_uParent) then + if Chars (Old_C) in Name_uTag | Name_uParent then Append_Elmt (Old_C, Comp_List); end if; @@ -15003,8 +14918,6 @@ package body Sem_Ch3 is Bound_Val : Ureal; begin - Check_SPARK_05_Restriction - ("decimal fixed point type is not allowed", Def); Check_Restriction (No_Fixed_Point, Def); -- Create implicit base type @@ -15546,9 +15459,9 @@ package body Sem_Ch3 is or else Is_Private_Overriding or else Is_Internal_Name (Chars (Parent_Subp)) or else (Is_Controlled (Parent_Type) - and then Nam_In (Chars (Parent_Subp), Name_Adjust, - Name_Finalize, - Name_Initialize)) + and then Chars (Parent_Subp) in Name_Adjust + | Name_Finalize + | Name_Initialize) then Set_Derived_Name; @@ -15640,6 +15553,15 @@ package body Sem_Ch3 is while Present (Formal) loop New_Formal := New_Copy (Formal); + -- Extra formals are not inherited from a limited interface parent + -- since limitedness is not inherited in such case (AI-419) and this + -- affects the extra formals. + + if Is_Limited_Interface (Parent_Type) then + Set_Extra_Formal (New_Formal, Empty); + Set_Extra_Accessibility (New_Formal, Empty); + end if; + -- Normally we do not go copying parents, but in the case of -- formals, we need to link up to the declaration (which is the -- parameter specification), and it is fine to link up to the @@ -15658,6 +15580,22 @@ package body Sem_Ch3 is Next_Formal (Formal); end loop; + -- Extra formals are shared between the parent subprogram and the + -- derived subprogram (implicit in the above copy of formals), unless + -- the parent type is a limited interface type; hence we must inherit + -- also the reference to the first extra formal. When the parent type is + -- an interface the extra formals will be added when the subprogram is + -- frozen (see Freeze.Freeze_Subprogram). + + if not Is_Limited_Interface (Parent_Type) then + Set_Extra_Formals (New_Subp, Extra_Formals (Parent_Subp)); + + if Ekind (New_Subp) = E_Function then + Set_Extra_Accessibility_Of_Result (New_Subp, + Extra_Accessibility_Of_Result (Parent_Subp)); + end if; + end if; + -- If this derivation corresponds to a tagged generic actual, then -- primitive operations rename those of the actual. Otherwise the -- primitive operations rename those of the parent type, If the parent @@ -15722,9 +15660,9 @@ package body Sem_Ch3 is -- set on both views of the type. if Is_Controlled (Parent_Type) - and then Nam_In (Chars (Parent_Subp), Name_Initialize, - Name_Adjust, - Name_Finalize) + and then Chars (Parent_Subp) in Name_Initialize + | Name_Adjust + | Name_Finalize and then Is_Hidden (Parent_Subp) and then not Is_Visibly_Controlled (Parent_Type) then @@ -15743,9 +15681,9 @@ package body Sem_Ch3 is end if; -- No_Return must be inherited properly. If this is overridden in the - -- case of a dispatching operation, then a check is made in Sem_Disp - -- that the overriding operation is also No_Return (no such check is - -- required for the case of non-dispatching operation. + -- case of a dispatching operation, then the check is made later in + -- Check_Abstract_Overriding that the overriding operation is also + -- No_Return (no such check is required for the nondispatching case). Set_No_Return (New_Subp, No_Return (Parent_Subp)); @@ -15763,6 +15701,9 @@ package body Sem_Ch3 is -- Ada 2005 (AI-228): Calculate the "require overriding" and "abstract" -- properties of the subprogram, as defined in RM-3.9.3(4/2-6/2). + -- Ada 202x (AI12-0042): Similarly, set those properties for + -- implementing the rule of RM 7.3.2(6.1/4). + -- A subprogram subject to pragma Extensions_Visible with value False -- requires overriding if the subprogram has at least one controlling -- OUT parameter (SPARK RM 6.1.7(6)). @@ -15779,7 +15720,26 @@ package body Sem_Ch3 is Derived_Type and then not Is_Null_Extension (Derived_Type)) or else (Comes_From_Source (Alias (New_Subp)) - and then Is_EVF_Procedure (Alias (New_Subp)))) + and then Is_EVF_Procedure (Alias (New_Subp))) + + -- AI12-0042: Set Requires_Overriding when a type extension + -- inherits a private operation that is visible at the + -- point of extension (Has_Private_Ancestor is False) from + -- an ancestor that has Type_Invariant'Class, and when the + -- type extension is in a visible part (the latter as + -- clarified by AI12-0382). + + or else + (not Has_Private_Ancestor (Derived_Type) + and then Has_Invariants (Parent_Type) + and then + Present (Get_Pragma (Parent_Type, Pragma_Invariant)) + and then + Class_Present + (Get_Pragma (Parent_Type, Pragma_Invariant)) + and then Is_Private_Primitive (Parent_Subp) + and then In_Visible_Part (Scope (Derived_Type)))) + and then No (Actual_Subp) then if not Is_Tagged_Type (Derived_Type) @@ -15898,6 +15858,17 @@ package body Sem_Ch3 is if Ekind (New_Subp) = E_Function then Set_Mechanism (New_Subp, Mechanism (Parent_Subp)); end if; + + -- Ada 2020 (AI12-0279): If a Yield aspect is specified True for a + -- primitive subprogram S of a type T, then the aspect is inherited + -- by the corresponding primitive subprogram of each descendant of T. + + if Is_Tagged_Type (Derived_Type) + and then Is_Dispatching_Operation (New_Subp) + and then Has_Yield_Aspect (Alias (New_Subp)) + then + Set_Has_Yield_Aspect (New_Subp, Has_Yield_Aspect (Alias (New_Subp))); + end if; end Derive_Subprogram; ------------------------ @@ -15955,7 +15926,7 @@ package body Sem_Ch3 is return True; end if; - E := Next_Entity (E); + Next_Entity (E); end loop; List := Collect_Primitive_Operations (Derived_Type); @@ -16646,8 +16617,6 @@ package body Sem_Ch3 is -- parent is also an interface. if Interface_Present (Def) then - Check_SPARK_05_Restriction ("interface is not allowed", Def); - if not Is_Interface (Parent_Type) then Diagnose_Interface (Indic, Parent_Type); @@ -16893,11 +16862,6 @@ package body Sem_Ch3 is if Is_Type (T) then Set_Has_Discriminants (T, False); end if; - - -- The type is allowed to have discriminants - - else - Check_SPARK_05_Restriction ("discriminant type is not allowed", N); end if; end if; @@ -16917,7 +16881,7 @@ package body Sem_Ch3 is -- Check for early use of incomplete or private type - if Ekind_In (Parent_Type, E_Void, E_Incomplete_Type) then + if Ekind (Parent_Type) in E_Void | E_Incomplete_Type then Error_Msg_N ("premature derivation of incomplete type", Indic); return; @@ -17084,14 +17048,6 @@ package body Sem_Ch3 is end if; end if; end if; - - -- In SPARK, there are no derived type definitions other than type - -- extensions of tagged record types. - - if No (Extension) then - Check_SPARK_05_Restriction - ("derived type is not allowed", Original_Node (N)); - end if; end Derived_Type_Declaration; ------------------------ @@ -17462,14 +17418,14 @@ package body Sem_Ch3 is -- Check invalid completion of private or incomplete type - elsif not Nkind_In (N, N_Full_Type_Declaration, - N_Task_Type_Declaration, - N_Protected_Type_Declaration) + elsif Nkind (N) not in N_Full_Type_Declaration + | N_Task_Type_Declaration + | N_Protected_Type_Declaration and then (Ada_Version < Ada_2012 or else not Is_Incomplete_Type (Prev) - or else not Nkind_In (N, N_Private_Type_Declaration, - N_Private_Extension_Declaration)) + or else Nkind (N) not in N_Private_Type_Declaration + | N_Private_Extension_Declaration) then -- Completion must be a full type declarations (RM 7.3(4)) @@ -17546,9 +17502,8 @@ package body Sem_Ch3 is end if; if Nkind (N) = N_Full_Type_Declaration - and then Nkind_In - (Type_Definition (N), N_Record_Definition, - N_Derived_Type_Definition) + and then Nkind (Type_Definition (N)) in + N_Record_Definition | N_Derived_Type_Definition and then Interface_Present (Type_Definition (N)) then Error_Msg_N @@ -17565,15 +17520,15 @@ package body Sem_Ch3 is New_Id := Id; elsif Ekind (Prev) = E_Private_Type - and then Nkind_In (N, N_Task_Type_Declaration, - N_Protected_Type_Declaration) + and then Nkind (N) in N_Task_Type_Declaration + | N_Protected_Type_Declaration then Error_Msg_N ("completion of nonlimited type cannot be limited", N); elsif Ekind (Prev) = E_Record_Type_With_Private - and then Nkind_In (N, N_Task_Type_Declaration, - N_Protected_Type_Declaration) + and then Nkind (N) in N_Task_Type_Declaration + | N_Protected_Type_Declaration then if not Is_Limited_Record (Prev) then Error_Msg_N @@ -17590,8 +17545,8 @@ package body Sem_Ch3 is -- type or a protected type. This case arises when covering -- interface types. - elsif Nkind_In (N, N_Task_Type_Declaration, - N_Protected_Type_Declaration) + elsif Nkind (N) in N_Task_Type_Declaration + | N_Protected_Type_Declaration then null; @@ -17688,8 +17643,8 @@ package body Sem_Ch3 is if Ada_Version >= Ada_2012 and then Is_Incomplete_Type (Prev) - and then Nkind_In (N, N_Private_Type_Declaration, - N_Private_Extension_Declaration) + and then Nkind (N) in N_Private_Type_Declaration + | N_Private_Extension_Declaration then -- No need to check private extensions since they are tagged @@ -17703,8 +17658,8 @@ package body Sem_Ch3 is -- a synchronized type that implements interfaces) or a -- type extension, otherwise this is an error. - elsif Nkind_In (N, N_Task_Type_Declaration, - N_Protected_Type_Declaration) + elsif Nkind (N) in N_Task_Type_Declaration + | N_Protected_Type_Declaration then if No (Interface_List (N)) and then not Error_Posted (N) then Tag_Mismatch; @@ -17772,8 +17727,8 @@ package body Sem_Ch3 is -- Case of an anonymous array subtype - if Nkind_In (Def_Kind, N_Constrained_Array_Definition, - N_Unconstrained_Array_Definition) + if Def_Kind in + N_Constrained_Array_Definition | N_Unconstrained_Array_Definition then T := Empty; Array_Type_Declaration (T, Obj_Def); @@ -17840,19 +17795,6 @@ package body Sem_Ch3 is else T := Process_Subtype (Obj_Def, Related_Nod); - - -- If expansion is disabled an object definition that is an aggregate - -- will not get expanded and may lead to scoping problems in the back - -- end, if the object is referenced in an inner scope. In that case - -- create an itype reference for the object definition now. This - -- may be redundant in some cases, but harmless. - - if Is_Itype (T) - and then Nkind (Related_Nod) = N_Object_Declaration - and then ASIS_Mode - then - Build_Itype_Reference (T, Related_Nod); - end if; end if; return T; @@ -18725,8 +18667,7 @@ package body Sem_Ch3 is then null; - elsif Ekind_In (Derived_Base, E_Private_Type, - E_Limited_Private_Type) + elsif Ekind (Derived_Base) in E_Private_Type | E_Limited_Private_Type then null; @@ -18752,38 +18693,6 @@ package body Sem_Ch3 is return Assoc_List; end Inherit_Components; - ----------------------------- - -- Inherit_Predicate_Flags -- - ----------------------------- - - procedure Inherit_Predicate_Flags (Subt, Par : Entity_Id) is - begin - if Present (Predicate_Function (Subt)) then - return; - end if; - - Set_Has_Predicates (Subt, Has_Predicates (Par)); - Set_Has_Static_Predicate_Aspect - (Subt, Has_Static_Predicate_Aspect (Par)); - Set_Has_Dynamic_Predicate_Aspect - (Subt, Has_Dynamic_Predicate_Aspect (Par)); - - -- A named subtype does not inherit the predicate function of its - -- parent but an itype declared for a loop index needs the discrete - -- predicate information of its parent to execute the loop properly. - -- A non-discrete type may has a static predicate (for example True) - -- but has no static_discrete_predicate. - - if Is_Itype (Subt) and then Present (Predicate_Function (Par)) then - Set_Subprograms_For_Type (Subt, Subprograms_For_Type (Par)); - - if Has_Static_Predicate (Par) and then Is_Discrete_Type (Par) then - Set_Static_Discrete_Predicate - (Subt, Static_Discrete_Predicate (Par)); - end if; - end if; - end Inherit_Predicate_Flags; - ---------------------- -- Is_EVF_Procedure -- ---------------------- @@ -18863,6 +18772,29 @@ package body Sem_Ch3 is end if; end Is_Null_Extension; + -------------------------- + -- Is_Private_Primitive -- + -------------------------- + + function Is_Private_Primitive (Prim : Entity_Id) return Boolean is + Prim_Scope : constant Entity_Id := Scope (Prim); + Priv_Entity : Entity_Id; + begin + if Is_Package_Or_Generic_Package (Prim_Scope) then + Priv_Entity := First_Private_Entity (Prim_Scope); + + while Present (Priv_Entity) loop + if Priv_Entity = Prim then + return True; + end if; + + Next_Entity (Priv_Entity); + end loop; + end if; + + return False; + end Is_Private_Primitive; + ------------------------------ -- Is_Valid_Constraint_Kind -- ------------------------------ @@ -18879,16 +18811,13 @@ package body Sem_Ch3 is return Constraint_Kind = N_Range_Constraint; when Decimal_Fixed_Point_Kind => - return Nkind_In (Constraint_Kind, N_Digits_Constraint, - N_Range_Constraint); + return Constraint_Kind in N_Digits_Constraint | N_Range_Constraint; when Ordinary_Fixed_Point_Kind => - return Nkind_In (Constraint_Kind, N_Delta_Constraint, - N_Range_Constraint); + return Constraint_Kind in N_Delta_Constraint | N_Range_Constraint; when Float_Kind => - return Nkind_In (Constraint_Kind, N_Digits_Constraint, - N_Range_Constraint); + return Constraint_Kind in N_Digits_Constraint | N_Range_Constraint; when Access_Kind | Array_Kind @@ -18948,7 +18877,7 @@ package body Sem_Ch3 is -- Start of processing for Is_Visible_Component begin - if Ekind_In (C, E_Component, E_Discriminant) then + if Ekind (C) in E_Component | E_Discriminant then Original_Comp := Original_Record_Component (C); end if; @@ -18999,39 +18928,6 @@ package body Sem_Ch3 is then return True; - -- In the body of an instantiation, check the visibility of a component - -- in case it has a homograph that is a primitive operation of a private - -- type which was not visible in the generic unit. - - -- Should Is_Prefixed_Call be propagated from template to instance??? - - elsif In_Instance_Body then - if not Is_Tagged_Type (Original_Type) - or else not Is_Private_Type (Original_Type) - then - return True; - - else - declare - Subp_Elmt : Elmt_Id; - - begin - Subp_Elmt := First_Elmt (Primitive_Operations (Original_Type)); - while Present (Subp_Elmt) loop - - -- The component is hidden by a primitive operation - - if Chars (Node (Subp_Elmt)) = Chars (C) then - return False; - end if; - - Next_Elmt (Subp_Elmt); - end loop; - - return True; - end; - end if; - -- If the component has been declared in an ancestor which is currently -- a private type, then it is not visible. The same applies if the -- component's containing type is not in an open scope and the original @@ -19040,7 +18936,9 @@ package body Sem_Ch3 is -- a component in a sibling package that is inherited from a visible -- component of a type in an ancestor package; the component in the -- sibling package should not be visible even though the component it - -- inherited from is visible). This does not apply however in the case + -- inherited from is visible), but instance bodies are not subject to + -- this second case since they have the Has_Private_View mechanism to + -- ensure proper visibility. This does not apply however in the case -- where the scope of the type is a private child unit, or when the -- parent comes from a local package in which the ancestor is currently -- visible. The latter suppression of visibility is needed for cases @@ -19050,7 +18948,8 @@ package body Sem_Ch3 is or else (not Is_Private_Descendant (Type_Scope) and then not In_Open_Scopes (Type_Scope) - and then Has_Private_Declaration (Original_Type)) + and then Has_Private_Declaration (Original_Type) + and then not In_Instance_Body) then -- If the type derives from an entity in a formal package, there -- are no additional visible components. @@ -19221,8 +19120,7 @@ package body Sem_Ch3 is (N : Node_Id; Related_Nod : Node_Id; Related_Id : Entity_Id := Empty; - Suffix_Index : Nat := 1; - In_Iter_Schm : Boolean := False) + Suffix_Index : Nat := 1) is R : Node_Id; T : Entity_Id; @@ -19334,7 +19232,7 @@ package body Sem_Ch3 is end if; R := N; - Process_Range_Expr_In_Decl (R, T, In_Iter_Schm => In_Iter_Schm); + Process_Range_Expr_In_Decl (R, T); elsif Nkind (N) = N_Subtype_Indication then @@ -19351,8 +19249,7 @@ package body Sem_Ch3 is R := Range_Expression (Constraint (N)); Resolve (R, T); - Process_Range_Expr_In_Decl - (R, Entity (Subtype_Mark (N)), In_Iter_Schm => In_Iter_Schm); + Process_Range_Expr_In_Decl (R, Entity (Subtype_Mark (N))); elsif Nkind (N) = N_Attribute_Reference then @@ -19613,7 +19510,6 @@ package body Sem_Ch3 is -- Nonbinary case elsif M_Val < 2 ** Bits then - Check_SPARK_05_Restriction ("modulus should be a power of 2", T); Set_Non_Binary_Modulus (T); if Bits > System_Max_Nonbinary_Modulus_Power then @@ -20201,10 +20097,10 @@ package body Sem_Ch3 is (Defining_Identifier (Discr), Expression (Discr)); end if; - -- In gnatc or gnatprove mode, make sure set Do_Range_Check flag + -- In gnatc or GNATprove mode, make sure set Do_Range_Check flag -- gets set unless we can be sure that no range check is required. - if (GNATprove_Mode or not Expander_Active) + if not Expander_Active and then not Is_In_Range (Expression (Discr), Discr_Type, Assume_Valid => True) @@ -20296,10 +20192,13 @@ package body Sem_Ch3 is -- A discriminant cannot be effectively volatile (SPARK RM 7.1.3(4)). -- This check is relevant only when SPARK_Mode is on as it is not a - -- standard Ada legality rule. + -- standard Ada legality rule. The only way for a discriminant to be + -- effectively volatile is to have an effectively volatile type, so + -- we check this directly, because the Ekind of Discr might not be + -- set yet (to help preventing cascaded errors on derived types). if SPARK_Mode = On - and then Is_Effectively_Volatile (Defining_Identifier (Discr)) + and then Is_Effectively_Volatile (Discr_Type) then Error_Msg_N ("discriminant cannot be volatile", Discr); end if; @@ -20621,15 +20520,6 @@ package body Sem_Ch3 is -- ELSE. else - -- In formal mode, when completing a private extension the type - -- named in the private part must be exactly the same as that - -- named in the visible part. - - if Priv_Parent /= Full_Parent then - Error_Msg_Name_1 := Chars (Priv_Parent); - Check_SPARK_05_Restriction ("% expected", Full_Indic); - end if; - -- Check the rules of 7.3(10): if the private extension inherits -- known discriminants, then the full type must also inherit those -- discriminants from the same (ancestor) type, and the parent @@ -20813,9 +20703,9 @@ package body Sem_Ch3 is Priv := Node (Priv_Elmt); Priv_Scop := Scope (Priv); - if Ekind_In (Priv, E_Private_Subtype, - E_Limited_Private_Subtype, - E_Record_Subtype_With_Private) + if Ekind (Priv) in E_Private_Subtype + | E_Limited_Private_Subtype + | E_Record_Subtype_With_Private then Full := Make_Defining_Identifier (Sloc (Priv), Chars (Priv)); Set_Is_Itype (Full); @@ -20986,7 +20876,7 @@ package body Sem_Ch3 is Prim := Next_Entity (Full_T); while Present (Prim) and then Prim /= Priv_T loop - if Ekind_In (Prim, E_Procedure, E_Function) then + if Ekind (Prim) in E_Procedure | E_Function then Disp_Typ := Find_Dispatching_Type (Prim); if Disp_Typ = Full_T @@ -21083,16 +20973,32 @@ package body Sem_Ch3 is end if; -- Propagate Default_Initial_Condition-related attributes from the - -- partial view to the full view and its base type. + -- partial view to the full view. Propagate_DIC_Attributes (Full_T, From_Typ => Priv_T); - Propagate_DIC_Attributes (Base_Type (Full_T), From_Typ => Priv_T); + + -- And to the underlying full view, if any + + if Is_Private_Type (Full_T) + and then Present (Underlying_Full_View (Full_T)) + then + Propagate_DIC_Attributes + (Underlying_Full_View (Full_T), From_Typ => Priv_T); + end if; -- Propagate invariant-related attributes from the partial view to the - -- full view and its base type. + -- full view. Propagate_Invariant_Attributes (Full_T, From_Typ => Priv_T); - Propagate_Invariant_Attributes (Base_Type (Full_T), From_Typ => Priv_T); + + -- And to the underlying full view, if any + + if Is_Private_Type (Full_T) + and then Present (Underlying_Full_View (Full_T)) + then + Propagate_Invariant_Attributes + (Underlying_Full_View (Full_T), From_Typ => Priv_T); + end if; -- AI12-0041: Detect an attempt to inherit a class-wide type invariant -- in the full view without advertising the inheritance in the partial @@ -21123,12 +21029,13 @@ package body Sem_Ch3 is -- view cannot be frozen yet, and the predicate function has not been -- built. Still it is a cheap check and seems safer to make it. - if Has_Predicates (Priv_T) then - Set_Has_Predicates (Full_T); + Propagate_Predicate_Attributes (Full_T, Priv_T); - if Present (Predicate_Function (Priv_T)) then - Set_Predicate_Function (Full_T, Predicate_Function (Priv_T)); - end if; + if Is_Private_Type (Full_T) + and then Present (Underlying_Full_View (Full_T)) + then + Propagate_Predicate_Attributes + (Underlying_Full_View (Full_T), Priv_T); end if; <<Leave>> @@ -21261,9 +21168,8 @@ package body Sem_Ch3 is (R : Node_Id; T : Entity_Id; Subtyp : Entity_Id := Empty; - Check_List : List_Id := Empty_List; - R_Check_Off : Boolean := False; - In_Iter_Schm : Boolean := False) + Check_List : List_Id := No_List; + R_Check_Off : Boolean := False) is Lo, Hi : Node_Id; R_Checks : Check_Result; @@ -21274,16 +21180,6 @@ package body Sem_Ch3 is Analyze_And_Resolve (R, Base_Type (T)); if Nkind (R) = N_Range then - - -- In SPARK, all ranges should be static, with the exception of the - -- discrete type definition of a loop parameter specification. - - if not In_Iter_Schm - and then not Is_OK_Static_Range (R) - then - Check_SPARK_05_Restriction ("range should be static", R); - end if; - Lo := Low_Bound (R); Hi := High_Bound (R); @@ -21434,17 +21330,16 @@ package body Sem_Ch3 is exit when Nkind (Insert_Node) in N_Declaration and then - not Nkind_In - (Insert_Node, N_Component_Declaration, - N_Loop_Parameter_Specification, - N_Function_Specification, - N_Procedure_Specification); - - exit when Nkind (Insert_Node) in N_Later_Decl_Item - or else Nkind (Insert_Node) in - N_Statement_Other_Than_Procedure_Call - or else Nkind_In (Insert_Node, N_Procedure_Call_Statement, - N_Pragma); + Nkind (Insert_Node) not in N_Component_Declaration + | N_Loop_Parameter_Specification + | N_Function_Specification + | N_Procedure_Specification; + + exit when Nkind (Insert_Node) in + N_Later_Decl_Item | + N_Statement_Other_Than_Procedure_Call | + N_Procedure_Call_Statement | + N_Pragma; Insert_Node := Parent (Insert_Node); end loop; @@ -21477,14 +21372,17 @@ package body Sem_Ch3 is Insert_Node, Def_Id, Sloc (Insert_Node), - R, Do_Before => True); end if; end; - -- Insertion before a declaration. If the declaration - -- includes discriminants, the list of applicable checks - -- is given by the caller. + -- Case of declarations. If the declaration is for a type + -- and involves discriminants, the checks are premature at + -- the declaration point and need to wait for the expansion + -- of the initialization procedure, which will pass in the + -- list to put them on; otherwise, the checks are done at + -- the declaration point and there is no need to do them + -- again in the initialization procedure. elsif Nkind (Insert_Node) in N_Declaration then Def_Id := Defining_Identifier (Insert_Node); @@ -21495,19 +21393,22 @@ package body Sem_Ch3 is (Ekind (Def_Id) = E_Protected_Type and then Has_Discriminants (Def_Id)) then - Append_Range_Checks - (R_Checks, - Check_List, Def_Id, Sloc (Insert_Node), R); + if Present (Check_List) then + Append_Range_Checks + (R_Checks, + Check_List, Def_Id, Sloc (Insert_Node)); + end if; else - Insert_Range_Checks - (R_Checks, - Insert_Node, Def_Id, Sloc (Insert_Node), R); - + if No (Check_List) then + Insert_Range_Checks + (R_Checks, + Insert_Node, Def_Id, Sloc (Insert_Node)); + end if; end if; - -- Insertion before a statement. Range appears in the - -- context of a quantified expression. Insertion will + -- Case of statements. Drop the checks, as the range appears + -- in the context of a quantified expression. Insertion will -- take place when expression is expanded. else @@ -21652,20 +21553,19 @@ package body Sem_Ch3 is -- The following is ugly, can't we have a range or even a flag??? May_Have_Null_Exclusion := - Nkind_In (P, N_Access_Definition, - N_Access_Function_Definition, - N_Access_Procedure_Definition, - N_Access_To_Object_Definition, - N_Allocator, - N_Component_Definition) - or else - Nkind_In (P, N_Derived_Type_Definition, - N_Discriminant_Specification, - N_Formal_Object_Declaration, - N_Object_Declaration, - N_Object_Renaming_Declaration, - N_Parameter_Specification, - N_Subtype_Declaration); + Nkind (P) in N_Access_Definition + | N_Access_Function_Definition + | N_Access_Procedure_Definition + | N_Access_To_Object_Definition + | N_Allocator + | N_Component_Definition + | N_Derived_Type_Definition + | N_Discriminant_Specification + | N_Formal_Object_Declaration + | N_Object_Declaration + | N_Object_Renaming_Declaration + | N_Parameter_Specification + | N_Subtype_Declaration; -- Create an Itype that is a duplicate of Entity (S) but with the -- null-exclusion attribute. @@ -21997,14 +21897,6 @@ package body Sem_Ch3 is -- Normal case if Ada_Version < Ada_2005 or else not Interface_Present (Def) then - if Limited_Present (Def) then - Check_SPARK_05_Restriction ("limited is not allowed", N); - end if; - - if Abstract_Present (Def) then - Check_SPARK_05_Restriction ("abstract is not allowed", N); - end if; - -- The flag Is_Tagged_Type might have already been set by -- Find_Type_Name if it detected an error for declaration T. This -- arises in the case of private tagged types where the full view @@ -22028,8 +21920,6 @@ package body Sem_Ch3 is or else Abstract_Present (Def)); else - Check_SPARK_05_Restriction ("interface is not allowed", N); - Is_Tagged := True; Analyze_Interface_Declaration (T, Def); @@ -22171,40 +22061,6 @@ package body Sem_Ch3 is T := Prev_T; end if; - -- In SPARK, tagged types and type extensions may only be declared in - -- the specification of library unit packages. - - if Present (Def) and then Is_Tagged_Type (T) then - declare - Typ : Node_Id; - Ctxt : Node_Id; - - begin - if Nkind (Parent (Def)) = N_Full_Type_Declaration then - Typ := Parent (Def); - else - pragma Assert - (Nkind (Parent (Def)) = N_Derived_Type_Definition); - Typ := Parent (Parent (Def)); - end if; - - Ctxt := Parent (Typ); - - if Nkind (Ctxt) = N_Package_Body - and then Nkind (Parent (Ctxt)) = N_Compilation_Unit - then - Check_SPARK_05_Restriction - ("type should be defined in package specification", Typ); - - elsif Nkind (Ctxt) /= N_Package_Specification - or else Nkind (Parent (Parent (Ctxt))) /= N_Compilation_Unit - then - Check_SPARK_05_Restriction - ("type should be defined in library unit package", Typ); - end if; - end; - end if; - Final_Storage_Only := not Is_Controlled (T); -- Ada 2005: Check whether an explicit Limited is present in a derived @@ -22223,19 +22079,13 @@ package body Sem_Ch3 is -- record extension, in which case the current scope may have inherited -- components. - if No (Def) - or else No (Component_List (Def)) - or else Null_Present (Component_List (Def)) + if Present (Def) + and then Present (Component_List (Def)) + and then not Null_Present (Component_List (Def)) then - if not Is_Tagged_Type (T) then - Check_SPARK_05_Restriction ("untagged record cannot be null", Def); - end if; - - else Analyze_Declarations (Component_Items (Component_List (Def))); if Present (Variant_Part (Component_List (Def))) then - Check_SPARK_05_Restriction ("variant part is not allowed", Def); Analyze (Variant_Part (Component_List (Def))); end if; end if; @@ -22292,11 +22142,11 @@ package body Sem_Ch3 is end if; end Record_Type_Definition; - ------------------------ - -- Replace_Components -- - ------------------------ + --------------------------- + -- Replace_Discriminants -- + --------------------------- - procedure Replace_Components (Typ : Entity_Id; Decl : Node_Id) is + procedure Replace_Discriminants (Typ : Entity_Id; Decl : Node_Id) is function Process (N : Node_Id) return Traverse_Result; ------------- @@ -22310,7 +22160,9 @@ package body Sem_Ch3 is if Nkind (N) = N_Discriminant_Specification then Comp := First_Discriminant (Typ); while Present (Comp) loop - if Chars (Comp) = Chars (Defining_Identifier (N)) then + if Original_Record_Component (Comp) = Defining_Identifier (N) + or else Chars (Comp) = Chars (Defining_Identifier (N)) + then Set_Defining_Identifier (N, Comp); exit; end if; @@ -22321,23 +22173,25 @@ package body Sem_Ch3 is elsif Nkind (N) = N_Variant_Part then Comp := First_Discriminant (Typ); while Present (Comp) loop - if Chars (Comp) = Chars (Name (N)) then - Set_Entity (Name (N), Comp); - exit; - end if; - - Next_Discriminant (Comp); - end loop; + if Original_Record_Component (Comp) = Entity (Name (N)) + or else Chars (Comp) = Chars (Name (N)) + then + -- Make sure to preserve the type coming from the parent on + -- the Name, even if the subtype of the discriminant can be + -- constrained, so that discrete choices inherited from the + -- parent in the variant part are not flagged as violating + -- the constraints of the subtype. - elsif Nkind (N) = N_Component_Declaration then - Comp := First_Component (Typ); - while Present (Comp) loop - if Chars (Comp) = Chars (Defining_Identifier (N)) then - Set_Defining_Identifier (N, Comp); + declare + Typ : constant Entity_Id := Etype (Name (N)); + begin + Rewrite (Name (N), New_Occurrence_Of (Comp, Sloc (N))); + Set_Etype (Name (N), Typ); + end; exit; end if; - Next_Component (Comp); + Next_Discriminant (Comp); end loop; end if; @@ -22346,11 +22200,11 @@ package body Sem_Ch3 is procedure Replace is new Traverse_Proc (Process); - -- Start of processing for Replace_Components + -- Start of processing for Replace_Discriminants begin Replace (Decl); - end Replace_Components; + end Replace_Discriminants; ------------------------------- -- Set_Completion_Referenced -- @@ -22549,18 +22403,10 @@ package body Sem_Ch3 is ("non-static expression used for integer type bound!", Expr); Errs := True; - -- The bounds are folded into literals, and we set their type to be - -- universal, to avoid typing difficulties: we cannot set the type - -- of the literal to the new type, because this would be a forward - -- reference for the back end, and if the original type is user- - -- defined this can lead to spurious semantic errors (e.g. 2928-003). - - else - if Is_Entity_Name (Expr) then - Fold_Uint (Expr, Expr_Value (Expr), True); - end if; + -- Otherwise the bounds are folded into literals - Set_Etype (Expr, Universal_Integer); + elsif Is_Entity_Name (Expr) then + Fold_Uint (Expr, Expr_Value (Expr), True); end if; end Check_Bound; @@ -22582,6 +22428,7 @@ package body Sem_Ch3 is if Hi = Error or else Lo = Error then Base_Typ := Any_Integer; Set_Error_Posted (T, True); + Errs := True; -- Here both bounds are OK expressions @@ -22626,6 +22473,17 @@ package body Sem_Ch3 is end if; end if; + -- Set the type of the bounds to the implicit base: we cannot set it to + -- the new type, because this would be a forward reference for the code + -- generator and, if the original type is user-defined, this could even + -- lead to spurious semantic errors. Furthermore we do not set it to be + -- universal, because this could make it much larger than needed here. + + if not Errs then + Set_Etype (Lo, Implicit_Base); + Set_Etype (Hi, Implicit_Base); + end if; + -- Complete both implicit base and declared first subtype entities. The -- inheritance of the rep item chain ensures that SPARK-related pragmas -- are not clobbered when the signed integer type acts as a full view of |