From 40016fa77fa2d0e814f9cd851c8863628c677c52 Mon Sep 17 00:00:00 2001 From: Hristian Kirtchev Date: Wed, 23 May 2018 10:21:42 +0000 Subject: [PATCH] [Ada] Initialize_Scalars optimization causes spurious runtime check failure This patch suppresses the optimization of scalar arrays when pragma Initialize_Scalars is in effect if the component type is subject to predicates. Since the scalar array is initialized with invalid values, these values may violate the predicate or a validity check within the predicate. ------------ -- Source -- ------------ -- gnat.adc pragma Initialize_Scalars; -- types.ads with System; use System; package Types is type Byte is mod System.Storage_Unit; subtype Inter_Byte is Byte; function Always_OK (B : Inter_Byte) return Boolean is (True); function Is_OK (B : Inter_Byte) return Boolean is (Always_OK (B)); subtype Final_Byte is Byte with Predicate => Is_OK (Final_Byte); type Bytes is array (1 .. 5) of Final_Byte; Obj : Bytes; end Types; -- main.adb with Types; use Types; procedure Main is begin null; end Main; ----------------- -- Compilation -- ----------------- $ gnatmake -q -gnata -gnatVa main.adb $ ./main 2018-05-23 Hristian Kirtchev gcc/ada/ * exp_ch3.adb (Default_Initialize_Object): Do not optimize scalar array initialization when the component type has predicates. * exp_ch4.adb (Expand_N_Allocator): Do not optimize scalar array allocation when the component type has predicates. From-SVN: r260572 --- gcc/ada/ChangeLog | 7 +++++++ gcc/ada/exp_ch3.adb | 42 ++++++++++++++++++++++++++++-------------- gcc/ada/exp_ch4.adb | 44 +++++++++++++++++++++++++++++--------------- 3 files changed, 64 insertions(+), 29 deletions(-) diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog index bb1e21f7082..5feb05b664b 100644 --- a/gcc/ada/ChangeLog +++ b/gcc/ada/ChangeLog @@ -1,3 +1,10 @@ +2018-05-23 Hristian Kirtchev + + * exp_ch3.adb (Default_Initialize_Object): Do not optimize scalar array + initialization when the component type has predicates. + * exp_ch4.adb (Expand_N_Allocator): Do not optimize scalar array + allocation when the component type has predicates. + 2018-05-23 Hristian Kirtchev * einfo.adb, exp_disp.adb, sem_ch3.adb, sem_ch6.adb, sem_prag.adb: diff --git a/gcc/ada/exp_ch3.adb b/gcc/ada/exp_ch3.adb index fe755e3b123..f4d2117b67d 100644 --- a/gcc/ada/exp_ch3.adb +++ b/gcc/ada/exp_ch3.adb @@ -6069,29 +6069,43 @@ package body Exp_Ch3 is null; -- Optimize the default initialization of an array object when - -- the following conditions are met: - -- - -- * Pragma Initialize_Scalars or Normalize_Scalars is in - -- effect. - -- - -- * The bounds of the array type are static and lack empty - -- ranges. - -- - -- * The array type does not contain atomic components or is - -- treated as packed. - -- - -- * The component is of a scalar type which requires simple - -- initialization. - -- + -- pragma Initialize_Scalars or Normalize_Scalars is in effect. -- Construct an in-place initialization aggregate which may be -- convert into a fast memset by the backend. elsif Init_Or_Norm_Scalars and then Is_Array_Type (Typ) + + -- The array must lack atomic components because they are + -- treated as non-static, and as a result the backend will + -- not initialize the memory in one go. + and then not Has_Atomic_Components (Typ) + + -- The array must not be packed because the invalid values + -- in System.Scalar_Values are multiples of Storage_Unit. + and then not Is_Packed (Typ) + + -- The array must have static non-empty ranges, otherwise + -- the backend cannot initialize the memory in one go. + and then Has_Static_Non_Empty_Array_Bounds (Typ) + + -- The optimization is only relevant for arrays of scalar + -- types. + and then Is_Scalar_Type (Component_Type (Typ)) + + -- Similar to regular array initialization using a type + -- init proc, predicate checks are not performed because the + -- initialization values are intentionally invalid, and may + -- violate the predicate. + + and then not Has_Predicates (Component_Type (Typ)) + + -- The component type must have a single initialization value + and then Simple_Initialization_OK (Component_Type (Typ)) then Set_No_Initialization (N, False); diff --git a/gcc/ada/exp_ch4.adb b/gcc/ada/exp_ch4.adb index 87a00826a77..3378580740e 100644 --- a/gcc/ada/exp_ch4.adb +++ b/gcc/ada/exp_ch4.adb @@ -4618,28 +4618,42 @@ package body Exp_Ch4 is Is_Allocate => True); end if; - -- Optimize the default allocation of an array object when the - -- following conditions are met: - -- - -- * Pragma Initialize_Scalars or Normalize_Scalars is in effect - -- - -- * The bounds of the array type are static and lack empty ranges - -- - -- * The array type does not contain atomic components or is - -- treated as packed. - -- - -- * The component is of a scalar type which requires simple - -- initialization. - -- - -- Construct an in-place initialization aggregate which may be - -- convert into a fast memset by the backend. + -- Optimize the default allocation of an array object when pragma + -- Initialize_Scalars or Normalize_Scalars is in effect. Construct an + -- in-place initialization aggregate which may be convert into a fast + -- memset by the backend. elsif Init_Or_Norm_Scalars and then Is_Array_Type (T) + + -- The array must lack atomic components because they are treated + -- as non-static, and as a result the backend will not initialize + -- the memory in one go. + and then not Has_Atomic_Components (T) + + -- The array must not be packed because the invalid values in + -- System.Scalar_Values are multiples of Storage_Unit. + and then not Is_Packed (T) + + -- The array must have static non-empty ranges, otherwise the + -- backend cannot initialize the memory in one go. + and then Has_Static_Non_Empty_Array_Bounds (T) + + -- The optimization is only relevant for arrays of scalar types + and then Is_Scalar_Type (Component_Type (T)) + + -- Similar to regular array initialization using a type init proc, + -- predicate checks are not performed because the initialization + -- values are intentionally invalid, and may violate the predicate. + + and then not Has_Predicates (Component_Type (T)) + + -- The component type must have a single initialization value + and then Needs_Simple_Initialization (Typ => Component_Type (T), Consider_IS => True) -- 2.30.2