1 ------------------------------------------------------------------------------
3 -- GNAT COMPILER COMPONENTS --
9 -- Copyright (C) 1992-2007, 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.
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_Queuing_Policy
;
55 procedure Check_Consistent_Restrictions
;
56 procedure Check_Consistent_Zero_Cost_Exception_Handling
;
58 procedure Consistency_Error_Msg
(Msg
: String);
59 -- Produce an error or a warning message, depending on whether an
60 -- inconsistent configuration is permitted or not.
62 function Same_Unit
(U1
: Unit_Name_Type
; U2
: Name_Id
) return Boolean;
63 -- Used to compare two unit names for No_Dependence checks. U1 is in
64 -- standard unit name format, and U2 is in literal form with periods.
66 -------------------------------------
67 -- Check_Configuration_Consistency --
68 -------------------------------------
70 procedure Check_Configuration_Consistency
is
72 if Float_Format_Specified
/= ' ' then
73 Check_Consistent_Floating_Point_Format
;
76 if Queuing_Policy_Specified
/= ' ' then
77 Check_Consistent_Queuing_Policy
;
80 if Locking_Policy_Specified
/= ' ' then
81 Check_Consistent_Locking_Policy
;
84 if Zero_Cost_Exceptions_Specified
then
85 Check_Consistent_Zero_Cost_Exception_Handling
;
88 Check_Consistent_Normalize_Scalars
;
89 Check_Consistent_Dynamic_Elaboration_Checking
;
91 Check_Consistent_Restrictions
;
92 Check_Consistent_Interrupt_States
;
93 Check_Consistent_Dispatching_Policy
;
94 end Check_Configuration_Consistency
;
96 -----------------------
97 -- Check_Consistency --
98 -----------------------
100 procedure Check_Consistency
is
102 -- Source file Id for this Sdep entry
104 ALI_Path_Id
: File_Name_Type
;
107 -- First, we go through the source table to see if there are any cases
108 -- in which we should go after source files and compute checksums of
109 -- the source files. We need to do this for any file for which we have
110 -- mismatching time stamps and (so far) matching checksums.
112 for S
in Source
.First
.. Source
.Last
loop
114 -- If all time stamps for a file match, then there is nothing to
115 -- do, since we will not be checking checksums in that case anyway
117 if Source
.Table
(S
).All_Timestamps_Match
then
120 -- If we did not find the source file, then we can't compute its
121 -- checksum anyway. Note that when we have a time stamp mismatch,
122 -- we try to find the source file unconditionally (i.e. if
123 -- Check_Source_Files is False).
125 elsif not Source
.Table
(S
).Source_Found
then
128 -- If we already have non-matching or missing checksums, then no
129 -- need to try going after source file, since we won't trust the
130 -- checksums in any case.
132 elsif not Source
.Table
(S
).All_Checksums_Match
then
135 -- Now we have the case where we have time stamp mismatches, and
136 -- the source file is around, but so far all checksums match. This
137 -- is the case where we need to compute the checksum from the source
138 -- file, since otherwise we would ignore the time stamp mismatches,
139 -- and that is wrong if the checksum of the source does not agree
140 -- with the checksums in the ALI files.
142 elsif Check_Source_Files
then
143 if not Checksums_Match
144 (Source
.Table
(S
).Checksum
,
145 Get_File_Checksum
(Source
.Table
(S
).Sfile
))
147 Source
.Table
(S
).All_Checksums_Match
:= False;
152 -- Loop through ALI files
154 ALIs_Loop
: for A
in ALIs
.First
.. ALIs
.Last
loop
156 -- Loop through Sdep entries in one ALI file
159 ALIs
.Table
(A
).First_Sdep
.. ALIs
.Table
(A
).Last_Sdep
161 if Sdep
.Table
(D
).Dummy_Entry
then
165 Src
:= Source_Id
(Get_Name_Table_Info
(Sdep
.Table
(D
).Sfile
));
167 -- If the time stamps match, or all checksums match, then we
168 -- are OK, otherwise we have a definite error.
170 if Sdep
.Table
(D
).Stamp
/= Source
.Table
(Src
).Stamp
171 and then not Source
.Table
(Src
).All_Checksums_Match
173 Error_Msg_File_1
:= ALIs
.Table
(A
).Sfile
;
174 Error_Msg_File_2
:= Sdep
.Table
(D
).Sfile
;
176 -- Two styles of message, depending on whether or not
177 -- the updated file is the one that must be recompiled
179 if Error_Msg_File_1
= Error_Msg_File_2
then
180 if Tolerate_Consistency_Errors
then
182 ("?{ has been modified and should be recompiled");
185 ("{ has been modified and must be recompiled");
190 Osint
.Find_File
((ALIs
.Table
(A
).Afile
), Osint
.Library
);
191 if Osint
.Is_Readonly_Library
(ALI_Path_Id
) then
192 if Tolerate_Consistency_Errors
then
193 Error_Msg
("?{ should be recompiled");
194 Error_Msg_File_1
:= ALI_Path_Id
;
195 Error_Msg
("?({ is obsolete and read-only)");
197 Error_Msg
("{ must be compiled");
198 Error_Msg_File_1
:= ALI_Path_Id
;
199 Error_Msg
("({ is obsolete and read-only)");
202 elsif Tolerate_Consistency_Errors
then
204 ("?{ should be recompiled ({ has been modified)");
207 Error_Msg
("{ must be recompiled ({ has been modified)");
211 if (not Tolerate_Consistency_Errors
) and Verbose_Mode
then
212 Error_Msg_File_1
:= Sdep
.Table
(D
).Sfile
;
214 ("{ time stamp " & String (Source
.Table
(Src
).Stamp
));
216 Error_Msg_File_1
:= Sdep
.Table
(D
).Sfile
;
217 -- Something wrong here, should be different file ???
220 (" conflicts with { timestamp " &
221 String (Sdep
.Table
(D
).Stamp
));
224 -- Exit from the loop through Sdep entries once we find one
225 -- that does not match.
234 end Check_Consistency
;
236 -----------------------------------------
237 -- Check_Consistent_Dispatching_Policy --
238 -----------------------------------------
240 -- The rule is that all files for which the dispatching policy is
241 -- significant must meet the following rules:
243 -- 1. All files for which a task dispatching policy is significant must
244 -- be compiled with the same setting.
246 -- 2. If a partition contains one or more Priority_Specific_Dispatching
247 -- pragmas it cannot contain a Task_Dispatching_Policy pragma.
249 -- 3. No overlap is allowed in the priority ranges specified in
250 -- Priority_Specific_Dispatching pragmas within the same partition.
252 -- 4. If a partition contains one or more Priority_Specific_Dispatching
253 -- pragmas then the Ceiling_Locking policy is the only one allowed for
256 procedure Check_Consistent_Dispatching_Policy
is
258 -- Maximum priority value for which a Priority_Specific_Dispatching
259 -- pragma has been specified.
261 TDP_Pragma_Afile
: ALI_Id
:= No_ALI_Id
;
262 -- ALI file where a Task_Dispatching_Policy pragma appears
265 -- Consistency checks in units specifying a Task_Dispatching_Policy
267 if Task_Dispatching_Policy_Specified
/= ' ' then
268 Find_Policy
: for A1
in ALIs
.First
.. ALIs
.Last
loop
269 if ALIs
.Table
(A1
).Task_Dispatching_Policy
/= ' ' then
271 -- Store the place where the first task dispatching pragma
272 -- appears. We may need this value for issuing consistency
273 -- errors if Priority_Specific_Dispatching pragmas are used.
275 TDP_Pragma_Afile
:= A1
;
277 Check_Policy
: declare
278 Policy
: constant Character :=
279 ALIs
.Table
(A1
).Task_Dispatching_Policy
;
282 for A2
in A1
+ 1 .. ALIs
.Last
loop
283 if ALIs
.Table
(A2
).Task_Dispatching_Policy
/= ' '
285 ALIs
.Table
(A2
).Task_Dispatching_Policy
/= Policy
287 Error_Msg_File_1
:= ALIs
.Table
(A1
).Sfile
;
288 Error_Msg_File_2
:= ALIs
.Table
(A2
).Sfile
;
290 Consistency_Error_Msg
291 ("{ and { compiled with different task" &
292 " dispatching policies");
300 end loop Find_Policy
;
303 -- If no Priority_Specific_Dispatching entries, nothing else to do
305 if Specific_Dispatching
.Last
>= Specific_Dispatching
.First
then
307 -- Find out the maximum priority value for which one of the
308 -- Priority_Specific_Dispatching pragmas applies.
311 for J
in Specific_Dispatching
.First
.. Specific_Dispatching
.Last
loop
312 if Specific_Dispatching
.Table
(J
).Last_Priority
> Max_Prio
then
313 Max_Prio
:= Specific_Dispatching
.Table
(J
).Last_Priority
;
317 -- Now establish tables to be used for consistency checking
320 -- The following record type is used to record locations of the
321 -- Priority_Specific_Dispatching pragmas applying to the Priority.
323 type Specific_Dispatching_Entry
is record
324 Dispatching_Policy
: Character := ' ';
325 -- First character (upper case) of corresponding policy name
327 Afile
: ALI_Id
:= No_ALI_Id
;
328 -- ALI file that generated Priority Specific Dispatching
329 -- entry for consistency message.
332 -- Line numbers from Priority_Specific_Dispatching pragma
335 PSD_Table
: array (0 .. Max_Prio
) of Specific_Dispatching_Entry
:=
336 (others => Specific_Dispatching_Entry
'
337 (Dispatching_Policy => ' ',
340 -- Array containing an entry per priority containing the location
341 -- where there is a Priority_Specific_Dispatching pragma that
342 -- applies to the priority.
345 for F in ALIs.First .. ALIs.Last loop
346 for K in ALIs.Table (F).First_Specific_Dispatching ..
347 ALIs.Table (F).Last_Specific_Dispatching
350 DTK : Specific_Dispatching_Record
351 renames Specific_Dispatching.Table (K);
353 -- Check whether pragma Task_Dispatching_Policy and
354 -- pragma Priority_Specific_Dispatching are used in the
357 if Task_Dispatching_Policy_Specified /= ' ' then
358 Error_Msg_File_1 := ALIs.Table (F).Sfile;
360 ALIs.Table (TDP_Pragma_Afile).Sfile;
362 Error_Msg_Nat_1 := DTK.PSD_Pragma_Line;
364 Consistency_Error_Msg
365 ("Priority_Specific_Dispatching at {:#" &
366 " incompatible with Task_Dispatching_Policy at {");
369 -- Ceiling_Locking must also be specified for a partition
370 -- with at least one Priority_Specific_Dispatching
373 if Locking_Policy_Specified /= ' '
374 and then Locking_Policy_Specified /= 'C
'
376 for A in ALIs.First .. ALIs.Last loop
377 if ALIs.Table (A).Locking_Policy /= ' '
378 and then ALIs.Table (A).Locking_Policy /= 'C
'
380 Error_Msg_File_1 := ALIs.Table (F).Sfile;
381 Error_Msg_File_2 := ALIs.Table (A).Sfile;
383 Error_Msg_Nat_1 := DTK.PSD_Pragma_Line;
385 Consistency_Error_Msg
386 ("Priority_Specific_Dispatching at {:#" &
387 " incompatible with Locking_Policy at {");
392 -- Check overlapping priority ranges
394 Find_Overlapping : for Prio in
395 DTK.First_Priority .. DTK.Last_Priority
397 if PSD_Table (Prio).Afile = No_ALI_Id then
399 (Dispatching_Policy => DTK.Dispatching_Policy,
400 Afile => F, Loc => DTK.PSD_Pragma_Line);
402 elsif PSD_Table (Prio).Dispatching_Policy /=
403 DTK.Dispatching_Policy
407 ALIs.Table (PSD_Table (Prio).Afile).Sfile;
408 Error_Msg_File_2 := ALIs.Table (F).Sfile;
409 Error_Msg_Nat_1 := PSD_Table (Prio).Loc;
410 Error_Msg_Nat_2 := DTK.PSD_Pragma_Line;
412 Consistency_Error_Msg
413 ("overlapping priority ranges at {:# and {:#");
415 exit Find_Overlapping;
417 end loop Find_Overlapping;
423 end Check_Consistent_Dispatching_Policy;
425 ---------------------------------------------------
426 -- Check_Consistent_Dynamic_Elaboration_Checking --
427 ---------------------------------------------------
429 -- The rule here is that if a unit has dynamic elaboration checks,
430 -- then any unit it withs must meeting one of the following criteria:
432 -- 1. There is a pragma Elaborate_All for the with'ed unit
433 -- 2. The with'ed unit was compiled with dynamic elaboration checks
434 -- 3. The with'ed unit has pragma Preelaborate or Pure
435 -- 4. It is an internal GNAT unit (including children of GNAT)
437 procedure Check_Consistent_Dynamic_Elaboration_Checking is
439 if Dynamic_Elaboration_Checks_Specified then
440 for U in First_Unit_Entry .. Units.Last loop
442 UR : Unit_Record renames Units.Table (U);
445 if UR.Dynamic_Elab then
446 for W in UR.First_With .. UR.Last_With loop
448 WR : With_Record renames Withs.Table (W);
451 if Get_Name_Table_Info (WR.Uname) /= 0 then
453 WU : Unit_Record renames
456 (Get_Name_Table_Info (WR.Uname)));
459 -- Case 1. Elaborate_All for with'ed unit
461 if WR.Elaborate_All then
464 -- Case 2. With'ed unit has dynamic elab checks
466 elsif WU.Dynamic_Elab then
469 -- Case 3. With'ed unit is Preelaborate or Pure
471 elsif WU.Preelab or WU.Pure then
474 -- Case 4. With'ed unit is internal file
476 elsif Is_Internal_File_Name (WU.Sfile) then
479 -- Issue warning, not one of the safe cases
482 Error_Msg_File_1 := UR.Sfile;
484 ("?{ has dynamic elaboration checks " &
487 Error_Msg_File_1 := WU.Sfile;
489 ("? { which has static elaboration " &
492 Warnings_Detected := Warnings_Detected - 1;
502 end Check_Consistent_Dynamic_Elaboration_Checking;
504 --------------------------------------------
505 -- Check_Consistent_Floating_Point_Format --
506 --------------------------------------------
508 -- The rule is that all files must be compiled with the same setting
509 -- for the floating-point format.
511 procedure Check_Consistent_Floating_Point_Format is
513 -- First search for a unit specifying a floating-point format and then
514 -- check all remaining units against it.
516 Find_Format : for A1 in ALIs.First .. ALIs.Last loop
517 if ALIs.Table (A1).Float_Format /= ' ' then
518 Check_Format : declare
519 Format : constant Character := ALIs.Table (A1).Float_Format;
521 for A2 in A1 + 1 .. ALIs.Last loop
522 if ALIs.Table (A2).Float_Format /= Format then
523 Error_Msg_File_1 := ALIs.Table (A1).Sfile;
524 Error_Msg_File_2 := ALIs.Table (A2).Sfile;
526 Consistency_Error_Msg
527 ("{ and { compiled with different " &
528 "floating-point representations");
536 end loop Find_Format;
537 end Check_Consistent_Floating_Point_Format;
539 ---------------------------------------
540 -- Check_Consistent_Interrupt_States --
541 ---------------------------------------
543 -- The rule is that if the state of a given interrupt is specified
544 -- in more than one unit, it must be specified with a consistent state.
546 procedure Check_Consistent_Interrupt_States is
550 -- If no Interrupt_State entries, nothing to do
552 if Interrupt_States.Last < Interrupt_States.First then
556 -- First find out the maximum interrupt value
559 for J in Interrupt_States.First .. Interrupt_States.Last loop
560 if Interrupt_States.Table (J).Interrupt_Id > Max_Intrup then
561 Max_Intrup := Interrupt_States.Table (J).Interrupt_Id;
565 -- Now establish tables to be used for consistency checking
568 Istate : array (0 .. Max_Intrup) of Character := (others => 'n
');
569 -- Interrupt state entries, 'u
'/'s
'/'r
' or 'n
' to indicate an
570 -- entry that has not been set.
572 Afile : array (0 .. Max_Intrup) of ALI_Id;
573 -- ALI file that generated Istate entry for consistency message
575 Loc : array (0 .. Max_Intrup) of Nat;
576 -- Line numbers from IS pragma generating Istate entry
579 -- Interrupt number from entry being tested
582 -- Interrupt state from entry being tested
585 -- Line number from entry being tested
588 for F in ALIs.First .. ALIs.Last loop
589 for K in ALIs.Table (F).First_Interrupt_State ..
590 ALIs.Table (F).Last_Interrupt_State
592 Inum := Interrupt_States.Table (K).Interrupt_Id;
593 Stat := Interrupt_States.Table (K).Interrupt_State;
594 Lnum := Interrupt_States.Table (K).IS_Pragma_Line;
596 if Istate (Inum) = 'n
' then
597 Istate (Inum) := Stat;
601 elsif Istate (Inum) /= Stat then
602 Error_Msg_File_1 := ALIs.Table (Afile (Inum)).Sfile;
603 Error_Msg_File_2 := ALIs.Table (F).Sfile;
604 Error_Msg_Nat_1 := Loc (Inum);
605 Error_Msg_Nat_2 := Lnum;
607 Consistency_Error_Msg
608 ("inconsistent interrupt states at {:# and {:#");
613 end Check_Consistent_Interrupt_States;
615 -------------------------------------
616 -- Check_Consistent_Locking_Policy --
617 -------------------------------------
619 -- The rule is that all files for which the locking policy is
620 -- significant must be compiled with the same setting.
622 procedure Check_Consistent_Locking_Policy is
624 -- First search for a unit specifying a policy and then
625 -- check all remaining units against it.
627 Find_Policy : for A1 in ALIs.First .. ALIs.Last loop
628 if ALIs.Table (A1).Locking_Policy /= ' ' then
629 Check_Policy : declare
630 Policy : constant Character := ALIs.Table (A1).Locking_Policy;
633 for A2 in A1 + 1 .. ALIs.Last loop
634 if ALIs.Table (A2).Locking_Policy /= ' ' and
635 ALIs.Table (A2).Locking_Policy /= Policy
637 Error_Msg_File_1 := ALIs.Table (A1).Sfile;
638 Error_Msg_File_2 := ALIs.Table (A2).Sfile;
640 Consistency_Error_Msg
641 ("{ and { compiled with different locking policies");
649 end loop Find_Policy;
650 end Check_Consistent_Locking_Policy;
652 ----------------------------------------
653 -- Check_Consistent_Normalize_Scalars --
654 ----------------------------------------
656 -- The rule is that if any unit is compiled with Normalized_Scalars,
657 -- then all other units in the partition must also be compiled with
658 -- Normalized_Scalars in effect.
660 -- There is some issue as to whether this consistency check is
661 -- desirable, it is certainly required at the moment by the RM.
662 -- We should keep a watch on the ARG and HRG deliberations here.
663 -- GNAT no longer depends on this consistency (it used to do so,
664 -- but that has been corrected in the latest version, since the
665 -- Initialize_Scalars pragma does not require consistency.
667 procedure Check_Consistent_Normalize_Scalars is
669 if Normalize_Scalars_Specified and No_Normalize_Scalars_Specified then
670 Consistency_Error_Msg
671 ("some but not all files compiled with Normalize_Scalars");
674 Write_Str ("files compiled with Normalize_Scalars");
677 for A1 in ALIs.First .. ALIs.Last loop
678 if ALIs.Table (A1).Normalize_Scalars then
680 Write_Name (ALIs.Table (A1).Sfile);
686 Write_Str ("files compiled without Normalize_Scalars");
689 for A1 in ALIs.First .. ALIs.Last loop
690 if not ALIs.Table (A1).Normalize_Scalars then
692 Write_Name (ALIs.Table (A1).Sfile);
697 end Check_Consistent_Normalize_Scalars;
699 -------------------------------------
700 -- Check_Consistent_Queuing_Policy --
701 -------------------------------------
703 -- The rule is that all files for which the queuing policy is
704 -- significant must be compiled with the same setting.
706 procedure Check_Consistent_Queuing_Policy is
708 -- First search for a unit specifying a policy and then
709 -- check all remaining units against it.
711 Find_Policy : for A1 in ALIs.First .. ALIs.Last loop
712 if ALIs.Table (A1).Queuing_Policy /= ' ' then
713 Check_Policy : declare
714 Policy : constant Character := ALIs.Table (A1).Queuing_Policy;
716 for A2 in A1 + 1 .. ALIs.Last loop
717 if ALIs.Table (A2).Queuing_Policy /= ' '
719 ALIs.Table (A2).Queuing_Policy /= Policy
721 Error_Msg_File_1 := ALIs.Table (A1).Sfile;
722 Error_Msg_File_2 := ALIs.Table (A2).Sfile;
724 Consistency_Error_Msg
725 ("{ and { compiled with different queuing policies");
733 end loop Find_Policy;
734 end Check_Consistent_Queuing_Policy;
736 -----------------------------------
737 -- Check_Consistent_Restrictions --
738 -----------------------------------
740 -- The rule is that if a restriction is specified in any unit,
741 -- then all units must obey the restriction. The check applies
742 -- only to restrictions which require partition wide consistency,
743 -- and not to internal units.
745 procedure Check_Consistent_Restrictions is
746 Restriction_File_Output : Boolean;
747 -- Shows if we have output header messages for restriction violation
749 procedure Print_Restriction_File (R : All_Restrictions);
750 -- Print header line for R if not printed yet
752 ----------------------------
753 -- Print_Restriction_File --
754 ----------------------------
756 procedure Print_Restriction_File (R : All_Restrictions) is
758 if not Restriction_File_Output then
759 Restriction_File_Output := True;
761 -- Find an ali file specifying the restriction
763 for A in ALIs.First .. ALIs.Last loop
764 if ALIs.Table (A).Restrictions.Set (R)
765 and then (R in All_Boolean_Restrictions
766 or else ALIs.Table (A).Restrictions.Value (R) =
767 Cumulative_Restrictions.Value (R))
769 -- We have found that ALI file A specifies the restriction
770 -- that is being violated (the minimum value is specified
771 -- in the case of a parameter restriction).
774 M1 : constant String := "{ has restriction ";
775 S : constant String := Restriction_Id'Image (R);
776 M2 : String (1 .. 200); -- big enough!
780 Name_Buffer (1 .. S'Length) := S;
781 Name_Len := S'Length;
782 Set_Casing (Mixed_Case);
786 M2 (P .. P + S'Length - 1) := Name_Buffer (1 .. S'Length);
789 if R in All_Parameter_Restrictions then
790 M2 (P .. P + 4) := " => #";
792 Int (Cumulative_Restrictions.Value (R));
796 Error_Msg_File_1 := ALIs.Table (A).Sfile;
797 Consistency_Error_Msg (M2 (1 .. P - 1));
798 Consistency_Error_Msg
799 ("but the following files violate this restriction:");
805 end Print_Restriction_File;
807 -- Start of processing for Check_Consistent_Restrictions
810 -- Loop through all restriction violations
812 for R in All_Restrictions loop
814 -- Check for violation of this restriction
816 if Cumulative_Restrictions.Set (R)
817 and then Cumulative_Restrictions.Violated (R)
818 and then (R in Partition_Boolean_Restrictions
819 or else (R in All_Parameter_Restrictions
821 Cumulative_Restrictions.Count (R) >
822 Cumulative_Restrictions.Value (R)))
824 Restriction_File_Output := False;
826 -- Loop through files looking for violators
828 for A2 in ALIs.First .. ALIs.Last loop
830 T : ALIs_Record renames ALIs.Table (A2);
833 if T.Restrictions.Violated (R) then
835 -- We exclude predefined files from the list of
836 -- violators. This should be rethought. It is not
837 -- clear that this is the right thing to do, that
838 -- is particularly the case for restricted runtimes.
840 if not Is_Internal_File_Name (T.Sfile) then
842 -- Case of Boolean restriction, just print file name
844 if R in All_Boolean_Restrictions then
845 Print_Restriction_File (R);
846 Error_Msg_File_1 := T.Sfile;
847 Consistency_Error_Msg (" {");
849 -- Case of Parameter restriction where violation
850 -- count exceeds restriction value, print file
851 -- name and count, adding "at least" if the
852 -- exact count is not known.
854 elsif R in Checked_Add_Parameter_Restrictions
855 or else T.Restrictions.Count (R) >
856 Cumulative_Restrictions.Value (R)
858 Print_Restriction_File (R);
859 Error_Msg_File_1 := T.Sfile;
860 Error_Msg_Nat_1 := Int (T.Restrictions.Count (R));
862 if T.Restrictions.Unknown (R) then
863 Consistency_Error_Msg
864 (" { (count = at least #)");
866 Consistency_Error_Msg
877 -- Now deal with No_Dependence indications. Note that we put the loop
878 -- through entries in the no dependency table first, since this loop
879 -- is most often empty (no such pragma Restrictions in use).
881 for ND in No_Deps.First .. No_Deps.Last loop
883 ND_Unit : constant Name_Id :=
884 No_Deps.Table (ND).No_Dep_Unit;
887 for J in ALIs.First .. ALIs.Last loop
889 A : ALIs_Record renames ALIs.Table (J);
892 for K in A.First_Unit .. A.Last_Unit loop
894 U : Unit_Record renames Units.Table (K);
896 for L in U.First_With .. U.Last_With loop
898 (Withs.Table (L).Uname, ND_Unit)
900 Error_Msg_File_1 := U.Sfile;
901 Error_Msg_Name_1 := ND_Unit;
902 Consistency_Error_Msg
903 ("file { violates restriction " &
904 "No_Dependence => %");
913 end Check_Consistent_Restrictions;
915 ---------------------------------------------------
916 -- Check_Consistent_Zero_Cost_Exception_Handling --
917 ---------------------------------------------------
919 -- Check consistent zero cost exception handling. The rule is that
920 -- all units must have the same exception handling mechanism.
922 procedure Check_Consistent_Zero_Cost_Exception_Handling is
924 Check_Mechanism : for A1 in ALIs.First + 1 .. ALIs.Last loop
925 if ALIs.Table (A1).Zero_Cost_Exceptions /=
926 ALIs.Table (ALIs.First).Zero_Cost_Exceptions
928 Error_Msg_File_1 := ALIs.Table (A1).Sfile;
929 Error_Msg_File_2 := ALIs.Table (ALIs.First).Sfile;
931 Consistency_Error_Msg ("{ and { compiled with different "
932 & "exception handling mechanisms");
934 end loop Check_Mechanism;
935 end Check_Consistent_Zero_Cost_Exception_Handling;
937 -------------------------------
938 -- Check_Duplicated_Subunits --
939 -------------------------------
941 procedure Check_Duplicated_Subunits is
943 for J in Sdep.First .. Sdep.Last loop
944 if Sdep.Table (J).Subunit_Name /= No_Name then
945 Get_Decoded_Name_String (Sdep.Table (J).Subunit_Name);
946 Name_Len := Name_Len + 2;
947 Name_Buffer (Name_Len - 1) := '%';
949 -- See if there is a body or spec with the same name
951 for K in Boolean loop
953 Name_Buffer (Name_Len) := 'b
';
955 Name_Buffer (Name_Len) := 's
';
959 Unit : constant Unit_Name_Type := Name_Find;
960 Info : constant Int := Get_Name_Table_Info (Unit);
965 Write_Str ("error: subunit """);
966 Write_Name_Decoded (Sdep.Table (J).Subunit_Name);
967 Write_Str (""" in file """);
968 Write_Name_Decoded (Sdep.Table (J).Sfile);
971 Write_Str (" has same name as unit
""");
972 Write_Unit_Name (Units.Table (Unit_Id (Info)).Uname);
973 Write_Str (""" found
in file
""");
974 Write_Name_Decoded (Units.Table (Unit_Id (Info)).Sfile);
977 Write_Str (" this is not allowed within a single "
978 & "partition (RM 10.2(19))");
980 Osint.Exit_Program (Osint.E_Fatal);
986 end Check_Duplicated_Subunits;
992 procedure Check_Versions is
993 VL : constant Natural := ALIs.Table (ALIs.First).Ver_Len;
996 for A in ALIs.First .. ALIs.Last loop
997 if ALIs.Table (A).Ver_Len /= VL
998 or else ALIs.Table (A).Ver (1 .. VL) /=
999 ALIs.Table (ALIs.First).Ver (1 .. VL)
1001 Error_Msg_File_1 := ALIs.Table (A).Sfile;
1002 Error_Msg_File_2 := ALIs.Table (ALIs.First).Sfile;
1004 Consistency_Error_Msg
1005 ("{ and { compiled with different GNAT versions");
1010 ---------------------------
1011 -- Consistency_Error_Msg --
1012 ---------------------------
1014 procedure Consistency_Error_Msg (Msg : String) is
1016 if Tolerate_Consistency_Errors then
1018 -- If consistency errors are tolerated,
1019 -- output the message as a warning.
1022 Warning_Msg : String (1 .. Msg'Length + 1);
1025 Warning_Msg (1) := '?
';
1026 Warning_Msg (2 .. Warning_Msg'Last) := Msg;
1028 Error_Msg (Warning_Msg);
1031 -- Otherwise the consistency error is a true error
1036 end Consistency_Error_Msg;
1042 function Same_Unit (U1 : Unit_Name_Type; U2 : Name_Id) return Boolean is
1044 -- Note, the string U1 has a terminating %s or %b, U2 does not
1046 if Length_Of_Name (U1) - 2 = Length_Of_Name (U2) then
1047 Get_Name_String (U1);
1050 U1_Str : constant String := Name_Buffer (1 .. Name_Len - 2);
1052 Get_Name_String (U2);
1053 return U1_Str = Name_Buffer (1 .. Name_Len);