From: Viljar Indus <in...@adacore.com>

Some pragmas where the ghostness is based on the argument of
the pragma triggered ghost policy errors because we had not marked
the pragmas as ghost. However we could only do so once the argument
of the pragma was analyzed.

We can safely ignore the policy checks for those pragmas since
if the argument was ghost then the pragma also had to be ghost.

Marking the pragma afterwards as ghost is only for the cleanup of
ignored ghost purposes.

gcc/ada/ChangeLog:

        * ghost.adb (Is_OK_Pragma): Use the
        Suppressed_Ghost_Policy_Check_Pragma list for ignoring certain
        pragmas.
        * sem_prag.ads (Suppressed_Ghost_Policy_Check_Pragma): New variable
        to store the pragmas that could be ignored when checking for
        consitant ghost policy.

Tested on x86_64-pc-linux-gnu, committed on master.

---
 gcc/ada/ghost.adb    |  7 +-----
 gcc/ada/sem_prag.ads | 57 ++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 58 insertions(+), 6 deletions(-)

diff --git a/gcc/ada/ghost.adb b/gcc/ada/ghost.adb
index 54153081ad5..7d8bcc2a96b 100644
--- a/gcc/ada/ghost.adb
+++ b/gcc/ada/ghost.adb
@@ -467,12 +467,7 @@ package body Ghost is
             --  not determined yet, but it is guaranteed to be Ghost when
             --  referencing a Ghost entity.
 
-            if Prag_Nam
-               in Name_Annotate
-                | Name_Compile_Time_Error
-                | Name_Compile_Time_Warning
-                | Name_Unreferenced
-            then
+            if Suppressed_Ghost_Policy_Check_Pragma (Prag_Id) then
                return True;
 
             --  An assertion expression pragma is Ghost when it contains a
diff --git a/gcc/ada/sem_prag.ads b/gcc/ada/sem_prag.ads
index 1657d6db691..49552fdd3fe 100644
--- a/gcc/ada/sem_prag.ads
+++ b/gcc/ada/sem_prag.ads
@@ -253,6 +253,63 @@ package Sem_Prag is
      (Pragma_Extensions_Visible => True,
       others                    => False);
 
+   --  List of pragmas where the ghost policy checks have been disabled.
+   --
+   --  There is an analysis circularity issue here. These pragmas are marked as
+   --  Ghost based on the ghostness of the entity in their argument. We need to
+   --  analyze the argument to determine the ghostness of the pragma. However
+   --  if we are analyzing a ghost argument we need to validate its context and
+   --  for that we need to mark the ghostness of the pragma beforehand.
+   --
+   --  We suppress the checks for these pragmas in order to break that loop. We
+   --  do not need to emit an error since if the argument was ghost that means
+   --  that the pragma was ghost as well.
+
+   Suppressed_Ghost_Policy_Check_Pragma :
+     constant array (Pragma_Id) of Boolean :=
+       (Pragma_All_Calls_Remote             => True,
+        Pragma_Annotate                     => True,
+        Pragma_Asynchronous                 => True,
+        Pragma_Atomic_Components            => True,
+        Pragma_Compile_Time_Error           => True,
+        Pragma_Compile_Time_Warning         => True,
+        Pragma_Convention                   => True,
+        Pragma_Default_Storage_Pool         => True,
+        Pragma_Discard_Names                => True,
+        Pragma_Elaborate_Body               => True,
+        Pragma_Export                       => True,
+        Pragma_Extended_Access              => True,
+        Pragma_External                     => True,
+        Pragma_Favor_Top_Level              => True,
+        Pragma_Import                       => True,
+        Pragma_Independent_Components       => True,
+        Pragma_Interface                    => True,
+        Pragma_No_Return                    => True,
+        Pragma_Obsolescent                  => True,
+        Pragma_Pack                         => True,
+        Pragma_Persistent_BSS               => True,
+        Pragma_Preelaborable_Initialization => True,
+        Pragma_Preelaborate                 => True,
+        Pragma_Pure                         => True,
+        Pragma_Pure_Function                => True,
+        Pragma_Remote_Access_Type           => True,
+        Pragma_Remote_Call_Interface        => True,
+        Pragma_Remote_Types                 => True,
+        Pragma_Shared_Passive               => True,
+        Pragma_Simple_Storage_Pool_Type     => True,
+        Pragma_Suppress                     => True,
+        Pragma_Suppress_Debug_Info          => True,
+        Pragma_Suppress_Initialization      => True,
+        Pragma_Thread_Local_Storage         => True,
+        Pragma_Unchecked_Union              => True,
+        Pragma_Universal_Aliasing           => True,
+        Pragma_Unreferenced                 => True,
+        Pragma_Unreferenced_Objects         => True,
+        Pragma_Unsuppress                   => True,
+        Pragma_Unused                       => True,
+        Pragma_Volatile_Components          => True,
+        others                              => False);
+
    function Find_Assertion_Level (Nam : Name_Id) return Entity_Id;
    --  Find an existing definition with the given name that has been inserted
    --  into the Assertion_Levels table.
-- 
2.43.0

Reply via email to