[Ada] Reference in Unbounded_String is almost never null

Message ID 20211025150908.GA346506@adacore.com
State Committed
Commit 98f939e9c98403636f10168be568bb9b800aac41
Headers
Series [Ada] Reference in Unbounded_String is almost never null |

Commit Message

Pierre-Marie de Rodat Oct. 25, 2021, 3:09 p.m. UTC
  There are two variants of the Ada.Strings.Unbounded_String package, with
and without atomic reference counters. The underlying pointer is never
null in one variant (and had a null-excluding type) and almost never
null in the other variant (and now has a null-excluding type as well).

Cleanup related to sync of contracts for GNATprove between both variants
of the package.

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

gcc/ada/

	* libgnat/a-strunb.ads (Unbounded_String): Reference is never
	null.
	* libgnat/a-strunb.adb (Finalize): Copy reference while it needs
	to be deallocated.
  

Patch

diff --git a/gcc/ada/libgnat/a-strunb.adb b/gcc/ada/libgnat/a-strunb.adb
--- a/gcc/ada/libgnat/a-strunb.adb
+++ b/gcc/ada/libgnat/a-strunb.adb
@@ -505,8 +505,14 @@  package body Ada.Strings.Unbounded is
       --  Note: Don't try to free statically allocated null string
 
       if Object.Reference /= Null_String'Access then
-         Deallocate (Object.Reference);
-         Object.Reference := Null_Unbounded_String.Reference;
+         declare
+            Reference_Copy : String_Access := Object.Reference;
+            --  The original reference cannot be null, so we must create a
+            --  copy which will become null when deallocated.
+         begin
+            Deallocate (Reference_Copy);
+            Object.Reference := Null_Unbounded_String.Reference;
+         end;
          Object.Last := 0;
       end if;
    end Finalize;


diff --git a/gcc/ada/libgnat/a-strunb.ads b/gcc/ada/libgnat/a-strunb.ads
--- a/gcc/ada/libgnat/a-strunb.ads
+++ b/gcc/ada/libgnat/a-strunb.ads
@@ -746,8 +746,8 @@  private
      renames To_Unbounded_String;
 
    type Unbounded_String is new AF.Controlled with record
-      Reference : String_Access := Null_String'Access;
-      Last      : Natural       := 0;
+      Reference : not null String_Access := Null_String'Access;
+      Last      : Natural                := 0;
    end record with Put_Image => Put_Image;
 
    procedure Put_Image