diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog index b16262327d83..fd56c3aae97d 100644 --- a/gcc/ada/ChangeLog +++ b/gcc/ada/ChangeLog @@ -1,3 +1,10 @@ +2018-12-11 Yannick Moy + + * sem_ch6.adb (Analyze_Subprogram_Body_Helper): Deactivate + expansion in ignored ghost subprogram body. + * sem_ch7.adb (Analyze_Package_Body_Helper): Deactivate + expansion in ignored ghost package body. + 2018-12-11 Ed Schonberg * exp_unst.adb (Register_Subprogram): A subprogram whose address diff --git a/gcc/ada/sem_ch6.adb b/gcc/ada/sem_ch6.adb index 32c45614d42a..c291fb635c38 100644 --- a/gcc/ada/sem_ch6.adb +++ b/gcc/ada/sem_ch6.adb @@ -3370,6 +3370,7 @@ package body Sem_Ch6 is Saved_GM : constant Ghost_Mode_Type := Ghost_Mode; Saved_IGR : constant Node_Id := Ignored_Ghost_Region; + Saved_EA : constant Boolean := Expander_Active; Saved_ISMP : constant Boolean := Ignore_SPARK_Mode_Pragmas_In_Instance; -- Save the Ghost and SPARK mode-related data to restore on exit @@ -3610,6 +3611,18 @@ package body Sem_Ch6 is end if; end if; + -- Deactivate expansion inside the body of ignored Ghost entities, + -- as this code will ultimately be ignored. This avoids requiring the + -- presence of run-time units which are not needed. Only do this for + -- user entities, as internally generated entitities might still need + -- to be expanded (e.g. those generated for types). + + if Present (Ignored_Ghost_Region) + and then Comes_From_Source (Body_Id) + then + Expander_Active := False; + end if; + -- Previously we scanned the body to look for nested subprograms, and -- rejected an inline directive if nested subprograms were present, -- because the back-end would generate conflicting symbols for the @@ -4588,6 +4601,10 @@ package body Sem_Ch6 is end if; <> + if Present (Ignored_Ghost_Region) then + Expander_Active := Saved_EA; + end if; + Ignore_SPARK_Mode_Pragmas_In_Instance := Saved_ISMP; Restore_Ghost_Region (Saved_GM, Saved_IGR); end Analyze_Subprogram_Body_Helper; diff --git a/gcc/ada/sem_ch7.adb b/gcc/ada/sem_ch7.adb index 50045170fde9..01c2260885f5 100644 --- a/gcc/ada/sem_ch7.adb +++ b/gcc/ada/sem_ch7.adb @@ -669,6 +669,7 @@ package body Sem_Ch7 is Saved_GM : constant Ghost_Mode_Type := Ghost_Mode; Saved_IGR : constant Node_Id := Ignored_Ghost_Region; + Saved_EA : constant Boolean := Expander_Active; Saved_ISMP : constant Boolean := Ignore_SPARK_Mode_Pragmas_In_Instance; -- Save the Ghost and SPARK mode-related data to restore on exit @@ -780,6 +781,18 @@ package body Sem_Ch7 is Mark_And_Set_Ghost_Body (N, Spec_Id); + -- Deactivate expansion inside the body of ignored Ghost entities, + -- as this code will ultimately be ignored. This avoids requiring the + -- presence of run-time units which are not needed. Only do this for + -- user entities, as internally generated entitities might still need + -- to be expanded (e.g. those generated for types). + + if Present (Ignored_Ghost_Region) + and then Comes_From_Source (Body_Id) + then + Expander_Active := False; + end if; + -- If the body completes the initial declaration of a compilation unit -- which is subject to pragma Elaboration_Checks, set the model of the -- pragma because it applies to all parts of the unit. @@ -1075,6 +1088,10 @@ package body Sem_Ch7 is end if; end if; + if Present (Ignored_Ghost_Region) then + Expander_Active := Saved_EA; + end if; + Ignore_SPARK_Mode_Pragmas_In_Instance := Saved_ISMP; Restore_Ghost_Region (Saved_GM, Saved_IGR); end Analyze_Package_Body_Helper; diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 61f1e31f9a10..b718fed5f17e 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2018-12-11 Yannick Moy + + * gnat.dg/ghost4.adb: New testcase. + 2018-12-11 Ed Schonberg * gnat.dg/iter4.adb: New testcase. diff --git a/gcc/testsuite/gnat.dg/ghost4.adb b/gcc/testsuite/gnat.dg/ghost4.adb new file mode 100644 index 000000000000..884c1e61cc5d --- /dev/null +++ b/gcc/testsuite/gnat.dg/ghost4.adb @@ -0,0 +1,15 @@ +pragma Restrictions (No_Secondary_Stack); + +procedure Ghost4 is + + procedure Dummy with Ghost is + function Slice (S : String) return String is + (S (S'First .. S'First + 3)); + + X : String := Slice ("hello"); + begin + null; + end Dummy; +begin + Dummy; +end Ghost4;