Merged with mainline at revision 128810.
[official-gcc.git] / gcc / ada / bcheck.adb
blobadab9588cf2b615459f82b40ba8191ba965d6262
1 ------------------------------------------------------------------------------
2 -- --
3 -- GNAT COMPILER COMPONENTS --
4 -- --
5 -- B C H E C K --
6 -- --
7 -- B o d y --
8 -- --
9 -- Copyright (C) 1992-2007, Free Software Foundation, Inc. --
10 -- --
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. --
20 -- --
21 -- GNAT was originally developed by the GNAT team at New York University. --
22 -- Extensive contributions were provided by Ada Core Technologies Inc. --
23 -- --
24 ------------------------------------------------------------------------------
26 with ALI; use ALI;
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;
33 with Opt; use Opt;
34 with Osint;
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
71 begin
72 if Float_Format_Specified /= ' ' then
73 Check_Consistent_Floating_Point_Format;
74 end if;
76 if Queuing_Policy_Specified /= ' ' then
77 Check_Consistent_Queuing_Policy;
78 end if;
80 if Locking_Policy_Specified /= ' ' then
81 Check_Consistent_Locking_Policy;
82 end if;
84 if Zero_Cost_Exceptions_Specified then
85 Check_Consistent_Zero_Cost_Exception_Handling;
86 end if;
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
101 Src : Source_Id;
102 -- Source file Id for this Sdep entry
104 ALI_Path_Id : File_Name_Type;
106 begin
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
118 null;
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
126 null;
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
133 null;
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))
146 then
147 Source.Table (S).All_Checksums_Match := False;
148 end if;
149 end if;
150 end loop;
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
158 Sdep_Loop : for D in
159 ALIs.Table (A).First_Sdep .. ALIs.Table (A).Last_Sdep
160 loop
161 if Sdep.Table (D).Dummy_Entry then
162 goto Continue;
163 end if;
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
172 then
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
181 Error_Msg
182 ("?{ has been modified and should be recompiled");
183 else
184 Error_Msg
185 ("{ has been modified and must be recompiled");
186 end if;
188 else
189 ALI_Path_Id :=
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)");
196 else
197 Error_Msg ("{ must be compiled");
198 Error_Msg_File_1 := ALI_Path_Id;
199 Error_Msg ("({ is obsolete and read-only)");
200 end if;
202 elsif Tolerate_Consistency_Errors then
203 Error_Msg
204 ("?{ should be recompiled ({ has been modified)");
206 else
207 Error_Msg ("{ must be recompiled ({ has been modified)");
208 end if;
209 end if;
211 if (not Tolerate_Consistency_Errors) and Verbose_Mode then
212 Error_Msg_File_1 := Sdep.Table (D).Sfile;
213 Error_Msg
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 ???
219 Error_Msg
220 (" conflicts with { timestamp " &
221 String (Sdep.Table (D).Stamp));
222 end if;
224 -- Exit from the loop through Sdep entries once we find one
225 -- that does not match.
227 exit Sdep_Loop;
228 end if;
230 <<Continue>>
231 null;
232 end loop Sdep_Loop;
233 end loop ALIs_Loop;
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
254 -- the partition.
256 procedure Check_Consistent_Dispatching_Policy is
257 Max_Prio : Nat := 0;
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
264 begin
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;
281 begin
282 for A2 in A1 + 1 .. ALIs.Last loop
283 if ALIs.Table (A2).Task_Dispatching_Policy /= ' '
284 and then
285 ALIs.Table (A2).Task_Dispatching_Policy /= Policy
286 then
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");
293 exit Find_Policy;
294 end if;
295 end loop;
296 end Check_Policy;
298 exit Find_Policy;
299 end if;
300 end loop Find_Policy;
301 end if;
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.
310 Max_Prio := 0;
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;
314 end if;
315 end loop;
317 -- Now establish tables to be used for consistency checking
319 declare
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.
331 Loc : Nat := 0;
332 -- Line numbers from Priority_Specific_Dispatching pragma
333 end record;
335 PSD_Table : array (0 .. Max_Prio) of Specific_Dispatching_Entry :=
336 (others => Specific_Dispatching_Entry'
337 (Dispatching_Policy => ' ',
338 Afile => No_ALI_Id,
339 Loc => 0));
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.
344 begin
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
348 loop
349 declare
350 DTK : Specific_Dispatching_Record
351 renames Specific_Dispatching.Table (K);
352 begin
353 -- Check whether pragma Task_Dispatching_Policy and
354 -- pragma Priority_Specific_Dispatching are used in the
355 -- same partition.
357 if Task_Dispatching_Policy_Specified /= ' ' then
358 Error_Msg_File_1 := ALIs.Table (F).Sfile;
359 Error_Msg_File_2 :=
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 {");
367 end if;
369 -- Ceiling_Locking must also be specified for a partition
370 -- with at least one Priority_Specific_Dispatching
371 -- pragma.
373 if Locking_Policy_Specified /= ' '
374 and then Locking_Policy_Specified /= 'C'
375 then
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'
379 then
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 {");
388 end if;
389 end loop;
390 end if;
392 -- Check overlapping priority ranges
394 Find_Overlapping : for Prio in
395 DTK.First_Priority .. DTK.Last_Priority
396 loop
397 if PSD_Table (Prio).Afile = No_ALI_Id then
398 PSD_Table (Prio) :=
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
405 then
406 Error_Msg_File_1 :=
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;
416 end if;
417 end loop Find_Overlapping;
418 end;
419 end loop;
420 end loop;
421 end;
422 end if;
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
438 begin
439 if Dynamic_Elaboration_Checks_Specified then
440 for U in First_Unit_Entry .. Units.Last loop
441 declare
442 UR : Unit_Record renames Units.Table (U);
444 begin
445 if UR.Dynamic_Elab then
446 for W in UR.First_With .. UR.Last_With loop
447 declare
448 WR : With_Record renames Withs.Table (W);
450 begin
451 if Get_Name_Table_Info (WR.Uname) /= 0 then
452 declare
453 WU : Unit_Record renames
454 Units.Table
455 (Unit_Id
456 (Get_Name_Table_Info (WR.Uname)));
458 begin
459 -- Case 1. Elaborate_All for with'ed unit
461 if WR.Elaborate_All then
462 null;
464 -- Case 2. With'ed unit has dynamic elab checks
466 elsif WU.Dynamic_Elab then
467 null;
469 -- Case 3. With'ed unit is Preelaborate or Pure
471 elsif WU.Preelab or WU.Pure then
472 null;
474 -- Case 4. With'ed unit is internal file
476 elsif Is_Internal_File_Name (WU.Sfile) then
477 null;
479 -- Issue warning, not one of the safe cases
481 else
482 Error_Msg_File_1 := UR.Sfile;
483 Error_Msg
484 ("?{ has dynamic elaboration checks " &
485 "and with's");
487 Error_Msg_File_1 := WU.Sfile;
488 Error_Msg
489 ("? { which has static elaboration " &
490 "checks");
492 Warnings_Detected := Warnings_Detected - 1;
493 end if;
494 end;
495 end if;
496 end;
497 end loop;
498 end if;
499 end;
500 end loop;
501 end if;
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
512 begin
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;
520 begin
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");
529 exit Find_Format;
530 end if;
531 end loop;
532 end Check_Format;
534 exit Find_Format;
535 end if;
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
547 Max_Intrup : Nat;
549 begin
550 -- If no Interrupt_State entries, nothing to do
552 if Interrupt_States.Last < Interrupt_States.First then
553 return;
554 end if;
556 -- First find out the maximum interrupt value
558 Max_Intrup := 0;
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;
562 end if;
563 end loop;
565 -- Now establish tables to be used for consistency checking
567 declare
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
578 Inum : Nat;
579 -- Interrupt number from entry being tested
581 Stat : Character;
582 -- Interrupt state from entry being tested
584 Lnum : Nat;
585 -- Line number from entry being tested
587 begin
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
591 loop
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;
598 Afile (Inum) := F;
599 Loc (Inum) := Lnum;
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 {:#");
609 end if;
610 end loop;
611 end loop;
612 end;
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
623 begin
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;
632 begin
633 for A2 in A1 + 1 .. ALIs.Last loop
634 if ALIs.Table (A2).Locking_Policy /= ' ' and
635 ALIs.Table (A2).Locking_Policy /= Policy
636 then
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");
642 exit Find_Policy;
643 end if;
644 end loop;
645 end Check_Policy;
647 exit Find_Policy;
648 end if;
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
668 begin
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");
673 Write_Eol;
674 Write_Str ("files compiled with Normalize_Scalars");
675 Write_Eol;
677 for A1 in ALIs.First .. ALIs.Last loop
678 if ALIs.Table (A1).Normalize_Scalars then
679 Write_Str (" ");
680 Write_Name (ALIs.Table (A1).Sfile);
681 Write_Eol;
682 end if;
683 end loop;
685 Write_Eol;
686 Write_Str ("files compiled without Normalize_Scalars");
687 Write_Eol;
689 for A1 in ALIs.First .. ALIs.Last loop
690 if not ALIs.Table (A1).Normalize_Scalars then
691 Write_Str (" ");
692 Write_Name (ALIs.Table (A1).Sfile);
693 Write_Eol;
694 end if;
695 end loop;
696 end if;
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
707 begin
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;
715 begin
716 for A2 in A1 + 1 .. ALIs.Last loop
717 if ALIs.Table (A2).Queuing_Policy /= ' '
718 and then
719 ALIs.Table (A2).Queuing_Policy /= Policy
720 then
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");
726 exit Find_Policy;
727 end if;
728 end loop;
729 end Check_Policy;
731 exit Find_Policy;
732 end if;
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
757 begin
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))
768 then
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).
773 declare
774 M1 : constant String := "{ has restriction ";
775 S : constant String := Restriction_Id'Image (R);
776 M2 : String (1 .. 200); -- big enough!
777 P : Integer;
779 begin
780 Name_Buffer (1 .. S'Length) := S;
781 Name_Len := S'Length;
782 Set_Casing (Mixed_Case);
784 M2 (M1'Range) := M1;
785 P := M1'Length + 1;
786 M2 (P .. P + S'Length - 1) := Name_Buffer (1 .. S'Length);
787 P := P + S'Length;
789 if R in All_Parameter_Restrictions then
790 M2 (P .. P + 4) := " => #";
791 Error_Msg_Nat_1 :=
792 Int (Cumulative_Restrictions.Value (R));
793 P := P + 5;
794 end if;
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:");
800 return;
801 end;
802 end if;
803 end loop;
804 end if;
805 end Print_Restriction_File;
807 -- Start of processing for Check_Consistent_Restrictions
809 begin
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
820 and then
821 Cumulative_Restrictions.Count (R) >
822 Cumulative_Restrictions.Value (R)))
823 then
824 Restriction_File_Output := False;
826 -- Loop through files looking for violators
828 for A2 in ALIs.First .. ALIs.Last loop
829 declare
830 T : ALIs_Record renames ALIs.Table (A2);
832 begin
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)
857 then
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 #)");
865 else
866 Consistency_Error_Msg
867 (" % (count = #)");
868 end if;
869 end if;
870 end if;
871 end if;
872 end;
873 end loop;
874 end if;
875 end loop;
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
882 declare
883 ND_Unit : constant Name_Id :=
884 No_Deps.Table (ND).No_Dep_Unit;
886 begin
887 for J in ALIs.First .. ALIs.Last loop
888 declare
889 A : ALIs_Record renames ALIs.Table (J);
891 begin
892 for K in A.First_Unit .. A.Last_Unit loop
893 declare
894 U : Unit_Record renames Units.Table (K);
895 begin
896 for L in U.First_With .. U.Last_With loop
897 if Same_Unit
898 (Withs.Table (L).Uname, ND_Unit)
899 then
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 => %");
905 end if;
906 end loop;
907 end;
908 end loop;
909 end;
910 end loop;
911 end;
912 end loop;
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
923 begin
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
927 then
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");
933 end if;
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
942 begin
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
952 if K then
953 Name_Buffer (Name_Len) := 'b';
954 else
955 Name_Buffer (Name_Len) := 's';
956 end if;
958 declare
959 Unit : constant Unit_Name_Type := Name_Find;
960 Info : constant Int := Get_Name_Table_Info (Unit);
962 begin
963 if Info /= 0 then
964 Set_Standard_Error;
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);
969 Write_Char ('"');
970 Write_Eol;
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);
975 Write_Char ('"');
976 Write_Eol;
977 Write_Str (" this is not allowed within a single "
978 & "partition (RM 10.2(19))");
979 Write_Eol;
980 Osint.Exit_Program (Osint.E_Fatal);
981 end if;
982 end;
983 end loop;
984 end if;
985 end loop;
986 end Check_Duplicated_Subunits;
988 --------------------
989 -- Check_Versions --
990 --------------------
992 procedure Check_Versions is
993 VL : constant Natural := ALIs.Table (ALIs.First).Ver_Len;
995 begin
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)
1000 then
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");
1006 end if;
1007 end loop;
1008 end Check_Versions;
1010 ---------------------------
1011 -- Consistency_Error_Msg --
1012 ---------------------------
1014 procedure Consistency_Error_Msg (Msg : String) is
1015 begin
1016 if Tolerate_Consistency_Errors then
1018 -- If consistency errors are tolerated,
1019 -- output the message as a warning.
1021 declare
1022 Warning_Msg : String (1 .. Msg'Length + 1);
1024 begin
1025 Warning_Msg (1) := '?';
1026 Warning_Msg (2 .. Warning_Msg'Last) := Msg;
1028 Error_Msg (Warning_Msg);
1029 end;
1031 -- Otherwise the consistency error is a true error
1033 else
1034 Error_Msg (Msg);
1035 end if;
1036 end Consistency_Error_Msg;
1038 ---------------
1039 -- Same_Unit --
1040 ---------------
1042 function Same_Unit (U1 : Unit_Name_Type; U2 : Name_Id) return Boolean is
1043 begin
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);
1049 declare
1050 U1_Str : constant String := Name_Buffer (1 .. Name_Len - 2);
1051 begin
1052 Get_Name_String (U2);
1053 return U1_Str = Name_Buffer (1 .. Name_Len);
1054 end;
1056 else
1057 return False;
1058 end if;
1059 end Same_Unit;
1061 end Bcheck;