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_ch12.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_ch12.adb')
-rw-r--r-- | gcc/ada/sem_ch12.adb | 1248 |
1 files changed, 755 insertions, 493 deletions
diff --git a/gcc/ada/sem_ch12.adb b/gcc/ada/sem_ch12.adb index dc3a3c2..cbf27e2 100644 --- a/gcc/ada/sem_ch12.adb +++ b/gcc/ada/sem_ch12.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- -- @@ -495,6 +495,22 @@ package body Sem_Ch12 is -- nodes or subprogram body and declaration nodes depending on the case). -- On return, the node N has been rewritten with the actual body. + function Build_Subprogram_Decl_Wrapper + (Formal_Subp : Entity_Id) return Node_Id; + -- Ada 2020 allows formal subprograms to carry pre/postconditions. + -- At the point of instantiation these contracts apply to uses of + -- the actual subprogram. This is implemented by creating wrapper + -- subprograms instead of the renamings previously used to link + -- formal subprograms and the corresponding actuals. If the actual + -- is not an entity (e.g. an attribute reference) a renaming is + -- created to handle the expansion of the attribute. + + function Build_Subprogram_Body_Wrapper + (Formal_Subp : Entity_Id; + Actual_Name : Node_Id) return Node_Id; + -- The body of the wrapper is a call to the actual, with the generated + -- pre/postconditon checks added. + procedure Check_Access_Definition (N : Node_Id); -- Subsidiary routine to null exclusion processing. Perform an assertion -- check on Ada version and the presence of an access definition in N. @@ -651,6 +667,10 @@ package body Sem_Ch12 is -- Traverse the Exchanged_Views list to see if a type was private -- and has already been flipped during this phase of instantiation. + function Has_Contracts (Decl : Node_Id) return Boolean; + -- Determine whether a formal subprogram has a Pre- or Postcondition, + -- in which case a subprogram wrapper has to be built for the actual. + procedure Hide_Current_Scope; -- When instantiating a generic child unit, the parent context must be -- present, but the instance and all entities that may be generated @@ -1078,6 +1098,14 @@ package body Sem_Ch12 is -- In Ada 2005, indicates partial parameterization of a formal -- package. As usual an other association must be last in the list. + procedure Build_Subprogram_Wrappers; + -- Ada 2020: AI12-0272 introduces pre/postconditions for formal + -- subprograms. The implementation of making the formal into a renaming + -- of the actual does not work, given that subprogram renaming cannot + -- carry aspect specifications. Instead we must create subprogram + -- wrappers whose body is a call to the actual, and whose declaration + -- carries the aspects of the formal. + procedure Check_Fixed_Point_Actual (Actual : Node_Id); -- Warn if an actual fixed-point type has user-defined arithmetic -- operations, but there is no corresponding formal in the generic, @@ -1101,7 +1129,7 @@ package body Sem_Ch12 is -- actuals are positional, return the next one, if any. If the actuals -- are named, scan the parameter associations to find the right one. -- A_F is the corresponding entity in the analyzed generic, which is - -- placed on the selector name for ASIS use. + -- placed on the selector name. -- -- In Ada 2005, a named association may be given with a box, in which -- case Matching_Actual sets Found_Assoc to the generic association, @@ -1131,6 +1159,70 @@ package body Sem_Ch12 is -- anonymous types, the presence a formal equality will introduce an -- implicit declaration for the corresponding inequality. + ----------------------------------------- + -- procedure Build_Subprogram_Wrappers -- + ----------------------------------------- + + procedure Build_Subprogram_Wrappers is + Formal : constant Entity_Id := + Defining_Unit_Name (Specification (Analyzed_Formal)); + Aspect_Spec : Node_Id; + Decl_Node : Node_Id; + Actual_Name : Node_Id; + + begin + -- Create declaration for wrapper subprogram + -- The actual can be overloaded, in which case it will be + -- resolved when the call in the wrapper body is analyzed. + -- We attach the possible interpretations of the actual to + -- the name to be used in the call in the wrapper body. + + if Is_Entity_Name (Match) then + Actual_Name := New_Occurrence_Of (Entity (Match), Sloc (Match)); + + if Is_Overloaded (Match) then + Save_Interps (Match, Actual_Name); + end if; + + else + -- Use renaming declaration created when analyzing actual. + -- This may be incomplete if there are several formal + -- subprograms whose actual is an attribute ??? + + declare + Renaming_Decl : constant Node_Id := Last (Assoc_List); + + begin + Actual_Name := New_Occurrence_Of + (Defining_Entity (Renaming_Decl), Sloc (Match)); + Set_Etype (Actual_Name, Get_Instance_Of (Etype (Formal))); + end; + end if; + + Decl_Node := Build_Subprogram_Decl_Wrapper (Formal); + + -- Transfer aspect specifications from formal subprogram to wrapper + + Set_Aspect_Specifications (Decl_Node, + New_Copy_List_Tree (Aspect_Specifications (Analyzed_Formal))); + + Aspect_Spec := First (Aspect_Specifications (Decl_Node)); + while Present (Aspect_Spec) loop + Set_Analyzed (Aspect_Spec, False); + Next (Aspect_Spec); + end loop; + + Append_To (Assoc_List, Decl_Node); + + -- Create corresponding body, and append it to association list + -- that appears at the head of the declarations in the instance. + -- The subprogram may be called in the analysis of subsequent + -- actuals. + + Append_To (Assoc_List, + Build_Subprogram_Body_Wrapper (Formal, Actual_Name)); + end Build_Subprogram_Wrappers; + ---------------------------------------- -- Check_Overloaded_Formal_Subprogram -- ---------------------------------------- @@ -1481,9 +1573,9 @@ package body Sem_Ch12 is (Defining_Unit_Name (Specification (Analyzed_Formal))); when N_Formal_Package_Declaration => - exit when Nkind_In (Kind, N_Formal_Package_Declaration, - N_Generic_Package_Declaration, - N_Package_Declaration); + exit when Kind in N_Formal_Package_Declaration + | N_Generic_Package_Declaration + | N_Package_Declaration; when N_Use_Package_Clause | N_Use_Type_Clause @@ -1497,10 +1589,10 @@ package body Sem_Ch12 is exit when Kind not in N_Formal_Subprogram_Declaration - and then not Nkind_In (Kind, N_Subprogram_Declaration, - N_Freeze_Entity, - N_Null_Statement, - N_Itype_Reference) + and then Kind not in N_Subprogram_Declaration + | N_Freeze_Entity + | N_Null_Statement + | N_Itype_Reference and then Chars (Defining_Identifier (Formal)) = Chars (Defining_Identifier (Analyzed_Formal)); end case; @@ -1626,7 +1718,7 @@ package body Sem_Ch12 is Assoc_List); -- For a defaulted in_parameter, create an entry in the - -- the list of defaulted actuals, for GNATProve use. Do + -- the list of defaulted actuals, for GNATprove use. Do -- not included these defaults for an instance nested -- within a generic, because the defaults are also used -- in the analysis of the enclosing generic, and only @@ -1685,7 +1777,7 @@ package body Sem_Ch12 is -- Warn when an actual is a fixed-point with user- -- defined promitives. The warning is superfluous - -- if the fornal is private, because there can be + -- if the formal is private, because there can be -- no arithmetic operations in the generic so there -- no danger of confusion. @@ -1793,6 +1885,16 @@ package body Sem_Ch12 is Instantiate_Formal_Subprogram (Formal, Match, Analyzed_Formal)); + -- If formal subprogram has contracts, create wrappers + -- for it. This is an expansion activity that cannot + -- take place e.g. within an enclosing generic unit. + + if Has_Contracts (Analyzed_Formal) + and then Expander_Active + then + Build_Subprogram_Wrappers; + end if; + -- An instantiation is a freeze point for the actuals, -- unless this is a rewritten formal package. @@ -1826,7 +1928,7 @@ package body Sem_Ch12 is end if; -- If this is a nested generic, preserve default for later - -- instantiations. We do this as well for GNATProve use, + -- instantiations. We do this as well for GNATprove use, -- so that the list of generic associations is complete. if No (Match) and then Box_Present (Formal) then @@ -1846,10 +1948,19 @@ package body Sem_Ch12 is end if; when N_Formal_Package_Declaration => - Match := - Matching_Actual - (Defining_Identifier (Formal), - Defining_Identifier (Original_Node (Analyzed_Formal))); + -- The name of the formal package may be hidden by the + -- formal parameter itself. + + if Error_Posted (Analyzed_Formal) then + Abandon_Instantiation (Instantiation_Node); + + else + Match := + Matching_Actual + (Defining_Identifier (Formal), + Defining_Identifier + (Original_Node (Analyzed_Formal))); + end if; if No (Match) then if Partial_Parameterization then @@ -1992,10 +2103,10 @@ package body Sem_Ch12 is S := Current_Scope; while Present (S) loop - if Ekind_In (S, E_Block, - E_Function, - E_Loop, - E_Procedure) + if Ekind (S) in E_Block + | E_Function + | E_Loop + | E_Procedure then Needs_Freezing := False; exit; @@ -2139,9 +2250,9 @@ package body Sem_Ch12 is if Nkind (Def) = N_Constrained_Array_Definition then DSS := First (Discrete_Subtype_Definitions (Def)); while Present (DSS) loop - if Nkind_In (DSS, N_Subtype_Indication, - N_Range, - N_Attribute_Reference) + if Nkind (DSS) in N_Subtype_Indication + | N_Range + | N_Attribute_Reference then Error_Msg_N ("only a subtype mark is allowed in a formal", DSS); end if; @@ -3048,8 +3159,7 @@ package body Sem_Ch12 is Set_Has_Completion (Formal, True); - -- Add semantic information to the original defining identifier for ASIS - -- use. + -- Add semantic information to the original defining identifier. Set_Ekind (Pack_Id, E_Package); Set_Etype (Pack_Id, Standard_Void_Type); @@ -3476,6 +3586,12 @@ package body Sem_Ch12 is end loop; Generate_Reference_To_Generic_Formals (Current_Scope); + + -- For Ada 2020, some formal parameters can carry aspects, which must + -- be name-resolved at the end of the list of formal parameters (which + -- has the semantics of a declaration list). + + Analyze_Contracts (Generic_Formal_Declarations (N)); end Analyze_Generic_Formal_Part; ------------------------------------------ @@ -3493,8 +3609,6 @@ package body Sem_Ch12 is Save_Parent : Node_Id; begin - Check_SPARK_05_Restriction ("generic is not allowed", N); - -- A generic may grant access to its private enclosing context depending -- on the placement of its corresponding body. From elaboration point of -- view, the flow of execution may enter this private context, and then @@ -3699,8 +3813,6 @@ package body Sem_Ch12 is Typ : Entity_Id; begin - Check_SPARK_05_Restriction ("generic is not allowed", N); - -- A generic may grant access to its private enclosing context depending -- on the placement of its corresponding body. From elaboration point of -- view, the flow of execution may enter this private context, and then @@ -3748,13 +3860,6 @@ package body Sem_Ch12 is Enter_Name (Id); Set_Scope_Depth_Value (Id, Scope_Depth (Current_Scope) + 1); - -- Analyze the aspects of the generic copy to ensure that all generated - -- pragmas (if any) perform their semantic effects. - - if Has_Aspects (N) then - Analyze_Aspect_Specifications (N, Id); - end if; - Push_Scope (Id); Enter_Generic_Scope (Id); Set_Inner_Instances (Id, New_Elmt_List); @@ -3839,6 +3944,13 @@ package body Sem_Ch12 is Set_Etype (Id, Standard_Void_Type); end if; + -- Analyze the aspects of the generic copy to ensure that all generated + -- pragmas (if any) perform their semantic effects. + + if Has_Aspects (N) then + Analyze_Aspect_Specifications (N, Id); + end if; + -- For a library unit, we have reconstructed the entity for the unit, -- and must reset it in the library tables. We also make sure that -- Body_Required is set properly in the original compilation unit node. @@ -4032,8 +4144,6 @@ package body Sem_Ch12 is Modes => True, Warnings => True); - Check_SPARK_05_Restriction ("generic is not allowed", N); - -- Very first thing: check for Text_IO special unit in case we are -- instantiating one of the children of [[Wide_]Wide_]Text_IO. @@ -4348,8 +4458,7 @@ package body Sem_Ch12 is -- body if there is one and it needs to be instantiated here. -- We instantiate the body only if we are generating code, or if we - -- are generating cross-reference information, or if we are building - -- trees for ASIS use or GNATprove use. + -- are generating cross-reference information, or for GNATprove use. declare Enclosing_Body_Present : Boolean := False; @@ -4446,7 +4555,7 @@ package body Sem_Ch12 is and then not Inline_Now and then (Operating_Mode = Generate_Code or else (Operating_Mode = Check_Semantics - and then (ASIS_Mode or GNATprove_Mode))); + and then GNATprove_Mode)); -- If front-end inlining is enabled or there are any subprograms -- marked with Inline_Always, do not instantiate body when within @@ -4781,17 +4890,6 @@ package body Sem_Ch12 is Inline_Instance_Body (N, Gen_Unit, Act_Decl); end if; - -- The following is a tree patch for ASIS: ASIS needs separate nodes to - -- be used as defining identifiers for a formal package and for the - -- corresponding expanded package. - - if Nkind (N) = N_Formal_Package_Declaration then - Act_Decl_Id := New_Copy (Defining_Entity (N)); - Set_Comes_From_Source (Act_Decl_Id, True); - Set_Is_Generic_Instance (Act_Decl_Id, False); - Set_Defining_Identifier (N, Act_Decl_Id); - end if; - -- Check that if N is an instantiation of System.Dim_Float_IO or -- System.Dim_Integer_IO, the formal type has a dimension system. @@ -4934,7 +5032,7 @@ package body Sem_Ch12 is while Present (S) and then S /= Standard_Standard loop if Is_Generic_Instance (S) and then (In_Package_Body (S) - or else Ekind_In (S, E_Procedure, E_Function)) + or else Ekind (S) in E_Procedure | E_Function) then -- We still have to remove the entities of the enclosing -- instance from direct visibility. @@ -5103,7 +5201,7 @@ package body Sem_Ch12 is Set_Is_Generic_Instance (Inst, True); if In_Package_Body (Inst) - or else Ekind_In (S, E_Procedure, E_Function) + or else Ekind (S) in E_Procedure | E_Function then E := First_Entity (Instances (J)); while Present (E) loop @@ -5185,17 +5283,17 @@ package body Sem_Ch12 is if (Is_In_Main_Unit (N) or else Is_Inlined_Or_Child_Of_Inlined (Subp)) - -- Must be generating code or analyzing code in ASIS/GNATprove mode + -- Must be generating code or analyzing code in GNATprove mode and then (Operating_Mode = Generate_Code or else (Operating_Mode = Check_Semantics - and then (ASIS_Mode or GNATprove_Mode))) + and then GNATprove_Mode)) - -- The body is needed when generating code (full expansion), in ASIS - -- mode for other tools, and in GNATprove mode (special expansion) for - -- formal verification of the body itself. + -- The body is needed when generating code (full expansion) and in + -- in GNATprove mode (special expansion) for formal verification of + -- the body itself. - and then (Expander_Active or ASIS_Mode or GNATprove_Mode) + and then (Expander_Active or GNATprove_Mode) -- No point in inlining if ABE is inevitable @@ -5367,7 +5465,7 @@ package body Sem_Ch12 is -- Subprogram instance comes from source only if generic does - Set_Comes_From_Source (Act_Decl_Id, Comes_From_Source (Gen_Unit)); + Preserve_Comes_From_Source (Act_Decl_Id, Gen_Unit); -- If the instance is a child unit, mark the Id accordingly. Mark -- the anonymous entity as well, which is the real subprogram and @@ -5491,8 +5589,6 @@ package body Sem_Ch12 is Modes => True, Warnings => True); - Check_SPARK_05_Restriction ("generic is not allowed", N); - -- Very first thing: check for special Text_IO unit in case we are -- instantiating one of the children of [[Wide_]Wide_]Text_IO. Of course -- such an instantiation is bogus (these are packages, not subprograms), @@ -5568,8 +5664,7 @@ package body Sem_Ch12 is -- If renaming, get original unit if Present (Renamed_Object (Gen_Unit)) - and then Ekind_In (Renamed_Object (Gen_Unit), E_Generic_Procedure, - E_Generic_Function) + and then Is_Generic_Subprogram (Renamed_Object (Gen_Unit)) then Gen_Unit := Renamed_Object (Gen_Unit); Set_Is_Instantiated (Gen_Unit); @@ -5814,8 +5909,7 @@ package body Sem_Ch12 is -- constitute a freeze point, but to insure that the freeze node -- is placed properly, it is created directly when instantiating -- the body (otherwise the freeze node might appear to early for - -- nested instantiations). For ASIS purposes, indicate that the - -- wrapper package has replaced the instantiation node. + -- nested instantiations). elsif Nkind (Parent (N)) = N_Compilation_Unit then Rewrite (N, Unit (Parent (N))); @@ -5823,7 +5917,7 @@ package body Sem_Ch12 is end if; -- Replace instance node for library-level instantiations of - -- intrinsic subprograms, for ASIS use. + -- intrinsic subprograms. elsif Nkind (Parent (N)) = N_Compilation_Unit then Rewrite (N, Unit (Parent (N))); @@ -5880,7 +5974,7 @@ package body Sem_Ch12 is if Nkind (Assoc) /= Nkind (N) then return Assoc; - elsif Nkind_In (Assoc, N_Aggregate, N_Extension_Aggregate) then + elsif Nkind (Assoc) in N_Aggregate | N_Extension_Aggregate then return Assoc; else @@ -5900,11 +5994,11 @@ package body Sem_Ch12 is if (Nkind (Assoc) = N_Identifier or else Nkind (Assoc) in N_Op) and then Present (Associated_Node (Assoc)) - and then (Nkind_In (Associated_Node (Assoc), N_Function_Call, - N_Explicit_Dereference, - N_Integer_Literal, - N_Real_Literal, - N_String_Literal)) + and then Nkind (Associated_Node (Assoc)) in N_Function_Call + | N_Explicit_Dereference + | N_Integer_Literal + | N_Real_Literal + | N_String_Literal then Assoc := Associated_Node (Assoc); end if; @@ -6129,6 +6223,117 @@ package body Sem_Ch12 is return Decl; end Build_Operator_Wrapper; + ----------------------------------- + -- Build_Subprogram_Decl_Wrapper -- + ----------------------------------- + + function Build_Subprogram_Decl_Wrapper + (Formal_Subp : Entity_Id) return Node_Id + is + Loc : constant Source_Ptr := Sloc (Current_Scope); + Ret_Type : constant Entity_Id := Get_Instance_Of (Etype (Formal_Subp)); + Decl : Node_Id; + Subp : Entity_Id; + Parm_Spec : Node_Id; + Profile : List_Id := New_List; + Spec : Node_Id; + Form_F : Entity_Id; + New_F : Entity_Id; + + begin + + Subp := Make_Defining_Identifier (Loc, Chars (Formal_Subp)); + Set_Ekind (Subp, Ekind (Formal_Subp)); + Set_Is_Generic_Actual_Subprogram (Subp); + + Profile := Parameter_Specifications ( + New_Copy_Tree + (Specification (Unit_Declaration_Node (Formal_Subp)))); + + Form_F := First_Formal (Formal_Subp); + Parm_Spec := First (Profile); + + -- Create new entities for the formals. Reset entities so that + -- parameter types are properly resolved when wrapper declaration + -- is analyzed. + + while Present (Parm_Spec) loop + New_F := Make_Defining_Identifier (Loc, Chars (Form_F)); + Set_Defining_Identifier (Parm_Spec, New_F); + Set_Entity (Parameter_Type (Parm_Spec), Empty); + Next (Parm_Spec); + Next_Formal (Form_F); + end loop; + + if Ret_Type = Standard_Void_Type 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_Occurrence_Of (Ret_Type, Loc)); + end if; + + Decl := + Make_Subprogram_Declaration (Loc, Specification => Spec); + + return Decl; + end Build_Subprogram_Decl_Wrapper; + + ----------------------------------- + -- Build_Subprogram_Body_Wrapper -- + ----------------------------------- + + function Build_Subprogram_Body_Wrapper + (Formal_Subp : Entity_Id; + Actual_Name : Node_Id) return Node_Id + is + Loc : constant Source_Ptr := Sloc (Current_Scope); + Ret_Type : constant Entity_Id := Get_Instance_Of (Etype (Formal_Subp)); + Spec_Node : constant Node_Id := + Specification + (Build_Subprogram_Decl_Wrapper (Formal_Subp)); + Act : Node_Id; + Actuals : List_Id; + Body_Node : Node_Id; + Stmt : Node_Id; + begin + Actuals := New_List; + Act := First (Parameter_Specifications (Spec_Node)); + + while Present (Act) loop + Append_To (Actuals, + Make_Identifier (Loc, Chars (Defining_Identifier (Act)))); + Next (Act); + end loop; + + if Ret_Type = Standard_Void_Type then + Stmt := Make_Procedure_Call_Statement (Loc, + Name => Actual_Name, + Parameter_Associations => Actuals); + + else + Stmt := Make_Simple_Return_Statement (Loc, + Expression => + Make_Function_Call (Loc, + Name => Actual_Name, + Parameter_Associations => Actuals)); + end if; + + Body_Node := Make_Subprogram_Body (Loc, + Specification => Spec_Node, + Declarations => New_List, + Handled_Statement_Sequence => + Make_Handled_Sequence_Of_Statements (Loc, + Statements => New_List (Stmt))); + + return Body_Node; + end Build_Subprogram_Body_Wrapper; + ------------------------------------------- -- Build_Instance_Compilation_Unit_Nodes -- ------------------------------------------- @@ -6301,9 +6506,9 @@ package body Sem_Ch12 is if Kind = N_Formal_Type_Declaration then return; - elsif Nkind_In (Kind, N_Formal_Object_Declaration, - N_Formal_Package_Declaration) - or else Kind in N_Formal_Subprogram_Declaration + elsif Kind in N_Formal_Object_Declaration + | N_Formal_Package_Declaration + | N_Formal_Subprogram_Declaration then null; @@ -6496,9 +6701,8 @@ package body Sem_Ch12 is -- If the formal entity comes from a formal declaration, it was -- defaulted in the formal package, and no check is needed on it. - elsif Nkind_In (Original_Node (Parent (E2)), - N_Formal_Object_Declaration, - N_Formal_Type_Declaration) + elsif Nkind (Original_Node (Parent (E2))) in + N_Formal_Object_Declaration | N_Formal_Type_Declaration then -- If the formal is a tagged type the corresponding class-wide -- type has been generated as well, and it must be skipped. @@ -6808,48 +7012,6 @@ package body Sem_Ch12 is E : Entity_Id; Astype : Entity_Id; - function Denotes_Previous_Actual (Typ : Entity_Id) return Boolean; - -- For a formal that is an array type, the component type is often a - -- previous formal in the same unit. The privacy status of the component - -- type will have been examined earlier in the traversal of the - -- corresponding actuals, and this status should not be modified for - -- the array (sub)type itself. However, if the base type of the array - -- (sub)type is private, its full view must be restored in the body to - -- be consistent with subsequent index subtypes, etc. - -- - -- To detect this case we have to rescan the list of formals, which is - -- usually short enough to ignore the resulting inefficiency. - - ----------------------------- - -- Denotes_Previous_Actual -- - ----------------------------- - - function Denotes_Previous_Actual (Typ : Entity_Id) return Boolean is - Prev : Entity_Id; - - begin - Prev := First_Entity (Instance); - while Present (Prev) loop - if Is_Type (Prev) - and then Nkind (Parent (Prev)) = N_Subtype_Declaration - and then Is_Entity_Name (Subtype_Indication (Parent (Prev))) - and then Entity (Subtype_Indication (Parent (Prev))) = Typ - then - return True; - - elsif Prev = E then - return False; - - else - Next_Entity (Prev); - end if; - end loop; - - return False; - end Denotes_Previous_Actual; - - -- Start of processing for Check_Generic_Actuals - begin E := First_Entity (Instance); while Present (E) loop @@ -6858,14 +7020,34 @@ package body Sem_Ch12 is and then Scope (Etype (E)) /= Instance and then Is_Entity_Name (Subtype_Indication (Parent (E))) then - if Is_Array_Type (E) - and then not Is_Private_Type (Etype (E)) - and then Denotes_Previous_Actual (Component_Type (E)) - then - null; - else - Check_Private_View (Subtype_Indication (Parent (E))); - end if; + -- Restore the proper view of the actual from the information + -- saved earlier by Instantiate_Type. + + Check_Private_View (Subtype_Indication (Parent (E))); + + -- If the actual is itself the formal of a parent instance, + -- then also restore the proper view of its actual and so on. + -- That's necessary for nested instantiations of the form + + -- generic + -- type Component is private; + -- type Array_Type is array (Positive range <>) of Component; + -- procedure Proc; + + -- when the outermost actuals have inconsistent views, because + -- the Component_Type of Array_Type of the inner instantiations + -- is the actual of Component of the outermost one and not that + -- of the corresponding inner instantiations. + + Astype := Ancestor_Subtype (E); + while Present (Astype) + and then Nkind (Parent (Astype)) = N_Subtype_Declaration + and then Present (Generic_Parent_Type (Parent (Astype))) + and then Is_Entity_Name (Subtype_Indication (Parent (Astype))) + loop + Check_Private_View (Subtype_Indication (Parent (Astype))); + Astype := Ancestor_Subtype (Astype); + end loop; Set_Is_Generic_Actual_Type (E); @@ -6900,15 +7082,6 @@ package body Sem_Ch12 is if Is_Discrete_Or_Fixed_Point_Type (E) then Set_RM_Size (E, RM_Size (Astype)); - - -- In nested instances, the base type of an access actual may - -- itself be private, and need to be exchanged. - - elsif Is_Access_Type (E) - and then Is_Private_Type (Etype (E)) - then - Check_Private_View - (New_Occurrence_Of (Etype (E), Sloc (Instance))); end if; elsif Ekind (E) = E_Package then @@ -7445,92 +7618,25 @@ package body Sem_Ch12 is and then Present (Full_View (T)) and then not In_Open_Scopes (Scope (T)) then - -- In the generic, the full type was visible. Save the private - -- entity, for subsequent exchange. + -- In the generic, the full declaration was visible Switch_View (T); elsif Has_Private_View (N) and then not Is_Private_Type (T) and then not Has_Been_Exchanged (T) - and then Etype (Get_Associated_Node (N)) /= T + and then (not In_Open_Scopes (Scope (T)) + or else Nkind (Parent (N)) = N_Subtype_Declaration) then - -- Only the private declaration was visible in the generic. If - -- the type appears in a subtype declaration, the subtype in the + -- In the generic, only the private declaration was visible + + -- If the type appears in a subtype declaration, the subtype in -- instance must have a view compatible with that of its parent, -- which must be exchanged (see corresponding code in Restore_ - -- Private_Views). Otherwise, if the type is defined in a parent - -- unit, leave full visibility within instance, which is safe. - - if In_Open_Scopes (Scope (Base_Type (T))) - and then not Is_Private_Type (Base_Type (T)) - and then Comes_From_Source (Base_Type (T)) - then - null; - - elsif Nkind (Parent (N)) = N_Subtype_Declaration - or else not In_Private_Part (Scope (Base_Type (T))) - then - Prepend_Elmt (T, Exchanged_Views); - Exchange_Declarations (Etype (Get_Associated_Node (N))); - end if; - - -- For composite types with inconsistent representation exchange - -- component types accordingly. - - elsif Is_Access_Type (T) - and then Is_Private_Type (Designated_Type (T)) - and then not Has_Private_View (N) - and then Present (Full_View (Designated_Type (T))) - then - Switch_View (Designated_Type (T)); - - elsif Is_Array_Type (T) then - if Is_Private_Type (Component_Type (T)) - and then not Has_Private_View (N) - and then Present (Full_View (Component_Type (T))) - then - Switch_View (Component_Type (T)); - end if; - - -- The normal exchange mechanism relies on the setting of a - -- flag on the reference in the generic. However, an additional - -- mechanism is needed for types that are not explicitly - -- mentioned in the generic, but may be needed in expanded code - -- in the instance. This includes component types of arrays and - -- designated types of access types. This processing must also - -- include the index types of arrays which we take care of here. - - declare - Indx : Node_Id; - Typ : Entity_Id; - - begin - Indx := First_Index (T); - while Present (Indx) loop - Typ := Base_Type (Etype (Indx)); - - if Is_Private_Type (Typ) - and then Present (Full_View (Typ)) - then - Switch_View (Typ); - end if; + -- Private_Views) so we make an exception to the open scope rule. - Next_Index (Indx); - end loop; - end; - - -- The following case does not test Has_Private_View (N) so it may - -- end up switching views when they are not supposed to be switched. - -- This might be in keeping with Set_Global_Type setting the flag - -- for an array type even if it is not private ??? - - elsif Is_Private_Type (T) - and then Present (Full_View (T)) - and then Is_Array_Type (Full_View (T)) - and then Is_Private_Type (Component_Type (Full_View (T))) - then - Switch_View (T); + Prepend_Elmt (T, Exchanged_Views); + Exchange_Declarations (Etype (Get_Associated_Node (N))); -- Finally, a non-private subtype may have a private base type, which -- must be exchanged for consistency. This can happen when a package @@ -7701,9 +7807,8 @@ package body Sem_Ch12 is function In_Defining_Unit_Name (Nam : Node_Id) return Boolean; -- True if an identifier is part of the defining program unit name of - -- a child unit. The entity of such an identifier must be kept (for - -- ASIS use) even though as the name of an enclosing generic it would - -- otherwise not be preserved in the generic tree. + -- a child unit. + -- Consider removing this subprogram now that ASIS no longer uses it. ---------------------- -- Copy_Descendants -- @@ -7852,11 +7957,11 @@ package body Sem_Ch12 is -- Special casing for identifiers and other entity names and operators - if Nkind_In (New_N, N_Character_Literal, - N_Expanded_Name, - N_Identifier, - N_Operator_Symbol) - or else Nkind (New_N) in N_Op + if Nkind (New_N) in N_Character_Literal + | N_Expanded_Name + | N_Identifier + | N_Operator_Symbol + | N_Op then if not Instantiating then @@ -7887,7 +7992,7 @@ package body Sem_Ch12 is -- The entities for parent units in the defining_program_unit of a -- generic child unit are established when the context of the unit -- is first analyzed, before the generic copy is made. They are - -- preserved in the copy for use in ASIS queries. + -- preserved in the copy for use in e.g. ASIS queries. Ent := Entity (New_N); @@ -7900,10 +8005,9 @@ package body Sem_Ch12 is end if; elsif No (Ent) - or else - not Nkind_In (Ent, N_Defining_Identifier, - N_Defining_Character_Literal, - N_Defining_Operator_Symbol) + or else Nkind (Ent) not in N_Defining_Identifier + | N_Defining_Character_Literal + | N_Defining_Operator_Symbol or else No (Scope (Ent)) or else (Scope (Ent) = Current_Instantiated_Parent.Gen_Id @@ -7936,6 +8040,117 @@ package body Sem_Ch12 is Set_Entity (New_N, Entity (Assoc)); Check_Private_View (N); + -- Here we deal with a very peculiar case for which the + -- Has_Private_View mechanism is not sufficient, because + -- the reference to the type is implicit in the tree, + -- that is to say, it's not referenced from a node but + -- only from another type, namely through Component_Type. + + -- package P is + + -- type Pt is private; + + -- generic + -- type Ft is array (Positive range <>) of Pt; + -- package G is + -- procedure Check (F1, F2 : Ft; Lt : Boolean); + -- end G; + + -- private + -- type Pt is new Boolean; + -- end P; + + -- package body P is + -- package body G is + -- procedure Check (F1, F2 : Ft; Lt : Boolean) is + -- begin + -- if (F1 < F2) /= Lt then + -- null; + -- end if; + -- end Check; + -- end G; + -- end P; + + -- type Arr is array (Positive range <>) of P.Pt; + + -- package Inst is new P.G (Arr); + + -- Pt is a global type for the generic package G and it + -- is not referenced in its body, but only as component + -- type of Ft, which is a local type. This means that no + -- references to Pt or Ft are seen during the copy of the + -- body, the only reference to Pt being seen is when the + -- actuals are checked by Check_Generic_Actuals, but Pt + -- is still private at this point. In the end, the views + -- of Pt are not switched in the body and, therefore, the + -- array comparison is rejected because the component is + -- still private. + + -- Adding e.g. a dummy variable of type Pt in the body is + -- sufficient to make everything work, so we generate an + -- artificial reference to Pt on the fly and thus force + -- the switching of views on the grounds that, if the + -- comparison was accepted during the semantic analysis + -- of the generic, this means that the component cannot + -- have been private (see Sem_Type.Valid_Comparison_Arg). + + if Nkind (Assoc) in N_Op_Compare + and then Present (Etype (Left_Opnd (Assoc))) + and then Is_Array_Type (Etype (Left_Opnd (Assoc))) + and then Present (Etype (Right_Opnd (Assoc))) + and then Is_Array_Type (Etype (Right_Opnd (Assoc))) + then + declare + Ltyp : constant Entity_Id := + Etype (Left_Opnd (Assoc)); + Rtyp : constant Entity_Id := + Etype (Right_Opnd (Assoc)); + begin + if Is_Private_Type (Component_Type (Ltyp)) then + Check_Private_View + (New_Occurrence_Of (Component_Type (Ltyp), + Sloc (N))); + end if; + if Is_Private_Type (Component_Type (Rtyp)) then + Check_Private_View + (New_Occurrence_Of (Component_Type (Rtyp), + Sloc (N))); + end if; + end; + + -- Here is a similar case, for the Designated_Type of an + -- access type that is present as target type in a type + -- conversion from another access type. In this case, if + -- the base types of the designated types are different + -- and the conversion was accepted during the semantic + -- analysis of the generic, this means that the target + -- type cannot have been private (see Valid_Conversion). + + elsif Nkind (Assoc) = N_Identifier + and then Nkind (Parent (Assoc)) = N_Type_Conversion + and then Subtype_Mark (Parent (Assoc)) = Assoc + and then Present (Etype (Assoc)) + and then Is_Access_Type (Etype (Assoc)) + and then Present (Etype (Expression (Parent (Assoc)))) + and then + Is_Access_Type (Etype (Expression (Parent (Assoc)))) + then + declare + Targ_Desig : constant Entity_Id := + Designated_Type (Etype (Assoc)); + Expr_Desig : constant Entity_Id := + Designated_Type + (Etype (Expression (Parent (Assoc)))); + begin + if Base_Type (Targ_Desig) /= Base_Type (Expr_Desig) + and then Is_Private_Type (Targ_Desig) + then + Check_Private_View + (New_Occurrence_Of (Targ_Desig, Sloc (N))); + end if; + end; + end if; + -- The node is a reference to a global type and acts as the -- subtype mark of a qualified expression created in order -- to aid resolution of accidental overloading in instances. @@ -7959,9 +8174,9 @@ package body Sem_Ch12 is then Set_Entity (New_N, Entity (Name (Assoc))); - elsif Nkind_In (Assoc, N_Defining_Identifier, - N_Defining_Character_Literal, - N_Defining_Operator_Symbol) + elsif Nkind (Assoc) in N_Defining_Identifier + | N_Defining_Character_Literal + | N_Defining_Operator_Symbol and then Expander_Active then -- Inlining case: we are copying a tree that contains @@ -8170,7 +8385,7 @@ package body Sem_Ch12 is Set_Assignment_OK (Name (New_N), True); end if; - elsif Nkind_In (N, N_Aggregate, N_Extension_Aggregate) then + elsif Nkind (N) in N_Aggregate | N_Extension_Aggregate then if not Instantiating then Set_Associated_Node (N, New_N); @@ -8290,7 +8505,7 @@ package body Sem_Ch12 is -- Do not copy Comment or Ident pragmas their content is relevant to -- the generic unit, not to the instantiating unit. - if Nam_In (Pragma_Name_Unmapped (N), Name_Comment, Name_Ident) then + if Pragma_Name_Unmapped (N) in Name_Comment | Name_Ident then New_N := Make_Null_Statement (Sloc (N)); -- Do not copy pragmas generated from aspects because the pragmas do @@ -8310,7 +8525,7 @@ package body Sem_Ch12 is Copy_Descendants; end if; - elsif Nkind_In (N, N_Integer_Literal, N_Real_Literal) then + elsif Nkind (N) in N_Integer_Literal | N_Real_Literal then -- No descendant fields need traversing @@ -9009,10 +9224,10 @@ package body Sem_Ch12 is else Inst := Next (Decl); - while not Nkind_In (Inst, N_Formal_Package_Declaration, - N_Function_Instantiation, - N_Package_Instantiation, - N_Procedure_Instantiation) + while Nkind (Inst) not in N_Formal_Package_Declaration + | N_Function_Instantiation + | N_Package_Instantiation + | N_Procedure_Instantiation loop Next (Inst); end loop; @@ -9041,6 +9256,32 @@ package body Sem_Ch12 is return False; end Has_Been_Exchanged; + ------------------- + -- Has_Contracts -- + ------------------- + + function Has_Contracts (Decl : Node_Id) return Boolean is + A_List : constant List_Id := Aspect_Specifications (Decl); + A_Spec : Node_Id; + A_Id : Aspect_Id; + begin + if No (A_List) then + return False; + else + A_Spec := First (A_List); + while Present (A_Spec) loop + A_Id := Get_Aspect_Id (A_Spec); + if A_Id = Aspect_Pre or else A_Id = Aspect_Post then + return True; + end if; + + Next (A_Spec); + end loop; + + return False; + end if; + end Has_Contracts; + ---------- -- Hash -- ---------- @@ -9279,7 +9520,7 @@ package body Sem_Ch12 is while Present (P) and then Nkind (Parent (P)) /= N_Compilation_Unit loop - if Nkind_In (P, N_Package_Body, N_Subprogram_Body) then + if Nkind (P) in N_Package_Body | N_Subprogram_Body then if Nkind (Parent (P)) = N_Subunit then return Corresponding_Stub (Parent (P)); else @@ -9377,8 +9618,8 @@ package body Sem_Ch12 is -- the current scope as well. elsif Present (Next (N)) - and then Nkind_In (Next (N), N_Subprogram_Body, - N_Package_Body) + and then Nkind (Next (N)) in N_Subprogram_Body + | N_Package_Body and then Comes_From_Source (Next (N)) then null; @@ -9592,8 +9833,8 @@ package body Sem_Ch12 is Must_Delay := (Gen_Unit = Act_Unit - and then (Nkind_In (Gen_Unit, N_Generic_Package_Declaration, - N_Package_Declaration) + and then (Nkind (Gen_Unit) in N_Generic_Package_Declaration + | N_Package_Declaration or else (Gen_Unit = Body_Unit and then True_Sloc (N, Act_Unit) < Sloc (Orig_Body))) @@ -9664,7 +9905,7 @@ package body Sem_Ch12 is -- Freeze package enclosing instance of inner generic after -- instance of enclosing generic. - elsif Nkind_In (Parent (N), N_Package_Body, N_Subprogram_Body) + elsif Nkind (Parent (N)) in N_Package_Body | N_Subprogram_Body and then In_Same_Declarative_Part (Parent (Freeze_Node (Par)), Parent (N)) then @@ -10168,7 +10409,9 @@ package body Sem_Ch12 is => Formal_Ent := Defining_Identifier (F); - while Chars (Act) /= Chars (Formal_Ent) loop + while Present (Act) + and then Chars (Act) /= Chars (Formal_Ent) + loop Next_Entity (Act); end loop; @@ -10179,7 +10422,9 @@ package body Sem_Ch12 is => Formal_Ent := Defining_Entity (F); - while Chars (Act) /= Chars (Formal_Ent) loop + while Present (Act) + and then Chars (Act) /= Chars (Formal_Ent) + loop Next_Entity (Act); end loop; @@ -10364,7 +10609,7 @@ package body Sem_Ch12 is -- such as a parent generic within the body of a generic child. if not Is_Entity_Name (Actual) - or else not Ekind_In (Entity (Actual), E_Generic_Package, E_Package) + or else not Is_Package_Or_Generic_Package (Entity (Actual)) then Error_Msg_N ("expect package instance to instantiate formal", Actual); @@ -10663,10 +10908,10 @@ package body Sem_Ch12 is end if; if (Present (Act_E) and then Is_Overloadable (Act_E)) - or else Nkind_In (Act, N_Attribute_Reference, - N_Indexed_Component, - N_Character_Literal, - N_Explicit_Dereference) + or else Nkind (Act) in N_Attribute_Reference + | N_Indexed_Component + | N_Character_Literal + | N_Explicit_Dereference then return; end if; @@ -10699,7 +10944,23 @@ package body Sem_Ch12 is -- Create new entity for the actual (New_Copy_Tree does not), and -- indicate that it is an actual. - New_Subp := Make_Defining_Identifier (Loc, Chars (Formal_Sub)); + -- If the actual is not an entity (i.e. an attribute reference) + -- and the formal includes aspect specifications for contracts, + -- we create an internal name for the renaming declaration. The + -- constructed wrapper contains a call to the entity in the renaming. + -- This is an expansion activity, as is the wrapper creation. + + if Ada_Version >= Ada_2020 + and then Has_Contracts (Analyzed_Formal) + and then not Is_Entity_Name (Actual) + and then Expander_Active + then + New_Subp := Make_Temporary (Sloc (Actual), 'S'); + Set_Defining_Unit_Name (New_Spec, New_Subp); + else + New_Subp := Make_Defining_Identifier (Loc, Chars (Formal_Sub)); + end if; + Set_Ekind (New_Subp, Ekind (Analyzed_S)); Set_Is_Generic_Actual_Subprogram (New_Subp); Set_Defining_Unit_Name (New_Spec, New_Subp); @@ -10749,10 +11010,10 @@ package body Sem_Ch12 is Nam := Actual; elsif Present (Default_Name (Formal)) then - if not Nkind_In (Default_Name (Formal), N_Attribute_Reference, - N_Selected_Component, - N_Indexed_Component, - N_Character_Literal) + if Nkind (Default_Name (Formal)) not in N_Attribute_Reference + | N_Selected_Component + | N_Indexed_Component + | N_Character_Literal and then Present (Entity (Default_Name (Formal))) then Nam := New_Occurrence_Of (Entity (Default_Name (Formal)), Loc); @@ -10788,7 +11049,13 @@ package body Sem_Ch12 is Make_Handled_Sequence_Of_Statements (Loc, Statements => New_List (Make_Null_Statement (Loc)))); - Set_Is_Intrinsic_Subprogram (Defining_Unit_Name (New_Spec)); + -- RM 12.6 (16 2/2): The procedure has convention Intrinsic + + Set_Convention (Defining_Unit_Name (New_Spec), Convention_Intrinsic); + + -- Eliminate the calls to it when optimization is enabled + + Set_Is_Inlined (Defining_Unit_Name (New_Spec)); return Decl_Node; else @@ -10924,41 +11191,6 @@ package body Sem_Ch12 is Subt_Decl : Node_Id := Empty; Subt_Mark : Node_Id := Empty; - function Copy_Access_Def return Node_Id; - -- If formal is an anonymous access, copy access definition of formal - -- for generated object declaration. - - --------------------- - -- Copy_Access_Def -- - --------------------- - - function Copy_Access_Def return Node_Id is - begin - Def := New_Copy_Tree (Acc_Def); - - -- In addition, if formal is an access to subprogram we need to - -- generate new formals for the signature of the default, so that - -- the tree is properly formatted for ASIS use. - - if Present (Access_To_Subprogram_Definition (Acc_Def)) then - declare - Par_Spec : Node_Id; - begin - Par_Spec := - First (Parameter_Specifications - (Access_To_Subprogram_Definition (Def))); - while Present (Par_Spec) loop - Set_Defining_Identifier (Par_Spec, - Make_Defining_Identifier (Sloc (Acc_Def), - Chars => Chars (Defining_Identifier (Par_Spec)))); - Next (Par_Spec); - end loop; - end; - end if; - - return Def; - end Copy_Access_Def; - -- Start of processing for Instantiate_Object begin @@ -10990,8 +11222,9 @@ package body Sem_Ch12 is -- use the actual directly, rather than a copy, because it is not -- used further in the list of actuals, and because a copy or a use -- of relocate_node is incorrect if the instance is nested within a - -- generic. In order to simplify ASIS searches, the Generic_Parent - -- field links the declaration to the generic association. + -- generic. In order to simplify e.g. ASIS queries, the + -- Generic_Parent field links the declaration to the generic + -- association. if No (Actual) then Error_Msg_NE @@ -11103,10 +11336,8 @@ package body Sem_Ch12 is -- access type. if Ada_Version < Ada_2005 - or else Ekind (Base_Type (Ftyp)) /= - E_Anonymous_Access_Type - or else Ekind (Base_Type (Etype (Actual))) /= - E_Anonymous_Access_Type + or else not Is_Anonymous_Access_Type (Base_Type (Ftyp)) + or else not Is_Anonymous_Access_Type (Base_Type (Etype (Actual))) then Error_Msg_NE ("type of actual does not match type of&", Actual, Gen_Obj); @@ -11147,6 +11378,44 @@ package body Sem_Ch12 is Actual); end if; + -- Check actual/formal compatibility with respect to the four + -- volatility refinement aspects. + + declare + Actual_Obj : Entity_Id; + N : Node_Id := Actual; + begin + -- Similar to Sem_Util.Get_Enclosing_Object, but treat + -- pointer dereference like component selection. + loop + if Is_Entity_Name (N) then + Actual_Obj := Entity (N); + exit; + end if; + + case Nkind (N) is + when N_Indexed_Component + | N_Selected_Component + | N_Slice + | N_Explicit_Dereference + => + N := Prefix (N); + + when N_Type_Conversion => + N := Expression (N); + + when others => + Actual_Obj := Etype (N); + exit; + end case; + end loop; + + Check_Volatility_Compatibility + (Actual_Obj, A_Gen_Obj, "actual object", + "its corresponding formal object of mode in out", + Srcpos_Bearer => Actual); + end; + -- Formal in-parameter else @@ -11159,8 +11428,9 @@ package body Sem_Ch12 is if Present (Actual) then if Present (Subt_Mark) then Def := New_Copy_Tree (Subt_Mark); - else pragma Assert (Present (Acc_Def)); - Def := Copy_Access_Def; + else + pragma Assert (Present (Acc_Def)); + Def := New_Copy_Tree (Acc_Def); end if; Decl_Node := @@ -11241,8 +11511,9 @@ package body Sem_Ch12 is if Present (Subt_Mark) then Def := New_Copy (Subt_Mark); - else pragma Assert (Present (Acc_Def)); - Def := Copy_Access_Def; + else + pragma Assert (Present (Acc_Def)); + Def := New_Copy_Tree (Acc_Def); end if; Decl_Node := @@ -11299,23 +11570,32 @@ package body Sem_Ch12 is Actual_Decl := Parent (Entity (Actual)); end if; - -- Ada 2005 (AI-423): For a formal object declaration with a null - -- exclusion or an access definition that has a null exclusion: If the - -- actual matching the formal object declaration denotes a generic - -- formal object of another generic unit G, and the instantiation - -- containing the actual occurs within the body of G or within the body - -- of a generic unit declared within the declarative region of G, then - -- the declaration of the formal object of G must have a null exclusion. - -- Otherwise, the subtype of the actual matching the formal object - -- declaration shall exclude null. + -- Ada 2005 (AI-423) refined by AI12-0287: + -- For an object_renaming_declaration with a null_exclusion or an + -- access_definition that has a null_exclusion, the subtype of the + -- object_name shall exclude null. In addition, if the + -- object_renaming_declaration occurs within the body of a generic unit + -- G or within the body of a generic unit declared within the + -- declarative region of generic unit G, then: + -- * if the object_name statically denotes a generic formal object of + -- mode in out of G, then the declaration of that object shall have a + -- null_exclusion; + -- * if the object_name statically denotes a call of a generic formal + -- function of G, then the declaration of the result of that function + -- shall have a null_exclusion. if Ada_Version >= Ada_2005 and then Present (Actual_Decl) - and then Nkind_In (Actual_Decl, N_Formal_Object_Declaration, - N_Object_Declaration) + and then Nkind (Actual_Decl) in N_Formal_Object_Declaration + | N_Object_Declaration and then Nkind (Analyzed_Formal) = N_Formal_Object_Declaration and then not Has_Null_Exclusion (Actual_Decl) and then Has_Null_Exclusion (Analyzed_Formal) + and then Ekind (Defining_Identifier (Analyzed_Formal)) + = E_Generic_In_Out_Parameter + and then ((In_Generic_Scope (Entity (Actual)) + and then In_Package_Body (Scope (Entity (Actual)))) + or else not Can_Never_Be_Null (Etype (Actual))) then Error_Msg_Sloc := Sloc (Analyzed_Formal); Error_Msg_N @@ -11331,6 +11611,7 @@ package body Sem_Ch12 is and then Present (Actual) and then Is_Object_Reference (Actual) and then Is_Effectively_Volatile_Object (Actual) + and then not Is_Effectively_Volatile (A_Gen_Obj) then Error_Msg_N ("volatile object cannot act as actual in generic instantiation", @@ -11622,7 +11903,7 @@ package body Sem_Ch12 is Act_Body_Id := Make_Defining_Identifier (Sloc (Act_Decl_Id), Chars (Act_Decl_Id)); - Set_Comes_From_Source (Act_Body_Id, Comes_From_Source (Act_Decl_Id)); + Preserve_Comes_From_Source (Act_Body_Id, Act_Decl_Id); -- Some attributes of spec entity are not inherited by body entity @@ -11746,6 +12027,19 @@ package body Sem_Ch12 is end if; Restore_Hidden_Primitives (Vis_Prims_List); + + -- Restore the private views that were made visible when the body of + -- the instantiation was created. Note that, in the case where one of + -- these private views is declared in the parent, there is a nesting + -- issue with the calls to Install_Parent and Remove_Parent made in + -- between above with In_Body set to True, because these calls also + -- want to swap and restore this private view respectively. In this + -- case, the call to Install_Parent does nothing, but the call to + -- Remove_Parent does restore the private view, thus undercutting the + -- call to Restore_Private_Views. That's OK under the condition that + -- the two mechanisms swap exactly the same entities, in particular + -- the private entities dependent on the primary private entities. + Restore_Private_Views (Act_Decl_Id); -- Remove the current unit from visibility if this is an instance @@ -11989,7 +12283,7 @@ package body Sem_Ch12 is Act_Body_Id := Make_Defining_Identifier (Sloc (Act_Decl_Id), Chars (Act_Decl_Id)); - Set_Comes_From_Source (Act_Body_Id, Comes_From_Source (Act_Decl_Id)); + Preserve_Comes_From_Source (Act_Body_Id, Act_Decl_Id); Set_Defining_Unit_Name (Specification (Act_Body), Act_Body_Id); Set_Corresponding_Spec (Act_Body, Act_Decl_Id); @@ -12183,7 +12477,7 @@ package body Sem_Ch12 is Subt : Entity_Id; procedure Check_Shared_Variable_Control_Aspects; - -- Ada_2020: Verify that shared variable control aspects (RM C.6) + -- Ada 2020: Verify that shared variable control aspects (RM C.6) -- that may be specified for a formal type are obeyed by the actual. procedure Diagnose_Predicated_Actual; @@ -12214,27 +12508,40 @@ package body Sem_Ch12 is -- Check_Shared_Variable_Control_Aspects -- -------------------------------------------- - -- Ada_2020: Verify that shared variable control aspects (RM C.6) + -- Ada 2020: Verify that shared variable control aspects (RM C.6) -- that may be specified for the formal are obeyed by the actual. + -- If the formal is a derived type the aspect specifications must match. + -- NOTE: AI12-0282 implies that matching of aspects is required between + -- formal and actual in all cases, but this is too restrictive. + -- In particular it violates a language design rule: a limited private + -- indefinite formal can be matched by any actual. The current code + -- reflects an older and more permissive version of RM C.6 (12/5). procedure Check_Shared_Variable_Control_Aspects is begin if Ada_Version >= Ada_2020 then if Is_Atomic (A_Gen_T) and then not Is_Atomic (Act_T) then Error_Msg_NE - ("actual for& must be an atomic type", Actual, A_Gen_T); + ("actual for& must have Atomic aspect", Actual, A_Gen_T); + + elsif Is_Derived_Type (A_Gen_T) + and then Is_Atomic (A_Gen_T) /= Is_Atomic (Act_T) + then + Error_Msg_NE + ("actual for& has different Atomic aspect", Actual, A_Gen_T); end if; if Is_Volatile (A_Gen_T) and then not Is_Volatile (Act_T) then Error_Msg_NE - ("actual for& must be a Volatile type", Actual, A_Gen_T); - end if; + ("actual for& has different Volatile aspect", + Actual, A_Gen_T); - if - Is_Independent (A_Gen_T) and then not Is_Independent (Act_T) + elsif Is_Derived_Type (A_Gen_T) + and then Is_Volatile (A_Gen_T) /= Is_Volatile (Act_T) then Error_Msg_NE - ("actual for& must be an Independent type", Actual, A_Gen_T); + ("actual for& has different Volatile aspect", + Actual, A_Gen_T); end if; -- We assume that an array type whose atomic component type @@ -12242,44 +12549,60 @@ package body Sem_Ch12 is -- aspect Has_Atomic_Components. This is a reasonable inference -- from the intent of AI12-0282, and makes it legal to use an -- actual that does not have the identical aspect as the formal. + -- Ditto for volatile components. - if Has_Atomic_Components (A_Gen_T) - and then not Has_Atomic_Components (Act_T) - then - if Is_Array_Type (Act_T) - and then Is_Atomic (Component_Type (Act_T)) - then - null; + declare + Actual_Atomic_Comp : constant Boolean := + Has_Atomic_Components (Act_T) + or else (Is_Array_Type (Act_T) + and then Is_Atomic (Component_Type (Act_T))); + begin + if Has_Atomic_Components (A_Gen_T) /= Actual_Atomic_Comp then + Error_Msg_NE + ("formal and actual for& must agree on atomic components", + Actual, A_Gen_T); + end if; + end; - else + declare + Actual_Volatile_Comp : constant Boolean := + Has_Volatile_Components (Act_T) + or else (Is_Array_Type (Act_T) + and then Is_Volatile (Component_Type (Act_T))); + begin + if Has_Volatile_Components (A_Gen_T) /= Actual_Volatile_Comp + then Error_Msg_NE - ("actual for& must have atomic components", + ("actual for& must have volatile components", Actual, A_Gen_T); end if; + end; + + -- The following two aspects do not require exact matching, + -- but only one-way agreement. See RM C.6. + + if Is_Independent (A_Gen_T) and then not Is_Independent (Act_T) + then + Error_Msg_NE + ("actual for& must have Independent aspect specified", + Actual, A_Gen_T); end if; if Has_Independent_Components (A_Gen_T) - and then not Has_Independent_Components (Act_T) + and then not Has_Independent_Components (Act_T) then Error_Msg_NE - ("actual for& must have independent components", - Actual, A_Gen_T); + ("actual for& must have Independent_Components specified", + Actual, A_Gen_T); end if; - if Has_Volatile_Components (A_Gen_T) - and then not Has_Volatile_Components (Act_T) - then - if Is_Array_Type (Act_T) - and then Is_Volatile (Component_Type (Act_T)) - then - null; + -- Check actual/formal compatibility with respect to the four + -- volatility refinement aspects. - else - Error_Msg_NE - ("actual for& must have volatile components", - Actual, A_Gen_T); - end if; - end if; + Check_Volatility_Compatibility + (Act_T, A_Gen_T, + "actual type", "its corresponding formal type", + Srcpos_Bearer => Act_T); end if; end Check_Shared_Variable_Control_Aspects; @@ -12327,8 +12650,8 @@ package body Sem_Ch12 is Root_Type (Act_T))) or else - (Ekind_In (Gen_T, E_Anonymous_Access_Subprogram_Type, - E_Anonymous_Access_Type) + (Ekind (Gen_T) in E_Anonymous_Access_Subprogram_Type + | E_Anonymous_Access_Type and then Ekind (Act_T) = Ekind (Gen_T) and then Subtypes_Statically_Match (Designated_Type (Gen_T), Designated_Type (Act_T))); @@ -12901,8 +13224,8 @@ package body Sem_Ch12 is -- Perform atomic/volatile checks (RM C.6(12)). Note that AI05-0218-1 -- removes the second instance of the phrase "or allow pass by copy". - -- In Ada_2020 the aspect may be specified explicitly for the formal - -- regardless of whether an ancestor obeys it. + -- For Ada 2020, the aspect may be specified explicitly for the + -- formal regardless of whether an ancestor obeys it. if Is_Atomic (Act_T) and then not Is_Atomic (Ancestor) @@ -13016,8 +13339,16 @@ package body Sem_Ch12 is if not Subtypes_Statically_Compatible (Act_T, Ancestor, Formal_Derived_Matching => True) then - Error_Msg_N - ("constraint on actual is incompatible with formal", Actual); + Error_Msg_NE + ("actual for & must be statically compatible with ancestor", + Actual, Gen_T); + + if not Predicates_Compatible (Act_T, Ancestor) then + Error_Msg_N + ("\predicate on actual is not compatible with ancestor", + Actual); + end if; + Abandon_Instantiation (Actual); end if; end if; @@ -13261,17 +13592,8 @@ package body Sem_Ch12 is -- explicitly so. If not declared limited, the actual cannot be -- limited (see AI05-0087). - -- Even though this AI is a binding interpretation, we enable the - -- check only in Ada 2012 mode, because this improper construct - -- shows up in user code and in existing B-tests. - - if Is_Limited_Type (Act_T) - and then not Is_Limited_Type (A_Gen_T) - and then Ada_Version >= Ada_2012 - then - if In_Instance then - null; - else + if Is_Limited_Type (Act_T) and then not Is_Limited_Type (A_Gen_T) then + if not In_Instance then Error_Msg_NE ("actual for non-limited & cannot be a limited type", Actual, Gen_T); @@ -13280,30 +13602,25 @@ package body Sem_Ch12 is end if; end if; - -- Don't check Ada_Version here (for now) because AI12-0036 is - -- a binding interpretation; this decision may be reversed if - -- the situation turns out to be similar to that of the preceding - -- Is_Limited_Type test (see preceding comment). + -- Check for AI12-0036 declare Formal_Is_Private_Extension : constant Boolean := Nkind (Parent (A_Gen_T)) = N_Private_Extension_Declaration; Actual_Is_Tagged : constant Boolean := Is_Tagged_Type (Act_T); + begin if Actual_Is_Tagged /= Formal_Is_Private_Extension then - if In_Instance then - null; - else + if not In_Instance then if Actual_Is_Tagged then Error_Msg_NE - ("actual for & cannot be a tagged type", - Actual, Gen_T); + ("actual for & cannot be a tagged type", Actual, Gen_T); else Error_Msg_NE - ("actual for & must be a tagged type", - Actual, Gen_T); + ("actual for & must be a tagged type", Actual, Gen_T); end if; + Abandon_Instantiation (Actual); end if; end if; @@ -13696,12 +14013,11 @@ package body Sem_Ch12 is Defining_Identifier => Subt, Subtype_Indication => New_Occurrence_Of (Act_T, Loc)); - if Is_Private_Type (Act_T) then - Set_Has_Private_View (Subtype_Indication (Decl_Node)); + -- Record whether the actual is private at this point, so that + -- Check_Generic_Actuals can restore its proper view before the + -- semantic analysis of the instance. - elsif Is_Access_Type (Act_T) - and then Is_Private_Type (Designated_Type (Act_T)) - then + if Is_Private_Type (Act_T) then Set_Has_Private_View (Subtype_Indication (Decl_Node)); end if; @@ -13734,8 +14050,8 @@ package body Sem_Ch12 is Set_Generic_Parent_Type (Decl_Node, Ancestor); end if; - elsif Nkind_In (Def, N_Formal_Private_Type_Definition, - N_Formal_Incomplete_Type_Definition) + elsif Nkind (Def) in N_Formal_Private_Type_Definition + | N_Formal_Incomplete_Type_Definition then Set_Generic_Parent_Type (Decl_Node, A_Gen_T); end if; @@ -13886,8 +14202,8 @@ package body Sem_Ch12 is -- For a subprogram instantiation, omit instantiations intrinsic -- operations (Unchecked_Conversions, etc.) that have no bodies. - elsif Nkind_In (Decl, N_Function_Instantiation, - N_Procedure_Instantiation) + elsif Nkind (Decl) in N_Function_Instantiation + | N_Procedure_Instantiation and then not Is_Intrinsic_Subprogram (Entity (Name (Decl))) then Append_Elmt (Decl, Previous_Instances); @@ -13987,6 +14303,21 @@ package body Sem_Ch12 is exit; + -- If an ancestor of the generic comes from a formal package + -- there is no source for the ancestor body. This is detected + -- by examining the scope of the ancestor and its declaration. + -- The body, if any is needed, will be available when the + -- current unit (containing a formal package) is instantiated. + + elsif Nkind (True_Parent) = N_Package_Specification + and then Present (Generic_Parent (True_Parent)) + and then Nkind + (Original_Node (Unit_Declaration_Node + (Scope (Generic_Parent (True_Parent))))) + = N_Formal_Package_Declaration + then + return; + else True_Parent := Parent (True_Parent); end if; @@ -14114,10 +14445,10 @@ package body Sem_Ch12 is (Last (Visible_Declarations (Specification (Info.Act_Decl)))); begin - while Nkind_In (Decl, - N_Null_Statement, - N_Pragma, - N_Subprogram_Renaming_Declaration) + while Nkind (Decl) in + N_Null_Statement | + N_Pragma | + N_Subprogram_Renaming_Declaration loop Decl := Prev (Decl); end loop; @@ -14836,9 +15167,9 @@ package body Sem_Ch12 is -- explicitly now, in order to remain consistent with the view of the -- parent type. - if Ekind_In (Typ, E_Private_Type, - E_Limited_Private_Type, - E_Record_Type_With_Private) + if Ekind (Typ) in E_Private_Type + | E_Limited_Private_Type + | E_Record_Type_With_Private then Dep_Elmt := First_Elmt (Private_Dependents (Typ)); while Present (Dep_Elmt) loop @@ -15270,11 +15601,7 @@ package body Sem_Ch12 is -- If not a private type, nothing else to do if not Is_Private_Type (Typ) then - if Is_Array_Type (Typ) - and then Is_Private_Type (Component_Type (Typ)) - then - Set_Has_Private_View (N); - end if; + null; -- If it is a derivation of a private type in a context where no -- full view is needed, nothing to do either. @@ -15329,9 +15656,9 @@ package body Sem_Ch12 is -- preserve in this case, since the expansion will be redone in -- the instance. - if not Nkind_In (E, N_Defining_Character_Literal, - N_Defining_Identifier, - N_Defining_Operator_Symbol) + if Nkind (E) not in N_Defining_Character_Literal + | N_Defining_Identifier + | N_Defining_Operator_Symbol then Set_Associated_Node (N, Empty); Set_Etype (N, Empty); @@ -15353,38 +15680,7 @@ package body Sem_Ch12 is end if; if Is_Global (E) then - - -- If the entity is a package renaming that is the prefix of - -- an expanded name, it has been rewritten as the renamed - -- package, which is necessary semantically but complicates - -- ASIS tree traversal, so we recover the original entity to - -- expose the renaming. Take into account that the context may - -- be a nested generic, that the original node may itself have - -- an associated node that had better be an entity, and that - -- the current node is still a selected component. - - if Ekind (E) = E_Package - and then Nkind (N) = N_Selected_Component - and then Nkind (Parent (N)) = N_Expanded_Name - and then Present (Original_Node (N2)) - and then Is_Entity_Name (Original_Node (N2)) - and then Present (Entity (Original_Node (N2))) - then - if Is_Global (Entity (Original_Node (N2))) then - N2 := Original_Node (N2); - Set_Associated_Node (N, N2); - Set_Global_Type (N, N2); - - -- Renaming is local, and will be resolved in instance - - else - Set_Associated_Node (N, Empty); - Set_Etype (N, Empty); - end if; - - else - Set_Global_Type (N, N2); - end if; + Set_Global_Type (N, N2); elsif Nkind (N) = N_Op_Concat and then Is_Generic_Type (Etype (N2)) @@ -15453,7 +15749,7 @@ package body Sem_Ch12 is -- its value. Otherwise the folding will happen in any instantiation. elsif Nkind (Parent (N)) = N_Selected_Component - and then Nkind_In (Parent (N2), N_Integer_Literal, N_Real_Literal) + and then Nkind (Parent (N2)) in N_Integer_Literal | N_Real_Literal then if Present (Entity (Original_Node (Parent (N2)))) and then Is_Global (Entity (Original_Node (Parent (N2)))) @@ -15755,12 +16051,12 @@ package body Sem_Ch12 is -- global references within their aspects due to the timing of -- annotation analysis. - if Nkind_In (Nod, N_Generic_Package_Declaration, - N_Generic_Subprogram_Declaration, - N_Package_Body, - N_Package_Body_Stub, - N_Subprogram_Body, - N_Subprogram_Body_Stub) + if Nkind (Nod) in N_Generic_Package_Declaration + | N_Generic_Subprogram_Declaration + | N_Package_Body + | N_Package_Body_Stub + | N_Subprogram_Body + | N_Subprogram_Body_Stub then -- Since the capture of global references is done on the -- unanalyzed generic template, there is no information around @@ -15917,41 +16213,14 @@ package body Sem_Ch12 is -- The node did not undergo a transformation if Nkind (N) = Nkind (Get_Associated_Node (N)) then - declare - Aux_N2 : constant Node_Id := Get_Associated_Node (N); - Orig_N2_Parent : constant Node_Id := - Original_Node (Parent (Aux_N2)); - begin - -- The parent of this identifier is a selected component - -- which denotes a named number that was constant folded. - -- Preserve the original name for ASIS and link the parent - -- with its expanded name. The constant folding will be - -- repeated in the instance. - - if Nkind (Parent (N)) = N_Selected_Component - and then Nkind_In (Parent (Aux_N2), N_Integer_Literal, - N_Real_Literal) - and then Is_Entity_Name (Orig_N2_Parent) - and then Ekind (Entity (Orig_N2_Parent)) in Named_Kind - and then Is_Global (Entity (Orig_N2_Parent)) - then - N2 := Aux_N2; - Set_Associated_Node - (Parent (N), Original_Node (Parent (N2))); - - -- Common case + -- If this is a discriminant reference, always save it. + -- It is used in the instance to find the corresponding + -- discriminant positionally rather than by name. - else - -- If this is a discriminant reference, always save it. - -- It is used in the instance to find the corresponding - -- discriminant positionally rather than by name. - - Set_Original_Discriminant - (N, Original_Discriminant (Get_Associated_Node (N))); - end if; + Set_Original_Discriminant + (N, Original_Discriminant (Get_Associated_Node (N))); - Reset_Entity (N); - end; + Reset_Entity (N); -- The analysis of the generic copy transformed the identifier -- into another construct. Propagate the changes to the template. @@ -15975,8 +16244,9 @@ package body Sem_Ch12 is -- The identifier denotes a named number that was constant -- folded. Preserve the original name for ASIS and undo the -- constant folding which will be repeated in the instance. + -- Is this still needed??? - elsif Nkind_In (N2, N_Integer_Literal, N_Real_Literal) + elsif Nkind (N2) in N_Integer_Literal | N_Real_Literal and then Is_Entity_Name (Original_Node (N2)) then Set_Associated_Node (N, Original_Node (N2)); @@ -16078,16 +16348,17 @@ package body Sem_Ch12 is -- The operator was folded into a literal - elsif Nkind_In (N2, N_Integer_Literal, - N_Real_Literal, - N_String_Literal) + elsif Nkind (N2) in N_Integer_Literal + | N_Real_Literal + | N_String_Literal then if Present (Original_Node (N2)) and then Nkind (Original_Node (N2)) = Nkind (N) then -- Operation was constant-folded. Whenever possible, - -- recover semantic information from unfolded node, - -- for ASIS use. + -- recover semantic information from unfolded node. + -- This was initially done for ASIS but is apparently + -- needed also for e.g. compiling a-nbnbin.adb. Set_Associated_Node (N, Original_Node (N2)); @@ -16189,12 +16460,12 @@ package body Sem_Ch12 is -- Aggregates - elsif Nkind_In (N, N_Aggregate, N_Extension_Aggregate) then + elsif Nkind (N) in N_Aggregate | N_Extension_Aggregate then Save_References_In_Aggregate (N); -- Character literals, operator symbols - elsif Nkind_In (N, N_Character_Literal, N_Operator_Symbol) then + elsif Nkind (N) in N_Character_Literal | N_Operator_Symbol then Save_References_In_Char_Lit_Or_Op_Symbol (N); -- Defining identifiers @@ -16420,19 +16691,9 @@ package body Sem_Ch12 is end if; while Present (Priv_Elmt) loop - Priv_Sub := (Node (Priv_Elmt)); - - -- We avoid flipping the subtype if the Etype of its full view is - -- private because this would result in a malformed subtype. This - -- occurs when the Etype of the subtype full view is the full view of - -- the base type (and since the base types were just switched, the - -- subtype is pointing to the wrong view). This is currently the case - -- for tagged record types, access types (maybe more?) and needs to - -- be resolved. ??? - - if Present (Full_View (Priv_Sub)) - and then not Is_Private_Type (Etype (Full_View (Priv_Sub))) - then + Priv_Sub := Node (Priv_Elmt); + + if Present (Full_View (Priv_Sub)) then Prepend_Elmt (Full_View (Priv_Sub), Exchanged_Views); Exchange_Declarations (Priv_Sub); end if; @@ -16513,6 +16774,7 @@ package body Sem_Ch12 is OK := (Is_Fun and then Num_F = 1); when Attribute_Output + | Attribute_Put_Image | Attribute_Read | Attribute_Write => |