diff options
author | Ronan Desplanques <desplanques@adacore.com> | 2024-06-19 09:26:35 +0200 |
---|---|---|
committer | Marc Poulhiès <dkm@gcc.gnu.org> | 2024-08-01 17:14:34 +0200 |
commit | a9302802e56547ba14e8bdd7bbf667bb3a253155 (patch) | |
tree | f9a5f9e31751c517ad23d41a9c992167b1786192 /gcc/ada | |
parent | f61d9979a75b171a917ffcd03da5e4e5f62bcc50 (diff) | |
download | gcc-a9302802e56547ba14e8bdd7bbf667bb3a253155.zip gcc-a9302802e56547ba14e8bdd7bbf667bb3a253155.tar.gz gcc-a9302802e56547ba14e8bdd7bbf667bb3a253155.tar.bz2 |
ada: Allow making empty aggregates positional
This patch makes Exp_Aggr.Convert_To_Positional accepts appropriate
empty aggregates. The end goal is to remove violations of the
No_Elaboration_Code restriction in some cases of library-level array
objects.
gcc/ada/
* exp_aggr.adb (Flatten): Do not reject empty aggregates. Adjust
criterion for emitting warning about ineffective others clause.
* sem_aggr.adb (Array_Aggr_Subtype): Fix typo. Add handling of
aggregates that were converted to positional form.
(Resolve_Aggregate): Tweak criterion for transforming into a
string literal.
(Resolve_Array_Aggregate): Tweak criterion for reusing existing
bounds of aggregate.
(Retrieve_Aggregate_Bounds): New procedure.
* sem_util.adb (Has_Static_Empty_Array_Bounds): New function.
* sem_util.ads (Has_Static_Empty_Array_Bounds): Likewise.
Diffstat (limited to 'gcc/ada')
-rw-r--r-- | gcc/ada/exp_aggr.adb | 6 | ||||
-rw-r--r-- | gcc/ada/sem_aggr.adb | 53 | ||||
-rw-r--r-- | gcc/ada/sem_util.adb | 14 | ||||
-rw-r--r-- | gcc/ada/sem_util.ads | 3 |
4 files changed, 57 insertions, 19 deletions
diff --git a/gcc/ada/exp_aggr.adb b/gcc/ada/exp_aggr.adb index df22871..419a98c 100644 --- a/gcc/ada/exp_aggr.adb +++ b/gcc/ada/exp_aggr.adb @@ -4657,8 +4657,7 @@ package body Exp_Aggr is -- present we can proceed since the bounds can be obtained from the -- aggregate. - if Hiv < Lov - or else (not Compile_Time_Known_Value (Blo) and then Others_Present) + if not Compile_Time_Known_Value (Blo) and then Others_Present then return False; end if; @@ -4801,6 +4800,9 @@ package body Exp_Aggr is if Rep_Count = 0 and then Warn_On_Redundant_Constructs + -- We don't emit warnings on null arrays initialized + -- with an aggregate of the form "(others => ...)". + and then Vals'Length > 0 then Error_Msg_N ("there are no others?r?", Elmt); end if; diff --git a/gcc/ada/sem_aggr.adb b/gcc/ada/sem_aggr.adb index bc53ea9..bddfbec 100644 --- a/gcc/ada/sem_aggr.adb +++ b/gcc/ada/sem_aggr.adb @@ -468,6 +468,12 @@ package body Sem_Aggr is -- corresponding to the same dimension are static and found to differ, -- then emit a warning, and mark N as raising Constraint_Error. + procedure Retrieve_Aggregate_Bounds (This_Range : Node_Id); + -- In some cases, an appropriate list of aggregate bounds has been + -- created during resolution. Populate Aggr_Range with that list, and + -- remove the elements from the list so they can be added to another + -- list later. + ------------------------- -- Collect_Aggr_Bounds -- ------------------------- @@ -631,6 +637,24 @@ package body Sem_Aggr is end if; end Collect_Aggr_Bounds; + ------------------------------- + -- Retrieve_Aggregate_Bounds -- + ------------------------------- + + procedure Retrieve_Aggregate_Bounds (This_Range : Node_Id) is + R : Node_Id := This_Range; + begin + for J in 1 .. Aggr_Dimension loop + Aggr_Range (J) := R; + Next_Index (R); + + -- Remove bounds from the list, so they can be reattached as + -- the First_Index/Next_Index again. + + Remove (Aggr_Range (J)); + end loop; + end Retrieve_Aggregate_Bounds; + -- Array_Aggr_Subtype variables Itype : Entity_Id; @@ -655,25 +679,17 @@ package body Sem_Aggr is Set_Parent (Index_Constraints, N); + if Is_Rewrite_Substitution (N) + and then Present (Component_Associations (Original_Node (N))) + then + Retrieve_Aggregate_Bounds (First_Index (Etype (Original_Node (N)))); + -- When resolving a null aggregate we created a list of aggregate bounds -- for the consecutive dimensions. The bounds for the first dimension -- are attached as the Aggregate_Bounds of the aggregate node. - if Is_Null_Aggregate (N) then - declare - This_Range : Node_Id := Aggregate_Bounds (N); - begin - for J in 1 .. Aggr_Dimension loop - Aggr_Range (J) := This_Range; - Next_Index (This_Range); - - -- Remove bounds from the list, so they can be reattached as - -- the First_Index/Next_Index again by the code that also - -- handles non-null aggregates. - - Remove (Aggr_Range (J)); - end loop; - end; + elsif Is_Null_Aggregate (N) then + Retrieve_Aggregate_Bounds (Aggregate_Bounds (N)); else Collect_Aggr_Bounds (N, 1); end if; @@ -1378,6 +1394,7 @@ package body Sem_Aggr is and then Is_OK_Static_Subtype (Component_Type (Typ)) and then Base_Type (Etype (First_Index (Typ))) = Base_Type (Standard_Integer) + and then not Has_Static_Empty_Array_Bounds (Typ) then declare Expr : Node_Id; @@ -3595,10 +3612,12 @@ package body Sem_Aggr is -- If the aggregate already has bounds attached to it, it means this is -- a positional aggregate created as an optimization by -- Exp_Aggr.Convert_To_Positional, so we don't want to change those - -- bounds. + -- bounds, unless they depend on discriminants. If they do, we have to + -- perform analysis in the current context. if Present (Aggregate_Bounds (N)) - and then not Others_Allowed + and then No (Others_N) + and then not Depends_On_Discriminant (Aggregate_Bounds (N)) and then not Comes_From_Source (N) then Aggr_Low := Low_Bound (Aggregate_Bounds (N)); diff --git a/gcc/ada/sem_util.adb b/gcc/ada/sem_util.adb index 9d4fd74..19941ae 100644 --- a/gcc/ada/sem_util.adb +++ b/gcc/ada/sem_util.adb @@ -13250,6 +13250,20 @@ package body Sem_Util is return All_Static; end Has_Static_Array_Bounds; + ----------------------------------- + -- Has_Static_Empty_Array_Bounds -- + ----------------------------------- + + function Has_Static_Empty_Array_Bounds (Typ : Node_Id) return Boolean is + All_Static : Boolean; + Has_Empty : Boolean; + + begin + Examine_Array_Bounds (Typ, All_Static, Has_Empty); + + return Has_Empty; + end Has_Static_Empty_Array_Bounds; + --------------------------------------- -- Has_Static_Non_Empty_Array_Bounds -- --------------------------------------- diff --git a/gcc/ada/sem_util.ads b/gcc/ada/sem_util.ads index 21e90dc..eccbd43 100644 --- a/gcc/ada/sem_util.ads +++ b/gcc/ada/sem_util.ads @@ -1531,6 +1531,9 @@ package Sem_Util is function Has_Static_Array_Bounds (Typ : Node_Id) return Boolean; -- Return whether an array type has static bounds + function Has_Static_Empty_Array_Bounds (Typ : Node_Id) return Boolean; + -- Return whether array type Typ has static empty bounds + function Has_Static_Non_Empty_Array_Bounds (Typ : Node_Id) return Boolean; -- Determine whether array type Typ has static non-empty bounds |