From: Viljar Indus <in...@adacore.com> There are cases where we need to analyze the argument of the pragma in order to determine the ghostliness of the pragma. However during that analysis the ghost region of the pragma is not set yet so we cannot perform the ghost context checks at that moment.
This patch provides the mechanism for disabling ghost context checks and disables them for pragma arguments that determine the ghostliness of the pragma. gcc/ada/ChangeLog: * ghost.adb (Check_Ghost_Context): Avoid context checks when they are globally disabled. * sem.ads (Ghost_Context_Checks_Disabled): New flag to control whether ghost context checks are activated or not. * sem_prag.adb (Analyze_Pragma): Disable ghost context checks for pragmas that determine their ghostliness based on one of its arguments. Tested on x86_64-pc-linux-gnu, committed on master. --- gcc/ada/ghost.adb | 4 ++++ gcc/ada/sem.ads | 12 ++++++++++++ gcc/ada/sem_prag.adb | 39 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 55 insertions(+) diff --git a/gcc/ada/ghost.adb b/gcc/ada/ghost.adb index 4f1a0d9d6a46..ae20ef972c82 100644 --- a/gcc/ada/ghost.adb +++ b/gcc/ada/ghost.adb @@ -932,6 +932,10 @@ package body Ghost is -- Start of processing for Check_Ghost_Context begin + if Ghost_Context_Checks_Disabled then + return; + end if; + -- Class-wide pre/postconditions of ignored pragmas are preanalyzed -- to report errors on wrong conditions; however, ignored pragmas may -- also have references to ghost entities and we must disable checking diff --git a/gcc/ada/sem.ads b/gcc/ada/sem.ads index 611309775279..63cf1daad37d 100644 --- a/gcc/ada/sem.ads +++ b/gcc/ada/sem.ads @@ -307,6 +307,18 @@ package Sem is -- case. We could perhaps do a more accurate job and retain some of the -- warnings, but it is quite a tricky job. + Ghost_Context_Checks_Disabled : Boolean := False; + -- This flag controls whether ghost context related checks are enabled or + -- disabled. Typically they are enabled however they need to be disabled in + -- instances where the ghost region context has not been set. + -- + -- Typically this is done for pragmas where the ghostliness of the pragma + -- is determined by an entity specified as one of the arguments. In these + -- cases we need to analyze that argument before the pragma itself to + -- determine the ghostliness of the pragma. However at that point we have + -- not set the ghost region for the pragma in order to determine the ghost + -- context of the argument. + ----------------------------------- -- Handling of Check Suppression -- ----------------------------------- diff --git a/gcc/ada/sem_prag.adb b/gcc/ada/sem_prag.adb index 661d4401d7a2..00c9b17ff6ee 100644 --- a/gcc/ada/sem_prag.adb +++ b/gcc/ada/sem_prag.adb @@ -6439,7 +6439,14 @@ package body Sem_Prag is end if; end if; + -- We are going to check the entity that determines the ghost + -- region of that pragma. We need to disable the checks for ghost + -- context since the ghost region can only be set after analyzing + -- this entity. + + Ghost_Context_Checks_Disabled := True; Analyze (Argx); + Ghost_Context_Checks_Disabled := False; if Nkind (Argx) not in N_Direct_Name and then (Nkind (Argx) /= N_Attribute_Reference @@ -9221,8 +9228,15 @@ package body Sem_Prag is Check_Optional_Identifier (Arg2, Name_Entity); Check_Arg_Is_Local_Name (Arg2); + -- We are going to check the entity that determines the ghost + -- region of that pragma. We need to disable the checks for ghost + -- context since the ghost region can only be set after analyzing + -- this entity. + + Ghost_Context_Checks_Disabled := True; Id := Get_Pragma_Arg (Arg2); Analyze (Id); + Ghost_Context_Checks_Disabled := False; if not Is_Entity_Name (Id) then Error_Pragma_Arg ("entity name required", Arg2); @@ -12022,7 +12036,15 @@ package body Sem_Prag is Check_Optional_Identifier (Arg2, Name_On); E_Id := Get_Pragma_Arg (Arg2); + + -- We are going to check the entity that determines the ghost + -- region of that pragma. We need to disable the checks for ghost + -- context since the ghost region can only be set after analyzing + -- this entity. + + Ghost_Context_Checks_Disabled := True; Analyze (E_Id); + Ghost_Context_Checks_Disabled := False; if not Is_Entity_Name (E_Id) then Error_Pragma_Arg @@ -15041,6 +15063,7 @@ package body Sem_Prag is Check_Ada_83_Warning; Check_No_Identifiers; Check_Arg_Count (1); + Check_Arg_Is_Local_Name (Arg1); if Debug_Flag_U then @@ -15048,8 +15071,16 @@ package body Sem_Prag is end if; C_Ent := Cunit_Entity (Current_Sem_Unit); + + -- We are going to check the entity that determines the ghost + -- region of that pragma. We need to disable the checks for ghost + -- context since the ghost region can only be set after analyzing + -- this entity. + + Ghost_Context_Checks_Disabled := True; Analyze (Get_Pragma_Arg (Arg1)); Nm := Entity (Get_Pragma_Arg (Arg1)); + Ghost_Context_Checks_Disabled := False; -- A pragma that applies to a Ghost entity becomes Ghost for the -- purposes of legality checks and removal of ignored Ghost code. @@ -22359,7 +22390,15 @@ package body Sem_Prag is while Present (Arg) loop Check_Arg_Is_Local_Name (Arg); Id := Get_Pragma_Arg (Arg); + + -- We are going to check the entity that determines the ghost + -- region of that pragma. We need to disable the checks for + -- ghost context since the ghost region can only be set after + -- analyzing this entity. + + Ghost_Context_Checks_Disabled := True; Analyze (Id); + Ghost_Context_Checks_Disabled := False; if not Is_Entity_Name (Id) then Error_Pragma_Arg ("entity name required", Arg); -- 2.43.0