aboutsummaryrefslogtreecommitdiff
path: root/gcc/ada/sem_util.adb
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/ada/sem_util.adb')
-rw-r--r--gcc/ada/sem_util.adb192
1 files changed, 79 insertions, 113 deletions
diff --git a/gcc/ada/sem_util.adb b/gcc/ada/sem_util.adb
index 762fe48..c306e27 100644
--- a/gcc/ada/sem_util.adb
+++ b/gcc/ada/sem_util.adb
@@ -6808,13 +6808,18 @@ package body Sem_Util is
procedure Compute_Returns_By_Ref (Func : Entity_Id) is
Typ : constant Entity_Id := Etype (Func);
- Utyp : constant Entity_Id := Underlying_Type (Typ);
begin
if Is_Limited_View (Typ) then
Set_Returns_By_Ref (Func);
- elsif Present (Utyp) and then CW_Or_Has_Controlled_Part (Utyp) then
+ -- For class-wide types and types which both need finalization and are
+ -- returned on the secondary stack, the secondary stack allocation is
+ -- done by the front end, see Expand_Simple_Function_Return.
+
+ elsif Returns_On_Secondary_Stack (Typ)
+ and then CW_Or_Needs_Finalization (Underlying_Type (Typ))
+ then
Set_Returns_By_Ref (Func);
end if;
end Compute_Returns_By_Ref;
@@ -7294,14 +7299,14 @@ package body Sem_Util is
end if;
end Current_Subprogram;
- -------------------------------
- -- CW_Or_Has_Controlled_Part --
- -------------------------------
+ ------------------------------
+ -- CW_Or_Needs_Finalization --
+ ------------------------------
- function CW_Or_Has_Controlled_Part (T : Entity_Id) return Boolean is
+ function CW_Or_Needs_Finalization (Typ : Entity_Id) return Boolean is
begin
- return Is_Class_Wide_Type (T) or else Needs_Finalization (T);
- end CW_Or_Has_Controlled_Part;
+ return Is_Class_Wide_Type (Typ) or else Needs_Finalization (Typ);
+ end CW_Or_Needs_Finalization;
-------------------------------
-- Deepest_Type_Access_Level --
@@ -27301,11 +27306,61 @@ package body Sem_Util is
-- Requires_Transient_Scope --
------------------------------
- -- A transient scope is required when variable-sized temporaries are
- -- allocated on the secondary stack, or when finalization actions must be
- -- generated before the next instruction.
+ function Requires_Transient_Scope (Typ : Entity_Id) return Boolean is
+ begin
+ return Returns_On_Secondary_Stack (Typ) or else Needs_Finalization (Typ);
+ end Requires_Transient_Scope;
+
+ --------------------------
+ -- Reset_Analyzed_Flags --
+ --------------------------
+
+ procedure Reset_Analyzed_Flags (N : Node_Id) is
+ function Clear_Analyzed (N : Node_Id) return Traverse_Result;
+ -- Function used to reset Analyzed flags in tree. Note that we do
+ -- not reset Analyzed flags in entities, since there is no need to
+ -- reanalyze entities, and indeed, it is wrong to do so, since it
+ -- can result in generating auxiliary stuff more than once.
+
+ --------------------
+ -- Clear_Analyzed --
+ --------------------
+
+ function Clear_Analyzed (N : Node_Id) return Traverse_Result is
+ begin
+ if Nkind (N) not in N_Entity then
+ Set_Analyzed (N, False);
+ end if;
+
+ return OK;
+ end Clear_Analyzed;
+
+ procedure Reset_Analyzed is new Traverse_Proc (Clear_Analyzed);
+
+ -- Start of processing for Reset_Analyzed_Flags
+
+ begin
+ Reset_Analyzed (N);
+ end Reset_Analyzed_Flags;
+
+ ------------------------
+ -- Restore_SPARK_Mode --
+ ------------------------
+
+ procedure Restore_SPARK_Mode
+ (Mode : SPARK_Mode_Type;
+ Prag : Node_Id)
+ is
+ begin
+ SPARK_Mode := Mode;
+ SPARK_Mode_Pragma := Prag;
+ end Restore_SPARK_Mode;
+
+ ---------------------------------
+ -- Returns_On_Secondary_Stack --
+ ---------------------------------
- function Requires_Transient_Scope (Id : Entity_Id) return Boolean is
+ function Returns_On_Secondary_Stack (Id : Entity_Id) return Boolean is
pragma Assert (if Present (Id) then Ekind (Id) in E_Void | Type_Kind);
function Caller_Known_Size_Record (Typ : Entity_Id) return Boolean;
@@ -27318,11 +27373,6 @@ package body Sem_Util is
-- could be nested inside some other record that is constrained by
-- nondiscriminants). That is, the recursive calls are too conservative.
- procedure Ensure_Minimum_Decoration (Typ : Entity_Id);
- -- If Typ is not frozen then add to Typ the minimum decoration required
- -- by Requires_Transient_Scope to reliably provide its functionality;
- -- otherwise no action is performed.
-
function Large_Max_Size_Mutable (Typ : Entity_Id) return Boolean;
-- Returns True if Typ is a nonlimited record with defaulted
-- discriminants whose max size makes it unsuitable for allocating on
@@ -27378,46 +27428,6 @@ package body Sem_Util is
return True;
end Caller_Known_Size_Record;
- -------------------------------
- -- Ensure_Minimum_Decoration --
- -------------------------------
-
- procedure Ensure_Minimum_Decoration (Typ : Entity_Id) is
- Comp : Entity_Id;
- begin
- -- Do not set Has_Controlled_Component on a class-wide equivalent
- -- type. See Make_CW_Equivalent_Type.
-
- if not Is_Frozen (Typ)
- and then Is_Base_Type (Typ)
- and then (Is_Record_Type (Typ)
- or else Is_Concurrent_Type (Typ)
- or else Is_Incomplete_Or_Private_Type (Typ))
- and then not Is_Class_Wide_Equivalent_Type (Typ)
- then
- Comp := First_Component (Typ);
- while Present (Comp) loop
- if Has_Controlled_Component (Etype (Comp))
- or else
- (Chars (Comp) /= Name_uParent
- and then Is_Controlled (Etype (Comp)))
- or else
- (Is_Protected_Type (Etype (Comp))
- and then
- Present (Corresponding_Record_Type (Etype (Comp)))
- and then
- Has_Controlled_Component
- (Corresponding_Record_Type (Etype (Comp))))
- then
- Set_Has_Controlled_Component (Typ);
- exit;
- end if;
-
- Next_Component (Comp);
- end loop;
- end if;
- end Ensure_Minimum_Decoration;
-
------------------------------
-- Large_Max_Size_Mutable --
------------------------------
@@ -27502,7 +27512,7 @@ package body Sem_Util is
Typ : constant Entity_Id := Underlying_Type (Id);
- -- Start of processing for Requires_Transient_Scope
+ -- Start of processing for Returns_On_Secondary_Stack
begin
-- This is a private type which is not completed yet. This can only
@@ -27513,8 +27523,6 @@ package body Sem_Util is
return False;
end if;
- Ensure_Minimum_Decoration (Id);
-
-- Do not expand transient scope for non-existent procedure return or
-- string literal types.
@@ -27529,20 +27537,23 @@ package body Sem_Util is
elsif Ekind (Typ) = E_Record_Subtype
and then Present (Cloned_Subtype (Typ))
then
- return Requires_Transient_Scope (Cloned_Subtype (Typ));
+ return Returns_On_Secondary_Stack (Cloned_Subtype (Typ));
-- Functions returning specific tagged types may dispatch on result, so
-- their returned value is allocated on the secondary stack, even in the
-- definite case. We must treat nondispatching functions the same way,
-- because access-to-function types can point at both, so the calling
- -- conventions must be compatible. Is_Tagged_Type includes controlled
- -- types and class-wide types. Controlled type temporaries need
- -- finalization.
+ -- conventions must be compatible.
+
+ elsif Is_Tagged_Type (Typ) then
+ return True;
- -- ???It's not clear why we need to return noncontrolled types with
- -- controlled components on the secondary stack.
+ -- If the return slot of the back end cannot be accessed, then there
+ -- is no way to call Adjust at the right time for the return object if
+ -- the type needs finalization, so the return object must be allocated
+ -- on the secondary stack.
- elsif Is_Tagged_Type (Typ) or else Has_Controlled_Component (Typ) then
+ elsif not Back_End_Return_Slot and then Needs_Finalization (Typ) then
return True;
-- Untagged definite subtypes are known size. This includes all
@@ -27571,52 +27582,7 @@ package body Sem_Util is
pragma Assert (Is_Array_Type (Typ) and not Is_Definite_Subtype (Typ));
return True;
end if;
- end Requires_Transient_Scope;
-
- --------------------------
- -- Reset_Analyzed_Flags --
- --------------------------
-
- procedure Reset_Analyzed_Flags (N : Node_Id) is
- function Clear_Analyzed (N : Node_Id) return Traverse_Result;
- -- Function used to reset Analyzed flags in tree. Note that we do
- -- not reset Analyzed flags in entities, since there is no need to
- -- reanalyze entities, and indeed, it is wrong to do so, since it
- -- can result in generating auxiliary stuff more than once.
-
- --------------------
- -- Clear_Analyzed --
- --------------------
-
- function Clear_Analyzed (N : Node_Id) return Traverse_Result is
- begin
- if Nkind (N) not in N_Entity then
- Set_Analyzed (N, False);
- end if;
-
- return OK;
- end Clear_Analyzed;
-
- procedure Reset_Analyzed is new Traverse_Proc (Clear_Analyzed);
-
- -- Start of processing for Reset_Analyzed_Flags
-
- begin
- Reset_Analyzed (N);
- end Reset_Analyzed_Flags;
-
- ------------------------
- -- Restore_SPARK_Mode --
- ------------------------
-
- procedure Restore_SPARK_Mode
- (Mode : SPARK_Mode_Type;
- Prag : Node_Id)
- is
- begin
- SPARK_Mode := Mode;
- SPARK_Mode_Pragma := Prag;
- end Restore_SPARK_Mode;
+ end Returns_On_Secondary_Stack;
--------------------------------
-- Returns_Unconstrained_Type --