diff options
author | Etienne Servais <servais@adacore.com> | 2021-11-15 17:32:40 +0100 |
---|---|---|
committer | Pierre-Marie de Rodat <derodat@adacore.com> | 2022-01-05 11:32:36 +0000 |
commit | e2642e2b2c13b64d3d8453bc611fee20f73aa420 (patch) | |
tree | fd429b660e9d3dc1fffd58f26548f368a72b4147 | |
parent | bfcc4dd71b5e17488c85a42db86aef433ac712fd (diff) | |
download | gcc-e2642e2b2c13b64d3d8453bc611fee20f73aa420.zip gcc-e2642e2b2c13b64d3d8453bc611fee20f73aa420.tar.gz gcc-e2642e2b2c13b64d3d8453bc611fee20f73aa420.tar.bz2 |
[Ada] Fix condition to build subtype for discriminated types
gcc/ada/
* sem_ch3.adb (Analyze_Component_Declaration): Rework condition
to build subtypes.
(Analyze_Object_Declaration): Likewise.
(Should_Build_Subtype): New.
-rw-r--r-- | gcc/ada/sem_ch3.adb | 105 |
1 files changed, 88 insertions, 17 deletions
diff --git a/gcc/ada/sem_ch3.adb b/gcc/ada/sem_ch3.adb index 6b25a6a..7fcde4d 100644 --- a/gcc/ada/sem_ch3.adb +++ b/gcc/ada/sem_ch3.adb @@ -723,6 +723,16 @@ package body Sem_Ch3 is -- sets the flags SSO_Set_Low_By_Default/SSO_Set_High_By_Default according -- to the setting of Opt.Default_SSO. + function Should_Build_Subtype (T : Entity_Id) return Boolean; + -- When analyzing components or object declarations, it is possible, in + -- some cases, to build subtypes for discriminated types. This is + -- worthwhile to avoid the backend allocating the maximum possible size for + -- objects of the type. + -- In particular, when T is limited, the discriminants and therefore the + -- size of an object of type T cannot change. Furthermore, if T is definite + -- with statically initialized defaulted discriminants, we are able and + -- want to build a constrained subtype of the right size. + procedure Signed_Integer_Type_Declaration (T : Entity_Id; Def : Node_Id); -- Create a new signed integer entity, and apply the constraint to obtain -- the required first named subtype of this type. @@ -2203,17 +2213,9 @@ package body Sem_Ch3 is end if; end if; - -- If the component is an unconstrained task or protected type with - -- discriminants, the component and the enclosing record are limited - -- and the component is constrained by its default values. Compute - -- its actual subtype, else it may be allocated the maximum size by - -- the backend, and possibly overflow. + -- When possible, build the default subtype - if Is_Concurrent_Type (T) - and then not Is_Constrained (T) - and then Has_Discriminants (T) - and then not Has_Discriminants (Current_Scope) - then + if Should_Build_Subtype (T) then declare Act_T : constant Entity_Id := Build_Default_Subtype (T, N); @@ -4799,14 +4801,9 @@ package body Sem_Ch3 is Apply_Length_Check (E, T); end if; - -- If the type is limited unconstrained with defaulted discriminants and - -- there is no expression, then the object is constrained by the - -- defaults, so it is worthwhile building the corresponding subtype. + -- When possible, build the default subtype - elsif (Is_Limited_Record (T) or else Is_Concurrent_Type (T)) - and then not Is_Constrained (T) - and then Has_Discriminants (T) - then + elsif Should_Build_Subtype (T) then if No (E) then Act_T := Build_Default_Subtype (T, N); else @@ -22879,6 +22876,80 @@ package body Sem_Ch3 is end if; end Set_Stored_Constraint_From_Discriminant_Constraint; + -------------------------- + -- Should_Build_Subtype -- + -------------------------- + + function Should_Build_Subtype (T : Entity_Id) return Boolean is + + function Default_Discriminant_Values_Known_At_Compile_Time + (T : Entity_Id) return Boolean; + -- For an unconstrained type T, return False if the given type has a + -- discriminant with default value not known at compile time. Return + -- True otherwise. + + --------------------------------------------------------- + -- Default_Discriminant_Values_Known_At_Compile_Time -- + --------------------------------------------------------- + + function Default_Discriminant_Values_Known_At_Compile_Time + (T : Entity_Id) return Boolean + is + Discr : Entity_Id; + DDV : Node_Id; + + begin + + -- If the type has no discriminant, we know them all at compile time + + if not Has_Discriminants (T) then + return True; + end if; + + -- The type has discriminants, check that none of them has a default + -- value not known at compile time. + + Discr := First_Discriminant (T); + + while Present (Discr) loop + DDV := Discriminant_Default_Value (Discr); + + if Present (DDV) and then not Compile_Time_Known_Value (DDV) then + return False; + end if; + + Next_Discriminant (Discr); + end loop; + + return True; + end Default_Discriminant_Values_Known_At_Compile_Time; + + -- Start of processing for Should_Build_Subtype + + begin + + if Is_Constrained (T) then + + -- We won't build a new subtype if T is constrained + + return False; + end if; + + if not Default_Discriminant_Values_Known_At_Compile_Time (T) then + + -- This is a special case of definite subtypes. To allocate a + -- specific size to the subtype, we need to know the value at compile + -- time. This might not be the case if the default value is the + -- result of a function. In that case, the object might be definite + -- and limited but the needed size might not be statically known or + -- too tricky to obtain. In that case, we will not build the subtype. + + return False; + end if; + + return Is_Definite_Subtype (T) and then Is_Limited_View (T); + end Should_Build_Subtype; + ------------------------------------- -- Signed_Integer_Type_Declaration -- ------------------------------------- |