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

commit r16-1145-gd8610fb01b7a380acdd5872f4eb080599643f903
Author: Ronan Desplanques <desplanq...@adacore.com>
Date:   Mon Jan 20 13:37:08 2025 +0100

    ada: Fix unnecessarily large allocation in New_String
    
    This patches fixes an issue where Interfaces.C.Strings.New_String
    allocates more memory than necessary when passed a string that contains
    a NUL character.
    
    gcc/ada/ChangeLog:
    
            * libgnat/i-cstrin.adb (New_String): Fix size of allocation.

Diff:
---
 gcc/ada/libgnat/i-cstrin.adb | 35 ++++++++++++++++++++++++-----------
 1 file changed, 24 insertions(+), 11 deletions(-)

diff --git a/gcc/ada/libgnat/i-cstrin.adb b/gcc/ada/libgnat/i-cstrin.adb
index 6d329254aff3..974ba3a0e8ca 100644
--- a/gcc/ada/libgnat/i-cstrin.adb
+++ b/gcc/ada/libgnat/i-cstrin.adb
@@ -153,20 +153,33 @@ is
       --  the result, and doesn't copy the string on the stack, otherwise its
       --  use is limited when used from tasks on large strings.
 
-      Result : constant chars_ptr := Memory_Alloc (Str'Length + 1);
+      Len : Natural := 0;
+      --  Length of the longest prefix of Str that doesn't contain NUL
 
-      Result_Array : char_array  (1 .. Str'Length + 1);
-      for Result_Array'Address use To_Address (Result);
-      pragma Import (Ada, Result_Array);
+      Result : chars_ptr;
+   begin
+      for C of Str loop
+         if C = ASCII.NUL then
+            exit;
+         end if;
+         Len := Len + 1;
+      end loop;
 
-      Count : size_t;
+      Result := Memory_Alloc (size_t (Len) + 1);
+
+      declare
+         Result_Array : char_array (1 .. size_t (Len) + 1)
+         with Address => To_Address (Result), Import, Convention => Ada;
+
+         Count : size_t;
+      begin
+         To_C
+           (Item       => Str (Str'First .. Str'First + Len - 1),
+            Target     => Result_Array,
+            Count      => Count,
+            Append_Nul => True);
+      end;
 
-   begin
-      To_C
-        (Item       => Str,
-         Target     => Result_Array,
-         Count      => Count,
-         Append_Nul => True);
       return Result;
    end New_String;

Reply via email to