This patch fixes two errors in the handling of extension aggregates for limited
types: Ancestor part of extension aggregate can itself be an extension aggregate
as well as a function call that is rewritten as a reference.

The following must compile quietly:

   gcc -c p2.adb
   gcc -c bugzilla.ads

---
package body P1 is
    function Create return T1 is
    begin
       return (Length => 3);
    end Create;
end P1;
---
package P1 is
    type T1 is tagged limited private;

    function Create return T1;
private
    type T1 (Length : Positive := 3) is
      tagged limited null record;
end P1;
---
with P1;
package P2 is
    type T2 is
      limited new P1.T1 with null record;

    function Create return T2;
end P2;
---
package body P2 is
    function Create return T2 is
    begin
       return (P1.Create with null record);
    end Create;
end P2;
---
with Ada.Finalization;
package Bugzilla is
   type T1 is limited new Ada.Finalization.Limited_Controlled with null record;
   type T2 is new T1 with null record;
   X : T2 := (T1 with null record);
   Z : T2 := (T1'(Ada.Finalization.Limited_Controlled with null record)
       with null record);
end Bugzilla;

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

2014-11-20  Ed Schonberg  <schonb...@adacore.com>

        * sem_aggr.adb (Valid_Limited_Ancestor): Ancestor part of
        extension aggregate can itself be an extension aggregate, as
        well as a call that is rewritten as a reference.

Index: sem_aggr.adb
===================================================================
--- sem_aggr.adb        (revision 217828)
+++ sem_aggr.adb        (working copy)
@@ -2663,12 +2663,19 @@
 
       function Valid_Limited_Ancestor (Anc : Node_Id) return Boolean is
       begin
-         if Is_Entity_Name (Anc)
-           and then Is_Type (Entity (Anc))
+         if Is_Entity_Name (Anc) and then Is_Type (Entity (Anc)) then
+            return True;
+
+         --  The ancestor must be a call or an aggregate, but a call may
+         --  have been expanded into a temporary, so check original node.
+
+         elsif Nkind_In (Anc, N_Aggregate,
+                              N_Extension_Aggregate,
+                              N_Function_Call)
          then
             return True;
 
-         elsif Nkind_In (Anc, N_Aggregate, N_Function_Call) then
+         elsif Nkind (Original_Node (Anc)) = N_Function_Call then
             return True;
 
          elsif Nkind (Anc) = N_Attribute_Reference

Reply via email to