[Ada] Spurious undefined symbol with nested call to expression function
authorEd Schonberg <schonberg@adacore.com>
Thu, 2 Apr 2020 20:47:17 +0000 (16:47 -0400)
committerPierre-Marie de Rodat <derodat@adacore.com>
Tue, 16 Jun 2020 13:07:11 +0000 (09:07 -0400)
2020-06-16  Ed Schonberg  <schonberg@adacore.com>

gcc/ada/

* freeze.adb: (Freeze_Expression, In_Expanded_Body): Treat the
generated body of an expression function like other bodies
generated during expansion (e.g. stream subprograms) so that
those bodies are not treated as freezing points. Handle properly
other global references in such completions.

gcc/ada/freeze.adb

index ea1274e7c77958a8deea8e61c110a27437f3f342..5c0fbee50832d2b01e479a21b06e10cace975f2f 100644 (file)
@@ -7071,8 +7071,9 @@ package body Freeze is
       function In_Expanded_Body (N : Node_Id) return Boolean;
       --  Given an N_Handled_Sequence_Of_Statements node N, determines whether
       --  it is the handled statement sequence of an expander-generated
-      --  subprogram (init proc, stream subprogram, or renaming as body).
-      --  If so, this is not a freezing context.
+      --  subprogram: init proc, stream subprogram, renaming as body, or body
+      --  created for an expression function. If so, this is not a freezing
+      --  context and the entity will be frozen at a later point.
 
       -----------------------------------------
       -- Find_Aggregate_Component_Desig_Type --
@@ -7126,6 +7127,13 @@ package body Freeze is
          if Nkind (P) /= N_Subprogram_Body then
             return False;
 
+         --  AI12-0152 : an expression function that is a completion
+         --  is a freeze point. If the body is the result of expansion
+         --  it is not.
+
+         elsif Was_Expression_Function (P) then
+            return not Comes_From_Source (P);
+
          else
             Id := Defining_Unit_Name (Specification (P));
 
@@ -7539,28 +7547,16 @@ package body Freeze is
                            end if;
                         end if;
 
-                        --  An expression function may act as a completion of
-                        --  a function declaration. As such, it can reference
-                        --  entities declared between the two views:
-
-                        --     Hidden [];                             -- 1
-                        --     function F return ...;
-                        --     private
-                        --        function Hidden return ...;
-                        --        function F return ... is (Hidden);  -- 2
-
-                        --  Refering to the example above, freezing the
-                        --  expression of F (2) would place Hidden's freeze
-                        --  node (1) in the wrong place. Avoid explicit
-                        --  freezing and let the usual scenarios do the job
-                        --  (for example, reaching the end of the private
-                        --  declarations, or a call to F.)
+                        --  If the entity is not frozen by an expression
+                        --  function that is a completion, continue climing
+                        --  the tree.
 
-                        if Nkind (Original_Node (Subp)) = N_Expression_Function
+                        if Nkind (Subp) = N_Subprogram_Body
+                          and then Was_Expression_Function (Subp)
                         then
                            null;
 
-                        --  Freeze outside the body
+                           --  Freeze outside the body
 
                         else
                            Parent_P := Parent (Parent_P);