https://gcc.gnu.org/g:f9a4b558c24290665ebaf0d0c11246187c87a367

commit r17-4606-gf9a4b558c24290665ebaf0d0c11246187c87a367
Author: Eric Botcazou <[email protected]>
Date:   Wed Sep 23 11:32:21 2026 +0200

    Ada: Fix missing check with nonstatic array and string literal
    
    This makes sure that the high bound computed from the low bound and the
    length of the literal is within the range of the index type.
    
    gcc/ada/
            * sem_res.adb (Set_String_Literal_Subtype): In the nonstatic case,
            set String_Literal_Low_Bound first, and check that the actual high
            bound is not larger than the high bound of the index type.

Diff:
---
 gcc/ada/sem_res.adb | 52 +++++++++++++++++++++++++++++-----------------------
 1 file changed, 29 insertions(+), 23 deletions(-)

diff --git a/gcc/ada/sem_res.adb b/gcc/ada/sem_res.adb
index fe39ba3f9c6d..758d90cbfa5d 100644
--- a/gcc/ada/sem_res.adb
+++ b/gcc/ada/sem_res.adb
@@ -13088,6 +13088,32 @@ package body Sem_Res is
             Index_Subtype : Entity_Id;
 
          begin
+            --  The back end expects the String_Literal_Subtype to have a
+            --  static lower bound.
+
+            if Is_Integer_Type (Index_Type) then
+               Set_String_Literal_Low_Bound
+                 (Subtype_Id, Make_Integer_Literal (Loc, 1));
+
+            --  If the index type is an enumeration type, build the bound
+            --  expression by means of an attribute.
+
+            else
+               Set_String_Literal_Low_Bound
+                 (Subtype_Id,
+                  Make_Attribute_Reference (Loc,
+                    Attribute_Name => Name_First,
+                    Prefix         =>
+                      New_Occurrence_Of (Base_Type (Index_Type), Loc)));
+            end if;
+
+            Analyze_And_Resolve
+              (String_Literal_Low_Bound (Subtype_Id), Base_Type (Index_Type));
+
+            --  Now build a subtype with the actual bounds and wrap the literal
+            --  in an unchecked conversion to it, after checking that the high
+            --  bound is within the range of the index type if need be.
+
             if Length = 1 then
                High_Bound := New_Copy_Tree (Low_Bound);
 
@@ -13096,6 +13122,9 @@ package body Sem_Res is
                  Make_Op_Add (Loc,
                    Left_Opnd  => New_Copy_Tree (Low_Bound),
                    Right_Opnd => Make_Integer_Literal (Loc, Length - 1));
+               if Length > 0 then
+                  High_Bound := Convert_To (Index_Type, High_Bound);
+               end if;
 
             else
                High_Bound :=
@@ -13116,29 +13145,6 @@ package body Sem_Res is
                          Make_Integer_Literal (Loc, Length - 1))));
             end if;
 
-            if Is_Integer_Type (Index_Type) then
-               Set_String_Literal_Low_Bound
-                 (Subtype_Id, Make_Integer_Literal (Loc, 1));
-
-            else
-               --  If the index type is an enumeration type, build bounds
-               --  expression with attributes.
-
-               Set_String_Literal_Low_Bound
-                 (Subtype_Id,
-                  Make_Attribute_Reference (Loc,
-                    Attribute_Name => Name_First,
-                    Prefix         =>
-                      New_Occurrence_Of (Base_Type (Index_Type), Loc)));
-            end if;
-
-            Analyze_And_Resolve
-              (String_Literal_Low_Bound (Subtype_Id), Base_Type (Index_Type));
-
-            --  Build bona fide subtype for the string, and wrap it in an
-            --  unchecked conversion, because the back end expects the
-            --  String_Literal_Subtype to have a static lower bound.
-
             Index_Subtype :=
               Create_Itype (Subtype_Kind (Ekind (Index_Type)), N);
             Drange := Make_Range (Loc, New_Copy_Tree (Low_Bound), High_Bound);

Reply via email to