public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc r12-10178] Finalization of object allocated by anonymous access designating local type
@ 2024-02-26 12:23 Eric Botcazou
  0 siblings, 0 replies; only message in thread
From: Eric Botcazou @ 2024-02-26 12:23 UTC (permalink / raw)
  To: gcc-cvs

https://gcc.gnu.org/g:1a915f6ab52eff19eb3c890a127c6693c8ce4f65

commit r12-10178-g1a915f6ab52eff19eb3c890a127c6693c8ce4f65
Author: Eric Botcazou <ebotcazou@adacore.com>
Date:   Mon Feb 26 13:13:34 2024 +0100

    Finalization of object allocated by anonymous access designating local type
    
    The finalization of objects dynamically allocated through an anonymous
    access type is deferred to the enclosing library unit in the current
    implementation and a warning is given on each of them.
    
    However this cannot be done if the designated type is local, because this
    would generate dangling references to the local finalization routine, so
    the finalization needs to be dropped in this case and the warning adjusted.
    
    gcc/ada/
            PR ada/113893
            * exp_ch7.adb (Build_Anonymous_Master): Do not build the master
            for a local designated type.
            * exp_util.adb (Build_Allocate_Deallocate_Proc): Force Needs_Fin
            to false if no finalization master is attached to an access type
            and assert that it is anonymous in this case.
            * sem_res.adb (Resolve_Allocator): Mention that the object might
            not be finalized at all in the warning given when the type is an
            anonymous access-to-controlled type.
    
    gcc/testsuite/
            * gnat.dg/access10.adb: New test.

Diff:
---
 gcc/ada/exp_ch7.adb                | 13 +++++++++
 gcc/ada/exp_util.adb               | 15 ++++++----
 gcc/ada/sem_res.adb                | 14 ++++-----
 gcc/testsuite/gnat.dg/access10.adb | 58 ++++++++++++++++++++++++++++++++++++++
 4 files changed, 88 insertions(+), 12 deletions(-)

diff --git a/gcc/ada/exp_ch7.adb b/gcc/ada/exp_ch7.adb
index d7863c30b68f..a0f95403dda8 100644
--- a/gcc/ada/exp_ch7.adb
+++ b/gcc/ada/exp_ch7.adb
@@ -796,6 +796,7 @@ package body Exp_Ch7 is
       Desig_Typ : Entity_Id;
       FM_Id     : Entity_Id;
       Priv_View : Entity_Id;
+      Scop      : Entity_Id;
       Unit_Decl : Node_Id;
       Unit_Id   : Entity_Id;
 
@@ -834,6 +835,18 @@ package body Exp_Ch7 is
          Desig_Typ := Priv_View;
       end if;
 
+      --  For a designated type not declared at library level, we cannot create
+      --  a finalization collection attached to an outer unit since this would
+      --  generate dangling references to the dynamic scope through access-to-
+      --  procedure values designating the local Finalize_Address primitive.
+
+      Scop := Enclosing_Dynamic_Scope (Desig_Typ);
+      if Scop /= Standard_Standard
+        and then Scope_Depth (Scop) > Scope_Depth (Unit_Id)
+      then
+         return;
+      end if;
+
       --  Determine whether the current semantic unit already has an anonymous
       --  master which services the designated type.
 
diff --git a/gcc/ada/exp_util.adb b/gcc/ada/exp_util.adb
index 64324bfcb72c..e18b2ace44b9 100644
--- a/gcc/ada/exp_util.adb
+++ b/gcc/ada/exp_util.adb
@@ -859,6 +859,16 @@ package body Exp_Util is
         Needs_Finalization (Desig_Typ)
           and then not No_Heap_Finalization (Ptr_Typ);
 
+      --  The allocation/deallocation of a controlled object must be associated
+      --  with an attachment to/detachment from a finalization master, but the
+      --  implementation cannot guarantee this property for every anonymous
+      --  access tyoe, see Build_Anonymous_Collection.
+
+      if Needs_Fin and then No (Finalization_Master (Ptr_Typ)) then
+         pragma Assert (Ekind (Ptr_Typ) = E_Anonymous_Access_Type);
+         Needs_Fin := False;
+      end if;
+
       if Needs_Fin then
 
          --  Do nothing if the access type may never allocate / deallocate
@@ -868,11 +878,6 @@ package body Exp_Util is
             return;
          end if;
 
-         --  The allocation / deallocation of a controlled object must be
-         --  chained on / detached from a finalization master.
-
-         pragma Assert (Present (Finalization_Master (Ptr_Typ)));
-
       --  The only other kind of allocation / deallocation supported by this
       --  routine is on / from a subpool.
 
diff --git a/gcc/ada/sem_res.adb b/gcc/ada/sem_res.adb
index 4f66b7157789..09a2d8adb507 100644
--- a/gcc/ada/sem_res.adb
+++ b/gcc/ada/sem_res.adb
@@ -5691,19 +5691,19 @@ package body Sem_Res is
                Set_Is_Dynamic_Coextension (N, False);
                Set_Is_Static_Coextension  (N, False);
 
-               --  Anonymous access-to-controlled objects are not finalized on
-               --  time because this involves run-time ownership and currently
-               --  this property is not available. In rare cases the object may
-               --  not be finalized at all. Warn on potential issues involving
-               --  anonymous access-to-controlled objects.
+               --  Objects allocated through anonymous access types are not
+               --  finalized on time because this involves run-time ownership
+               --  and currently this property is not available. In rare cases
+               --  the object might not be finalized at all. Warn on potential
+               --  issues involving anonymous access-to-controlled types.
 
                if Ekind (Typ) = E_Anonymous_Access_Type
                  and then Is_Controlled_Active (Desig_T)
                then
                   Error_Msg_N
-                    ("??object designated by anonymous access object might "
+                    ("??object designated by anonymous access value might "
                      & "not be finalized until its enclosing library unit "
-                     & "goes out of scope", N);
+                     & "goes out of scope, or not be finalized at all", N);
                   Error_Msg_N ("\use named access type instead", N);
                end if;
             end if;
diff --git a/gcc/testsuite/gnat.dg/access10.adb b/gcc/testsuite/gnat.dg/access10.adb
new file mode 100644
index 000000000000..189df464eefa
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/access10.adb
@@ -0,0 +1,58 @@
+--  PR ada/113893
+--  Testcase by Pascal Pignard <p.p11@orange.fr>
+
+--  { dg-do run }
+
+with Ada.Text_IO;
+with Ada.Finalization;
+
+procedure Access10 is
+
+   generic
+      type Element_Type is private;
+      with function Image (Item : Element_Type) return String is <>;
+   package Sanitize is
+      type Container is new Ada.Finalization.Controlled with record
+         Data : Element_Type;
+      end record;
+      overriding procedure Finalize (Object : in out Container);
+   end Sanitize;
+
+   package body Sanitize is
+      overriding procedure Finalize (Object : in out Container) is
+      begin
+         Ada.Text_IO.Put_Line ("Current:" & Image (Object.Data));
+      end Finalize;
+   end Sanitize;
+
+   procedure Test01 is
+      package Float_Sanitized is new Sanitize (Float, Float'Image);
+      V  : Float_Sanitized.Container;
+      C  : constant Float_Sanitized.Container :=
+	     (Ada.Finalization.Controlled with 8.8);
+      A  : access Float_Sanitized.Container := 
+	     new Float_Sanitized.Container'(Ada.Finalization.Controlled with 7.7);  -- { dg-warning "not be finalized|named" }
+      AC : access constant Float_Sanitized.Container :=
+             new Float_Sanitized.Container'(Ada.Finalization.Controlled with 6.6);  -- { dg-warning "not be finalized|named" }
+   begin
+      V.Data := 9.9 + C.Data + A.Data;
+      Ada.Text_IO.Put_Line ("Value:" & Float'Image (V.Data));
+   end Test01;
+
+   procedure Test02 is
+      type Float_Sanitized is new Float;
+      V  : Float_Sanitized;
+      C  : constant Float_Sanitized        := (8.8);
+      A  : access Float_Sanitized          := new Float_Sanitized'(7.7);
+      AC : access constant Float_Sanitized := new Float_Sanitized'(6.6);
+   begin
+      V := 9.9 + C + A.all;
+      Ada.Text_IO.Put_Line ("Value:" & Float_Sanitized'Image (V));
+   end Test02;
+
+begin
+   Ada.Text_IO.Put_Line ("Test01:");
+   Test01;
+   Ada.Text_IO.Put_Line ("Test02:");
+   Test02;
+end;

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2024-02-26 12:23 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2024-02-26 12:23 [gcc r12-10178] Finalization of object allocated by anonymous access designating local type Eric Botcazou

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).