------------------------------------------------------------------------------
--                                                                          --
--                         GNAT COMPILER COMPONENTS                         --
--                                                                          --
--                               B C H E C K                                --
--                                                                          --
--                                 B o d y                                  --
--                                                                          --
--          Copyright (C) 1992-2022, Free Software Foundation, Inc.         --
--                                                                          --
-- GNAT is free software;  you can  redistribute it  and/or modify it under --
-- terms of the  GNU General Public License as published  by the Free Soft- --
-- ware  Foundation;  either version 3,  or (at your option) any later ver- --
-- sion.  GNAT is distributed in the hope that it will be useful, but WITH- --
-- OUT ANY WARRANTY;  without even the  implied warranty of MERCHANTABILITY --
-- or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License --
-- for  more details.  You should have  received  a copy of the GNU General --
-- Public License  distributed with GNAT; see file COPYING3.  If not, go to --
-- http://www.gnu.org/licenses for a complete copy of the license.          --
--                                                                          --
-- GNAT was originally developed  by the GNAT team at  New York University. --
-- Extensive contributions were provided by Ada Core Technologies Inc.      --
--                                                                          --
------------------------------------------------------------------------------

with ALI;      use ALI;
with ALI.Util; use ALI.Util;
with Binderr;  use Binderr;
with Butil;    use Butil;
with Casing;   use Casing;
with Fname;    use Fname;
with Gnatvsn;
with Namet;    use Namet;
with Opt;      use Opt;
with Osint;
with Output;   use Output;
with Rident;   use Rident;
with Types;    use Types;

package body Bcheck is

   -----------------------
   -- Local Subprograms --
   -----------------------

   --  The following checking subprograms make up the parts of the
   --  configuration consistency check. See bodies for details of checks.

   procedure Check_Consistent_Dispatching_Policy;
   procedure Check_Consistent_Dynamic_Elaboration_Checking;
   procedure Check_Consistent_Interrupt_States;
   procedure Check_Consistent_Locking_Policy;
   procedure Check_Consistent_No_Component_Reordering;
   procedure Check_Consistent_Normalize_Scalars;
   procedure Check_Consistent_Optimize_Alignment;
   procedure Check_Consistent_Partition_Elaboration_Policy;
   procedure Check_Consistent_Queuing_Policy;
   procedure Check_Consistent_Restrictions;
   procedure Check_Consistent_Restriction_No_Default_Initialization;
   procedure Check_Consistent_SSO_Default;
   procedure Check_Consistent_Exception_Handling;

   procedure Consistency_Error_Msg (Msg : String);
   --  Produce an error or a warning message, depending on whether an
   --  inconsistent configuration is permitted or not.

   function Same_Unit (U1 : Unit_Name_Type; U2 : Name_Id) return Boolean;
   --  Used to compare two unit names for No_Dependence checks. U1 is in
   --  standard unit name format, and U2 is in literal form with periods.

   -------------------------------------
   -- Check_Configuration_Consistency --
   -------------------------------------

   procedure Check_Configuration_Consistency is
   begin
      if Queuing_Policy_Specified /= ' ' then
         Check_Consistent_Queuing_Policy;
      end if;

      if Locking_Policy_Specified /= ' ' then
         Check_Consistent_Locking_Policy;
      end if;

      if No_Component_Reordering_Specified then
         Check_Consistent_No_Component_Reordering;
      end if;

      if Partition_Elaboration_Policy_Specified /= ' ' then
         Check_Consistent_Partition_Elaboration_Policy;
      end if;

      if SSO_Default_Specified then
         Check_Consistent_SSO_Default;
      end if;

      if Zero_Cost_Exceptions_Specified then
         Check_Consistent_Exception_Handling;
      end if;

      Check_Consistent_Normalize_Scalars;
      Check_Consistent_Optimize_Alignment;
      Check_Consistent_Dynamic_Elaboration_Checking;
      Check_Consistent_Restrictions;
      Check_Consistent_Restriction_No_Default_Initialization;
      Check_Consistent_Interrupt_States;
      Check_Consistent_Dispatching_Policy;
   end Check_Configuration_Consistency;

   -----------------------
   -- Check_Consistency --
   -----------------------

   procedure Check_Consistency is
      Src : Source_Id;
      --  Source file Id for this Sdep entry

      ALI_Path_Id : File_Name_Type;

   begin
      --  First, we go through the source table to see if there are any cases
      --  in which we should go after source files and compute checksums of
      --  the source files. We need to do this for any file for which we have
      --  mismatching time stamps and (so far) matching checksums.

      for S in Source.First .. Source.Last loop

         --  If all time stamps for a file match, then there is nothing to
         --  do, since we will not be checking checksums in that case anyway

         if Source.Table (S).All_Timestamps_Match then
            null;

         --  If we did not find the source file, then we can't compute its
         --  checksum anyway. Note that when we have a time stamp mismatch,
         --  we try to find the source file unconditionally (i.e. if
         --  Check_Source_Files is False).

         elsif not Source.Table (S).Source_Found then
            null;

         --  If we already have non-matching or missing checksums, then no
         --  need to try going after source file, since we won't trust the
         --  checksums in any case.

         elsif not Source.Table (S).All_Checksums_Match then
            null;

         --  Now we have the case where we have time stamp mismatches, and
         --  the source file is around, but so far all checksums match. This
         --  is the case where we need to compute the checksum from the source
         --  file, since otherwise we would ignore the time stamp mismatches,
         --  and that is wrong if the checksum of the source does not agree
         --  with the checksums in the ALI files.

         elsif Check_Source_Files then
            if not Checksums_Match
              (Source.Table (S).Checksum,
               Get_File_Checksum (Source.Table (S).Sfile))
            then
               Source.Table (S).All_Checksums_Match := False;
            end if;
         end if;
      end loop;

      --  Loop through ALI files

      ALIs_Loop : for A in ALIs.First .. ALIs.Last loop

         --  Loop through Sdep entries in one ALI file

         Sdep_Loop : for D in
           ALIs.Table (A).First_Sdep .. ALIs.Table (A).Last_Sdep
         loop
            if Sdep.Table (D).Dummy_Entry then
               goto Continue;
            end if;

            Src := Source_Id (Get_Name_Table_Int (Sdep.Table (D).Sfile));

            --  If the time stamps match, or all checksums match, then we
            --  are OK, otherwise we have a definite error.

            if Sdep.Table (D).Stamp /= Source.Table (Src).Stamp
              and then not Source.Table (Src).All_Checksums_Match
            then
               Error_Msg_File_1 := ALIs.Table (A).Sfile;
               Error_Msg_File_2 := Sdep.Table (D).Sfile;

               --  Two styles of message, depending on whether or not
               --  the updated file is the one that must be recompiled

               if Error_Msg_File_1 = Error_Msg_File_2 then
                  if Tolerate_Consistency_Errors then
                     Error_Msg
                        ("?{ has been modified and should be recompiled");
                  else
                     Error_Msg
                       ("{ has been modified and must be recompiled");
                  end if;

               else
                  ALI_Path_Id :=
                    Osint.Full_Lib_File_Name (ALIs.Table (A).Afile);

                  if Osint.Is_Readonly_Library (ALI_Path_Id) then
                     if Tolerate_Consistency_Errors then
                        Error_Msg ("?{ should be recompiled");
                        Error_Msg_File_1 := ALI_Path_Id;
                        Error_Msg ("?({ is obsolete and read-only)");
                     else
                        Error_Msg ("{ must be compiled");
                        Error_Msg_File_1 := ALI_Path_Id;
                        Error_Msg ("({ is obsolete and read-only)");
                     end if;

                  elsif Tolerate_Consistency_Errors then
                     Error_Msg
                       ("?{ should be recompiled ({ has been modified)");

                  else
                     Error_Msg ("{ must be recompiled ({ has been modified)");
                  end if;
               end if;

               if (not Tolerate_Consistency_Errors) and Verbose_Mode then
                  Error_Msg_File_1 := Source.Table (Src).Stamp_File;

                  if Source.Table (Src).Source_Found then
                     Error_Msg_File_1 :=
                       Osint.Full_Source_Name (Error_Msg_File_1);
                  else
                     Error_Msg_File_1 :=
                       Osint.Full_Lib_File_Name (Error_Msg_File_1);
                  end if;

                  Error_Msg
                    ("time stamp from { " & String (Source.Table (Src).Stamp));

                  Error_Msg_File_1 := Sdep.Table (D).Sfile;
                  Error_Msg
                    (" conflicts with { timestamp " &
                     String (Sdep.Table (D).Stamp));

                  Error_Msg_File_1 :=
                    Osint.Full_Lib_File_Name (ALIs.Table (A).Afile);
                  Error_Msg (" from {");
               end if;

               --  Exit from the loop through Sdep entries once we find one
               --  that does not match.

               exit Sdep_Loop;
            end if;

         <<Continue>>
            null;
         end loop Sdep_Loop;
      end loop ALIs_Loop;
   end Check_Consistency;

   -----------------------------------------
   -- Check_Consistent_Dispatching_Policy --
   -----------------------------------------

   --  The rule is that all files for which the dispatching policy is
   --  significant must meet the following rules:

   --    1. All files for which a task dispatching policy is significant must
   --    be compiled with the same setting.

   --    2. If a partition contains one or more Priority_Specific_Dispatching
   --    pragmas it cannot contain a Task_Dispatching_Policy pragma.

   --    3. No overlap is allowed in the priority ranges specified in
   --    Priority_Specific_Dispatching pragmas within the same partition.

   --    4. If a partition contains one or more Priority_Specific_Dispatching
   --    pragmas then the Ceiling_Locking policy is the only one allowed for
   --    the partition.

   procedure Check_Consistent_Dispatching_Policy is
      Max_Prio : Nat := 0;
      --  Maximum priority value for which a Priority_Specific_Dispatching
      --  pragma has been specified.

      TDP_Pragma_Afile : ALI_Id := No_ALI_Id;
      --  ALI file where a Task_Dispatching_Policy pragma appears

   begin
      --  Consistency checks in units specifying a Task_Dispatching_Policy

      if Task_Dispatching_Policy_Specified /= ' ' then
         Find_Policy : for A1 in ALIs.First .. ALIs.Last loop
            if ALIs.Table (A1).Task_Dispatching_Policy /= ' ' then

               --  Store the place where the first task dispatching pragma
               --  appears. We may need this value for issuing consistency
               --  errors if Priority_Specific_Dispatching pragmas are used.

               TDP_Pragma_Afile := A1;

               Check_Policy : declare
                  Policy : constant Character :=
                    ALIs.Table (A1).Task_Dispatching_Policy;

               begin
                  for A2 in A1 + 1 .. ALIs.Last loop
                     if ALIs.Table (A2).Task_Dispatching_Policy /= ' '
                          and then
                        ALIs.Table (A2).Task_Dispatching_Policy /= Policy
                     then
                        Error_Msg_File_1 := ALIs.Table (A1).Sfile;
                        Error_Msg_File_2 := ALIs.Table (A2).Sfile;

                        Consistency_Error_Msg
                          ("{ and { compiled with different task" &
                           " dispatching policies");
                        exit Find_Policy;
                     end if;
                  end loop;
               end Check_Policy;

               exit Find_Policy;
            end if;
         end loop Find_Policy;
      end if;

      --  If no Priority_Specific_Dispatching entries, nothing else to do

      if Specific_Dispatching.Last >= Specific_Dispatching.First then

         --  Find out the maximum priority value for which one of the
         --  Priority_Specific_Dispatching pragmas applies.

         Max_Prio := 0;
         for J in Specific_Dispatching.First .. Specific_Dispatching.Last loop
            if Specific_Dispatching.Table (J).Last_Priority > Max_Prio then
               Max_Prio := Specific_Dispatching.Table (J).Last_Priority;
            end if;
         end loop;

         --  Now establish tables to be used for consistency checking

         declare
            --  The following record type is used to record locations of the
            --  Priority_Specific_Dispatching pragmas applying to the Priority.

            type Specific_Dispatching_Entry is record
               Dispatching_Policy : Character := ' ';
               --  First character (upper case) of corresponding policy name

               Afile : ALI_Id := No_ALI_Id;
               --  ALI file that generated Priority Specific Dispatching
               --  entry for consistency message.

               Loc : Nat := 0;
               --  Line numbers from Priority_Specific_Dispatching pragma
            end record;

            PSD_Table  : array (0 .. Max_Prio) of Specific_Dispatching_Entry :=
              (others => Specific_Dispatching_Entry'
                 (Dispatching_Policy => ' ',
                  Afile              => No_ALI_Id,
                  Loc                => 0));
            --  Array containing an entry per priority containing the location
            --  where there is a Priority_Specific_Dispatching pragma that
            --  applies to the priority.

         begin
            for F in ALIs.First .. ALIs.Last loop
               for K in ALIs.Table (F).First_Specific_Dispatching ..
                        ALIs.Table (F).Last_Specific_Dispatching
               loop
                  declare
                     DTK : Specific_Dispatching_Record
                             renames Specific_Dispatching.Table (K);
                  begin
                     --  Check whether pragma Task_Dispatching_Policy and
                     --  pragma Priority_Specific_Dispatching are used in the
                     --  same partition.

                     if Task_Dispatching_Policy_Specified /= ' ' then
                        Error_Msg_File_1 := ALIs.Table (F).Sfile;
                        Error_Msg_File_2 :=
                          ALIs.Table (TDP_Pragma_Afile).Sfile;

                        Error_Msg_Nat_1 := DTK.PSD_Pragma_Line;

                        Consistency_Error_Msg
                          ("Priority_Specific_Dispatching at {:#" &
                           " incompatible with Task_Dispatching_Policy at {");
                     end if;

                     --  Ceiling_Locking must also be specified for a partition
                     --  with at least one Priority_Specific_Dispatching
                     --  pragma.

                     if Locking_Policy_Specified /= ' '
                       and then Locking_Policy_Specified /= 'C'
                     then
                        for A in ALIs.First .. ALIs.Last loop
                           if ALIs.Table (A).Locking_Policy /= ' '
                             and then ALIs.Table (A).Locking_Policy /= 'C'
                           then
                              Error_Msg_File_1 := ALIs.Table (F).Sfile;
                              Error_Msg_File_2 := ALIs.Table (A).Sfile;

                              Error_Msg_Nat_1  := DTK.PSD_Pragma_Line;

                              Consistency_Error_Msg
                                ("Priority_Specific_Dispatching at {:#" &
                                 " incompatible with Locking_Policy at {");
                           end if;
                        end loop;
                     end if;

                     --  Check overlapping priority ranges

                     Find_Overlapping : for Prio in
                       DTK.First_Priority .. DTK.Last_Priority
                     loop
                        if PSD_Table (Prio).Afile = No_ALI_Id then
                           PSD_Table (Prio) :=
                             (Dispatching_Policy => DTK.Dispatching_Policy,
                              Afile => F, Loc => DTK.PSD_Pragma_Line);

                        elsif PSD_Table (Prio).Dispatching_Policy /=
                              DTK.Dispatching_Policy

                        then
                           Error_Msg_File_1 :=
                             ALIs.Table (PSD_Table (Prio).Afile).Sfile;
                           Error_Msg_File_2 := ALIs.Table (F).Sfile;
                           Error_Msg_Nat_1  := PSD_Table (Prio).Loc;
                           Error_Msg_Nat_2  := DTK.PSD_Pragma_Line;

                           Consistency_Error_Msg
                             ("overlapping priority ranges at {:# and {:#");

                           exit Find_Overlapping;
                        end if;
                     end loop Find_Overlapping;
                  end;
               end loop;
            end loop;
         end;
      end if;
   end Check_Consistent_Dispatching_Policy;

   ---------------------------------------------------
   -- Check_Consistent_Dynamic_Elaboration_Checking --
   ---------------------------------------------------

   --  The rule here is that if a unit has dynamic elaboration checks,
   --  then any unit it withs must meet one of the following criteria:

   --    1. There is a pragma Elaborate_All for the with'ed unit
   --    2. The with'ed unit was compiled with dynamic elaboration checks
   --    3. The with'ed unit has pragma Preelaborate or Pure
   --    4. It is an internal GNAT unit (including children of GNAT)
   --    5. It is an interface of a Stand-Alone Library

   procedure Check_Consistent_Dynamic_Elaboration_Checking is
   begin
      if Dynamic_Elaboration_Checks_Specified then
         for U in First_Unit_Entry .. Units.Last loop
            declare
               UR : Unit_Record renames Units.Table (U);

            begin
               if UR.Dynamic_Elab then
                  for W in UR.First_With .. UR.Last_With loop
                     declare
                        WR : With_Record renames Withs.Table (W);

                     begin
                        if Get_Name_Table_Int (WR.Uname) /= 0 then
                           declare
                              WU : Unit_Record renames
                                     Units.Table
                                       (Unit_Id
                                         (Get_Name_Table_Int (WR.Uname)));

                           begin
                              --  Case 1. Elaborate_All for with'ed unit

                              if WR.Elaborate_All then
                                 null;

                              --  Case 2. With'ed unit has dynamic elab checks

                              elsif WU.Dynamic_Elab then
                                 null;

                              --  Case 3. With'ed unit is Preelaborate or Pure

                              elsif WU.Preelab or else WU.Pure then
                                 null;

                              --  Case 4. With'ed unit is internal file

                              elsif Is_Internal_File_Name (WU.Sfile) then
                                 null;

                              --  Case 5. With'ed unit is a SAL interface

                              elsif WU.SAL_Interface then
                                 null;

                              --  Issue warning, not one of the safe cases

                              else
                                 Error_Msg_File_1 := UR.Sfile;
                                 Error_Msg
                                   ("?{ has dynamic elaboration checks " &
                                                                 "and with's");

                                 Error_Msg_File_1 := WU.Sfile;
                                 Error_Msg
                                   ("?  { which has static elaboration " &
                                                                     "checks");

                                 Warnings_Detected := Warnings_Detected + 1;
                              end if;
                           end;
                        end if;
                     end;
                  end loop;
               end if;
            end;
         end loop;
      end if;
   end Check_Consistent_Dynamic_Elaboration_Checking;

   ---------------------------------------
   -- Check_Consistent_Interrupt_States --
   ---------------------------------------

   --  The rule is that if the state of a given interrupt is specified
   --  in more than one unit, it must be specified with a consistent state.

   procedure Check_Consistent_Interrupt_States is
      Max_Intrup : Nat;

   begin
      --  If no Interrupt_State entries, nothing to do

      if Interrupt_States.Last < Interrupt_States.First then
         return;
      end if;

      --  First find out the maximum interrupt value

      Max_Intrup := 0;
      for J in Interrupt_States.First .. Interrupt_States.Last loop
         if Interrupt_States.Table (J).Interrupt_Id > Max_Intrup then
            Max_Intrup := Interrupt_States.Table (J).Interrupt_Id;
         end if;
      end loop;

      --  Now establish tables to be used for consistency checking

      declare
         Istate : array (0 .. Max_Intrup) of Character := (others => 'n');
         --  Interrupt state entries, 'u'/'s'/'r' or 'n' to indicate an
         --  entry that has not been set.

         Afile : array (0 .. Max_Intrup) of ALI_Id;
         --  ALI file that generated Istate entry for consistency message

         Loc : array (0 .. Max_Intrup) of Nat;
         --  Line numbers from IS pragma generating Istate entry

         Inum : Nat;
         --  Interrupt number from entry being tested

         Stat : Character;
         --  Interrupt state from entry being tested

         Lnum : Nat;
         --  Line number from entry being tested

      begin
         for F in ALIs.First .. ALIs.Last loop
            for K in ALIs.Table (F).First_Interrupt_State ..
                     ALIs.Table (F).Last_Interrupt_State
            loop
               Inum := Interrupt_States.Table (K).Interrupt_Id;
               Stat := Interrupt_States.Table (K).Interrupt_State;
               Lnum := Interrupt_States.Table (K).IS_Pragma_Line;

               if Istate (Inum) = 'n' then
                  Istate (Inum) := Stat;
                  Afile  (Inum) := F;
                  Loc    (Inum) := Lnum;

               elsif Istate (Inum) /= Stat then
                  Error_Msg_File_1 := ALIs.Table (Afile (Inum)).Sfile;
                  Error_Msg_File_2 := ALIs.Table (F).Sfile;
                  Error_Msg_Nat_1  := Loc (Inum);
                  Error_Msg_Nat_2  := Lnum;

                  Consistency_Error_Msg
                    ("inconsistent interrupt states at {:# and {:#");
               end if;
            end loop;
         end loop;
      end;
   end Check_Consistent_Interrupt_States;

   -------------------------------------
   -- Check_Consistent_Locking_Policy --
   -------------------------------------

   --  The rule is that all files for which the locking policy is
   --  significant must be compiled with the same setting.

   procedure Check_Consistent_Locking_Policy is
   begin
      --  First search for a unit specifying a policy and then
      --  check all remaining units against it.

      Find_Policy : for A1 in ALIs.First .. ALIs.Last loop
         if ALIs.Table (A1).Locking_Policy /= ' ' then
            Check_Policy : declare
               Policy : constant Character := ALIs.Table (A1).Locking_Policy;

            begin
               for A2 in A1 + 1 .. ALIs.Last loop
                  if ALIs.Table (A2).Locking_Policy /= ' '
                       and then
                     ALIs.Table (A2).Locking_Policy /= Policy
                  then
                     Error_Msg_File_1 := ALIs.Table (A1).Sfile;
                     Error_Msg_File_2 := ALIs.Table (A2).Sfile;

                     Consistency_Error_Msg
                       ("{ and { compiled with different locking policies");
                     exit Find_Policy;
                  end if;
               end loop;
            end Check_Policy;

            exit Find_Policy;
         end if;
      end loop Find_Policy;
   end Check_Consistent_Locking_Policy;

   ----------------------------------------------
   -- Check_Consistent_No_Component_Reordering --
   ----------------------------------------------

   --  This routine checks for a consistent No_Component_Reordering setting.
   --  Note that internal units are excluded from this check, since we don't
   --  in any case allow the pragma to affect types in internal units, and
   --  there is thus no requirement to recompile the run-time with the setting.

   procedure Check_Consistent_No_Component_Reordering is
      OK : Boolean := True;
   begin
      --  Check that all entries have No_Component_Reordering set

      for A1 in ALIs.First .. ALIs.Last loop
         if not Is_Internal_File_Name (ALIs.Table (A1).Sfile)
           and then not ALIs.Table (A1).No_Component_Reordering
         then
            OK := False;
            exit;
         end if;
      end loop;

      --  All do, return

      if OK then
         return;
      end if;

      --  Here we have an inconsistency

      Consistency_Error_Msg
        ("some but not all files compiled with No_Component_Reordering");

      Write_Eol;
      Write_Str ("files compiled with No_Component_Reordering");
      Write_Eol;

      for A1 in ALIs.First .. ALIs.Last loop
         if not Is_Internal_File_Name (ALIs.Table (A1).Sfile)
           and then ALIs.Table (A1).No_Component_Reordering
         then
            Write_Str ("  ");
            Write_Name (ALIs.Table (A1).Sfile);
            Write_Eol;
         end if;
      end loop;

      Write_Eol;
      Write_Str ("files compiled without No_Component_Reordering");
      Write_Eol;

      for A1 in ALIs.First .. ALIs.Last loop
         if not Is_Internal_File_Name (ALIs.Table (A1).Sfile)
           and then not ALIs.Table (A1).No_Component_Reordering
         then
            Write_Str ("  ");
            Write_Name (ALIs.Table (A1).Sfile);
            Write_Eol;
         end if;
      end loop;
   end Check_Consistent_No_Component_Reordering;

   ----------------------------------------
   -- Check_Consistent_Normalize_Scalars --
   ----------------------------------------

   --  The rule is that if any unit is compiled with Normalize_Scalars,
   --  then all other units in the partition must also be compiled with
   --  Normalize_Scalars in effect.

   --  There is some issue as to whether this consistency check is desirable,
   --  it is certainly required at the moment by the RM. We should keep a watch
   --  on the ARG and HRG deliberations here. GNAT no longer depends on this
   --  consistency (it used to do so, but that is no longer the case, since
   --  pragma Initialize_Scalars pragma does not require consistency.)

   procedure Check_Consistent_Normalize_Scalars is
   begin
      if Normalize_Scalars_Specified and No_Normalize_Scalars_Specified then
         Consistency_Error_Msg
              ("some but not all files compiled with Normalize_Scalars");

         Write_Eol;
         Write_Str ("files compiled with Normalize_Scalars");
         Write_Eol;

         for A1 in ALIs.First .. ALIs.Last loop
            if ALIs.Table (A1).Normalize_Scalars then
               Write_Str ("  ");
               Write_Name (ALIs.Table (A1).Sfile);
               Write_Eol;
            end if;
         end loop;

         Write_Eol;
         Write_Str ("files compiled without Normalize_Scalars");
         Write_Eol;

         for A1 in ALIs.First .. ALIs.Last loop
            if not ALIs.Table (A1).Normalize_Scalars then
               Write_Str ("  ");
               Write_Name (ALIs.Table (A1).Sfile);
               Write_Eol;
            end if;
         end loop;
      end if;
   end Check_Consistent_Normalize_Scalars;

   -----------------------------------------
   -- Check_Consistent_Optimize_Alignment --
   -----------------------------------------

   --  The rule is that all units which depend on the global default setting
   --  of Optimize_Alignment must be compiled with the same setting for this
   --  default. Units which specify an explicit local value for this setting
   --  are exempt from the consistency rule (this includes all internal units).

   procedure Check_Consistent_Optimize_Alignment is
      OA_Setting : Character := ' ';
      --  Reset when we find a unit that depends on the default and does
      --  not have a local specification of the Optimize_Alignment setting.

      OA_Unit : Unit_Id := No_Unit_Id;
      --  Id of unit from which OA_Setting was set

      C : Character;

   begin
      for U in First_Unit_Entry .. Units.Last loop
         C := Units.Table (U).Optimize_Alignment;

         if C /= 'L' then
            if OA_Setting = ' ' then
               OA_Setting := C;
               OA_Unit := U;

            elsif OA_Setting = C then
               null;

            else
               pragma Assert (Present (OA_Unit));
               Error_Msg_Unit_1 := Units.Table (OA_Unit).Uname;
               Error_Msg_Unit_2 := Units.Table (U).Uname;

               Consistency_Error_Msg
                 ("$ and $ compiled with different "
                  & "default Optimize_Alignment settings");
               return;
            end if;
         end if;
      end loop;
   end Check_Consistent_Optimize_Alignment;

   ---------------------------------------------------
   -- Check_Consistent_Partition_Elaboration_Policy --
   ---------------------------------------------------

   --  The rule is that all files for which the partition elaboration policy is
   --  significant must be compiled with the same setting.

   procedure Check_Consistent_Partition_Elaboration_Policy is
   begin
      --  First search for a unit specifying a policy and then
      --  check all remaining units against it.

      Find_Policy : for A1 in ALIs.First .. ALIs.Last loop
         if ALIs.Table (A1).Partition_Elaboration_Policy /= ' ' then
            Check_Policy : declare
               Policy : constant Character :=
                  ALIs.Table (A1).Partition_Elaboration_Policy;

            begin
               for A2 in A1 + 1 .. ALIs.Last loop
                  if ALIs.Table (A2).Partition_Elaboration_Policy /= ' '
                       and then
                     ALIs.Table (A2).Partition_Elaboration_Policy /= Policy
                  then
                     Error_Msg_File_1 := ALIs.Table (A1).Sfile;
                     Error_Msg_File_2 := ALIs.Table (A2).Sfile;

                     Consistency_Error_Msg
                       ("{ and { compiled with different partition "
                          & "elaboration policies");
                     exit Find_Policy;
                  end if;
               end loop;
            end Check_Policy;

            --  A No_Task_Hierarchy restriction must be specified for the
            --  Sequential policy (RM H.6(6/2)).

            if Partition_Elaboration_Policy_Specified = 'S'
              and then not Cumulative_Restrictions.Set (No_Task_Hierarchy)
            then
               Error_Msg_File_1 := ALIs.Table (A1).Sfile;
               Error_Msg
                 ("{ has sequential partition elaboration policy, but no");
               Error_Msg
                 ("pragma Restrictions (No_Task_Hierarchy) was specified");
            end if;

            exit Find_Policy;
         end if;
      end loop Find_Policy;
   end Check_Consistent_Partition_Elaboration_Policy;

   -------------------------------------
   -- Check_Consistent_Queuing_Policy --
   -------------------------------------

   --  The rule is that all files for which the queuing policy is
   --  significant must be compiled with the same setting.

   procedure Check_Consistent_Queuing_Policy is
   begin
      --  First search for a unit specifying a policy and then
      --  check all remaining units against it.

      Find_Policy : for A1 in ALIs.First .. ALIs.Last loop
         if ALIs.Table (A1).Queuing_Policy /= ' ' then
            Check_Policy : declare
               Policy : constant Character := ALIs.Table (A1).Queuing_Policy;
            begin
               for A2 in A1 + 1 .. ALIs.Last loop
                  if ALIs.Table (A2).Queuing_Policy /= ' '
                       and then
                     ALIs.Table (A2).Queuing_Policy /= Policy
                  then
                     Error_Msg_File_1 := ALIs.Table (A1).Sfile;
                     Error_Msg_File_2 := ALIs.Table (A2).Sfile;

                     Consistency_Error_Msg
                       ("{ and { compiled with different queuing policies");
                     exit Find_Policy;
                  end if;
               end loop;
            end Check_Policy;

            exit Find_Policy;
         end if;
      end loop Find_Policy;
   end Check_Consistent_Queuing_Policy;

   -----------------------------------
   -- Check_Consistent_Restrictions --
   -----------------------------------

   --  The rule is that if a restriction is specified in any unit, then all
   --  units must obey the restriction. The check applies only to restrictions
   --  which require partition wide consistency, and not to internal units.

   procedure Check_Consistent_Restrictions is
      Restriction_File_Output : Boolean;
      --  Shows if we have output header messages for restriction violation

      procedure Print_Restriction_File (R : All_Restrictions);
      --  Print header line for R if not printed yet

      ----------------------------
      -- Print_Restriction_File --
      ----------------------------

      procedure Print_Restriction_File (R : All_Restrictions) is
      begin
         if not Restriction_File_Output then
            Restriction_File_Output := True;

            --  Find an ali file specifying the restriction

            for A in ALIs.First .. ALIs.Last loop
               if ALIs.Table (A).Restrictions.Set (R)
                 and then (R in All_Boolean_Restrictions
                             or else ALIs.Table (A).Restrictions.Value (R) =
                                     Cumulative_Restrictions.Value (R))
               then
                  --  We have found that ALI file A specifies the restriction
                  --  that is being violated (the minimum value is specified
                  --  in the case of a parameter restriction).

                  declare
                     M1 : constant String := "{ has restriction ";
                     S  : constant String := Restriction_Id'Image (R);
                     M2 : String (1 .. 2000); -- big enough
                     P  : Integer;

                  begin
                     Name_Buffer (1 .. S'Length) := S;
                     Name_Len := S'Length;
                     Set_Casing (Mixed_Case);

                     M2 (M1'Range) := M1;
                     P := M1'Length + 1;
                     M2 (P .. P + S'Length - 1) := Name_Buffer (1 .. S'Length);
                     P := P + S'Length;

                     if R in All_Parameter_Restrictions then
                        M2 (P .. P + 4) := " => #";
                        Error_Msg_Nat_1 :=
                          Int (Cumulative_Restrictions.Value (R));
                        P := P + 5;
                     end if;

                     Error_Msg_File_1 := ALIs.Table (A).Sfile;
                     Consistency_Error_Msg (M2 (1 .. P - 1));
                     Consistency_Error_Msg
                       ("but the following files violate this restriction:");
                     return;
                  end;
               end if;
            end loop;
         end if;
      end Print_Restriction_File;

   --  Start of processing for Check_Consistent_Restrictions

   begin
      --  We used to have a special test here:

         --  A special test, if we have a main program, then if it has an
         --  allocator in the body, this is considered to be a violation of
         --  the restriction No_Allocators_After_Elaboration. We just mark
         --  this restriction and then the normal circuit will flag it.

      --  But we don't do that any more, because in the final version of Ada
      --  2012, it is statically illegal to have an allocator in a library-
      --  level subprogram, so we don't need this bind time test any more.
      --  If we have a main program with parameters (which GNAT allows), then
      --  allocators in that will be caught by the run-time check.

      --  Loop through all restriction violations

      for R in All_Restrictions loop

         --  Check for violation of this restriction

         if Cumulative_Restrictions.Set (R)
           and then Cumulative_Restrictions.Violated (R)
           and then (R in Partition_Boolean_Restrictions
                       or else (R in All_Parameter_Restrictions
                                   and then
                                     Cumulative_Restrictions.Count (R) >
                                     Cumulative_Restrictions.Value (R)))
         then
            Restriction_File_Output := False;

            --  Loop through files looking for violators

            for A2 in ALIs.First .. ALIs.Last loop
               declare
                  T : ALIs_Record renames ALIs.Table (A2);

               begin
                  if T.Restrictions.Violated (R) then

                     --  We exclude predefined files from the list of
                     --  violators. This should be rethought. It is not
                     --  clear that this is the right thing to do, that
                     --  is particularly the case for restricted runtimes.

                     if not Is_Internal_File_Name (T.Sfile) then

                        --  Case of Boolean restriction, just print file name

                        if R in All_Boolean_Restrictions then
                           Print_Restriction_File (R);
                           Error_Msg_File_1 := T.Sfile;
                           Consistency_Error_Msg ("  {");

                        --  Case of Parameter restriction where violation
                        --  count exceeds restriction value, print file
                        --  name and count, adding "at least" if the
                        --  exact count is not known.

                        elsif R in Checked_Add_Parameter_Restrictions
                          or else T.Restrictions.Count (R) >
                          Cumulative_Restrictions.Value (R)
                        then
                           Print_Restriction_File (R);
                           Error_Msg_File_1 := T.Sfile;
                           Error_Msg_Nat_1 := Int (T.Restrictions.Count (R));

                           if T.Restrictions.Unknown (R) then
                              Consistency_Error_Msg
                                ("  { (count = at least #)");
                           else
                              Consistency_Error_Msg
                                ("  { (count = #)");
                           end if;
                        end if;
                     end if;
                  end if;
               end;
            end loop;
         end if;
      end loop;

      --  Now deal with No_Dependence indications. Note that we put the loop
      --  through entries in the no dependency table first, since this loop
      --  is most often empty (no such pragma Restrictions in use).

      for ND in No_Deps.First .. No_Deps.Last loop
         declare
            ND_Unit : constant Name_Id := No_Deps.Table (ND).No_Dep_Unit;
         begin
            for J in ALIs.First .. ALIs.Last loop
               declare
                  A : ALIs_Record renames ALIs.Table (J);
               begin
                  for K in A.First_Unit .. A.Last_Unit loop
                     declare
                        U : Unit_Record renames Units.Table (K);
                     begin
                        --  Exclude runtime units from this check since the
                        --  user does not care how a runtime unit is
                        --  implemented.

                        if not Is_Internal_File_Name (U.Sfile) then
                           for L in U.First_With .. U.Last_With loop
                              if Same_Unit (Withs.Table (L).Uname, ND_Unit)
                              then
                                 Error_Msg_File_1 := U.Sfile;
                                 Error_Msg_Name_1 := ND_Unit;
                                 Consistency_Error_Msg
                                   ("file { violates restriction " &
                                    "No_Dependence => %");
                              end if;
                           end loop;
                        end if;
                     end;
                  end loop;
               end;
            end loop;
         end;
      end loop;
   end Check_Consistent_Restrictions;

   ------------------------------------------------------------
   -- Check_Consistent_Restriction_No_Default_Initialization --
   ------------------------------------------------------------

   --  The Restriction (No_Default_Initialization) has special consistency
   --  rules. The rule is that no unit compiled without this restriction
   --  that violates the restriction can WITH a unit that is compiled with
   --  the restriction.

   procedure Check_Consistent_Restriction_No_Default_Initialization is
   begin
      --  Nothing to do if no one set this restriction

      if not Cumulative_Restrictions.Set (No_Default_Initialization) then
         return;
      end if;

      --  Nothing to do if no one violates the restriction

      if not Cumulative_Restrictions.Violated (No_Default_Initialization) then
         return;
      end if;

      --  Otherwise we go into a full scan to find possible problems

      for U in Units.First .. Units.Last loop
         declare
            UTE : Unit_Record renames Units.Table (U);
            ATE : ALIs_Record renames ALIs.Table (UTE.My_ALI);

         begin
            if ATE.Restrictions.Violated (No_Default_Initialization) then
               for W in UTE.First_With .. UTE.Last_With loop
                  declare
                     AFN : constant File_Name_Type := Withs.Table (W).Afile;

                  begin
                     --  The file name may not be present for withs of certain
                     --  generic run-time files. The test can be safely left
                     --  out in such cases anyway.

                     if AFN /= No_File then
                        declare
                           WAI : constant ALI_Id :=
                             ALI_Id (Get_Name_Table_Int (AFN));
                           WTE : ALIs_Record renames ALIs.Table (WAI);

                        begin
                           if WTE.Restrictions.Set
                               (No_Default_Initialization)
                           then
                              Error_Msg_Unit_1 := UTE.Uname;
                              Consistency_Error_Msg
                                ("unit $ compiled without restriction "
                                 & "No_Default_Initialization");
                              Error_Msg_Unit_1 := Withs.Table (W).Uname;
                              Consistency_Error_Msg
                                ("withs unit $, compiled with restriction "
                                 & "No_Default_Initialization");
                           end if;
                        end;
                     end if;
                  end;
               end loop;
            end if;
         end;
      end loop;
   end Check_Consistent_Restriction_No_Default_Initialization;

   ----------------------------------
   -- Check_Consistent_SSO_Default --
   ----------------------------------

   --  This routine checks for a consistent SSO default setting. Note that
   --  internal units are excluded from this check, since we don't in any
   --  case allow the pragma to affect types in internal units, and there
   --  is thus no requirement to recompile the run-time with the default set.

   procedure Check_Consistent_SSO_Default is
      Default : Character;

   begin
      Default := ALIs.Table (ALIs.First).SSO_Default;

      --  The default must be set from a non-internal unit

      pragma Assert
        (not Is_Internal_File_Name (ALIs.Table (ALIs.First).Sfile));

      --  Check all entries match the default above from the first entry

      for A1 in ALIs.First + 1 .. ALIs.Last loop
         if not Is_Internal_File_Name (ALIs.Table (A1).Sfile)
           and then ALIs.Table (A1).SSO_Default /= Default
         then
            Default := '?';
            exit;
         end if;
      end loop;

      --  All match, return

      if Default /= '?' then
         return;
      end if;

      --  Here we have a mismatch

      Consistency_Error_Msg
        ("files not compiled with same Default_Scalar_Storage_Order");

      Write_Eol;
      Write_Str ("files compiled with High_Order_First");
      Write_Eol;

      for A1 in ALIs.First .. ALIs.Last loop
         if ALIs.Table (A1).SSO_Default = 'H' then
            Write_Str ("  ");
            Write_Name (ALIs.Table (A1).Sfile);
            Write_Eol;
         end if;
      end loop;

      Write_Eol;
      Write_Str ("files compiled with Low_Order_First");
      Write_Eol;

      for A1 in ALIs.First .. ALIs.Last loop
         if ALIs.Table (A1).SSO_Default = 'L' then
            Write_Str ("  ");
            Write_Name (ALIs.Table (A1).Sfile);
            Write_Eol;
         end if;
      end loop;

      Write_Eol;
      Write_Str ("files compiled with no Default_Scalar_Storage_Order");
      Write_Eol;

      for A1 in ALIs.First .. ALIs.Last loop
         if not Is_Internal_File_Name (ALIs.Table (A1).Sfile)
           and then ALIs.Table (A1).SSO_Default = ' '
         then
            Write_Str ("  ");
            Write_Name (ALIs.Table (A1).Sfile);
            Write_Eol;
         end if;
      end loop;
   end Check_Consistent_SSO_Default;

   -----------------------------------------
   -- Check_Consistent_Exception_Handling --
   -----------------------------------------

   --  All units must have the same exception handling mechanism.

   procedure Check_Consistent_Exception_Handling is
   begin
      Check_Mechanism : for A1 in ALIs.First + 1 .. ALIs.Last loop
         if ALIs.Table (A1).Zero_Cost_Exceptions /=
             ALIs.Table (ALIs.First).Zero_Cost_Exceptions
         then
            Error_Msg_File_1 := ALIs.Table (A1).Sfile;
            Error_Msg_File_2 := ALIs.Table (ALIs.First).Sfile;

            Consistency_Error_Msg
              ("{ and { compiled with different exception handling "
               & "mechanisms");
         end if;
      end loop Check_Mechanism;
   end Check_Consistent_Exception_Handling;

   -------------------------------
   -- Check_Duplicated_Subunits --
   -------------------------------

   procedure Check_Duplicated_Subunits is
   begin
      for J in Sdep.First .. Sdep.Last loop
         if Sdep.Table (J).Subunit_Name /= No_Name then
            Get_Decoded_Name_String (Sdep.Table (J).Subunit_Name);
            Name_Len := Name_Len + 2;
            Name_Buffer (Name_Len - 1) := '%';

            --  See if there is a body or spec with the same name

            for K in Boolean loop
               if K then
                  Name_Buffer (Name_Len) := 'b';
               else
                  Name_Buffer (Name_Len) := 's';
               end if;

               declare
                  Unit : constant Unit_Name_Type := Name_Find;
                  Info : constant Int := Get_Name_Table_Int (Unit);

               begin
                  if Info /= 0 then
                     Set_Standard_Error;
                     Write_Str ("error: subunit """);
                     Write_Name_Decoded (Sdep.Table (J).Subunit_Name);
                     Write_Str (""" in file """);
                     Write_Name_Decoded (Sdep.Table (J).Sfile);
                     Write_Char ('"');
                     Write_Eol;
                     Write_Str ("       has same name as unit """);
                     Write_Unit_Name (Units.Table (Unit_Id (Info)).Uname);
                     Write_Str (""" found in file """);
                     Write_Name_Decoded (Units.Table (Unit_Id (Info)).Sfile);
                     Write_Char ('"');
                     Write_Eol;
                     Write_Str ("       this is not allowed within a single "
                                & "partition (RM 10.2(19))");
                     Write_Eol;
                     Osint.Exit_Program (Osint.E_Fatal);
                  end if;
               end;
            end loop;
         end if;
      end loop;
   end Check_Duplicated_Subunits;

   --------------------
   -- Check_Versions --
   --------------------

   procedure Check_Versions is
      VL : constant Natural := ALIs.Table (ALIs.First).Ver_Len;

   begin
      for A in ALIs.First .. ALIs.Last loop
         if ALIs.Table (A).Ver_Len /= VL
           or else ALIs.Table (A).Ver          (1 .. VL) /=
                   ALIs.Table (ALIs.First).Ver (1 .. VL)
         then
            --  Version mismatch found; generate error message.

            declare
               use Gnatvsn;

               Prefix : constant String :=
                 Verbose_Library_Version
                   (1 .. Verbose_Library_Version'Length
                           - Library_Version'Length);

               type ALI_Version is record
                  Primary, Secondary : Int range -1 .. Int'Last;
               end record;

               No_Version : constant ALI_Version := (-1, -1);

               function Remove_Prefix (S : String) return String is
                 (S (S'First + Prefix'Length .. S'Last));

               function Extract_Version (S : String) return ALI_Version;
               --  Attempts to extract and return a pair of nonnegative library
               --  version numbers from the given string; if unsuccessful,
               --  then returns No_Version.

               ---------------------
               -- Extract_Version --
               ---------------------

               function Extract_Version (S : String) return ALI_Version is
                  pragma Assert (S'First = 1);

                  function Int_Value (Img : String) return Int;
                  --  Using Int'Value leads to complications in
                  --  building the binder, so DIY.

                  ---------------
                  -- Int_Value --
                  ---------------

                  function Int_Value (Img : String) return Int is
                     Result : Nat := 0;
                  begin
                     if Img'Length in 1 .. 9
                       and then (for all C of Img => C in '0' .. '9')
                     then
                        for C of Img loop
                           Result := (10 * Result) +
                             (Character'Pos (C) - Character'Pos ('0'));
                        end loop;
                        return Result;
                     else
                        return -1;
                     end if;
                  end Int_Value;

               begin
                  if S'Length > Prefix'Length
                    and then S (1 .. Prefix'Length) = Prefix
                  then
                     declare
                        Suffix    : constant String := Remove_Prefix (S);
                        Dot_Found : Boolean := False;
                        Primary, Secondary : Int;
                     begin
                        for Dot_Index in Suffix'Range loop
                           if Suffix (Dot_Index) = '.' then
                              Dot_Found := True;
                              Primary :=
                                Int_Value (Suffix (Suffix'First
                                                   .. Dot_Index - 1));
                              Secondary :=
                                Int_Value (Suffix (Dot_Index + 1
                                                   .. Suffix'Last));
                              exit;
                           end if;
                        end loop;

                        if not Dot_Found then
                           Primary   := Int_Value (Suffix);
                           Secondary := 0;
                        end if;

                        if (Primary /= -1) and (Secondary /= -1) then
                           return (Primary   => Primary,
                                   Secondary => Secondary);
                        end if;
                     end;
                  end if;
                  return No_Version;
               end Extract_Version;

               --  Local constants

               V1_Text : constant String :=
                 ALIs.Table (A).Ver (1 .. ALIs.Table (A).Ver_Len);
               V2_Text : constant String :=
                 ALIs.Table (ALIs.First).Ver (1 .. VL);
               V1      : constant ALI_Version := Extract_Version (V1_Text);
               V2      : constant ALI_Version := Extract_Version (V2_Text);

               Include_Version_Numbers_In_Message : constant Boolean :=
                 (V1 /= V2) and (V1 /= No_Version) and (V2 /= No_Version);
            begin
               Error_Msg_File_1 := ALIs.Table (A).Sfile;
               Error_Msg_File_2 := ALIs.Table (ALIs.First).Sfile;

               if Include_Version_Numbers_In_Message then
                  if V1.Secondary = V2.Secondary then
                     --  Excluding equal secondary values from error
                     --  message text matters for generating reproducible
                     --  regression test outputs.

                     Error_Msg_Nat_1 := V1.Primary;
                     Error_Msg_Nat_2 := V2.Primary;
                     Consistency_Error_Msg
                       ("{ and { compiled with different GNAT versions"
                        & ", v# and v#");
                  else
                     Consistency_Error_Msg
                       ("{ and { compiled with different GNAT versions"
                        & ", v"
                        & Remove_Prefix (V1_Text)
                        & " and v"
                        & Remove_Prefix (V2_Text));
                  end if;
               else
                  Consistency_Error_Msg
                    ("{ and { compiled with different GNAT versions");
               end if;
            end;
         end if;
      end loop;
   end Check_Versions;

   ---------------------------
   -- Consistency_Error_Msg --
   ---------------------------

   procedure Consistency_Error_Msg (Msg : String) is
   begin
      if Tolerate_Consistency_Errors then

         --  If consistency errors are tolerated,
         --  output the message as a warning.

         Error_Msg ('?' & Msg);

      --  Otherwise the consistency error is a true error

      else
         Error_Msg (Msg);
      end if;
   end Consistency_Error_Msg;

   ---------------
   -- Same_Unit --
   ---------------

   function Same_Unit (U1 : Unit_Name_Type; U2 : Name_Id) return Boolean is
   begin
      --  Note, the string U1 has a terminating %s or %b, U2 does not

      if Length_Of_Name (U1) - 2 = Length_Of_Name (U2) then
         Get_Name_String (U1);

         declare
            U1_Str : constant String := Name_Buffer (1 .. Name_Len - 2);
         begin
            Get_Name_String (U2);
            return U1_Str = Name_Buffer (1 .. Name_Len);
         end;

      else
         return False;
      end if;
   end Same_Unit;

end Bcheck;
