When resolving a slice with subtype name we created a shallow copy of
the type range and applied range checks to this copy. This was wrong,
because when applying checks we were modifying the type declaration
itself (and the type could be anything, for example the predefined
Integer type).

Instead of a shallow copy, we now create a subtype'range attribute,
analyze it and apply checks, but insert those checks into the slice
range expression node.

Tested on x86_64-pc-linux-gnu, committed on trunk

gcc/ada/

        * sem_res.adb (Resolve_Slice): Fix application of range checks
        to slice range given as a subtype name.
diff --git a/gcc/ada/sem_res.adb b/gcc/ada/sem_res.adb
--- a/gcc/ada/sem_res.adb
+++ b/gcc/ada/sem_res.adb
@@ -11347,18 +11347,19 @@ package body Sem_Res is
       then
          null;
 
-      --  The discrete_range is specified by a subtype indication. Create a
-      --  shallow copy and inherit the type, parent and source location from
-      --  the discrete_range. This ensures that the range check is inserted
-      --  relative to the slice and that the runtime exception points to the
-      --  proper construct.
+      --  The discrete_range is specified by a subtype name. Create an
+      --  equivalent range attribute, apply checks to this attribute, but
+      --  insert them into the range expression of the slice itself.
 
       elsif Is_Entity_Name (Drange) then
-         Dexpr := New_Copy (Scalar_Range (Entity (Drange)));
+         Dexpr :=
+           Make_Attribute_Reference
+             (Sloc (Drange),
+              Prefix         =>
+                New_Occurrence_Of (Entity (Drange), Sloc (Drange)),
+              Attribute_Name => Name_Range);
 
-         Set_Etype  (Dexpr, Etype  (Drange));
-         Set_Parent (Dexpr, Parent (Drange));
-         Set_Sloc   (Dexpr, Sloc   (Drange));
+         Analyze_And_Resolve (Dexpr, Etype  (Drange));
 
       elsif Nkind (Drange) = N_Subtype_Indication then
          Dexpr := Range_Expression (Constraint (Drange));
@@ -11379,7 +11380,7 @@ package body Sem_Res is
       end if;
 
       if Present (Dexpr) then
-         Apply_Range_Check (Dexpr, Index_Type);
+         Apply_Range_Check (Dexpr, Index_Type, Insert_Node => Drange);
       end if;
 
       Set_Slice_Subtype (N);


Reply via email to