fixing pr42337
[official-gcc.git] / gcc / ada / restrict.adb
bloba57ac4c66ee16b77e7b0cee3bdd607dd5e873a3c
1 ------------------------------------------------------------------------------
2 -- --
3 -- GNAT COMPILER COMPONENTS --
4 -- --
5 -- R E S T R I C T --
6 -- --
7 -- B o d y --
8 -- --
9 -- Copyright (C) 1992-2008, 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 Atree; use Atree;
27 with Casing; use Casing;
28 with Errout; use Errout;
29 with Debug; use Debug;
30 with Fname; use Fname;
31 with Fname.UF; use Fname.UF;
32 with Lib; use Lib;
33 with Opt; use Opt;
34 with Sinfo; use Sinfo;
35 with Sinput; use Sinput;
36 with Snames; use Snames;
37 with Uname; use Uname;
39 package body Restrict is
41 Restricted_Profile_Result : Boolean := False;
42 -- This switch memoizes the result of Restricted_Profile function
43 -- calls for improved efficiency. Its setting is valid only if
44 -- Restricted_Profile_Cached is True. Note that if this switch
45 -- is ever set True, it need never be turned off again.
47 Restricted_Profile_Cached : Boolean := False;
48 -- This flag is set to True if the Restricted_Profile_Result
49 -- contains the correct cached result of Restricted_Profile calls.
51 -----------------------
52 -- Local Subprograms --
53 -----------------------
55 procedure Restriction_Msg (R : Restriction_Id; N : Node_Id);
56 -- Called if a violation of restriction R at node N is found. This routine
57 -- outputs the appropriate message or messages taking care of warning vs
58 -- real violation, serious vs non-serious, implicit vs explicit, the second
59 -- message giving the profile name if needed, and the location information.
61 function Same_Unit (U1, U2 : Node_Id) return Boolean;
62 -- Returns True iff U1 and U2 represent the same library unit. Used for
63 -- handling of No_Dependence => Unit restriction case.
65 function Suppress_Restriction_Message (N : Node_Id) return Boolean;
66 -- N is the node for a possible restriction violation message, but the
67 -- message is to be suppressed if this is an internal file and this file is
68 -- not the main unit. Returns True if message is to be suppressed.
70 -------------------
71 -- Abort_Allowed --
72 -------------------
74 function Abort_Allowed return Boolean is
75 begin
76 if Restrictions.Set (No_Abort_Statements)
77 and then Restrictions.Set (Max_Asynchronous_Select_Nesting)
78 and then Restrictions.Value (Max_Asynchronous_Select_Nesting) = 0
79 then
80 return False;
81 else
82 return True;
83 end if;
84 end Abort_Allowed;
86 -------------------------
87 -- Check_Compiler_Unit --
88 -------------------------
90 procedure Check_Compiler_Unit (N : Node_Id) is
91 begin
92 if Is_Compiler_Unit (Get_Source_Unit (N)) then
93 Error_Msg_N ("use of construct not allowed in compiler", N);
94 end if;
95 end Check_Compiler_Unit;
97 ------------------------------------
98 -- Check_Elaboration_Code_Allowed --
99 ------------------------------------
101 procedure Check_Elaboration_Code_Allowed (N : Node_Id) is
102 begin
103 Check_Restriction (No_Elaboration_Code, N);
104 end Check_Elaboration_Code_Allowed;
106 -----------------------------------------
107 -- Check_Implicit_Dynamic_Code_Allowed --
108 -----------------------------------------
110 procedure Check_Implicit_Dynamic_Code_Allowed (N : Node_Id) is
111 begin
112 Check_Restriction (No_Implicit_Dynamic_Code, N);
113 end Check_Implicit_Dynamic_Code_Allowed;
115 ----------------------------------
116 -- Check_No_Implicit_Heap_Alloc --
117 ----------------------------------
119 procedure Check_No_Implicit_Heap_Alloc (N : Node_Id) is
120 begin
121 Check_Restriction (No_Implicit_Heap_Allocations, N);
122 end Check_No_Implicit_Heap_Alloc;
124 ---------------------------
125 -- Check_Restricted_Unit --
126 ---------------------------
128 procedure Check_Restricted_Unit (U : Unit_Name_Type; N : Node_Id) is
129 begin
130 if Suppress_Restriction_Message (N) then
131 return;
133 elsif Is_Spec_Name (U) then
134 declare
135 Fnam : constant File_Name_Type :=
136 Get_File_Name (U, Subunit => False);
138 begin
139 -- Get file name
141 Get_Name_String (Fnam);
143 -- Nothing to do if name not at least 5 characters long ending
144 -- in .ads or .adb extension, which we strip.
146 if Name_Len < 5
147 or else (Name_Buffer (Name_Len - 3 .. Name_Len) /= ".ads"
148 and then
149 Name_Buffer (Name_Len - 3 .. Name_Len) /= ".adb")
150 then
151 return;
152 end if;
154 -- Strip extension and pad to eight characters
156 Name_Len := Name_Len - 4;
157 Add_Str_To_Name_Buffer ((Name_Len + 1 .. 8 => ' '));
159 -- If predefined unit, check the list of restricted units
161 if Is_Predefined_File_Name (Fnam) then
162 for J in Unit_Array'Range loop
163 if Name_Len = 8
164 and then Name_Buffer (1 .. 8) = Unit_Array (J).Filenm
165 then
166 Check_Restriction (Unit_Array (J).Res_Id, N);
167 end if;
168 end loop;
170 -- If not predefined unit, then one special check still
171 -- remains. GNAT.Current_Exception is not allowed if we have
172 -- restriction No_Exception_Propagation active.
174 else
175 if Name_Buffer (1 .. 8) = "g-curexc" then
176 Check_Restriction (No_Exception_Propagation, N);
177 end if;
178 end if;
179 end;
180 end if;
181 end Check_Restricted_Unit;
183 -----------------------
184 -- Check_Restriction --
185 -----------------------
187 procedure Check_Restriction
188 (R : Restriction_Id;
189 N : Node_Id;
190 V : Uint := Uint_Minus_1)
192 VV : Integer;
193 -- V converted to integer form. If V is greater than Integer'Last,
194 -- it is reset to minus 1 (unknown value).
196 procedure Update_Restrictions (Info : in out Restrictions_Info);
197 -- Update violation information in Info.Violated and Info.Count
199 -------------------------
200 -- Update_Restrictions --
201 -------------------------
203 procedure Update_Restrictions (Info : in out Restrictions_Info) is
204 begin
205 -- If not violated, set as violated now
207 if not Info.Violated (R) then
208 Info.Violated (R) := True;
210 if R in All_Parameter_Restrictions then
211 if VV < 0 then
212 Info.Unknown (R) := True;
213 Info.Count (R) := 1;
214 else
215 Info.Count (R) := VV;
216 end if;
217 end if;
219 -- Otherwise if violated already and a parameter restriction,
220 -- update count by maximizing or summing depending on restriction.
222 elsif R in All_Parameter_Restrictions then
224 -- If new value is unknown, result is unknown
226 if VV < 0 then
227 Info.Unknown (R) := True;
229 -- If checked by maximization, do maximization
231 elsif R in Checked_Max_Parameter_Restrictions then
232 Info.Count (R) := Integer'Max (Info.Count (R), VV);
234 -- If checked by adding, do add, checking for overflow
236 elsif R in Checked_Add_Parameter_Restrictions then
237 declare
238 pragma Unsuppress (Overflow_Check);
239 begin
240 Info.Count (R) := Info.Count (R) + VV;
241 exception
242 when Constraint_Error =>
243 Info.Count (R) := Integer'Last;
244 Info.Unknown (R) := True;
245 end;
247 -- Should not be able to come here, known counts should only
248 -- occur for restrictions that are Checked_max or Checked_Sum.
250 else
251 raise Program_Error;
252 end if;
253 end if;
254 end Update_Restrictions;
256 -- Start of processing for Check_Restriction
258 begin
259 if UI_Is_In_Int_Range (V) then
260 VV := Integer (UI_To_Int (V));
261 else
262 VV := -1;
263 end if;
265 -- Count can only be specified in the checked val parameter case
267 pragma Assert (VV < 0 or else R in Checked_Val_Parameter_Restrictions);
269 -- Nothing to do if value of zero specified for parameter restriction
271 if VV = 0 then
272 return;
273 end if;
275 -- Update current restrictions
277 Update_Restrictions (Restrictions);
279 -- If in main extended unit, update main restrictions as well
281 if Current_Sem_Unit = Main_Unit
282 or else In_Extended_Main_Source_Unit (N)
283 then
284 Update_Restrictions (Main_Restrictions);
285 end if;
287 -- Nothing to do if restriction message suppressed
289 if Suppress_Restriction_Message (N) then
290 null;
292 -- If restriction not set, nothing to do
294 elsif not Restrictions.Set (R) then
295 null;
297 -- Here if restriction set, check for violation (either this is a
298 -- Boolean restriction, or a parameter restriction with a value of
299 -- zero and an unknown count, or a parameter restriction with a
300 -- known value that exceeds the restriction count).
302 elsif R in All_Boolean_Restrictions
303 or else (Restrictions.Unknown (R)
304 and then Restrictions.Value (R) = 0)
305 or else Restrictions.Count (R) > Restrictions.Value (R)
306 then
307 Restriction_Msg (R, N);
308 end if;
309 end Check_Restriction;
311 -------------------------------------
312 -- Check_Restriction_No_Dependence --
313 -------------------------------------
315 procedure Check_Restriction_No_Dependence (U : Node_Id; Err : Node_Id) is
316 DU : Node_Id;
318 begin
319 -- Ignore call if node U is not in the main source unit. This avoids
320 -- cascaded errors, e.g. when Ada.Containers units with other units.
322 if not In_Extended_Main_Source_Unit (U) then
323 return;
324 end if;
326 -- Loop through entries in No_Dependence table to check each one in turn
328 for J in No_Dependence.First .. No_Dependence.Last loop
329 DU := No_Dependence.Table (J).Unit;
331 if Same_Unit (U, DU) then
332 Error_Msg_Sloc := Sloc (DU);
333 Error_Msg_Node_1 := DU;
335 if No_Dependence.Table (J).Warn then
336 Error_Msg
337 ("?violation of restriction `No_Dependence '='> &`#",
338 Sloc (Err));
339 else
340 Error_Msg
341 ("|violation of restriction `No_Dependence '='> &`#",
342 Sloc (Err));
343 end if;
345 return;
346 end if;
347 end loop;
348 end Check_Restriction_No_Dependence;
350 ----------------------------------------
351 -- Cunit_Boolean_Restrictions_Restore --
352 ----------------------------------------
354 procedure Cunit_Boolean_Restrictions_Restore
355 (R : Save_Cunit_Boolean_Restrictions)
357 begin
358 for J in Cunit_Boolean_Restrictions loop
359 Restrictions.Set (J) := R (J);
360 end loop;
361 end Cunit_Boolean_Restrictions_Restore;
363 -------------------------------------
364 -- Cunit_Boolean_Restrictions_Save --
365 -------------------------------------
367 function Cunit_Boolean_Restrictions_Save
368 return Save_Cunit_Boolean_Restrictions
370 R : Save_Cunit_Boolean_Restrictions;
372 begin
373 for J in Cunit_Boolean_Restrictions loop
374 R (J) := Restrictions.Set (J);
375 Restrictions.Set (J) := False;
376 end loop;
378 return R;
379 end Cunit_Boolean_Restrictions_Save;
381 ------------------------
382 -- Get_Restriction_Id --
383 ------------------------
385 function Get_Restriction_Id
386 (N : Name_Id) return Restriction_Id
388 begin
389 Get_Name_String (N);
390 Set_Casing (All_Upper_Case);
392 for J in All_Restrictions loop
393 declare
394 S : constant String := Restriction_Id'Image (J);
395 begin
396 if S = Name_Buffer (1 .. Name_Len) then
397 return J;
398 end if;
399 end;
400 end loop;
402 return Not_A_Restriction_Id;
403 end Get_Restriction_Id;
405 -------------------------------
406 -- No_Exception_Handlers_Set --
407 -------------------------------
409 function No_Exception_Handlers_Set return Boolean is
410 begin
411 return (No_Run_Time_Mode or else Configurable_Run_Time_Mode)
412 and then (Restrictions.Set (No_Exception_Handlers)
413 or else
414 Restrictions.Set (No_Exception_Propagation));
415 end No_Exception_Handlers_Set;
417 -------------------------------------
418 -- No_Exception_Propagation_Active --
419 -------------------------------------
421 function No_Exception_Propagation_Active return Boolean is
422 begin
423 return (No_Run_Time_Mode
424 or else Configurable_Run_Time_Mode
425 or else Debug_Flag_Dot_G)
426 and then Restriction_Active (No_Exception_Propagation);
427 end No_Exception_Propagation_Active;
429 ----------------------------------
430 -- Process_Restriction_Synonyms --
431 ----------------------------------
433 -- Note: body of this function must be coordinated with list of
434 -- renaming declarations in System.Rident.
436 function Process_Restriction_Synonyms (N : Node_Id) return Name_Id
438 Old_Name : constant Name_Id := Chars (N);
439 New_Name : Name_Id;
441 begin
442 case Old_Name is
443 when Name_Boolean_Entry_Barriers =>
444 New_Name := Name_Simple_Barriers;
446 when Name_Max_Entry_Queue_Depth =>
447 New_Name := Name_Max_Entry_Queue_Length;
449 when Name_No_Dynamic_Interrupts =>
450 New_Name := Name_No_Dynamic_Attachment;
452 when Name_No_Requeue =>
453 New_Name := Name_No_Requeue_Statements;
455 when Name_No_Task_Attributes =>
456 New_Name := Name_No_Task_Attributes_Package;
458 when others =>
459 return Old_Name;
460 end case;
462 if Warn_On_Obsolescent_Feature then
463 Error_Msg_Name_1 := Old_Name;
464 Error_Msg_N ("restriction identifier % is obsolescent?", N);
465 Error_Msg_Name_1 := New_Name;
466 Error_Msg_N ("|use restriction identifier % instead", N);
467 end if;
469 return New_Name;
470 end Process_Restriction_Synonyms;
472 ------------------------
473 -- Restricted_Profile --
474 ------------------------
476 function Restricted_Profile return Boolean is
477 begin
478 if Restricted_Profile_Cached then
479 return Restricted_Profile_Result;
481 else
482 Restricted_Profile_Result := True;
483 Restricted_Profile_Cached := True;
485 declare
486 R : Restriction_Flags renames Profile_Info (Restricted).Set;
487 V : Restriction_Values renames Profile_Info (Restricted).Value;
488 begin
489 for J in R'Range loop
490 if R (J)
491 and then (Restrictions.Set (J) = False
492 or else Restriction_Warnings (J)
493 or else
494 (J in All_Parameter_Restrictions
495 and then Restrictions.Value (J) > V (J)))
496 then
497 Restricted_Profile_Result := False;
498 exit;
499 end if;
500 end loop;
502 return Restricted_Profile_Result;
503 end;
504 end if;
505 end Restricted_Profile;
507 ------------------------
508 -- Restriction_Active --
509 ------------------------
511 function Restriction_Active (R : All_Restrictions) return Boolean is
512 begin
513 return Restrictions.Set (R) and then not Restriction_Warnings (R);
514 end Restriction_Active;
516 ---------------------
517 -- Restriction_Msg --
518 ---------------------
520 procedure Restriction_Msg (R : Restriction_Id; N : Node_Id) is
521 Msg : String (1 .. 100);
522 Len : Natural := 0;
524 procedure Add_Char (C : Character);
525 -- Append given character to Msg, bumping Len
527 procedure Add_Str (S : String);
528 -- Append given string to Msg, bumping Len appropriately
530 procedure Id_Case (S : String; Quotes : Boolean := True);
531 -- Given a string S, case it according to current identifier casing,
532 -- and store in Error_Msg_String. Then append `~` to the message buffer
533 -- to output the string unchanged surrounded in quotes. The quotes are
534 -- suppressed if Quotes = False.
536 --------------
537 -- Add_Char --
538 --------------
540 procedure Add_Char (C : Character) is
541 begin
542 Len := Len + 1;
543 Msg (Len) := C;
544 end Add_Char;
546 -------------
547 -- Add_Str --
548 -------------
550 procedure Add_Str (S : String) is
551 begin
552 Msg (Len + 1 .. Len + S'Length) := S;
553 Len := Len + S'Length;
554 end Add_Str;
556 -------------
557 -- Id_Case --
558 -------------
560 procedure Id_Case (S : String; Quotes : Boolean := True) is
561 begin
562 Name_Buffer (1 .. S'Last) := S;
563 Name_Len := S'Length;
564 Set_Casing (Identifier_Casing (Get_Source_File_Index (Sloc (N))));
565 Error_Msg_Strlen := Name_Len;
566 Error_Msg_String (1 .. Name_Len) := Name_Buffer (1 .. Name_Len);
568 if Quotes then
569 Add_Str ("`~`");
570 else
571 Add_Char ('~');
572 end if;
573 end Id_Case;
575 -- Start of processing for Restriction_Msg
577 begin
578 -- Set warning message if warning
580 if Restriction_Warnings (R) then
581 Add_Char ('?');
583 -- If real violation (not warning), then mark it as non-serious unless
584 -- it is a violation of No_Finalization in which case we leave it as a
585 -- serious message, since otherwise we get crashes during attempts to
586 -- expand stuff that is not properly formed due to assumptions made
587 -- about no finalization being present.
589 elsif R /= No_Finalization then
590 Add_Char ('|');
591 end if;
593 Error_Msg_Sloc := Restrictions_Loc (R);
595 -- Set main message, adding implicit if no source location
597 if Error_Msg_Sloc > No_Location
598 or else Error_Msg_Sloc = System_Location
599 then
600 Add_Str ("violation of restriction ");
601 else
602 Add_Str ("violation of implicit restriction ");
603 Error_Msg_Sloc := No_Location;
604 end if;
606 -- Case of parametrized restriction
608 if R in All_Parameter_Restrictions then
609 Add_Char ('`');
610 Id_Case (Restriction_Id'Image (R), Quotes => False);
611 Add_Str (" = ^`");
612 Error_Msg_Uint_1 := UI_From_Int (Int (Restrictions.Value (R)));
614 -- Case of boolean restriction
616 else
617 Id_Case (Restriction_Id'Image (R));
618 end if;
620 -- Case of no secondary profile continuation message
622 if Restriction_Profile_Name (R) = No_Profile then
623 if Error_Msg_Sloc /= No_Location then
624 Add_Char ('#');
625 end if;
627 Add_Char ('!');
628 Error_Msg_N (Msg (1 .. Len), N);
630 -- Case of secondary profile continuation message present
632 else
633 Add_Char ('!');
634 Error_Msg_N (Msg (1 .. Len), N);
636 Len := 0;
637 Add_Char ('\');
639 -- Set as warning if warning case
641 if Restriction_Warnings (R) then
642 Add_Char ('?');
643 end if;
645 -- Set main message
647 Add_Str ("from profile ");
648 Id_Case (Profile_Name'Image (Restriction_Profile_Name (R)));
650 -- Add location if we have one
652 if Error_Msg_Sloc /= No_Location then
653 Add_Char ('#');
654 end if;
656 -- Output unconditional message and we are done
658 Add_Char ('!');
659 Error_Msg_N (Msg (1 .. Len), N);
660 end if;
661 end Restriction_Msg;
663 ---------------
664 -- Same_Unit --
665 ---------------
667 function Same_Unit (U1, U2 : Node_Id) return Boolean is
668 begin
669 if Nkind (U1) = N_Identifier then
670 return Nkind (U2) = N_Identifier and then Chars (U1) = Chars (U2);
672 elsif Nkind (U2) = N_Identifier then
673 return False;
675 elsif (Nkind (U1) = N_Selected_Component
676 or else Nkind (U1) = N_Expanded_Name)
677 and then
678 (Nkind (U2) = N_Selected_Component
679 or else Nkind (U2) = N_Expanded_Name)
680 then
681 return Same_Unit (Prefix (U1), Prefix (U2))
682 and then Same_Unit (Selector_Name (U1), Selector_Name (U2));
683 else
684 return False;
685 end if;
686 end Same_Unit;
688 ------------------------------
689 -- Set_Profile_Restrictions --
690 ------------------------------
692 procedure Set_Profile_Restrictions
693 (P : Profile_Name;
694 N : Node_Id;
695 Warn : Boolean)
697 R : Restriction_Flags renames Profile_Info (P).Set;
698 V : Restriction_Values renames Profile_Info (P).Value;
700 begin
701 for J in R'Range loop
702 if R (J) then
703 declare
704 Already_Restricted : constant Boolean := Restriction_Active (J);
706 begin
707 -- Set the restriction
709 if J in All_Boolean_Restrictions then
710 Set_Restriction (J, N);
711 else
712 Set_Restriction (J, N, V (J));
713 end if;
715 -- Record that this came from a Profile[_Warnings] restriction
717 Restriction_Profile_Name (J) := P;
719 -- Set warning flag, except that we do not set the warning
720 -- flag if the restriction was already active and this is
721 -- the warning case. That avoids a warning overriding a real
722 -- restriction, which should never happen.
724 if not (Warn and Already_Restricted) then
725 Restriction_Warnings (J) := Warn;
726 end if;
727 end;
728 end if;
729 end loop;
730 end Set_Profile_Restrictions;
732 ---------------------
733 -- Set_Restriction --
734 ---------------------
736 -- Case of Boolean restriction
738 procedure Set_Restriction
739 (R : All_Boolean_Restrictions;
740 N : Node_Id)
742 begin
743 -- Restriction No_Elaboration_Code must be enforced on a unit by unit
744 -- basis. Hence, we avoid setting the restriction when processing an
745 -- unit which is not the main one being compiled (or its corresponding
746 -- spec). It can happen, for example, when processing an inlined body
747 -- (the package containing the inlined subprogram is analyzed,
748 -- including its pragma Restrictions).
750 -- This seems like a very nasty kludge??? This is not the only per unit
751 -- restriction why is this treated specially ???
753 if R = No_Elaboration_Code
754 and then Current_Sem_Unit /= Main_Unit
755 and then Cunit (Current_Sem_Unit) /= Library_Unit (Cunit (Main_Unit))
756 then
757 return;
758 end if;
760 Restrictions.Set (R) := True;
762 if Restricted_Profile_Cached and Restricted_Profile_Result then
763 null;
764 else
765 Restricted_Profile_Cached := False;
766 end if;
768 -- Set location, but preserve location of system restriction for nice
769 -- error msg with run time name.
771 if Restrictions_Loc (R) /= System_Location then
772 Restrictions_Loc (R) := Sloc (N);
773 end if;
775 -- Note restriction came from restriction pragma, not profile
777 Restriction_Profile_Name (R) := No_Profile;
779 -- Record the restriction if we are in the main unit, or in the extended
780 -- main unit. The reason that we test separately for Main_Unit is that
781 -- gnat.adc is processed with Current_Sem_Unit = Main_Unit, but nodes in
782 -- gnat.adc do not appear to be in the extended main source unit (they
783 -- probably should do ???)
785 if Current_Sem_Unit = Main_Unit
786 or else In_Extended_Main_Source_Unit (N)
787 then
788 if not Restriction_Warnings (R) then
789 Main_Restrictions.Set (R) := True;
790 end if;
791 end if;
792 end Set_Restriction;
794 -- Case of parameter restriction
796 procedure Set_Restriction
797 (R : All_Parameter_Restrictions;
798 N : Node_Id;
799 V : Integer)
801 begin
802 if Restricted_Profile_Cached and Restricted_Profile_Result then
803 null;
804 else
805 Restricted_Profile_Cached := False;
806 end if;
808 if Restrictions.Set (R) then
809 if V < Restrictions.Value (R) then
810 Restrictions.Value (R) := V;
811 Restrictions_Loc (R) := Sloc (N);
812 end if;
814 else
815 Restrictions.Set (R) := True;
816 Restrictions.Value (R) := V;
817 Restrictions_Loc (R) := Sloc (N);
818 end if;
820 -- Record the restriction if we are in the main unit, or in the extended
821 -- main unit. The reason that we test separately for Main_Unit is that
822 -- gnat.adc is processed with Current_Sem_Unit = Main_Unit, but nodes in
823 -- gnat.adc do not appear to be the extended main source unit (they
824 -- probably should do ???)
826 if Current_Sem_Unit = Main_Unit
827 or else In_Extended_Main_Source_Unit (N)
828 then
829 if Main_Restrictions.Set (R) then
830 if V < Main_Restrictions.Value (R) then
831 Main_Restrictions.Value (R) := V;
832 end if;
834 elsif not Restriction_Warnings (R) then
835 Main_Restrictions.Set (R) := True;
836 Main_Restrictions.Value (R) := V;
837 end if;
838 end if;
840 -- Note restriction came from restriction pragma, not profile
842 Restriction_Profile_Name (R) := No_Profile;
843 end Set_Restriction;
845 -----------------------------------
846 -- Set_Restriction_No_Dependence --
847 -----------------------------------
849 procedure Set_Restriction_No_Dependence
850 (Unit : Node_Id;
851 Warn : Boolean;
852 Profile : Profile_Name := No_Profile)
854 begin
855 -- Loop to check for duplicate entry
857 for J in No_Dependence.First .. No_Dependence.Last loop
859 -- Case of entry already in table
861 if Same_Unit (Unit, No_Dependence.Table (J).Unit) then
863 -- Error has precedence over warning
865 if not Warn then
866 No_Dependence.Table (J).Warn := False;
867 end if;
869 return;
870 end if;
871 end loop;
873 -- Entry is not currently in table
875 No_Dependence.Append ((Unit, Warn, Profile));
876 end Set_Restriction_No_Dependence;
878 ----------------------------------
879 -- Suppress_Restriction_Message --
880 ----------------------------------
882 function Suppress_Restriction_Message (N : Node_Id) return Boolean is
883 begin
884 -- We only output messages for the extended main source unit
886 if In_Extended_Main_Source_Unit (N) then
887 return False;
889 -- If loaded by rtsfind, then suppress message
891 elsif Sloc (N) <= No_Location then
892 return True;
894 -- Otherwise suppress message if internal file
896 else
897 return Is_Internal_File_Name (Unit_File_Name (Get_Source_Unit (N)));
898 end if;
899 end Suppress_Restriction_Message;
901 ---------------------
902 -- Tasking_Allowed --
903 ---------------------
905 function Tasking_Allowed return Boolean is
906 begin
907 return not Restrictions.Set (No_Tasking)
908 and then (not Restrictions.Set (Max_Tasks)
909 or else Restrictions.Value (Max_Tasks) > 0);
910 end Tasking_Allowed;
912 end Restrict;