https://gcc.gnu.org/g:7c7a8d60881fb727ce8ed4685bc1f484834db110
commit r15-4912-g7c7a8d60881fb727ce8ed4685bc1f484834db110 Author: Javier Miranda <mira...@adacore.com> Date: Tue Oct 15 09:32:43 2024 +0000 ada: Missing runtime check in interpolated string When the type imposed by the context for an interpolated string is constrained, the compiler silently omits adding a runtime check. gcc/ada/ChangeLog: * exp_ch2.adb (Expand_N_Interpolated_String_Literal): Use the base type of the type imposed by the context for building the interpolated string image; required to allow the expander adding the missing runtime check when the target type is constrained. (Apply_Static_Length_Check): New subprogram. Diff: --- gcc/ada/exp_ch2.adb | 72 ++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 69 insertions(+), 3 deletions(-) diff --git a/gcc/ada/exp_ch2.adb b/gcc/ada/exp_ch2.adb index 99a169475250..aacf26c51281 100644 --- a/gcc/ada/exp_ch2.adb +++ b/gcc/ada/exp_ch2.adb @@ -51,7 +51,9 @@ with Sinfo.Utils; use Sinfo.Utils; with Sinput; use Sinput; with Snames; use Snames; with Stand; +with Stringt; use Stringt; with Tbuild; use Tbuild; +with Uintp; use Uintp; package body Exp_Ch2 is @@ -721,6 +723,12 @@ package body Exp_Ch2 is procedure Expand_N_Interpolated_String_Literal (N : Node_Id) is + procedure Apply_Static_Length_Check (Typ : Entity_Id); + -- Tries to determine statically whether the length of the interpolated + -- string N exceeds the length of the target subtype Typ. If it can be + -- determined at compile time then an N_Raise_Constraint_Error node + -- replaces the interpolated string N, and a warning message is issued. + function Build_Interpolated_String_Image (N : Node_Id) return Node_Id; -- Build the following Expression_With_Actions node: -- do @@ -733,6 +741,47 @@ package body Exp_Ch2 is -- Destroy (Sink); -- in Result end + ------------------------------- + -- Apply_Static_Length_Check -- + ------------------------------- + + procedure Apply_Static_Length_Check (Typ : Entity_Id) is + HB : constant Node_Id := High_Bound (First_Index (Typ)); + LB : constant Node_Id := Low_Bound (First_Index (Typ)); + Str_Elem : Node_Id; + Str_Length : Nat; + Typ_Length : Nat; + + begin + if Compile_Time_Known_Value (LB) + and then Compile_Time_Known_Value (HB) + then + Typ_Length := UI_To_Int (Expr_Value (HB) - Expr_Value (LB) + 1); + + -- Compute the minimum length of the interpolated string: the + -- length of the concatenation of the string literals composing + -- the interpolated string. + + Str_Length := 0; + Str_Elem := First (Expressions (N)); + while Present (Str_Elem) loop + if Nkind (Str_Elem) = N_String_Literal then + Str_Length := Str_Length + String_Length (Strval (Str_Elem)); + end if; + + Next (Str_Elem); + end loop; + + if Str_Length > Typ_Length then + Apply_Compile_Time_Constraint_Error + (N, "wrong length for interpolated string of}??", + CE_Length_Check_Failed, + Ent => Typ, + Typ => Typ); + end if; + end if; + end Apply_Static_Length_Check; + ------------------------------------- -- Build_Interpolated_String_Image -- ------------------------------------- @@ -747,10 +796,11 @@ package body Exp_Ch2 is Object_Definition => New_Occurrence_Of (RTE (RE_Buffer_Type), Loc)); + B_Type : constant Entity_Id := Base_Type (Etype (N)); Get_Id : constant RE_Id := - (if Etype (N) = Stand.Standard_String then + (if B_Type = Stand.Standard_String then RE_Get - elsif Etype (N) = Stand.Standard_Wide_String then + elsif B_Type = Stand.Standard_Wide_String then RE_Wide_Get else RE_Wide_Wide_Get); @@ -760,7 +810,7 @@ package body Exp_Ch2 is Make_Object_Declaration (Loc, Defining_Identifier => Result_Entity, Object_Definition => - New_Occurrence_Of (Etype (N), Loc), + New_Occurrence_Of (B_Type, Loc), Expression => Make_Function_Call (Loc, Name => New_Occurrence_Of (RTE (Get_Id), Loc), @@ -838,8 +888,24 @@ package body Exp_Ch2 is -- Start of processing for Expand_N_Interpolated_String_Literal begin + -- If the type imposed by the context is constrained then check that + -- the statically known length of the interpolated string does not + -- exceed the length of its type. + + if Is_Constrained (Typ) then + Apply_Static_Length_Check (Typ); + + if Nkind (N) = N_Raise_Constraint_Error then + return; + end if; + end if; + Rewrite (N, Build_Interpolated_String_Image (N)); Analyze_And_Resolve (N, Typ); + + if Is_Constrained (Typ) then + Apply_Length_Check (Expression (N), Typ); + end if; end Expand_N_Interpolated_String_Literal; end Exp_Ch2;