[Ada] ICE during unnesting when nested subprograms have address taken

Message ID 20200602085939.GA119880@adacore.com
State New
Headers show
  • [Ada] ICE during unnesting when nested subprograms have address taken
Related show

Commit Message

Pierre-Marie de Rodat June 2, 2020, 8:59 a.m.
When doing subprogram unnesting for GNAT-LLVM (or CCG), the compiler can
crash when it tries to access an unreachable enclosing subprogram that
contains nested subprograms that are marked reachable due to having
Access or Unchecked_Access applied to them. This is fixed by ensuring
that the subprograms enclosing such nested subprograms are marked again
as being reachable (same handling as already done in the case of nested
subprograms occurring within synchronized units).

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

2020-06-02  Gary Dismukes  <dismukes@adacore.com>


	* exp_unst.adb (Register_Subprogram): Test for Address_Taken (in
	addition to the existing test for In_Synchonized_Unit) when
	deciding whether to reset the Reachable flag on all subprograms
	enclosing the subprogram being registered.


--- gcc/ada/exp_unst.adb
+++ gcc/ada/exp_unst.adb
@@ -841,9 +841,13 @@  package body Exp_Unst is
                --  If we marked this reachable because it's in a synchronized
                --  unit, we have to mark all enclosing subprograms as reachable
-               --  as well.
+               --  as well. We do the same for subprograms with Address_Taken,
+               --  because otherwise we can run into problems with looking at
+               --  enclosing subprograms in Subps.Table due to their being
+               --  unreachable (the Subp_Index of unreachable subps is later
+               --  set to zero and their entry in Subps.Table is removed).
-               if In_Synchronized_Unit (E) then
+               if In_Synchronized_Unit (E) or else Address_Taken (E) then
                      S : Entity_Id := E;