1 ------------------------------------------------------------------------------
3 -- GNAT COMPILER COMPONENTS --
9 -- Copyright (C) 1992-2012, Free Software Foundation, Inc. --
11 -- GNAT is free software; you can redistribute it and/or modify it under --
12 -- terms of the GNU General Public License as published by the Free Soft- --
13 -- ware Foundation; either version 3, or (at your option) any later ver- --
14 -- sion. GNAT is distributed in the hope that it will be useful, but WITH- --
15 -- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --
16 -- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License --
17 -- for more details. You should have received a copy of the GNU General --
18 -- Public License distributed with GNAT; see file COPYING3. If not, go to --
19 -- http://www.gnu.org/licenses for a complete copy of the license. --
21 -- GNAT was originally developed by the GNAT team at New York University. --
22 -- Extensive contributions were provided by Ada Core Technologies Inc. --
24 ------------------------------------------------------------------------------
27 with ALI
.Util
; use ALI
.Util
;
28 with Binderr
; use Binderr
;
29 with Butil
; use Butil
;
30 with Casing
; use Casing
;
31 with Fname
; use Fname
;
32 with Namet
; use Namet
;
35 with Output
; use Output
;
36 with Rident
; use Rident
;
37 with Types
; use Types
;
39 package body Bcheck
is
41 -----------------------
42 -- Local Subprograms --
43 -----------------------
45 -- The following checking subprograms make up the parts of the
46 -- configuration consistency check. See bodies for details of checks.
48 procedure Check_Consistent_Dispatching_Policy
;
49 procedure Check_Consistent_Dynamic_Elaboration_Checking
;
50 procedure Check_Consistent_Floating_Point_Format
;
51 procedure Check_Consistent_Interrupt_States
;
52 procedure Check_Consistent_Locking_Policy
;
53 procedure Check_Consistent_Normalize_Scalars
;
54 procedure Check_Consistent_Optimize_Alignment
;
55 procedure Check_Consistent_Partition_Elaboration_Policy
;
56 procedure Check_Consistent_Queuing_Policy
;
57 procedure Check_Consistent_Restrictions
;
58 procedure Check_Consistent_Restriction_No_Default_Initialization
;
59 procedure Check_Consistent_Zero_Cost_Exception_Handling
;
61 procedure Consistency_Error_Msg
(Msg
: String);
62 -- Produce an error or a warning message, depending on whether an
63 -- inconsistent configuration is permitted or not.
65 function Same_Unit
(U1
: Unit_Name_Type
; U2
: Name_Id
) return Boolean;
66 -- Used to compare two unit names for No_Dependence checks. U1 is in
67 -- standard unit name format, and U2 is in literal form with periods.
69 -------------------------------------
70 -- Check_Configuration_Consistency --
71 -------------------------------------
73 procedure Check_Configuration_Consistency
is
75 if Float_Format_Specified
/= ' ' then
76 Check_Consistent_Floating_Point_Format
;
79 if Queuing_Policy_Specified
/= ' ' then
80 Check_Consistent_Queuing_Policy
;
83 if Locking_Policy_Specified
/= ' ' then
84 Check_Consistent_Locking_Policy
;
87 if Partition_Elaboration_Policy_Specified
/= ' ' then
88 Check_Consistent_Partition_Elaboration_Policy
;
91 if Zero_Cost_Exceptions_Specified
then
92 Check_Consistent_Zero_Cost_Exception_Handling
;
95 Check_Consistent_Normalize_Scalars
;
96 Check_Consistent_Optimize_Alignment
;
97 Check_Consistent_Dynamic_Elaboration_Checking
;
98 Check_Consistent_Restrictions
;
99 Check_Consistent_Restriction_No_Default_Initialization
;
100 Check_Consistent_Interrupt_States
;
101 Check_Consistent_Dispatching_Policy
;
102 end Check_Configuration_Consistency
;
104 -----------------------
105 -- Check_Consistency --
106 -----------------------
108 procedure Check_Consistency
is
110 -- Source file Id for this Sdep entry
112 ALI_Path_Id
: File_Name_Type
;
115 -- First, we go through the source table to see if there are any cases
116 -- in which we should go after source files and compute checksums of
117 -- the source files. We need to do this for any file for which we have
118 -- mismatching time stamps and (so far) matching checksums.
120 for S
in Source
.First
.. Source
.Last
loop
122 -- If all time stamps for a file match, then there is nothing to
123 -- do, since we will not be checking checksums in that case anyway
125 if Source
.Table
(S
).All_Timestamps_Match
then
128 -- If we did not find the source file, then we can't compute its
129 -- checksum anyway. Note that when we have a time stamp mismatch,
130 -- we try to find the source file unconditionally (i.e. if
131 -- Check_Source_Files is False).
133 elsif not Source
.Table
(S
).Source_Found
then
136 -- If we already have non-matching or missing checksums, then no
137 -- need to try going after source file, since we won't trust the
138 -- checksums in any case.
140 elsif not Source
.Table
(S
).All_Checksums_Match
then
143 -- Now we have the case where we have time stamp mismatches, and
144 -- the source file is around, but so far all checksums match. This
145 -- is the case where we need to compute the checksum from the source
146 -- file, since otherwise we would ignore the time stamp mismatches,
147 -- and that is wrong if the checksum of the source does not agree
148 -- with the checksums in the ALI files.
150 elsif Check_Source_Files
then
151 if not Checksums_Match
152 (Source
.Table
(S
).Checksum
,
153 Get_File_Checksum
(Source
.Table
(S
).Sfile
))
155 Source
.Table
(S
).All_Checksums_Match
:= False;
160 -- Loop through ALI files
162 ALIs_Loop
: for A
in ALIs
.First
.. ALIs
.Last
loop
164 -- Loop through Sdep entries in one ALI file
167 ALIs
.Table
(A
).First_Sdep
.. ALIs
.Table
(A
).Last_Sdep
169 if Sdep
.Table
(D
).Dummy_Entry
then
173 Src
:= Source_Id
(Get_Name_Table_Info
(Sdep
.Table
(D
).Sfile
));
175 -- If the time stamps match, or all checksums match, then we
176 -- are OK, otherwise we have a definite error.
178 if Sdep
.Table
(D
).Stamp
/= Source
.Table
(Src
).Stamp
179 and then not Source
.Table
(Src
).All_Checksums_Match
181 Error_Msg_File_1
:= ALIs
.Table
(A
).Sfile
;
182 Error_Msg_File_2
:= Sdep
.Table
(D
).Sfile
;
184 -- Two styles of message, depending on whether or not
185 -- the updated file is the one that must be recompiled
187 if Error_Msg_File_1
= Error_Msg_File_2
then
188 if Tolerate_Consistency_Errors
then
190 ("?{ has been modified and should be recompiled");
193 ("{ has been modified and must be recompiled");
198 Osint
.Full_Lib_File_Name
(ALIs
.Table
(A
).Afile
);
200 if Osint
.Is_Readonly_Library
(ALI_Path_Id
) then
201 if Tolerate_Consistency_Errors
then
202 Error_Msg
("?{ should be recompiled");
203 Error_Msg_File_1
:= ALI_Path_Id
;
204 Error_Msg
("?({ is obsolete and read-only)");
206 Error_Msg
("{ must be compiled");
207 Error_Msg_File_1
:= ALI_Path_Id
;
208 Error_Msg
("({ is obsolete and read-only)");
211 elsif Tolerate_Consistency_Errors
then
213 ("?{ should be recompiled ({ has been modified)");
216 Error_Msg
("{ must be recompiled ({ has been modified)");
220 if (not Tolerate_Consistency_Errors
) and Verbose_Mode
then
221 Error_Msg_File_1
:= Sdep
.Table
(D
).Sfile
;
223 ("{ time stamp " & String (Source
.Table
(Src
).Stamp
));
225 Error_Msg_File_1
:= Sdep
.Table
(D
).Sfile
;
226 -- Something wrong here, should be different file ???
229 (" conflicts with { timestamp " &
230 String (Sdep
.Table
(D
).Stamp
));
233 -- Exit from the loop through Sdep entries once we find one
234 -- that does not match.
243 end Check_Consistency
;
245 -----------------------------------------
246 -- Check_Consistent_Dispatching_Policy --
247 -----------------------------------------
249 -- The rule is that all files for which the dispatching policy is
250 -- significant must meet the following rules:
252 -- 1. All files for which a task dispatching policy is significant must
253 -- be compiled with the same setting.
255 -- 2. If a partition contains one or more Priority_Specific_Dispatching
256 -- pragmas it cannot contain a Task_Dispatching_Policy pragma.
258 -- 3. No overlap is allowed in the priority ranges specified in
259 -- Priority_Specific_Dispatching pragmas within the same partition.
261 -- 4. If a partition contains one or more Priority_Specific_Dispatching
262 -- pragmas then the Ceiling_Locking policy is the only one allowed for
265 procedure Check_Consistent_Dispatching_Policy
is
267 -- Maximum priority value for which a Priority_Specific_Dispatching
268 -- pragma has been specified.
270 TDP_Pragma_Afile
: ALI_Id
:= No_ALI_Id
;
271 -- ALI file where a Task_Dispatching_Policy pragma appears
274 -- Consistency checks in units specifying a Task_Dispatching_Policy
276 if Task_Dispatching_Policy_Specified
/= ' ' then
277 Find_Policy
: for A1
in ALIs
.First
.. ALIs
.Last
loop
278 if ALIs
.Table
(A1
).Task_Dispatching_Policy
/= ' ' then
280 -- Store the place where the first task dispatching pragma
281 -- appears. We may need this value for issuing consistency
282 -- errors if Priority_Specific_Dispatching pragmas are used.
284 TDP_Pragma_Afile
:= A1
;
286 Check_Policy
: declare
287 Policy
: constant Character :=
288 ALIs
.Table
(A1
).Task_Dispatching_Policy
;
291 for A2
in A1
+ 1 .. ALIs
.Last
loop
292 if ALIs
.Table
(A2
).Task_Dispatching_Policy
/= ' '
294 ALIs
.Table
(A2
).Task_Dispatching_Policy
/= Policy
296 Error_Msg_File_1
:= ALIs
.Table
(A1
).Sfile
;
297 Error_Msg_File_2
:= ALIs
.Table
(A2
).Sfile
;
299 Consistency_Error_Msg
300 ("{ and { compiled with different task" &
301 " dispatching policies");
309 end loop Find_Policy
;
312 -- If no Priority_Specific_Dispatching entries, nothing else to do
314 if Specific_Dispatching
.Last
>= Specific_Dispatching
.First
then
316 -- Find out the maximum priority value for which one of the
317 -- Priority_Specific_Dispatching pragmas applies.
320 for J
in Specific_Dispatching
.First
.. Specific_Dispatching
.Last
loop
321 if Specific_Dispatching
.Table
(J
).Last_Priority
> Max_Prio
then
322 Max_Prio
:= Specific_Dispatching
.Table
(J
).Last_Priority
;
326 -- Now establish tables to be used for consistency checking
329 -- The following record type is used to record locations of the
330 -- Priority_Specific_Dispatching pragmas applying to the Priority.
332 type Specific_Dispatching_Entry
is record
333 Dispatching_Policy
: Character := ' ';
334 -- First character (upper case) of corresponding policy name
336 Afile
: ALI_Id
:= No_ALI_Id
;
337 -- ALI file that generated Priority Specific Dispatching
338 -- entry for consistency message.
341 -- Line numbers from Priority_Specific_Dispatching pragma
344 PSD_Table
: array (0 .. Max_Prio
) of Specific_Dispatching_Entry
:=
345 (others => Specific_Dispatching_Entry
'
346 (Dispatching_Policy => ' ',
349 -- Array containing an entry per priority containing the location
350 -- where there is a Priority_Specific_Dispatching pragma that
351 -- applies to the priority.
354 for F in ALIs.First .. ALIs.Last loop
355 for K in ALIs.Table (F).First_Specific_Dispatching ..
356 ALIs.Table (F).Last_Specific_Dispatching
359 DTK : Specific_Dispatching_Record
360 renames Specific_Dispatching.Table (K);
362 -- Check whether pragma Task_Dispatching_Policy and
363 -- pragma Priority_Specific_Dispatching are used in the
366 if Task_Dispatching_Policy_Specified /= ' ' then
367 Error_Msg_File_1 := ALIs.Table (F).Sfile;
369 ALIs.Table (TDP_Pragma_Afile).Sfile;
371 Error_Msg_Nat_1 := DTK.PSD_Pragma_Line;
373 Consistency_Error_Msg
374 ("Priority_Specific_Dispatching at {:#" &
375 " incompatible with Task_Dispatching_Policy at {");
378 -- Ceiling_Locking must also be specified for a partition
379 -- with at least one Priority_Specific_Dispatching
382 if Locking_Policy_Specified /= ' '
383 and then Locking_Policy_Specified /= 'C
'
385 for A in ALIs.First .. ALIs.Last loop
386 if ALIs.Table (A).Locking_Policy /= ' '
387 and then ALIs.Table (A).Locking_Policy /= 'C
'
389 Error_Msg_File_1 := ALIs.Table (F).Sfile;
390 Error_Msg_File_2 := ALIs.Table (A).Sfile;
392 Error_Msg_Nat_1 := DTK.PSD_Pragma_Line;
394 Consistency_Error_Msg
395 ("Priority_Specific_Dispatching at {:#" &
396 " incompatible with Locking_Policy at {");
401 -- Check overlapping priority ranges
403 Find_Overlapping : for Prio in
404 DTK.First_Priority .. DTK.Last_Priority
406 if PSD_Table (Prio).Afile = No_ALI_Id then
408 (Dispatching_Policy => DTK.Dispatching_Policy,
409 Afile => F, Loc => DTK.PSD_Pragma_Line);
411 elsif PSD_Table (Prio).Dispatching_Policy /=
412 DTK.Dispatching_Policy
416 ALIs.Table (PSD_Table (Prio).Afile).Sfile;
417 Error_Msg_File_2 := ALIs.Table (F).Sfile;
418 Error_Msg_Nat_1 := PSD_Table (Prio).Loc;
419 Error_Msg_Nat_2 := DTK.PSD_Pragma_Line;
421 Consistency_Error_Msg
422 ("overlapping priority ranges at {:# and {:#");
424 exit Find_Overlapping;
426 end loop Find_Overlapping;
432 end Check_Consistent_Dispatching_Policy;
434 ---------------------------------------------------
435 -- Check_Consistent_Dynamic_Elaboration_Checking --
436 ---------------------------------------------------
438 -- The rule here is that if a unit has dynamic elaboration checks,
439 -- then any unit it withs must meeting one of the following criteria:
441 -- 1. There is a pragma Elaborate_All for the with'ed unit
442 -- 2. The with'ed unit was compiled with dynamic elaboration checks
443 -- 3. The with'ed unit has pragma Preelaborate or Pure
444 -- 4. It is an internal GNAT unit (including children of GNAT)
446 procedure Check_Consistent_Dynamic_Elaboration_Checking is
448 if Dynamic_Elaboration_Checks_Specified then
449 for U in First_Unit_Entry .. Units.Last loop
451 UR : Unit_Record renames Units.Table (U);
454 if UR.Dynamic_Elab then
455 for W in UR.First_With .. UR.Last_With loop
457 WR : With_Record renames Withs.Table (W);
460 if Get_Name_Table_Info (WR.Uname) /= 0 then
462 WU : Unit_Record renames
465 (Get_Name_Table_Info (WR.Uname)));
468 -- Case 1. Elaborate_All for with'ed unit
470 if WR.Elaborate_All then
473 -- Case 2. With'ed unit has dynamic elab checks
475 elsif WU.Dynamic_Elab then
478 -- Case 3. With'ed unit is Preelaborate or Pure
480 elsif WU.Preelab or else WU.Pure then
483 -- Case 4. With'ed unit is internal file
485 elsif Is_Internal_File_Name (WU.Sfile) then
488 -- Issue warning, not one of the safe cases
491 Error_Msg_File_1 := UR.Sfile;
493 ("?{ has dynamic elaboration checks " &
496 Error_Msg_File_1 := WU.Sfile;
498 ("? { which has static elaboration " &
501 Warnings_Detected := Warnings_Detected - 1;
511 end Check_Consistent_Dynamic_Elaboration_Checking;
513 --------------------------------------------
514 -- Check_Consistent_Floating_Point_Format --
515 --------------------------------------------
517 -- The rule is that all files must be compiled with the same setting
518 -- for the floating-point format.
520 procedure Check_Consistent_Floating_Point_Format is
522 -- First search for a unit specifying a floating-point format and then
523 -- check all remaining units against it.
525 Find_Format : for A1 in ALIs.First .. ALIs.Last loop
526 if ALIs.Table (A1).Float_Format /= ' ' then
527 Check_Format : declare
528 Format : constant Character := ALIs.Table (A1).Float_Format;
530 for A2 in A1 + 1 .. ALIs.Last loop
531 if ALIs.Table (A2).Float_Format /= Format then
532 Error_Msg_File_1 := ALIs.Table (A1).Sfile;
533 Error_Msg_File_2 := ALIs.Table (A2).Sfile;
535 Consistency_Error_Msg
536 ("{ and { compiled with different " &
537 "floating-point representations");
545 end loop Find_Format;
546 end Check_Consistent_Floating_Point_Format;
548 ---------------------------------------
549 -- Check_Consistent_Interrupt_States --
550 ---------------------------------------
552 -- The rule is that if the state of a given interrupt is specified
553 -- in more than one unit, it must be specified with a consistent state.
555 procedure Check_Consistent_Interrupt_States is
559 -- If no Interrupt_State entries, nothing to do
561 if Interrupt_States.Last < Interrupt_States.First then
565 -- First find out the maximum interrupt value
568 for J in Interrupt_States.First .. Interrupt_States.Last loop
569 if Interrupt_States.Table (J).Interrupt_Id > Max_Intrup then
570 Max_Intrup := Interrupt_States.Table (J).Interrupt_Id;
574 -- Now establish tables to be used for consistency checking
577 Istate : array (0 .. Max_Intrup) of Character := (others => 'n
');
578 -- Interrupt state entries, 'u
'/'s
'/'r
' or 'n
' to indicate an
579 -- entry that has not been set.
581 Afile : array (0 .. Max_Intrup) of ALI_Id;
582 -- ALI file that generated Istate entry for consistency message
584 Loc : array (0 .. Max_Intrup) of Nat;
585 -- Line numbers from IS pragma generating Istate entry
588 -- Interrupt number from entry being tested
591 -- Interrupt state from entry being tested
594 -- Line number from entry being tested
597 for F in ALIs.First .. ALIs.Last loop
598 for K in ALIs.Table (F).First_Interrupt_State ..
599 ALIs.Table (F).Last_Interrupt_State
601 Inum := Interrupt_States.Table (K).Interrupt_Id;
602 Stat := Interrupt_States.Table (K).Interrupt_State;
603 Lnum := Interrupt_States.Table (K).IS_Pragma_Line;
605 if Istate (Inum) = 'n
' then
606 Istate (Inum) := Stat;
610 elsif Istate (Inum) /= Stat then
611 Error_Msg_File_1 := ALIs.Table (Afile (Inum)).Sfile;
612 Error_Msg_File_2 := ALIs.Table (F).Sfile;
613 Error_Msg_Nat_1 := Loc (Inum);
614 Error_Msg_Nat_2 := Lnum;
616 Consistency_Error_Msg
617 ("inconsistent interrupt states at {:# and {:#");
622 end Check_Consistent_Interrupt_States;
624 -------------------------------------
625 -- Check_Consistent_Locking_Policy --
626 -------------------------------------
628 -- The rule is that all files for which the locking policy is
629 -- significant must be compiled with the same setting.
631 procedure Check_Consistent_Locking_Policy is
633 -- First search for a unit specifying a policy and then
634 -- check all remaining units against it.
636 Find_Policy : for A1 in ALIs.First .. ALIs.Last loop
637 if ALIs.Table (A1).Locking_Policy /= ' ' then
638 Check_Policy : declare
639 Policy : constant Character := ALIs.Table (A1).Locking_Policy;
642 for A2 in A1 + 1 .. ALIs.Last loop
643 if ALIs.Table (A2).Locking_Policy /= ' '
645 ALIs.Table (A2).Locking_Policy /= Policy
647 Error_Msg_File_1 := ALIs.Table (A1).Sfile;
648 Error_Msg_File_2 := ALIs.Table (A2).Sfile;
650 Consistency_Error_Msg
651 ("{ and { compiled with different locking policies");
659 end loop Find_Policy;
660 end Check_Consistent_Locking_Policy;
662 ----------------------------------------
663 -- Check_Consistent_Normalize_Scalars --
664 ----------------------------------------
666 -- The rule is that if any unit is compiled with Normalized_Scalars,
667 -- then all other units in the partition must also be compiled with
668 -- Normalized_Scalars in effect.
670 -- There is some issue as to whether this consistency check is desirable,
671 -- it is certainly required at the moment by the RM. We should keep a watch
672 -- on the ARG and HRG deliberations here. GNAT no longer depends on this
673 -- consistency (it used to do so, but that is no longer the case, since
674 -- pragma Initialize_Scalars pragma does not require consistency.)
676 procedure Check_Consistent_Normalize_Scalars is
678 if Normalize_Scalars_Specified and No_Normalize_Scalars_Specified then
679 Consistency_Error_Msg
680 ("some but not all files compiled with Normalize_Scalars");
683 Write_Str ("files compiled with Normalize_Scalars");
686 for A1 in ALIs.First .. ALIs.Last loop
687 if ALIs.Table (A1).Normalize_Scalars then
689 Write_Name (ALIs.Table (A1).Sfile);
695 Write_Str ("files compiled without Normalize_Scalars");
698 for A1 in ALIs.First .. ALIs.Last loop
699 if not ALIs.Table (A1).Normalize_Scalars then
701 Write_Name (ALIs.Table (A1).Sfile);
706 end Check_Consistent_Normalize_Scalars;
708 -----------------------------------------
709 -- Check_Consistent_Optimize_Alignment --
710 -----------------------------------------
712 -- The rule is that all units which depend on the global default setting
713 -- of Optimize_Alignment must be compiled with the same setting for this
714 -- default. Units which specify an explicit local value for this setting
715 -- are exempt from the consistency rule (this includes all internal units).
717 procedure Check_Consistent_Optimize_Alignment is
718 OA_Setting : Character := ' ';
719 -- Reset when we find a unit that depends on the default and does
720 -- not have a local specification of the Optimize_Alignment setting.
723 -- Id of unit from which OA_Setting was set
728 for U in First_Unit_Entry .. Units.Last loop
729 C := Units.Table (U).Optimize_Alignment;
732 if OA_Setting = ' ' then
736 elsif OA_Setting = C then
740 Error_Msg_Unit_1 := Units.Table (OA_Unit).Uname;
741 Error_Msg_Unit_2 := Units.Table (U).Uname;
743 Consistency_Error_Msg
744 ("$ and $ compiled with different "
745 & "default Optimize_Alignment settings");
750 end Check_Consistent_Optimize_Alignment;
752 ---------------------------------------------------
753 -- Check_Consistent_Partition_Elaboration_Policy --
754 ---------------------------------------------------
756 -- The rule is that all files for which the partition elaboration policy is
757 -- significant must be compiled with the same setting.
759 procedure Check_Consistent_Partition_Elaboration_Policy is
761 -- First search for a unit specifying a policy and then
762 -- check all remaining units against it.
764 Find_Policy : for A1 in ALIs.First .. ALIs.Last loop
765 if ALIs.Table (A1).Partition_Elaboration_Policy /= ' ' then
766 Check_Policy : declare
767 Policy : constant Character :=
768 ALIs.Table (A1).Partition_Elaboration_Policy;
771 for A2 in A1 + 1 .. ALIs.Last loop
772 if ALIs.Table (A2).Partition_Elaboration_Policy /= ' '
774 ALIs.Table (A2).Partition_Elaboration_Policy /= Policy
776 Error_Msg_File_1 := ALIs.Table (A1).Sfile;
777 Error_Msg_File_2 := ALIs.Table (A2).Sfile;
779 Consistency_Error_Msg
780 ("{ and { compiled with different partition "
781 & "elaboration policies");
787 -- A No_Task_Hierarchy restriction must be specified for the
788 -- Sequential policy (RM H.6(6/2)).
790 if Partition_Elaboration_Policy_Specified = 'S
'
791 and then not Cumulative_Restrictions.Set (No_Task_Hierarchy)
793 Error_Msg_File_1 := ALIs.Table (A1).Sfile;
795 ("{ has sequential partition elaboration policy, but no");
797 ("pragma Restrictions (No_Task_Hierarchy) was specified");
802 end loop Find_Policy;
803 end Check_Consistent_Partition_Elaboration_Policy;
805 -------------------------------------
806 -- Check_Consistent_Queuing_Policy --
807 -------------------------------------
809 -- The rule is that all files for which the queuing policy is
810 -- significant must be compiled with the same setting.
812 procedure Check_Consistent_Queuing_Policy is
814 -- First search for a unit specifying a policy and then
815 -- check all remaining units against it.
817 Find_Policy : for A1 in ALIs.First .. ALIs.Last loop
818 if ALIs.Table (A1).Queuing_Policy /= ' ' then
819 Check_Policy : declare
820 Policy : constant Character := ALIs.Table (A1).Queuing_Policy;
822 for A2 in A1 + 1 .. ALIs.Last loop
823 if ALIs.Table (A2).Queuing_Policy /= ' '
825 ALIs.Table (A2).Queuing_Policy /= Policy
827 Error_Msg_File_1 := ALIs.Table (A1).Sfile;
828 Error_Msg_File_2 := ALIs.Table (A2).Sfile;
830 Consistency_Error_Msg
831 ("{ and { compiled with different queuing policies");
839 end loop Find_Policy;
840 end Check_Consistent_Queuing_Policy;
842 -----------------------------------
843 -- Check_Consistent_Restrictions --
844 -----------------------------------
846 -- The rule is that if a restriction is specified in any unit, then all
847 -- units must obey the restriction. The check applies only to restrictions
848 -- which require partition wide consistency, and not to internal units.
850 procedure Check_Consistent_Restrictions is
851 Restriction_File_Output : Boolean;
852 -- Shows if we have output header messages for restriction violation
854 procedure Print_Restriction_File (R : All_Restrictions);
855 -- Print header line for R if not printed yet
857 ----------------------------
858 -- Print_Restriction_File --
859 ----------------------------
861 procedure Print_Restriction_File (R : All_Restrictions) is
863 if not Restriction_File_Output then
864 Restriction_File_Output := True;
866 -- Find an ali file specifying the restriction
868 for A in ALIs.First .. ALIs.Last loop
869 if ALIs.Table (A).Restrictions.Set (R)
870 and then (R in All_Boolean_Restrictions
871 or else ALIs.Table (A).Restrictions.Value (R) =
872 Cumulative_Restrictions.Value (R))
874 -- We have found that ALI file A specifies the restriction
875 -- that is being violated (the minimum value is specified
876 -- in the case of a parameter restriction).
879 M1 : constant String := "{ has restriction ";
880 S : constant String := Restriction_Id'Image (R);
881 M2 : String (1 .. 2000); -- big enough!
885 Name_Buffer (1 .. S'Length) := S;
886 Name_Len := S'Length;
887 Set_Casing (Mixed_Case);
891 M2 (P .. P + S'Length - 1) := Name_Buffer (1 .. S'Length);
894 if R in All_Parameter_Restrictions then
895 M2 (P .. P + 4) := " => #";
897 Int (Cumulative_Restrictions.Value (R));
901 Error_Msg_File_1 := ALIs.Table (A).Sfile;
902 Consistency_Error_Msg (M2 (1 .. P - 1));
903 Consistency_Error_Msg
904 ("but the following files violate this restriction:");
910 end Print_Restriction_File;
912 -- Start of processing for Check_Consistent_Restrictions
915 -- A special test, if we have a main program, then if it has an
916 -- allocator in the body, this is considered to be a violation of
917 -- the restriction No_Allocators_After_Elaboration. We just mark
918 -- this restriction and then the normal circuit will flag it.
921 and then ALIs.Table (ALIs.First).Main_Program /= None
922 and then not No_Main_Subprogram
923 and then ALIs.Table (ALIs.First).Allocator_In_Body
925 Cumulative_Restrictions.Violated
926 (No_Allocators_After_Elaboration) := True;
927 ALIs.Table (ALIs.First).Restrictions.Violated
928 (No_Allocators_After_Elaboration) := True;
931 -- Loop through all restriction violations
933 for R in All_Restrictions loop
935 -- Check for violation of this restriction
937 if Cumulative_Restrictions.Set (R)
938 and then Cumulative_Restrictions.Violated (R)
939 and then (R in Partition_Boolean_Restrictions
940 or else (R in All_Parameter_Restrictions
942 Cumulative_Restrictions.Count (R) >
943 Cumulative_Restrictions.Value (R)))
945 Restriction_File_Output := False;
947 -- Loop through files looking for violators
949 for A2 in ALIs.First .. ALIs.Last loop
951 T : ALIs_Record renames ALIs.Table (A2);
954 if T.Restrictions.Violated (R) then
956 -- We exclude predefined files from the list of
957 -- violators. This should be rethought. It is not
958 -- clear that this is the right thing to do, that
959 -- is particularly the case for restricted runtimes.
961 if not Is_Internal_File_Name (T.Sfile) then
963 -- Case of Boolean restriction, just print file name
965 if R in All_Boolean_Restrictions then
966 Print_Restriction_File (R);
967 Error_Msg_File_1 := T.Sfile;
968 Consistency_Error_Msg (" {");
970 -- Case of Parameter restriction where violation
971 -- count exceeds restriction value, print file
972 -- name and count, adding "at least" if the
973 -- exact count is not known.
975 elsif R in Checked_Add_Parameter_Restrictions
976 or else T.Restrictions.Count (R) >
977 Cumulative_Restrictions.Value (R)
979 Print_Restriction_File (R);
980 Error_Msg_File_1 := T.Sfile;
981 Error_Msg_Nat_1 := Int (T.Restrictions.Count (R));
983 if T.Restrictions.Unknown (R) then
984 Consistency_Error_Msg
985 (" { (count = at least #)");
987 Consistency_Error_Msg
998 -- Now deal with No_Dependence indications. Note that we put the loop
999 -- through entries in the no dependency table first, since this loop
1000 -- is most often empty (no such pragma Restrictions in use).
1002 for ND in No_Deps.First .. No_Deps.Last loop
1004 ND_Unit : constant Name_Id := No_Deps.Table (ND).No_Dep_Unit;
1006 for J in ALIs.First .. ALIs.Last loop
1008 A : ALIs_Record renames ALIs.Table (J);
1011 for K in A.First_Unit .. A.Last_Unit loop
1013 U : Unit_Record renames Units.Table (K);
1015 for L in U.First_With .. U.Last_With loop
1017 (Withs.Table (L).Uname, ND_Unit)
1019 Error_Msg_File_1 := U.Sfile;
1020 Error_Msg_Name_1 := ND_Unit;
1021 Consistency_Error_Msg
1022 ("file { violates restriction " &
1023 "No_Dependence => %");
1032 end Check_Consistent_Restrictions;
1034 ------------------------------------------------------------
1035 -- Check_Consistent_Restriction_No_Default_Initialization --
1036 ------------------------------------------------------------
1038 -- The Restriction (No_Default_Initialization) has special consistency
1039 -- rules. The rule is that no unit compiled without this restriction
1040 -- that violates the restriction can WITH a unit that is compiled with
1043 procedure Check_Consistent_Restriction_No_Default_Initialization is
1045 -- Nothing to do if no one set this restriction
1047 if not Cumulative_Restrictions.Set (No_Default_Initialization) then
1051 -- Nothing to do if no one violates the restriction
1053 if not Cumulative_Restrictions.Violated (No_Default_Initialization) then
1057 -- Otherwise we go into a full scan to find possible problems
1059 for U in Units.First .. Units.Last loop
1061 UTE : Unit_Record renames Units.Table (U);
1062 ATE : ALIs_Record renames ALIs.Table (UTE.My_ALI);
1065 if ATE.Restrictions.Violated (No_Default_Initialization) then
1066 for W in UTE.First_With .. UTE.Last_With loop
1068 AFN : constant File_Name_Type := Withs.Table (W).Afile;
1071 -- The file name may not be present for withs of certain
1072 -- generic run-time files. The test can be safely left
1073 -- out in such cases anyway.
1075 if AFN /= No_File then
1077 WAI : constant ALI_Id :=
1078 ALI_Id (Get_Name_Table_Info (AFN));
1079 WTE : ALIs_Record renames ALIs.Table (WAI);
1082 if WTE.Restrictions.Set
1083 (No_Default_Initialization)
1085 Error_Msg_Unit_1 := UTE.Uname;
1086 Consistency_Error_Msg
1087 ("unit $ compiled without restriction "
1088 & "No_Default_Initialization");
1089 Error_Msg_Unit_1 := Withs.Table (W).Uname;
1090 Consistency_Error_Msg
1091 ("withs unit $, compiled with restriction "
1092 & "No_Default_Initialization");
1101 end Check_Consistent_Restriction_No_Default_Initialization;
1103 ---------------------------------------------------
1104 -- Check_Consistent_Zero_Cost_Exception_Handling --
1105 ---------------------------------------------------
1107 -- Check consistent zero cost exception handling. The rule is that
1108 -- all units must have the same exception handling mechanism.
1110 procedure Check_Consistent_Zero_Cost_Exception_Handling is
1112 Check_Mechanism : for A1 in ALIs.First + 1 .. ALIs.Last loop
1113 if ALIs.Table (A1).Zero_Cost_Exceptions /=
1114 ALIs.Table (ALIs.First).Zero_Cost_Exceptions
1116 Error_Msg_File_1 := ALIs.Table (A1).Sfile;
1117 Error_Msg_File_2 := ALIs.Table (ALIs.First).Sfile;
1119 Consistency_Error_Msg ("{ and { compiled with different "
1120 & "exception handling mechanisms");
1122 end loop Check_Mechanism;
1123 end Check_Consistent_Zero_Cost_Exception_Handling;
1125 -------------------------------
1126 -- Check_Duplicated_Subunits --
1127 -------------------------------
1129 procedure Check_Duplicated_Subunits is
1131 for J in Sdep.First .. Sdep.Last loop
1132 if Sdep.Table (J).Subunit_Name /= No_Name then
1133 Get_Decoded_Name_String (Sdep.Table (J).Subunit_Name);
1134 Name_Len := Name_Len + 2;
1135 Name_Buffer (Name_Len - 1) := '%';
1137 -- See if there is a body or spec with the same name
1139 for K in Boolean loop
1141 Name_Buffer (Name_Len) := 'b
';
1143 Name_Buffer (Name_Len) := 's
';
1147 Unit : constant Unit_Name_Type := Name_Find;
1148 Info : constant Int := Get_Name_Table_Info (Unit);
1153 Write_Str ("error: subunit """);
1154 Write_Name_Decoded (Sdep.Table (J).Subunit_Name);
1155 Write_Str (""" in file """);
1156 Write_Name_Decoded (Sdep.Table (J).Sfile);
1159 Write_Str (" has same name as unit
""");
1160 Write_Unit_Name (Units.Table (Unit_Id (Info)).Uname);
1161 Write_Str (""" found
in file
""");
1162 Write_Name_Decoded (Units.Table (Unit_Id (Info)).Sfile);
1165 Write_Str (" this is not allowed within a single "
1166 & "partition (RM 10.2(19))");
1168 Osint.Exit_Program (Osint.E_Fatal);
1174 end Check_Duplicated_Subunits;
1176 --------------------
1177 -- Check_Versions --
1178 --------------------
1180 procedure Check_Versions is
1181 VL : constant Natural := ALIs.Table (ALIs.First).Ver_Len;
1184 for A in ALIs.First .. ALIs.Last loop
1185 if ALIs.Table (A).Ver_Len /= VL
1186 or else ALIs.Table (A).Ver (1 .. VL) /=
1187 ALIs.Table (ALIs.First).Ver (1 .. VL)
1189 Error_Msg_File_1 := ALIs.Table (A).Sfile;
1190 Error_Msg_File_2 := ALIs.Table (ALIs.First).Sfile;
1192 Consistency_Error_Msg
1193 ("{ and { compiled with different GNAT versions");
1198 ---------------------------
1199 -- Consistency_Error_Msg --
1200 ---------------------------
1202 procedure Consistency_Error_Msg (Msg : String) is
1204 if Tolerate_Consistency_Errors then
1206 -- If consistency errors are tolerated,
1207 -- output the message as a warning.
1209 Error_Msg ('?
' & Msg);
1211 -- Otherwise the consistency error is a true error
1216 end Consistency_Error_Msg;
1222 function Same_Unit (U1 : Unit_Name_Type; U2 : Name_Id) return Boolean is
1224 -- Note, the string U1 has a terminating %s or %b, U2 does not
1226 if Length_Of_Name (U1) - 2 = Length_Of_Name (U2) then
1227 Get_Name_String (U1);
1230 U1_Str : constant String := Name_Buffer (1 .. Name_Len - 2);
1232 Get_Name_String (U2);
1233 return U1_Str = Name_Buffer (1 .. Name_Len);