From: Eric Botcazou <ebotca...@adacore.com>

This flag is set in a single context, namely semantic analysis of record
type definitions, to avoid generating spurious range checks from it, and
a large testing campaign showed that, in practice, it makes a difference
in a single case, namely an access-to-constrained-array component with a
default expression, for example:

  type Acc_String is access all String (1 .. 100);

  type Rec (D : Positive) is record
    A : Acc_String := new String (1 .. D);
  end record;

Now there is another mechanism implemented in Process_Range_Expr_In_Decl to
avoid generating spurious range checks, which does not work in this specific
case but can be made to work with a small tweak to Denotes_Discriminant.

gcc/ada/ChangeLog:

        * checks.adb (Range_Checks_Suppressed): Remove test on the
        Kill_Range_Checks flag.
        * einfo.ads (Kill_Range_Checks): Delete.
        * gen_il-fields.ads (Opt_Field_Enum): Remove Kill_Range_Checks.
        * gen_il-gen-gen_entities.adb (Entity_Kind): Likewise.
        * sem_ch3.adb (Record_Type_Declaration): Do not set the
        Kill_Range_Checks flag.
        * sem_util.adb (Denotes_Discriminant): In a default expression,
        also return True for a discriminal.

Tested on x86_64-pc-linux-gnu, committed on master.

---
 gcc/ada/checks.adb                  | 13 ++++---------
 gcc/ada/einfo.ads                   |  8 --------
 gcc/ada/gen_il-fields.ads           |  1 -
 gcc/ada/gen_il-gen-gen_entities.adb |  1 -
 gcc/ada/sem_ch3.adb                 | 17 +----------------
 gcc/ada/sem_util.adb                |  6 ++++++
 6 files changed, 11 insertions(+), 35 deletions(-)

diff --git a/gcc/ada/checks.adb b/gcc/ada/checks.adb
index bc078766117..06e7997cb3f 100644
--- a/gcc/ada/checks.adb
+++ b/gcc/ada/checks.adb
@@ -9615,16 +9615,11 @@ package body Checks is
 
    function Range_Checks_Suppressed (E : Entity_Id) return Boolean is
    begin
-      if Present (E) then
-         if Kill_Range_Checks (E) then
-            return True;
-
-         elsif Checks_May_Be_Suppressed (E) then
-            return Is_Check_Suppressed (E, Range_Check);
-         end if;
+      if Present (E) and then Checks_May_Be_Suppressed (E) then
+         return Is_Check_Suppressed (E, Range_Check);
+      else
+         return Scope_Suppress.Suppress (Range_Check);
       end if;
-
-      return Scope_Suppress.Suppress (Range_Check);
    end Range_Checks_Suppressed;
 
    -----------------------------------------
diff --git a/gcc/ada/einfo.ads b/gcc/ada/einfo.ads
index f0ae45ccb59..8255ae95683 100644
--- a/gcc/ada/einfo.ads
+++ b/gcc/ada/einfo.ads
@@ -3510,13 +3510,6 @@ package Einfo is
 --       except that the effect is permanent and cannot be undone by a
 --       subsequent pragma Unsuppress.
 
---    Kill_Range_Checks
---       Defined in all entities. Equivalent in effect to the use of pragma
---       Suppress (Range_Checks) for that entity except that the result is
---       permanent and cannot be undone by a subsequent pragma Unsuppress.
---       This is currently only used in one odd situation in Sem_Ch3 for
---       record types, and it would be good to get rid of it???
-
 --    Known_To_Have_Preelab_Init
 --       Defined in all type and subtype entities. If set, then the type is
 --       known to have preelaborable initialization. In the case of a partial
@@ -4973,7 +4966,6 @@ package Einfo is
    --    Is_Unimplemented
    --    Is_Visible_Formal
    --    Kill_Elaboration_Checks
-   --    Kill_Range_Checks
    --    Low_Bound_Tested
    --    Materialize_Entity
    --    Needs_Debug_Info
diff --git a/gcc/ada/gen_il-fields.ads b/gcc/ada/gen_il-fields.ads
index 29f18a3586c..34ae14260ae 100644
--- a/gcc/ada/gen_il-fields.ads
+++ b/gcc/ada/gen_il-fields.ads
@@ -801,7 +801,6 @@ package Gen_IL.Fields is
       Is_Wrapper,
       Itype_Printed,
       Kill_Elaboration_Checks,
-      Kill_Range_Checks,
       Known_To_Have_Preelab_Init,
       Last_Aggregate_Assignment,
       Last_Assignment,
diff --git a/gcc/ada/gen_il-gen-gen_entities.adb 
b/gcc/ada/gen_il-gen-gen_entities.adb
index 4d2444ea347..f887e0c3c99 100644
--- a/gcc/ada/gen_il-gen-gen_entities.adb
+++ b/gcc/ada/gen_il-gen-gen_entities.adb
@@ -209,7 +209,6 @@ begin -- Gen_IL.Gen.Gen_Entities
         Sm (Is_Volatile_Full_Access, Flag),
         Sm (Is_Wrapper, Flag),
         Sm (Kill_Elaboration_Checks, Flag),
-        Sm (Kill_Range_Checks, Flag),
         Sm (Low_Bound_Tested, Flag),
         Sm (Materialize_Entity, Flag),
         Sm (May_Inherit_Delayed_Rep_Aspects, Flag),
diff --git a/gcc/ada/sem_ch3.adb b/gcc/ada/sem_ch3.adb
index 28fc25d0d0e..aa950692473 100644
--- a/gcc/ada/sem_ch3.adb
+++ b/gcc/ada/sem_ch3.adb
@@ -23079,22 +23079,7 @@ package body Sem_Ch3 is
          Set_Direct_Primitive_Operations (T, New_Elmt_List);
       end if;
 
-      --  We must suppress range checks when processing record components in
-      --  the presence of discriminants, since we don't want spurious checks to
-      --  be generated during their analysis, but Suppress_Range_Checks flags
-      --  must be reset the after processing the record definition.
-
-      --  Note: this is the only use of Kill_Range_Checks, and is a bit odd,
-      --  couldn't we just use the normal range check suppression method here.
-      --  That would seem cleaner ???
-
-      if Has_Discriminants (T) and then not Range_Checks_Suppressed (T) then
-         Set_Kill_Range_Checks (T, True);
-         Record_Type_Definition (Def, Prev);
-         Set_Kill_Range_Checks (T, False);
-      else
-         Record_Type_Definition (Def, Prev);
-      end if;
+      Record_Type_Definition (Def, Prev);
 
       --  Exit from record scope
 
diff --git a/gcc/ada/sem_util.adb b/gcc/ada/sem_util.adb
index 794bdedc490..25f164f8736 100644
--- a/gcc/ada/sem_util.adb
+++ b/gcc/ada/sem_util.adb
@@ -6698,12 +6698,18 @@ package body Sem_Util is
          E := Entity (N);
       end if;
 
+      --  If we are checking in a default expression, the discriminant has been
+      --  rewritten as the corresponding discriminal.
+
       --  If we are checking for a protected type, the discriminant may have
       --  been rewritten as the corresponding discriminal of the original type
       --  or of the corresponding concurrent record, depending on whether we
       --  are in the spec or body of the protected type.
 
       return Ekind (E) = E_Discriminant
+        or else (In_Default_Expr
+                  and then Ekind (E) = E_In_Parameter
+                  and then Present (Discriminal_Link (E)))
         or else
           (Check_Concurrent
             and then Ekind (E) = E_In_Parameter
-- 
2.43.0

Reply via email to