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);
