diff options
author | Hristian Kirtchev <kirtchev@adacore.com> | 2019-07-01 13:34:25 +0000 |
---|---|---|
committer | Pierre-Marie de Rodat <pmderodat@gcc.gnu.org> | 2019-07-01 13:34:25 +0000 |
commit | 867edb0b613898bec9128e1ecb055c3277e34dbc (patch) | |
tree | 82da28faf0e0f626407d351e1a5922e445560637 /gcc/ada | |
parent | 7b3a8d3440a387d326c7b659617fd126ff5371a6 (diff) | |
download | gcc-867edb0b613898bec9128e1ecb055c3277e34dbc.zip gcc-867edb0b613898bec9128e1ecb055c3277e34dbc.tar.gz gcc-867edb0b613898bec9128e1ecb055c3277e34dbc.tar.bz2 |
[Ada] Crash due to missing freeze nodes in transient scope
The following patch updates the freezing of expressions to insert the
generated freeze nodes prior to the expression that produced them when
the context is a transient scope within a type initialization procedure.
This ensures that the nodes are properly interleaved with respect to the
constructs that generated them.
2019-07-01 Hristian Kirtchev <kirtchev@adacore.com>
gcc/ada/
* freeze.adb (Freeze_Expression): Remove the horrible useless
name hiding of N. Insert the freeze nodes generated by the
expression prior to the expression when the nearest enclosing
scope is transient.
gcc/testsuite/
* gnat.dg/freezing1.adb, gnat.dg/freezing1.ads,
gnat.dg/freezing1_pack.adb, gnat.dg/freezing1_pack.ads: New
testcase.
From-SVN: r272854
Diffstat (limited to 'gcc/ada')
-rw-r--r-- | gcc/ada/ChangeLog | 7 | ||||
-rw-r--r-- | gcc/ada/freeze.adb | 19 |
2 files changed, 22 insertions, 4 deletions
diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog index 368e120..5d58a2c 100644 --- a/gcc/ada/ChangeLog +++ b/gcc/ada/ChangeLog @@ -1,3 +1,10 @@ +2019-07-01 Hristian Kirtchev <kirtchev@adacore.com> + + * freeze.adb (Freeze_Expression): Remove the horrible useless + name hiding of N. Insert the freeze nodes generated by the + expression prior to the expression when the nearest enclosing + scope is transient. + 2019-07-01 Pierre-Marie de Rodat <derodat@adacore.com> * doc/gnat_ugn/building_executable_programs_with_gnat.rst: Fix diff --git a/gcc/ada/freeze.adb b/gcc/ada/freeze.adb index 8e55fb8..f7e74af 100644 --- a/gcc/ada/freeze.adb +++ b/gcc/ada/freeze.adb @@ -7665,9 +7665,8 @@ package body Freeze is or else Ekind (Current_Scope) = E_Void then declare - N : constant Node_Id := Current_Scope; - Freeze_Nodes : List_Id := No_List; - Pos : Int := Scope_Stack.Last; + Freeze_Nodes : List_Id := No_List; + Pos : Int := Scope_Stack.Last; begin if Present (Desig_Typ) then @@ -7700,7 +7699,19 @@ package body Freeze is end if; if Is_Non_Empty_List (Freeze_Nodes) then - if No (Scope_Stack.Table (Pos).Pending_Freeze_Actions) then + + -- When the current scope is transient, insert the freeze nodes + -- prior to the expression that produced them. Transient scopes + -- may create additional declarations when finalizing objects + -- or managing the secondary stack. Inserting the freeze nodes + -- of those constructs prior to the scope would result in a + -- freeze-before-declaration, therefore the freeze node must + -- remain interleaved with their constructs. + + if Scope_Is_Transient then + Insert_Actions (N, Freeze_Nodes); + + elsif No (Scope_Stack.Table (Pos).Pending_Freeze_Actions) then Scope_Stack.Table (Pos).Pending_Freeze_Actions := Freeze_Nodes; else |