]> git.ipfire.org Git - thirdparty/gcc.git/blob - gcc/ada/bcheck.adb
[multiple changes]
[thirdparty/gcc.git] / gcc / ada / bcheck.adb
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-2004 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 2, 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 COPYING. If not, write --
19 -- to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, --
20 -- MA 02111-1307, USA. --
21 -- --
22 -- GNAT was originally developed by the GNAT team at New York University. --
23 -- Extensive contributions were provided by Ada Core Technologies Inc. --
24 -- --
25 ------------------------------------------------------------------------------
26
27 with ALI; use ALI;
28 with ALI.Util; use ALI.Util;
29 with Binderr; use Binderr;
30 with Butil; use Butil;
31 with Casing; use Casing;
32 with Fname; use Fname;
33 with Namet; use Namet;
34 with Opt; use Opt;
35 with Osint;
36 with Output; use Output;
37 with Rident; use Rident;
38 with Types; use Types;
39
40 package body Bcheck is
41
42 -----------------------
43 -- Local Subprograms --
44 -----------------------
45
46 -- The following checking subprograms make up the parts of the
47 -- configuration consistency check.
48
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;
57
58 procedure Consistency_Error_Msg (Msg : String);
59 -- Produce an error or a warning message, depending on whether
60 -- an inconsistent configuration is permitted or not.
61
62 ------------------------------------
63 -- Check_Consistent_Configuration --
64 ------------------------------------
65
66 procedure Check_Configuration_Consistency is
67 begin
68 if Float_Format_Specified /= ' ' then
69 Check_Consistent_Floating_Point_Format;
70 end if;
71
72 if Queuing_Policy_Specified /= ' ' then
73 Check_Consistent_Queuing_Policy;
74 end if;
75
76 if Locking_Policy_Specified /= ' ' then
77 Check_Consistent_Locking_Policy;
78 end if;
79
80 if Zero_Cost_Exceptions_Specified then
81 Check_Consistent_Zero_Cost_Exception_Handling;
82 end if;
83
84 Check_Consistent_Normalize_Scalars;
85 Check_Consistent_Dynamic_Elaboration_Checking;
86
87 Check_Consistent_Restrictions;
88 Check_Consistent_Interrupt_States;
89 end Check_Configuration_Consistency;
90
91 ---------------------------------------------------
92 -- Check_Consistent_Dynamic_Elaboration_Checking --
93 ---------------------------------------------------
94
95 -- The rule here is that if a unit has dynamic elaboration checks,
96 -- then any unit it withs must meeting one of the following criteria:
97
98 -- 1. There is a pragma Elaborate_All for the with'ed unit
99 -- 2. The with'ed unit was compiled with dynamic elaboration checks
100 -- 3. The with'ed unit has pragma Preelaborate or Pure
101 -- 4. It is an internal GNAT unit (including children of GNAT)
102
103 procedure Check_Consistent_Dynamic_Elaboration_Checking is
104 begin
105 if Dynamic_Elaboration_Checks_Specified then
106 for U in First_Unit_Entry .. Units.Last loop
107 declare
108 UR : Unit_Record renames Units.Table (U);
109
110 begin
111 if UR.Dynamic_Elab then
112 for W in UR.First_With .. UR.Last_With loop
113 declare
114 WR : With_Record renames Withs.Table (W);
115
116 begin
117 if Get_Name_Table_Info (WR.Uname) /= 0 then
118 declare
119 WU : Unit_Record renames
120 Units.Table
121 (Unit_Id
122 (Get_Name_Table_Info (WR.Uname)));
123
124 begin
125 -- Case 1. Elaborate_All for with'ed unit
126
127 if WR.Elaborate_All then
128 null;
129
130 -- Case 2. With'ed unit has dynamic elab checks
131
132 elsif WU.Dynamic_Elab then
133 null;
134
135 -- Case 3. With'ed unit is Preelaborate or Pure
136
137 elsif WU.Preelab or WU.Pure then
138 null;
139
140 -- Case 4. With'ed unit is internal file
141
142 elsif Is_Internal_File_Name (WU.Sfile) then
143 null;
144
145 -- Issue warning, not one of the safe cases
146
147 else
148 Error_Msg_Name_1 := UR.Sfile;
149 Error_Msg
150 ("?% has dynamic elaboration checks " &
151 "and with's");
152
153 Error_Msg_Name_1 := WU.Sfile;
154 Error_Msg
155 ("? % which has static elaboration " &
156 "checks");
157
158 Warnings_Detected := Warnings_Detected - 1;
159 end if;
160 end;
161 end if;
162 end;
163 end loop;
164 end if;
165 end;
166 end loop;
167 end if;
168 end Check_Consistent_Dynamic_Elaboration_Checking;
169
170 --------------------------------------------
171 -- Check_Consistent_Floating_Point_Format --
172 --------------------------------------------
173
174 -- The rule is that all files must be compiled with the same setting
175 -- for the floating-point format.
176
177 procedure Check_Consistent_Floating_Point_Format is
178 begin
179 -- First search for a unit specifying a floating-point format and then
180 -- check all remaining units against it.
181
182 Find_Format : for A1 in ALIs.First .. ALIs.Last loop
183 if ALIs.Table (A1).Float_Format /= ' ' then
184 Check_Format : declare
185 Format : constant Character := ALIs.Table (A1).Float_Format;
186 begin
187 for A2 in A1 + 1 .. ALIs.Last loop
188 if ALIs.Table (A2).Float_Format /= Format then
189 Error_Msg_Name_1 := ALIs.Table (A1).Sfile;
190 Error_Msg_Name_2 := ALIs.Table (A2).Sfile;
191
192 Consistency_Error_Msg
193 ("% and % compiled with different " &
194 "floating-point representations");
195 exit Find_Format;
196 end if;
197 end loop;
198 end Check_Format;
199
200 exit Find_Format;
201 end if;
202 end loop Find_Format;
203 end Check_Consistent_Floating_Point_Format;
204
205 ---------------------------------------
206 -- Check_Consistent_Interrupt_States --
207 ---------------------------------------
208
209 -- The rule is that if the state of a given interrupt is specified
210 -- in more than one unit, it must be specified with a consistent state.
211
212 procedure Check_Consistent_Interrupt_States is
213 Max_Intrup : Nat;
214
215 begin
216 -- If no Interrupt_State entries, nothing to do
217
218 if Interrupt_States.Last < Interrupt_States.First then
219 return;
220 end if;
221
222 -- First find out the maximum interrupt value
223
224 Max_Intrup := 0;
225 for J in Interrupt_States.First .. Interrupt_States.Last loop
226 if Interrupt_States.Table (J).Interrupt_Id > Max_Intrup then
227 Max_Intrup := Interrupt_States.Table (J).Interrupt_Id;
228 end if;
229 end loop;
230
231 -- Now establish tables to be used for consistency checking
232
233 declare
234 Istate : array (0 .. Max_Intrup) of Character := (others => 'n');
235 -- Interrupt state entries, 'u'/'s'/'r' or 'n' to indicate an
236 -- entry that has not been set.
237
238 Afile : array (0 .. Max_Intrup) of ALI_Id;
239 -- ALI file that generated Istate entry for consistency message
240
241 Loc : array (0 .. Max_Intrup) of Nat;
242 -- Line numbers from IS pragma generating Istate entry
243
244 Inum : Nat;
245 -- Interrupt number from entry being tested
246
247 Stat : Character;
248 -- Interrupt state from entry being tested
249
250 Lnum : Nat;
251 -- Line number from entry being tested
252
253 begin
254 for F in ALIs.First .. ALIs.Last loop
255 for K in ALIs.Table (F).First_Interrupt_State ..
256 ALIs.Table (F).Last_Interrupt_State
257 loop
258 Inum := Interrupt_States.Table (K).Interrupt_Id;
259 Stat := Interrupt_States.Table (K).Interrupt_State;
260 Lnum := Interrupt_States.Table (K).IS_Pragma_Line;
261
262 if Istate (Inum) = 'n' then
263 Istate (Inum) := Stat;
264 Afile (Inum) := F;
265 Loc (Inum) := Lnum;
266
267 elsif Istate (Inum) /= Stat then
268 Error_Msg_Name_1 := ALIs.Table (Afile (Inum)).Sfile;
269 Error_Msg_Name_2 := ALIs.Table (F).Sfile;
270 Error_Msg_Nat_1 := Loc (Inum);
271 Error_Msg_Nat_2 := Lnum;
272
273 Consistency_Error_Msg
274 ("inconsistent interrupt states at %:# and %:#");
275 end if;
276 end loop;
277 end loop;
278 end;
279 end Check_Consistent_Interrupt_States;
280
281 -------------------------------------
282 -- Check_Consistent_Locking_Policy --
283 -------------------------------------
284
285 -- The rule is that all files for which the locking policy is
286 -- significant must be compiled with the same setting.
287
288 procedure Check_Consistent_Locking_Policy is
289 begin
290 -- First search for a unit specifying a policy and then
291 -- check all remaining units against it.
292
293 Find_Policy : for A1 in ALIs.First .. ALIs.Last loop
294 if ALIs.Table (A1).Locking_Policy /= ' ' then
295 Check_Policy : declare
296 Policy : constant Character := ALIs.Table (A1).Locking_Policy;
297
298 begin
299 for A2 in A1 + 1 .. ALIs.Last loop
300 if ALIs.Table (A2).Locking_Policy /= ' ' and
301 ALIs.Table (A2).Locking_Policy /= Policy
302 then
303 Error_Msg_Name_1 := ALIs.Table (A1).Sfile;
304 Error_Msg_Name_2 := ALIs.Table (A2).Sfile;
305
306 Consistency_Error_Msg
307 ("% and % compiled with different locking policies");
308 exit Find_Policy;
309 end if;
310 end loop;
311 end Check_Policy;
312
313 exit Find_Policy;
314 end if;
315 end loop Find_Policy;
316 end Check_Consistent_Locking_Policy;
317
318 ----------------------------------------
319 -- Check_Consistent_Normalize_Scalars --
320 ----------------------------------------
321
322 -- The rule is that if any unit is compiled with Normalized_Scalars,
323 -- then all other units in the partition must also be compiled with
324 -- Normalized_Scalars in effect.
325
326 -- There is some issue as to whether this consistency check is
327 -- desirable, it is certainly required at the moment by the RM.
328 -- We should keep a watch on the ARG and HRG deliberations here.
329 -- GNAT no longer depends on this consistency (it used to do so,
330 -- but that has been corrected in the latest version, since the
331 -- Initialize_Scalars pragma does not require consistency.
332
333 procedure Check_Consistent_Normalize_Scalars is
334 begin
335 if Normalize_Scalars_Specified and No_Normalize_Scalars_Specified then
336 Consistency_Error_Msg
337 ("some but not all files compiled with Normalize_Scalars");
338
339 Write_Eol;
340 Write_Str ("files compiled with Normalize_Scalars");
341 Write_Eol;
342
343 for A1 in ALIs.First .. ALIs.Last loop
344 if ALIs.Table (A1).Normalize_Scalars then
345 Write_Str (" ");
346 Write_Name (ALIs.Table (A1).Sfile);
347 Write_Eol;
348 end if;
349 end loop;
350
351 Write_Eol;
352 Write_Str ("files compiled without Normalize_Scalars");
353 Write_Eol;
354
355 for A1 in ALIs.First .. ALIs.Last loop
356 if not ALIs.Table (A1).Normalize_Scalars then
357 Write_Str (" ");
358 Write_Name (ALIs.Table (A1).Sfile);
359 Write_Eol;
360 end if;
361 end loop;
362 end if;
363 end Check_Consistent_Normalize_Scalars;
364
365 -------------------------------------
366 -- Check_Consistent_Queuing_Policy --
367 -------------------------------------
368
369 -- The rule is that all files for which the queuing policy is
370 -- significant must be compiled with the same setting.
371
372 procedure Check_Consistent_Queuing_Policy is
373 begin
374 -- First search for a unit specifying a policy and then
375 -- check all remaining units against it.
376
377 Find_Policy : for A1 in ALIs.First .. ALIs.Last loop
378 if ALIs.Table (A1).Queuing_Policy /= ' ' then
379 Check_Policy : declare
380 Policy : constant Character := ALIs.Table (A1).Queuing_Policy;
381 begin
382 for A2 in A1 + 1 .. ALIs.Last loop
383 if ALIs.Table (A2).Queuing_Policy /= ' '
384 and then
385 ALIs.Table (A2).Queuing_Policy /= Policy
386 then
387 Error_Msg_Name_1 := ALIs.Table (A1).Sfile;
388 Error_Msg_Name_2 := ALIs.Table (A2).Sfile;
389
390 Consistency_Error_Msg
391 ("% and % compiled with different queuing policies");
392 exit Find_Policy;
393 end if;
394 end loop;
395 end Check_Policy;
396
397 exit Find_Policy;
398 end if;
399 end loop Find_Policy;
400 end Check_Consistent_Queuing_Policy;
401
402 -----------------------------------
403 -- Check_Consistent_Restrictions --
404 -----------------------------------
405
406 -- The rule is that if a restriction is specified in any unit,
407 -- then all units must obey the restriction. The check applies
408 -- only to restrictions which require partition wide consistency,
409 -- and not to internal units.
410
411 procedure Check_Consistent_Restrictions is
412 Restriction_File_Output : Boolean;
413 -- Shows if we have output header messages for restriction violation
414
415 procedure Print_Restriction_File (R : All_Restrictions);
416 -- Print header line for R if not printed yet
417
418 ----------------------------
419 -- Print_Restriction_File --
420 ----------------------------
421
422 procedure Print_Restriction_File (R : All_Restrictions) is
423 begin
424 if not Restriction_File_Output then
425 Restriction_File_Output := True;
426
427 -- Find an ali file specifying the restriction
428
429 for A in ALIs.First .. ALIs.Last loop
430 if ALIs.Table (A).Restrictions.Set (R)
431 and then (R in All_Boolean_Restrictions
432 or else ALIs.Table (A).Restrictions.Value (R) =
433 Cumulative_Restrictions.Value (R))
434 then
435 -- We have found that ALI file A specifies the restriction
436 -- that is being violated (the minimum value is specified
437 -- in the case of a parameter restriction).
438
439 declare
440 M1 : constant String := "% has restriction ";
441 S : constant String := Restriction_Id'Image (R);
442 M2 : String (1 .. 200); -- big enough!
443 P : Integer;
444
445 begin
446 Name_Buffer (1 .. S'Length) := S;
447 Name_Len := S'Length;
448 Set_Casing (Mixed_Case);
449
450 M2 (M1'Range) := M1;
451 P := M1'Length + 1;
452 M2 (P .. P + S'Length - 1) := Name_Buffer (1 .. S'Length);
453 P := P + S'Length;
454
455 if R in All_Parameter_Restrictions then
456 M2 (P .. P + 4) := " => #";
457 Error_Msg_Nat_1 :=
458 Int (Cumulative_Restrictions.Value (R));
459 P := P + 5;
460 end if;
461
462 Error_Msg_Name_1 := ALIs.Table (A).Sfile;
463 Consistency_Error_Msg (M2 (1 .. P - 1));
464 Consistency_Error_Msg
465 ("but the following files violate this restriction:");
466 return;
467 end;
468 end if;
469 end loop;
470 end if;
471 end Print_Restriction_File;
472
473 -- Start of processing for Check_Consistent_Restrictions
474
475 begin
476 -- Loop through all restriction violations
477
478 for R in All_Restrictions loop
479
480 -- Check for violation of this restriction
481
482 if Cumulative_Restrictions.Set (R)
483 and then Cumulative_Restrictions.Violated (R)
484 and then (R in Partition_Boolean_Restrictions
485 or else (R in All_Parameter_Restrictions
486 and then
487 Cumulative_Restrictions.Count (R) >
488 Cumulative_Restrictions.Value (R)))
489 then
490 Restriction_File_Output := False;
491
492 -- Loop through files looking for violators
493
494 for A2 in ALIs.First .. ALIs.Last loop
495 declare
496 T : ALIs_Record renames ALIs.Table (A2);
497
498 begin
499 if T.Restrictions.Violated (R) then
500
501 -- We exclude predefined files from the list of
502 -- violators. This should be rethought. It is not
503 -- clear that this is the right thing to do, that
504 -- is particularly the case for restricted runtimes.
505
506 if not Is_Internal_File_Name (T.Sfile) then
507
508 -- Case of Boolean restriction, just print file name
509
510 if R in All_Boolean_Restrictions then
511 Print_Restriction_File (R);
512 Error_Msg_Name_1 := T.Sfile;
513 Consistency_Error_Msg (" %");
514
515 -- Case of Parameter restriction where violation
516 -- count exceeds restriction value, print file
517 -- name and count, adding "at least" if the
518 -- exact count is not known.
519
520 elsif R in Checked_Add_Parameter_Restrictions
521 or else T.Restrictions.Count (R) >
522 Cumulative_Restrictions.Value (R)
523 then
524 Print_Restriction_File (R);
525 Error_Msg_Name_1 := T.Sfile;
526 Error_Msg_Nat_1 := Int (T.Restrictions.Count (R));
527
528 if T.Restrictions.Unknown (R) then
529 Consistency_Error_Msg
530 (" % (count = at least #)");
531 else
532 Consistency_Error_Msg
533 (" % (count = #)");
534 end if;
535 end if;
536 end if;
537 end if;
538 end;
539 end loop;
540 end if;
541 end loop;
542 end Check_Consistent_Restrictions;
543
544 ---------------------------------------------------
545 -- Check_Consistent_Zero_Cost_Exception_Handling --
546 ---------------------------------------------------
547
548 -- Check consistent zero cost exception handling. The rule is that
549 -- all units must have the same exception handling mechanism.
550
551 procedure Check_Consistent_Zero_Cost_Exception_Handling is
552 begin
553 Check_Mechanism : for A1 in ALIs.First + 1 .. ALIs.Last loop
554 if ALIs.Table (A1).Zero_Cost_Exceptions /=
555 ALIs.Table (ALIs.First).Zero_Cost_Exceptions
556
557 then
558 Error_Msg_Name_1 := ALIs.Table (A1).Sfile;
559 Error_Msg_Name_2 := ALIs.Table (ALIs.First).Sfile;
560
561 Consistency_Error_Msg ("% and % compiled with different "
562 & "exception handling mechanisms");
563 end if;
564 end loop Check_Mechanism;
565 end Check_Consistent_Zero_Cost_Exception_Handling;
566
567 -----------------------
568 -- Check_Consistency --
569 -----------------------
570
571 procedure Check_Consistency is
572 Src : Source_Id;
573 -- Source file Id for this Sdep entry
574
575 ALI_Path_Id : Name_Id;
576
577 begin
578 -- First, we go through the source table to see if there are any cases
579 -- in which we should go after source files and compute checksums of
580 -- the source files. We need to do this for any file for which we have
581 -- mismatching time stamps and (so far) matching checksums.
582
583 for S in Source.First .. Source.Last loop
584
585 -- If all time stamps for a file match, then there is nothing to
586 -- do, since we will not be checking checksums in that case anyway
587
588 if Source.Table (S).All_Timestamps_Match then
589 null;
590
591 -- If we did not find the source file, then we can't compute its
592 -- checksum anyway. Note that when we have a time stamp mismatch,
593 -- we try to find the source file unconditionally (i.e. if
594 -- Check_Source_Files is False).
595
596 elsif not Source.Table (S).Source_Found then
597 null;
598
599 -- If we already have non-matching or missing checksums, then no
600 -- need to try going after source file, since we won't trust the
601 -- checksums in any case.
602
603 elsif not Source.Table (S).All_Checksums_Match then
604 null;
605
606 -- Now we have the case where we have time stamp mismatches, and
607 -- the source file is around, but so far all checksums match. This
608 -- is the case where we need to compute the checksum from the source
609 -- file, since otherwise we would ignore the time stamp mismatches,
610 -- and that is wrong if the checksum of the source does not agree
611 -- with the checksums in the ALI files.
612
613 elsif Check_Source_Files then
614 if not Checksums_Match
615 (Source.Table (S).Checksum,
616 Get_File_Checksum (Source.Table (S).Sfile))
617 then
618 Source.Table (S).All_Checksums_Match := False;
619 end if;
620 end if;
621 end loop;
622
623 -- Loop through ALI files
624
625 ALIs_Loop : for A in ALIs.First .. ALIs.Last loop
626
627 -- Loop through Sdep entries in one ALI file
628
629 Sdep_Loop : for D in
630 ALIs.Table (A).First_Sdep .. ALIs.Table (A).Last_Sdep
631 loop
632 if Sdep.Table (D).Dummy_Entry then
633 goto Continue;
634 end if;
635
636 Src := Source_Id (Get_Name_Table_Info (Sdep.Table (D).Sfile));
637
638 -- If the time stamps match, or all checksums match, then we
639 -- are OK, otherwise we have a definite error.
640
641 if Sdep.Table (D).Stamp /= Source.Table (Src).Stamp
642 and then not Source.Table (Src).All_Checksums_Match
643 then
644 Error_Msg_Name_1 := ALIs.Table (A).Sfile;
645 Error_Msg_Name_2 := Sdep.Table (D).Sfile;
646
647 -- Two styles of message, depending on whether or not
648 -- the updated file is the one that must be recompiled
649
650 if Error_Msg_Name_1 = Error_Msg_Name_2 then
651 if Tolerate_Consistency_Errors then
652 Error_Msg
653 ("?% has been modified and should be recompiled");
654 else
655 Error_Msg
656 ("% has been modified and must be recompiled");
657 end if;
658
659 else
660 ALI_Path_Id :=
661 Osint.Find_File ((ALIs.Table (A).Afile), Osint.Library);
662 if Osint.Is_Readonly_Library (ALI_Path_Id) then
663 if Tolerate_Consistency_Errors then
664 Error_Msg ("?% should be recompiled");
665 Error_Msg_Name_1 := ALI_Path_Id;
666 Error_Msg ("?(% is obsolete and read-only)");
667
668 else
669 Error_Msg ("% must be compiled");
670 Error_Msg_Name_1 := ALI_Path_Id;
671 Error_Msg ("(% is obsolete and read-only)");
672 end if;
673
674 elsif Tolerate_Consistency_Errors then
675 Error_Msg
676 ("?% should be recompiled (% has been modified)");
677
678 else
679 Error_Msg ("% must be recompiled (% has been modified)");
680 end if;
681 end if;
682
683 if (not Tolerate_Consistency_Errors) and Verbose_Mode then
684 declare
685 Msg : constant String := "% time stamp ";
686 Buf : String (1 .. Msg'Length + Time_Stamp_Length);
687
688 begin
689 Buf (1 .. Msg'Length) := Msg;
690 Buf (Msg'Length + 1 .. Buf'Length) :=
691 String (Source.Table (Src).Stamp);
692 Error_Msg_Name_1 := Sdep.Table (D).Sfile;
693 Error_Msg (Buf);
694 end;
695
696 declare
697 Msg : constant String := " conflicts with % timestamp ";
698 Buf : String (1 .. Msg'Length + Time_Stamp_Length);
699
700 begin
701 Buf (1 .. Msg'Length) := Msg;
702 Buf (Msg'Length + 1 .. Buf'Length) :=
703 String (Sdep.Table (D).Stamp);
704 Error_Msg_Name_1 := Sdep.Table (D).Sfile;
705 Error_Msg (Buf);
706 end;
707 end if;
708
709 -- Exit from the loop through Sdep entries once we find one
710 -- that does not match.
711
712 exit Sdep_Loop;
713 end if;
714
715 <<Continue>>
716 null;
717 end loop Sdep_Loop;
718 end loop ALIs_Loop;
719 end Check_Consistency;
720
721 -------------------------------
722 -- Check_Duplicated_Subunits --
723 -------------------------------
724
725 procedure Check_Duplicated_Subunits is
726 begin
727 for J in Sdep.First .. Sdep.Last loop
728 if Sdep.Table (J).Subunit_Name /= No_Name then
729 Get_Decoded_Name_String (Sdep.Table (J).Subunit_Name);
730 Name_Len := Name_Len + 2;
731 Name_Buffer (Name_Len - 1) := '%';
732
733 -- See if there is a body or spec with the same name
734
735 for K in Boolean loop
736 if K then
737 Name_Buffer (Name_Len) := 'b';
738
739 else
740 Name_Buffer (Name_Len) := 's';
741 end if;
742
743 declare
744 Info : constant Int := Get_Name_Table_Info (Name_Find);
745
746 begin
747 if Info /= 0 then
748 Set_Standard_Error;
749 Write_Str ("error: subunit """);
750 Write_Name_Decoded (Sdep.Table (J).Subunit_Name);
751 Write_Str (""" in file """);
752 Write_Name_Decoded (Sdep.Table (J).Sfile);
753 Write_Char ('"');
754 Write_Eol;
755 Write_Str (" has same name as unit """);
756 Write_Unit_Name (Units.Table (Unit_Id (Info)).Uname);
757 Write_Str (""" found in file """);
758 Write_Name_Decoded (Units.Table (Unit_Id (Info)).Sfile);
759 Write_Char ('"');
760 Write_Eol;
761 Write_Str (" this is not allowed within a single "
762 & "partition (RM 10.2(19))");
763 Write_Eol;
764 Osint.Exit_Program (Osint.E_Fatal);
765 end if;
766 end;
767 end loop;
768 end if;
769 end loop;
770 end Check_Duplicated_Subunits;
771
772 --------------------
773 -- Check_Versions --
774 --------------------
775
776 procedure Check_Versions is
777 VL : constant Natural := ALIs.Table (ALIs.First).Ver_Len;
778
779 begin
780 for A in ALIs.First .. ALIs.Last loop
781 if ALIs.Table (A).Ver_Len /= VL
782 or else ALIs.Table (A).Ver (1 .. VL) /=
783 ALIs.Table (ALIs.First).Ver (1 .. VL)
784 then
785 Error_Msg_Name_1 := ALIs.Table (A).Sfile;
786 Error_Msg_Name_2 := ALIs.Table (ALIs.First).Sfile;
787
788 Consistency_Error_Msg
789 ("% and % compiled with different GNAT versions");
790 end if;
791 end loop;
792 end Check_Versions;
793
794 ---------------------------
795 -- Consistency_Error_Msg --
796 ---------------------------
797
798 procedure Consistency_Error_Msg (Msg : String) is
799 begin
800 if Tolerate_Consistency_Errors then
801
802 -- If consistency errors are tolerated,
803 -- output the message as a warning.
804
805 declare
806 Warning_Msg : String (1 .. Msg'Length + 1);
807
808 begin
809 Warning_Msg (1) := '?';
810 Warning_Msg (2 .. Warning_Msg'Last) := Msg;
811
812 Error_Msg (Warning_Msg);
813 end;
814
815 -- Otherwise the consistency error is a true error
816
817 else
818 Error_Msg (Msg);
819 end if;
820 end Consistency_Error_Msg;
821
822 end Bcheck;