From: Ronan Desplanques <desplanq...@adacore.com> Before this patch, Check_Discriminant_Use called Is_Limited type on entities before they were fully analyzed. That caused Is_Limited_Type to incorrectly return False for records that are limited because they have a limited component.
This patch pushes back the emissions of the Check_Discriminant_Use warning after analysis of record declarations. A new field to E_Record_Type entity is added to take relevant discriminant uses into account. gcc/ada/ChangeLog: * gen_il-fields.ads: New field. * gen_il-gen-gen_entities.adb: New field. * einfo.ads: Document new field. * sem_res.adb (Check_Discriminant_Use): Record relevant uses in new field. Move warning emission to... * sem_ch3.adb (Analyze_Full_Type_Declaration): ... Here. Tested on x86_64-pc-linux-gnu, committed on master. --- gcc/ada/einfo.ads | 5 +++++ gcc/ada/gen_il-fields.ads | 1 + gcc/ada/gen_il-gen-gen_entities.adb | 3 ++- gcc/ada/sem_ch3.adb | 7 +++++++ gcc/ada/sem_res.adb | 16 +++------------- 5 files changed, 18 insertions(+), 14 deletions(-) diff --git a/gcc/ada/einfo.ads b/gcc/ada/einfo.ads index f154e7f0d76..1fce2f98b8f 100644 --- a/gcc/ada/einfo.ads +++ b/gcc/ada/einfo.ads @@ -2967,6 +2967,11 @@ package Einfo is -- fully constructed, since it simply indicates the last state. -- Thus this flag has no meaning to the backend. +-- Is_Large_Unconstrained_Definite +-- Defined in record types. Used to detect types with default +-- discriminant values that have exaggerated sizes and emit warnings +-- about them. + -- Is_Limited_Composite -- Defined in all entities. Set for composite types that have a limited -- component. Used to enforce the rule that operations on the composite diff --git a/gcc/ada/gen_il-fields.ads b/gcc/ada/gen_il-fields.ads index c293e0fa63f..fe6d3387cfa 100644 --- a/gcc/ada/gen_il-fields.ads +++ b/gcc/ada/gen_il-fields.ads @@ -744,6 +744,7 @@ package Gen_IL.Fields is Is_Known_Non_Null, Is_Known_Null, Is_Known_Valid, + Is_Large_Unconstrained_Definite, Is_Limited_Composite, Is_Limited_Interface, Is_Limited_Record, diff --git a/gcc/ada/gen_il-gen-gen_entities.adb b/gcc/ada/gen_il-gen-gen_entities.adb index 37ddd851d7c..530af908530 100644 --- a/gcc/ada/gen_il-gen-gen_entities.adb +++ b/gcc/ada/gen_il-gen-gen_entities.adb @@ -781,7 +781,8 @@ begin -- Gen_IL.Gen.Gen_Entities Sm (No_Reordering, Flag, Impl_Base_Type_Only), Sm (Parent_Subtype, Node_Id, Base_Type_Only), Sm (Reverse_Bit_Order, Flag, Base_Type_Only), - Sm (Underlying_Record_View, Node_Id))); + Sm (Underlying_Record_View, Node_Id), + Sm (Is_Large_Unconstrained_Definite, Flag, Impl_Base_Type_Only))); Cc (E_Record_Subtype, Aggregate_Kind, -- A record subtype, created by a record subtype declaration diff --git a/gcc/ada/sem_ch3.adb b/gcc/ada/sem_ch3.adb index 47e7ede83e1..80359e5b68e 100644 --- a/gcc/ada/sem_ch3.adb +++ b/gcc/ada/sem_ch3.adb @@ -3553,6 +3553,13 @@ package body Sem_Ch3 is end; end if; end if; + + if Ekind (T) = E_Record_Type + and then Is_Large_Unconstrained_Definite (T) + and then not Is_Limited_Type (T) + then + Error_Msg_N ("??creation of & object may raise Storage_Error!", T); + end if; end Analyze_Full_Type_Declaration; ---------------------------------- diff --git a/gcc/ada/sem_res.adb b/gcc/ada/sem_res.adb index 865f967a5b9..1ae72fab662 100644 --- a/gcc/ada/sem_res.adb +++ b/gcc/ada/sem_res.adb @@ -757,14 +757,6 @@ package body Sem_Res is goto No_Danger; end if; - -- If the enclosing type is limited, we allocate only the - -- default value, not the maximum, and there is no need for - -- a warning. - - if Is_Limited_Type (Scope (Disc)) then - goto No_Danger; - end if; - -- Check that it is the high bound if N /= High_Bound (PN) @@ -811,11 +803,9 @@ package body Sem_Res is goto No_Danger; end if; - -- Warn about the danger - - Error_Msg_N - ("??creation of & object may raise Storage_Error!", - Scope (Disc)); + if Ekind (Scope (Disc)) = E_Record_Type then + Set_Is_Large_Unconstrained_Definite (Scope (Disc)); + end if; <<No_Danger>> null; -- 2.43.0