* [Ada] Crash on actual that is an instance of a generic child unit
@ 2017-10-09 15:18 Pierre-Marie de Rodat
0 siblings, 0 replies; only message in thread
From: Pierre-Marie de Rodat @ 2017-10-09 15:18 UTC (permalink / raw)
To: gcc-patches; +Cc: Ed Schonberg
[-- Attachment #1: Type: text/plain, Size: 2159 bytes --]
This patch fixes a compiler abort on an instantiation where the actual for
a formal package is an instantiation of a generic child unit. An instantiation
freezes its actuals, and in the case of formal packages whose instance
includes a body the back-end needs an explicit freeze node for the actual.
If the generic for that actual appears within an enclosing instantiation
that instantiation must be frozen as well. Additionally, if the actual is
an instantiation of a child unit it depends on an instance of its parent
unit, and that instantiation must be frozen as well. Previously only the
first kind of dependence on a previous instantiation was handled properly.
The following must compile quietly:
gcc -c p.ads
---
with Q;
with Q.Sub1;
with Q.Sub2;
package P is
type Rec is record
null;
end record;
package My_Q is new Q (Rec);
package My_Sub1 is new My_Q.Sub1;
package My_Sub2 is new My_Q.Sub2 (My_Sub1);
end P;
---
generic
type T is private;
package Q is
pragma Elaborate_Body;
package Inner is
generic
package G is
end G;
end Inner;
end Q;
---
generic
package Q.Sub1 is
pragma Elaborate_Body;
end Q.Sub1;
---
package body Q.Sub1 is
package My_G is new Q.Inner.G;
end Q.Sub1;
---
with Q.Sub1;
generic
with package F is new Q.Sub1 (<>);
package Q.Sub2 is
end Q.Sub2;
---
with R;
package body Q is
package My_R is new R (T);
package body Inner is
package body G is
package My_H is new My_R.H;
end G;
end Inner;
end Q;
---
generic
type Message is private;
package R is
pragma Elaborate_Body;
generic
package H is
end H;
end R;
---
package body R is
type Message_P is access Message;
package body H is
Obj : constant Message_P := null;
end H;
end R;
---
Tested on x86_64-pc-linux-gnu, committed on trunk
2017-10-09 Ed Schonberg <schonberg@adacore.com>
* sem_ch12.adb (Analyze_Associations, Check_Generic_Parent): If an
actual for a formal package is an instantiation of a child unit, create
a freeze node for the instance of the parent if it appears in the same
scope and is not frozen yet.
[-- Attachment #2: difs --]
[-- Type: text/plain, Size: 5364 bytes --]
Index: sem_ch12.adb
===================================================================
--- sem_ch12.adb (revision 253546)
+++ sem_ch12.adb (working copy)
@@ -1903,7 +1903,8 @@
-- body.
Explicit_Freeze_Check : declare
- Actual : constant Entity_Id := Entity (Match);
+ Actual : constant Entity_Id := Entity (Match);
+ Gen_Par : Entity_Id;
Needs_Freezing : Boolean;
S : Entity_Id;
@@ -1912,7 +1913,11 @@
-- The actual may be an instantiation of a unit
-- declared in a previous instantiation. If that
-- one is also in the current compilation, it must
- -- itself be frozen before the actual.
+ -- itself be frozen before the actual. The actual
+ -- may be an instantiation of a generic child unit,
+ -- in which case the same applies to the instance
+ -- of the parent which must be frozen before the
+ -- actual.
-- Should this itself be recursive ???
--------------------------
@@ -1920,30 +1925,71 @@
--------------------------
procedure Check_Generic_Parent is
- Par : Entity_Id;
+ Inst : constant Node_Id :=
+ Next (Unit_Declaration_Node (Actual));
+ Par : Entity_Id;
begin
- if Nkind (Parent (Actual)) =
- N_Package_Specification
+ Par := Empty;
+
+ if Nkind (Parent (Actual)) = N_Package_Specification
then
Par := Scope (Generic_Parent (Parent (Actual)));
+ if Is_Generic_Instance (Par) then
+ null;
- if Is_Generic_Instance (Par)
- and then Scope (Par) = Current_Scope
- and then
- (No (Freeze_Node (Par))
- or else
- not Is_List_Member (Freeze_Node (Par)))
+ -- If the actual is a child generic unit, check
+ -- whether the instantiation of the parent is
+ -- also local and must also be frozen now.
+ -- We must retrieve the instance node to locate
+ -- the parent instance if any.
+
+ elsif Ekind (Par) = E_Generic_Package
+ and then Is_Child_Unit (Gen_Par)
+ and then Ekind (Scope (Gen_Par))
+ = E_Generic_Package
then
- Set_Has_Delayed_Freeze (Par);
- Append_Elmt (Par, Actuals_To_Freeze);
+ if Nkind (Inst) = N_Package_Instantiation
+ and then
+ Nkind (Name (Inst)) = N_Expanded_Name
+ then
+
+ -- Retrieve entity of psarent instance.
+
+ Par := Entity (Prefix (Name (Inst)));
+ end if;
+
+ else
+ Par := Empty;
end if;
end if;
+
+ if Present (Par)
+ and then Is_Generic_Instance (Par)
+ and then Scope (Par) = Current_Scope
+ and then
+ (No (Freeze_Node (Par))
+ or else
+ not Is_List_Member (Freeze_Node (Par)))
+ then
+ Set_Has_Delayed_Freeze (Par);
+ Append_Elmt (Par, Actuals_To_Freeze);
+ end if;
end Check_Generic_Parent;
-- Start of processing for Explicit_Freeze_Check
begin
+ if Present (Renamed_Entity (Actual)) then
+ Gen_Par :=
+ Generic_Parent (Specification (
+ Unit_Declaration_Node (
+ Renamed_Entity (Actual))));
+ else
+ Gen_Par := Generic_Parent
+ (Specification (Unit_Declaration_Node (Actual)));
+ end if;
+
if not Expander_Active
or else not Has_Completion (Actual)
or else not In_Same_Source_Unit (I_Node, Actual)
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2017-10-09 15:17 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-10-09 15:18 [Ada] Crash on actual that is an instance of a generic child unit Pierre-Marie de Rodat
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).