From b09a237ab879a169416c3be1af8a773e982fd53a Mon Sep 17 00:00:00 2001 From: Javier Miranda Date: Tue, 31 Jul 2018 09:55:26 +0000 Subject: [PATCH] [Ada] Fix a freezing issue 2018-07-31 Javier Miranda gcc/ada/ * sem.ads (Inside_Preanalysis_Without_Freezing): New global counter. * sem.adb (Semantics): This subprogram has now the responsibility of resetting the counter before analyzing a unit, and restoring its previous value before returning. * freeze.adb (Freeze_Entity): Do not freeze if we are preanalyzing without freezing. * sem_res.adb (Preanalyze_And_Resolve): Set & restore In_Preanalysis_Without_Freezing. From-SVN: r263091 --- gcc/ada/ChangeLog | 12 ++++++++++++ gcc/ada/freeze.adb | 6 ++++++ gcc/ada/sem.adb | 11 +++++++++++ gcc/ada/sem.ads | 5 +++++ gcc/ada/sem_res.adb | 17 ++++++++++++++--- 5 files changed, 48 insertions(+), 3 deletions(-) diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog index ef1128ff2a7..33ff75bf2a6 100644 --- a/gcc/ada/ChangeLog +++ b/gcc/ada/ChangeLog @@ -1,3 +1,15 @@ +2018-07-31 Javier Miranda + + * sem.ads (Inside_Preanalysis_Without_Freezing): New global + counter. + * sem.adb (Semantics): This subprogram has now the + responsibility of resetting the counter before analyzing a unit, + and restoring its previous value before returning. + * freeze.adb (Freeze_Entity): Do not freeze if we are + preanalyzing without freezing. + * sem_res.adb (Preanalyze_And_Resolve): Set & restore + In_Preanalysis_Without_Freezing. + 2018-07-31 Ed Schonberg * sem_ch4.adb (Traverse_Homonyms): Consider generic actuals that diff --git a/gcc/ada/freeze.adb b/gcc/ada/freeze.adb index c0da0eb3ccb..9979cbf71e1 100644 --- a/gcc/ada/freeze.adb +++ b/gcc/ada/freeze.adb @@ -5280,6 +5280,12 @@ package body Freeze is Result := No_List; goto Leave; + -- Do not freeze if we are preanalyzing without freezing + + elsif Inside_Preanalysis_Without_Freezing > 0 then + Result := No_List; + goto Leave; + elsif Ekind (E) = E_Generic_Package then Result := Freeze_Generic_Entities (E); goto Leave; diff --git a/gcc/ada/sem.adb b/gcc/ada/sem.adb index 799d66d78ea..2415ef8f605 100644 --- a/gcc/ada/sem.adb +++ b/gcc/ada/sem.adb @@ -1447,9 +1447,18 @@ package body Sem is -- unit. All with'ed units are analyzed with config restrictions reset -- and we need to restore these saved values at the end. + Save_Preanalysis_Counter : constant Nat := + Inside_Preanalysis_Without_Freezing; + -- Saves the preanalysis nesting-level counter; required since we may + -- need to analyze a unit as a consequence of the preanalysis of an + -- expression without freezing (and the loaded unit must be fully + -- analyzed). + -- Start of processing for Semantics begin + Inside_Preanalysis_Without_Freezing := 0; + if Debug_Unit_Walk then if Already_Analyzed then Write_Str ("(done)"); @@ -1622,6 +1631,8 @@ package body Sem is Unit (Comp_Unit), Prefix => "<-- "); end if; + + Inside_Preanalysis_Without_Freezing := Save_Preanalysis_Counter; end Semantics; -------- diff --git a/gcc/ada/sem.ads b/gcc/ada/sem.ads index 0d8f41d7a07..58f3f055538 100644 --- a/gcc/ada/sem.ads +++ b/gcc/ada/sem.ads @@ -286,6 +286,11 @@ package Sem is -- freezing nodes can modify the status of this flag, any other client -- should regard it as read-only. + Inside_Preanalysis_Without_Freezing : Nat := 0; + -- Flag indicating whether we are preanalyzing an expression performing no + -- freezing. Non-zero means we are inside (it is actually a level counter + -- to deal with nested calls). + Unloaded_Subunits : Boolean := False; -- This flag is set True if we have subunits that are not loaded. This -- occurs when the main unit is a subunit, and contains lower level diff --git a/gcc/ada/sem_res.adb b/gcc/ada/sem_res.adb index 674aec4fc6b..5f9f1c3911d 100644 --- a/gcc/ada/sem_res.adb +++ b/gcc/ada/sem_res.adb @@ -1671,14 +1671,17 @@ package body Sem_Res is T : Entity_Id; With_Freezing : Boolean) is - Save_Full_Analysis : constant Boolean := Full_Analysis; - Save_Must_Not_Freeze : constant Boolean := Must_Not_Freeze (N); - + Save_Full_Analysis : constant Boolean := Full_Analysis; + Save_Must_Not_Freeze : constant Boolean := Must_Not_Freeze (N); + Save_Preanalysis_Count : constant Nat := + Inside_Preanalysis_Without_Freezing; begin pragma Assert (Nkind (N) in N_Subexpr); if not With_Freezing then Set_Must_Not_Freeze (N); + Inside_Preanalysis_Without_Freezing := + Inside_Preanalysis_Without_Freezing + 1; end if; Full_Analysis := False; @@ -1708,6 +1711,14 @@ package body Sem_Res is Expander_Mode_Restore; Full_Analysis := Save_Full_Analysis; Set_Must_Not_Freeze (N, Save_Must_Not_Freeze); + + if not With_Freezing then + Inside_Preanalysis_Without_Freezing := + Inside_Preanalysis_Without_Freezing - 1; + end if; + + pragma Assert + (Inside_Preanalysis_Without_Freezing = Save_Preanalysis_Count); end Preanalyze_And_Resolve; ---------------------------- -- 2.30.2