If the subtype indication for a formal parameter carries a non null indicator,
the compiler creates an internal subtype for it. This subtype must be frozen
after its designated type, so its freezing must be delayed, but only if the
designated type is itself not frozen yet.

The following must compile quietly:

   gcc -c -gnat05 markdown.adb

---
with Dressup.Parsers.Markdown;
procedure Markdown is
   package Parsers is new Dressup.Parsers;
   package Markdown is new Parsers.Markdown;
   pragma Warnings (off, Markdown);
begin
   null;
end Markdown;
---  
package body Dressup.Parsers.Markdown is
   procedure Image_Generic
     (Renderer       : in not null Element_Renderer) --<Cause>
   is
   begin
      null;
   end Image_Generic;
   procedure Image_Standard_Instance is --<Cause>
     new Image_Generic;
end Dressup.Parsers.Markdown;
---
generic
package Dressup.Parsers.Markdown is
   generic
   procedure Image_Generic
     (Renderer       : in not null Element_Renderer);
end Dressup.Parsers.Markdown;
---
generic
package Dressup.Parsers is
end Dressup.Parsers;
---
generic
package Dressup.Renderers.Html is
   type Renderer_State is tagged null record;
end Dressup.Renderers.Html;
---
package Dressup.Renderers is
end Dressup.Renderers;
package Dressup is
   type Element_Renderer is access procedure;--<Cause>
end Dressup;

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

2012-04-26  Ed Schonberg  <schonb...@adacore.com>

        * sem_ch6.adb (Process_Formals): If the type of the formal is
        a non null access type, mark the generated subtype as having a
        delayed freeze only if the designated type is not frozen yet.

Index: sem_ch6.adb
===================================================================
--- sem_ch6.adb (revision 186860)
+++ sem_ch6.adb (working copy)
@@ -10813,15 +10813,19 @@
                        Related_Nod => Related_Nod,
                        Scope_Id    => Scope (Current_Scope));
 
-                  --  If the designated type of the itype is an itype we
-                  --  decorate it with the Has_Delayed_Freeze attribute to
-                  --  avoid problems with the backend.
+                  --  If the designated type of the itype is an itype that is
+                  --  not frozen yet, we set the Has_Delayed_Freeze attribute
+                  --  on the access subtype, to prevent order-of-elaboration
+                  --  issues in the backend.
 
                   --  Example:
                   --     type T is access procedure;
                   --     procedure Op (O : not null T);
 
-                  if Is_Itype (Directly_Designated_Type (Formal_Type)) then
+                  if Is_Itype (Directly_Designated_Type (Formal_Type))
+                    and then
+                      not Is_Frozen (Directly_Designated_Type (Formal_Type))
+                  then
                      Set_Has_Delayed_Freeze (Formal_Type);
                   end if;
                end if;

Reply via email to