diff mbox

[Ada] Freezing a subprogram does not always freeze its profile

Message ID 20160421082534.GA112576@adacore.com
State New
Headers show

Commit Message

Arnaud Charlet April 21, 2016, 8:25 a.m. UTC
AI05-019 specifies the conditions under which freezing a subprogram also
freezes the profile of the subprogram. Prior to this patch the profile was
frozen unconditionally, leading to spurious errors.

Examples in ACATS test BDD2004.

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

2016-04-21  Ed Schonberg  <schonberg@adacore.com>

	* freeze.ads, freeze.adb (Freeze_Entity, Freeze_Before): Add
	boolean parameter to determine whether freezing an overloadable
	entity freezes its profile as well. This is required by
	AI05-019. The call to Freeze_Profile within Freeze_Entity is
	conditioned by the value of this flag, whose default is True.
	* sem_attr.adb (Resolve_Attribute, case 'Access): The attribute
	reference freezes the prefix, but it the prefix is a subprogram
	it does not freeze its profile.
diff mbox

Patch

Index: freeze.adb
===================================================================
--- freeze.adb	(revision 235267)
+++ freeze.adb	(working copy)
@@ -6,7 +6,7 @@ 
 --                                                                          --
 --                                 B o d y                                  --
 --                                                                          --
---          Copyright (C) 1992-2015, Free Software Foundation, Inc.         --
+--          Copyright (C) 1992-2016, Free Software Foundation, Inc.         --
 --                                                                          --
 -- GNAT is free software;  you can  redistribute it  and/or modify it under --
 -- terms of the  GNU General Public License as published  by the Free Soft- --
@@ -1908,9 +1908,17 @@ 
    -- Freeze_Before --
    -------------------
 
-   procedure Freeze_Before (N : Node_Id; T : Entity_Id) is
-      Freeze_Nodes : constant List_Id := Freeze_Entity (T, N);
+   procedure Freeze_Before
+     (N   : Node_Id;
+      T   : Entity_Id;
+      F_P : Boolean := True)
+   is
+   --  Freeze T, then insert the generated Freeze nodes before the node N.
+   --  The flag F_P is used when T is an overloadable entity, and indicates
+   --  whether its profile should be frozen at the same time.
 
+      Freeze_Nodes : constant List_Id := Freeze_Entity (T, N, F_P);
+
    begin
       if Ekind (T) = E_Function then
          Check_Expression_Function (N, T);
@@ -1925,7 +1933,11 @@ 
    -- Freeze_Entity --
    -------------------
 
-   function Freeze_Entity (E : Entity_Id; N : Node_Id) return List_Id is
+   function Freeze_Entity
+     (E : Entity_Id;
+      N : Node_Id;
+      F_P : Boolean := True) return List_Id
+   is
       Loc    : constant Source_Ptr := Sloc (N);
       Atype  : Entity_Id;
       Comp   : Entity_Id;
@@ -4990,12 +5002,13 @@ 
 
             --  In Ada 2012, freezing a subprogram does not always freeze
             --  the corresponding profile (see AI05-019). An attribute
-            --  reference is not a freezing point of the profile.
+            --  reference is not a freezing point of the profile. The boolean
+            --  Flag F_P indicates whether the profile should be frozen now.
             --  Other constructs that should not freeze ???
 
             --  This processing doesn't apply to internal entities (see below)
 
-            if not Is_Internal (E) then
+            if not Is_Internal (E) and then F_P then
                if not Freeze_Profile (E) then
                   Ghost_Mode := Save_Ghost_Mode;
                   return Result;
Index: freeze.ads
===================================================================
--- freeze.ads	(revision 235192)
+++ freeze.ads	(working copy)
@@ -6,7 +6,7 @@ 
 --                                                                          --
 --                                 S p e c                                  --
 --                                                                          --
---          Copyright (C) 1992-2015, Free Software Foundation, Inc.         --
+--          Copyright (C) 1992-2016, Free Software Foundation, Inc.         --
 --                                                                          --
 -- GNAT is free software;  you can  redistribute it  and/or modify it under --
 -- terms of the  GNU General Public License as published  by the Free Soft- --
@@ -187,13 +187,19 @@ 
    --  If Initialization_Statements (E) is an N_Compound_Statement, insert its
    --  actions in the enclosing list and reset the attribute.
 
-   function Freeze_Entity (E : Entity_Id; N : Node_Id) return List_Id;
+   function Freeze_Entity
+     (E : Entity_Id;
+      N : Node_Id;
+      F_P : Boolean := True) return List_Id;
    --  Freeze an entity, and return Freeze nodes, to be inserted at the point
    --  of call. N is a node whose source location corresponds to the freeze
    --  point. This is used in placing warning messages in the situation where
    --  it appears that a type has been frozen too early, e.g. when a primitive
    --  operation is declared after the freezing point of its tagged type.
    --  Returns No_List if no freeze nodes needed.
+   --  The defaulted parameter F_P is used when E is a subprogram, and
+   --  determines whether the profile of the subprogram should be frozen as
+   --  well.
 
    procedure Freeze_All (From : Entity_Id; After : in out Node_Id);
    --  Before a non-instance body, or at the end of a declarative part,
@@ -209,8 +215,13 @@ 
    --  in the scope. It is used to prevent a quadratic traversal over already
    --  frozen entities.
 
-   procedure Freeze_Before (N : Node_Id; T : Entity_Id);
+   procedure Freeze_Before
+     (N   : Node_Id;
+      T   : Entity_Id;
+      F_P : Boolean := True);
    --  Freeze T then Insert the generated Freeze nodes before the node N
+   --  The flag F_P is used when T is an overloadable entity, and indicates
+   --  whether its profile should be frozen at the same time.
 
    procedure Freeze_Expression (N : Node_Id);
    --  Freezes the required entities when the Expression N causes freezing.
Index: sem_attr.adb
===================================================================
--- sem_attr.adb	(revision 235267)
+++ sem_attr.adb	(working copy)
@@ -6,7 +6,7 @@ 
 --                                                                          --
 --                                 B o d y                                  --
 --                                                                          --
---          Copyright (C) 1992-2015, Free Software Foundation, Inc.         --
+--          Copyright (C) 1992-2016, Free Software Foundation, Inc.         --
 --                                                                          --
 -- GNAT is free software;  you can  redistribute it  and/or modify it under --
 -- terms of the  GNU General Public License as published  by the Free Soft- --
@@ -10161,18 +10161,20 @@ 
                   end loop;
 
                   --  If Prefix is a subprogram name, this reference freezes,
-                  --  but not if within spec expression mode
+                  --  but not if within spec expression mode. The profile of
+                  --  the subprogram is not frozen at this point.
 
                   if not In_Spec_Expression then
-                     Freeze_Before (N, Entity (P));
+                     Freeze_Before (N, Entity (P), False);
                   end if;
 
-               --  If it is a type, there is nothing to resolve. If it is an
-               --  object, complete its resolution.
+               --  If it is a type, there is nothing to resolve.
+               --  If it is a subprogram, do not freeze its profile.
+               --  If it is an object, complete its resolution.
 
                elsif Is_Overloadable (Entity (P)) then
                   if not In_Spec_Expression then
-                     Freeze_Before (N, Entity (P));
+                     Freeze_Before (N, Entity (P), False);
                   end if;
 
                --  Nothing to do if prefix is a type name