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  <dismu...@adacore.com>

gcc/ada/

        * 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
                   declare
                      S : Entity_Id := E;
 

Reply via email to