OSDN Git Service

2008-04-08 Ed Schonberg <schonberg@adacore.com>
[pf3gnuchains/gcc-fork.git] / gcc / ada / restrict.adb
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-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 ------------------------------------------------------------------------------
25
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;
38
39 package body Restrict is
40
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.
46
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.
50
51    -----------------------
52    -- Local Subprograms --
53    -----------------------
54
55    procedure Restriction_Msg (Msg : String; R : String; N : Node_Id);
56    --  Output error message at node N with given text, replacing the
57    --  '%' in the message with the name of the restriction given as R,
58    --  cased according to the current identifier casing. We do not use
59    --  the normal insertion mechanism, since this requires an entry
60    --  in the Names table, and this table will be locked if we are
61    --  generating a message from gigi.
62
63    function Same_Unit (U1, U2 : Node_Id) return Boolean;
64    --  Returns True iff U1 and U2 represent the same library unit. Used for
65    --  handling of No_Dependence => Unit restriction case.
66
67    function Suppress_Restriction_Message (N : Node_Id) return Boolean;
68    --  N is the node for a possible restriction violation message, but
69    --  the message is to be suppressed if this is an internal file and
70    --  this file is not the main unit.
71
72    -------------------
73    -- Abort_Allowed --
74    -------------------
75
76    function Abort_Allowed return Boolean is
77    begin
78       if Restrictions.Set (No_Abort_Statements)
79         and then Restrictions.Set (Max_Asynchronous_Select_Nesting)
80         and then Restrictions.Value (Max_Asynchronous_Select_Nesting) = 0
81       then
82          return False;
83       else
84          return True;
85       end if;
86    end Abort_Allowed;
87
88    -------------------------
89    -- Check_Compiler_Unit --
90    -------------------------
91
92    procedure Check_Compiler_Unit (N : Node_Id) is
93    begin
94       if Is_Compiler_Unit (Get_Source_Unit (N)) then
95          Error_Msg_N ("use of construct not allowed in compiler", N);
96       end if;
97    end Check_Compiler_Unit;
98
99    ------------------------------------
100    -- Check_Elaboration_Code_Allowed --
101    ------------------------------------
102
103    procedure Check_Elaboration_Code_Allowed (N : Node_Id) is
104    begin
105       Check_Restriction (No_Elaboration_Code, N);
106    end Check_Elaboration_Code_Allowed;
107
108    -----------------------------------------
109    -- Check_Implicit_Dynamic_Code_Allowed --
110    -----------------------------------------
111
112    procedure Check_Implicit_Dynamic_Code_Allowed (N : Node_Id) is
113    begin
114       Check_Restriction (No_Implicit_Dynamic_Code, N);
115    end Check_Implicit_Dynamic_Code_Allowed;
116
117    ----------------------------------
118    -- Check_No_Implicit_Heap_Alloc --
119    ----------------------------------
120
121    procedure Check_No_Implicit_Heap_Alloc (N : Node_Id) is
122    begin
123       Check_Restriction (No_Implicit_Heap_Allocations, N);
124    end Check_No_Implicit_Heap_Alloc;
125
126    ---------------------------
127    -- Check_Restricted_Unit --
128    ---------------------------
129
130    procedure Check_Restricted_Unit (U : Unit_Name_Type; N : Node_Id) is
131    begin
132       if Suppress_Restriction_Message (N) then
133          return;
134
135       elsif Is_Spec_Name (U) then
136          declare
137             Fnam : constant File_Name_Type :=
138                      Get_File_Name (U, Subunit => False);
139
140          begin
141             --  Get file name
142
143             Get_Name_String (Fnam);
144
145             --  Nothing to do if name not at least 5 characters long ending
146             --  in .ads or .adb extension, which we strip.
147
148             if Name_Len < 5
149               or else (Name_Buffer (Name_Len - 3 .. Name_Len) /= ".ads"
150                          and then
151                        Name_Buffer (Name_Len - 4 .. Name_Len) /= ".adb")
152             then
153                return;
154             end if;
155
156             --  Strip extension and pad to eight characters
157
158             Name_Len := Name_Len - 4;
159             while Name_Len < 8 loop
160                Name_Len := Name_Len + 1;
161                Name_Buffer (Name_Len) := ' ';
162             end loop;
163
164             --  If predefined unit, check the list of restricted units
165
166             if Is_Predefined_File_Name (Fnam) then
167                for J in Unit_Array'Range loop
168                   if Name_Len = 8
169                     and then Name_Buffer (1 .. 8) = Unit_Array (J).Filenm
170                   then
171                      Check_Restriction (Unit_Array (J).Res_Id, N);
172                   end if;
173                end loop;
174
175                --  If not predefied unit, then one special check still remains.
176                --  GNAT.Current_Exception is not allowed if we have restriction
177                --  No_Exception_Propagation active.
178
179             else
180                if Name_Buffer (1 .. 8) = "g-curexc" then
181                   Check_Restriction (No_Exception_Propagation, N);
182                end if;
183             end if;
184          end;
185       end if;
186    end Check_Restricted_Unit;
187
188    -----------------------
189    -- Check_Restriction --
190    -----------------------
191
192    procedure Check_Restriction
193      (R : Restriction_Id;
194       N : Node_Id;
195       V : Uint := Uint_Minus_1)
196    is
197       Rimage : constant String := Restriction_Id'Image (R);
198
199       VV : Integer;
200       --  V converted to integer form. If V is greater than Integer'Last,
201       --  it is reset to minus 1 (unknown value).
202
203       procedure Update_Restrictions (Info : in out Restrictions_Info);
204       --  Update violation information in Info.Violated and Info.Count
205
206       -------------------------
207       -- Update_Restrictions --
208       -------------------------
209
210       procedure Update_Restrictions (Info : in out Restrictions_Info) is
211       begin
212          --  If not violated, set as violated now
213
214          if not Info.Violated (R) then
215             Info.Violated (R) := True;
216
217             if R in All_Parameter_Restrictions then
218                if VV < 0 then
219                   Info.Unknown (R) := True;
220                   Info.Count (R) := 1;
221                else
222                   Info.Count (R) := VV;
223                end if;
224             end if;
225
226          --  Otherwise if violated already and a parameter restriction,
227          --  update count by maximizing or summing depending on restriction.
228
229          elsif R in All_Parameter_Restrictions then
230
231             --  If new value is unknown, result is unknown
232
233             if VV < 0 then
234                Info.Unknown (R) := True;
235
236             --  If checked by maximization, do maximization
237
238             elsif R in Checked_Max_Parameter_Restrictions then
239                Info.Count (R) := Integer'Max (Info.Count (R), VV);
240
241             --  If checked by adding, do add, checking for overflow
242
243             elsif R in Checked_Add_Parameter_Restrictions then
244                declare
245                   pragma Unsuppress (Overflow_Check);
246                begin
247                   Info.Count (R) := Info.Count (R) + VV;
248                exception
249                   when Constraint_Error =>
250                      Info.Count (R) := Integer'Last;
251                      Info.Unknown (R) := True;
252                end;
253
254             --  Should not be able to come here, known counts should only
255             --  occur for restrictions that are Checked_max or Checked_Sum.
256
257             else
258                raise Program_Error;
259             end if;
260          end if;
261       end Update_Restrictions;
262
263    --  Start of processing for Check_Restriction
264
265    begin
266       if UI_Is_In_Int_Range (V) then
267          VV := Integer (UI_To_Int (V));
268       else
269          VV := -1;
270       end if;
271
272       --  Count can only be specified in the checked val parameter case
273
274       pragma Assert (VV < 0 or else R in Checked_Val_Parameter_Restrictions);
275
276       --  Nothing to do if value of zero specified for parameter restriction
277
278       if VV = 0 then
279          return;
280       end if;
281
282       --  Update current restrictions
283
284       Update_Restrictions (Restrictions);
285
286       --  If in main extended unit, update main restrictions as well
287
288       if Current_Sem_Unit = Main_Unit
289         or else In_Extended_Main_Source_Unit (N)
290       then
291          Update_Restrictions (Main_Restrictions);
292       end if;
293
294       --  Nothing to do if restriction message suppressed
295
296       if Suppress_Restriction_Message (N) then
297          null;
298
299       --  If restriction not set, nothing to do
300
301       elsif not Restrictions.Set (R) then
302          null;
303
304       --  Here if restriction set, check for violation (either this is a
305       --  Boolean restriction, or a parameter restriction with a value of
306       --  zero and an unknown count, or a parameter restriction with a
307       --  known value that exceeds the restriction count).
308
309       elsif R in All_Boolean_Restrictions
310         or else (Restrictions.Unknown (R)
311                    and then Restrictions.Value (R) = 0)
312         or else Restrictions.Count (R) > Restrictions.Value (R)
313       then
314          Error_Msg_Sloc := Restrictions_Loc (R);
315
316          --  If we have a location for the Restrictions pragma, output it
317
318          if Error_Msg_Sloc > No_Location
319            or else Error_Msg_Sloc = System_Location
320          then
321             if Restriction_Warnings (R) then
322                Restriction_Msg ("|violation of restriction %#?", Rimage, N);
323             else
324                Restriction_Msg ("|violation of restriction %#", Rimage, N);
325             end if;
326
327          --  Otherwise we have the case of an implicit restriction
328          --  (e.g. a restriction implicitly set by another pragma)
329
330          else
331             Restriction_Msg
332               ("|violation of implicit restriction %", Rimage, N);
333          end if;
334       end if;
335    end Check_Restriction;
336
337    -------------------------------------
338    -- Check_Restriction_No_Dependence --
339    -------------------------------------
340
341    procedure Check_Restriction_No_Dependence (U : Node_Id; Err : Node_Id) is
342       DU : Node_Id;
343
344    begin
345       for J in No_Dependence.First .. No_Dependence.Last loop
346          DU := No_Dependence.Table (J).Unit;
347
348          if Same_Unit (U, DU) then
349             Error_Msg_Sloc := Sloc (DU);
350             Error_Msg_Node_1 := DU;
351
352             if No_Dependence.Table (J).Warn then
353                Error_Msg
354                  ("?violation of restriction `No_Dependence '='> &`#",
355                   Sloc (Err));
356             else
357                Error_Msg
358                  ("|violation of restriction `No_Dependence '='> &`#",
359                   Sloc (Err));
360             end if;
361
362             return;
363          end if;
364       end loop;
365    end Check_Restriction_No_Dependence;
366
367    ----------------------------------------
368    -- Cunit_Boolean_Restrictions_Restore --
369    ----------------------------------------
370
371    procedure Cunit_Boolean_Restrictions_Restore
372      (R : Save_Cunit_Boolean_Restrictions)
373    is
374    begin
375       for J in Cunit_Boolean_Restrictions loop
376          Restrictions.Set (J) := R (J);
377       end loop;
378    end Cunit_Boolean_Restrictions_Restore;
379
380    -------------------------------------
381    -- Cunit_Boolean_Restrictions_Save --
382    -------------------------------------
383
384    function Cunit_Boolean_Restrictions_Save
385      return Save_Cunit_Boolean_Restrictions
386    is
387       R : Save_Cunit_Boolean_Restrictions;
388
389    begin
390       for J in Cunit_Boolean_Restrictions loop
391          R (J) := Restrictions.Set (J);
392          Restrictions.Set (J) := False;
393       end loop;
394
395       return R;
396    end Cunit_Boolean_Restrictions_Save;
397
398    ------------------------
399    -- Get_Restriction_Id --
400    ------------------------
401
402    function Get_Restriction_Id
403      (N : Name_Id) return Restriction_Id
404    is
405    begin
406       Get_Name_String (N);
407       Set_Casing (All_Upper_Case);
408
409       for J in All_Restrictions loop
410          declare
411             S : constant String := Restriction_Id'Image (J);
412          begin
413             if S = Name_Buffer (1 .. Name_Len) then
414                return J;
415             end if;
416          end;
417       end loop;
418
419       return Not_A_Restriction_Id;
420    end Get_Restriction_Id;
421
422    -------------------------------
423    -- No_Exception_Handlers_Set --
424    -------------------------------
425
426    function No_Exception_Handlers_Set return Boolean is
427    begin
428       return (No_Run_Time_Mode or else Configurable_Run_Time_Mode)
429         and then (Restrictions.Set (No_Exception_Handlers)
430                     or else
431                   Restrictions.Set (No_Exception_Propagation));
432    end No_Exception_Handlers_Set;
433
434    -------------------------------------
435    -- No_Exception_Propagation_Active --
436    -------------------------------------
437
438    function No_Exception_Propagation_Active return Boolean is
439    begin
440       return (No_Run_Time_Mode
441                or else Configurable_Run_Time_Mode
442                or else Debug_Flag_Dot_G)
443         and then Restriction_Active (No_Exception_Propagation);
444    end No_Exception_Propagation_Active;
445
446    ----------------------------------
447    -- Process_Restriction_Synonyms --
448    ----------------------------------
449
450    --  Note: body of this function must be coordinated with list of
451    --  renaming declarations in System.Rident.
452
453    function Process_Restriction_Synonyms (N : Node_Id) return Name_Id
454    is
455       Old_Name : constant Name_Id := Chars (N);
456       New_Name : Name_Id;
457
458    begin
459       case Old_Name is
460          when Name_Boolean_Entry_Barriers =>
461             New_Name := Name_Simple_Barriers;
462
463          when Name_Max_Entry_Queue_Depth =>
464             New_Name := Name_Max_Entry_Queue_Length;
465
466          when Name_No_Dynamic_Interrupts =>
467             New_Name := Name_No_Dynamic_Attachment;
468
469          when Name_No_Requeue =>
470             New_Name := Name_No_Requeue_Statements;
471
472          when Name_No_Task_Attributes =>
473             New_Name := Name_No_Task_Attributes_Package;
474
475          when others =>
476             return Old_Name;
477       end case;
478
479       if Warn_On_Obsolescent_Feature then
480          Error_Msg_Name_1 := Old_Name;
481          Error_Msg_N ("restriction identifier % is obsolescent?", N);
482          Error_Msg_Name_1 := New_Name;
483          Error_Msg_N ("|use restriction identifier % instead", N);
484       end if;
485
486       return New_Name;
487    end Process_Restriction_Synonyms;
488
489    ------------------------
490    -- Restricted_Profile --
491    ------------------------
492
493    function Restricted_Profile return Boolean is
494    begin
495       if Restricted_Profile_Cached then
496          return Restricted_Profile_Result;
497
498       else
499          Restricted_Profile_Result := True;
500          Restricted_Profile_Cached := True;
501
502          declare
503             R : Restriction_Flags  renames Profile_Info (Restricted).Set;
504             V : Restriction_Values renames Profile_Info (Restricted).Value;
505          begin
506             for J in R'Range loop
507                if R (J)
508                  and then (Restrictions.Set (J) = False
509                              or else Restriction_Warnings (J)
510                              or else
511                                (J in All_Parameter_Restrictions
512                                   and then Restrictions.Value (J) > V (J)))
513                then
514                   Restricted_Profile_Result := False;
515                   exit;
516                end if;
517             end loop;
518
519             return Restricted_Profile_Result;
520          end;
521       end if;
522    end Restricted_Profile;
523
524    ------------------------
525    -- Restriction_Active --
526    ------------------------
527
528    function Restriction_Active (R : All_Restrictions) return Boolean is
529    begin
530       return Restrictions.Set (R) and then not Restriction_Warnings (R);
531    end Restriction_Active;
532
533    ---------------------
534    -- Restriction_Msg --
535    ---------------------
536
537    procedure Restriction_Msg (Msg : String; R : String; N : Node_Id) is
538       B : String (1 .. Msg'Length + 2 * R'Length + 1);
539       P : Natural := 1;
540
541    begin
542       Name_Buffer (1 .. R'Last) := R;
543       Name_Len := R'Length;
544       Set_Casing (Identifier_Casing (Get_Source_File_Index (Sloc (N))));
545
546       P := 0;
547       for J in Msg'Range loop
548          if Msg (J) = '%' then
549             P := P + 1;
550             B (P) := '`';
551
552             --  Put characters of image in message, quoting upper case letters
553
554             for J in 1 .. Name_Len loop
555                if Name_Buffer (J) in 'A' .. 'Z' then
556                   P := P + 1;
557                   B (P) := ''';
558                end if;
559
560                P := P + 1;
561                B (P) := Name_Buffer (J);
562             end loop;
563
564             P := P + 1;
565             B (P) := '`';
566
567          else
568             P := P + 1;
569             B (P) := Msg (J);
570          end if;
571       end loop;
572
573       Error_Msg_N (B (1 .. P), N);
574    end Restriction_Msg;
575
576    ---------------
577    -- Same_Unit --
578    ---------------
579
580    function Same_Unit (U1, U2 : Node_Id) return Boolean is
581    begin
582       if Nkind (U1) = N_Identifier then
583          return Nkind (U2) = N_Identifier and then Chars (U1) = Chars (U2);
584
585       elsif Nkind (U2) = N_Identifier then
586          return False;
587
588       elsif (Nkind (U1) = N_Selected_Component
589              or else Nkind (U1) = N_Expanded_Name)
590         and then
591           (Nkind (U2) = N_Selected_Component
592            or else Nkind (U2) = N_Expanded_Name)
593       then
594          return Same_Unit (Prefix (U1), Prefix (U2))
595            and then Same_Unit (Selector_Name (U1), Selector_Name (U2));
596       else
597          return False;
598       end if;
599    end Same_Unit;
600
601    ------------------------------
602    -- Set_Profile_Restrictions --
603    ------------------------------
604
605    procedure Set_Profile_Restrictions
606      (P    : Profile_Name;
607       N    : Node_Id;
608       Warn : Boolean)
609    is
610       R : Restriction_Flags  renames Profile_Info (P).Set;
611       V : Restriction_Values renames Profile_Info (P).Value;
612
613    begin
614       for J in R'Range loop
615          if R (J) then
616             declare
617                Already_Restricted : constant Boolean := Restriction_Active (J);
618
619             begin
620                --  Set the restriction
621
622                if J in All_Boolean_Restrictions then
623                   Set_Restriction (J, N);
624                else
625                   Set_Restriction (J, N, V (J));
626                end if;
627
628                --  Set warning flag, except that we do not set the warning
629                --  flag if the restriction was already active and this is
630                --  the warning case. That avoids a warning overriding a real
631                --  restriction, which should never happen.
632
633                if not (Warn and Already_Restricted) then
634                   Restriction_Warnings (J) := Warn;
635                end if;
636             end;
637          end if;
638       end loop;
639    end Set_Profile_Restrictions;
640
641    ---------------------
642    -- Set_Restriction --
643    ---------------------
644
645    --  Case of Boolean restriction
646
647    procedure Set_Restriction
648      (R : All_Boolean_Restrictions;
649       N : Node_Id)
650    is
651    begin
652       --  Restriction No_Elaboration_Code must be enforced on a unit by unit
653       --  basis. Hence, we avoid setting the restriction when processing an
654       --  unit which is not the main one being compiled (or its corresponding
655       --  spec). It can happen, for example, when processing an inlined body
656       --  (the package containing the inlined subprogram is analyzed,
657       --  including its pragma Restrictions).
658
659       --  This seems like a very nasty kludge??? This is not the only per unit
660       --  restriction why is this treated specially ???
661
662       if R = No_Elaboration_Code
663         and then Current_Sem_Unit /= Main_Unit
664         and then Cunit (Current_Sem_Unit) /= Library_Unit (Cunit (Main_Unit))
665       then
666          return;
667       end if;
668
669       Restrictions.Set (R) := True;
670
671       if Restricted_Profile_Cached and Restricted_Profile_Result then
672          null;
673       else
674          Restricted_Profile_Cached := False;
675       end if;
676
677       --  Set location, but preserve location of system
678       --  restriction for nice error msg with run time name
679
680       if Restrictions_Loc (R) /= System_Location then
681          Restrictions_Loc (R) := Sloc (N);
682       end if;
683
684       --  Record the restriction if we are in the main unit, or in the extended
685       --  main unit. The reason that we test separately for Main_Unit is that
686       --  gnat.adc is processed with Current_Sem_Unit = Main_Unit, but nodes in
687       --  gnat.adc do not appear to be in the extended main source unit (they
688       --  probably should do ???)
689
690       if Current_Sem_Unit = Main_Unit
691         or else In_Extended_Main_Source_Unit (N)
692       then
693          if not Restriction_Warnings (R) then
694             Main_Restrictions.Set (R) := True;
695          end if;
696       end if;
697    end Set_Restriction;
698
699    --  Case of parameter restriction
700
701    procedure Set_Restriction
702      (R : All_Parameter_Restrictions;
703       N : Node_Id;
704       V : Integer)
705    is
706    begin
707       if Restricted_Profile_Cached and Restricted_Profile_Result then
708          null;
709       else
710          Restricted_Profile_Cached := False;
711       end if;
712
713       if Restrictions.Set (R) then
714          if V < Restrictions.Value (R) then
715             Restrictions.Value (R) := V;
716             Restrictions_Loc (R) := Sloc (N);
717          end if;
718
719       else
720          Restrictions.Set (R) := True;
721          Restrictions.Value (R) := V;
722          Restrictions_Loc (R) := Sloc (N);
723       end if;
724
725       --  Record the restriction if we are in the main unit,
726       --  or in the extended main unit. The reason that we
727       --  test separately for Main_Unit is that gnat.adc is
728       --  processed with Current_Sem_Unit = Main_Unit, but
729       --  nodes in gnat.adc do not appear to be the extended
730       --  main source unit (they probably should do ???)
731
732       if Current_Sem_Unit = Main_Unit
733         or else In_Extended_Main_Source_Unit (N)
734       then
735          if Main_Restrictions.Set (R) then
736             if V < Main_Restrictions.Value (R) then
737                Main_Restrictions.Value (R) := V;
738             end if;
739
740          elsif not Restriction_Warnings (R) then
741             Main_Restrictions.Set (R) := True;
742             Main_Restrictions.Value (R) := V;
743          end if;
744       end if;
745    end Set_Restriction;
746
747    -----------------------------------
748    -- Set_Restriction_No_Dependence --
749    -----------------------------------
750
751    procedure Set_Restriction_No_Dependence
752      (Unit : Node_Id;
753       Warn : Boolean)
754    is
755    begin
756       --  Loop to check for duplicate entry
757
758       for J in No_Dependence.First .. No_Dependence.Last loop
759
760          --  Case of entry already in table
761
762          if Same_Unit (Unit, No_Dependence.Table (J).Unit) then
763
764             --  Error has precedence over warning
765
766             if not Warn then
767                No_Dependence.Table (J).Warn := False;
768             end if;
769
770             return;
771          end if;
772       end loop;
773
774       --  Entry is not currently in table
775
776       No_Dependence.Append ((Unit, Warn));
777    end Set_Restriction_No_Dependence;
778
779    ----------------------------------
780    -- Suppress_Restriction_Message --
781    ----------------------------------
782
783    function Suppress_Restriction_Message (N : Node_Id) return Boolean is
784    begin
785       --  We only output messages for the extended main source unit
786
787       if In_Extended_Main_Source_Unit (N) then
788          return False;
789
790       --  If loaded by rtsfind, then suppress message
791
792       elsif Sloc (N) <= No_Location then
793          return True;
794
795       --  Otherwise suppress message if internal file
796
797       else
798          return Is_Internal_File_Name (Unit_File_Name (Get_Source_Unit (N)));
799       end if;
800    end Suppress_Restriction_Message;
801
802    ---------------------
803    -- Tasking_Allowed --
804    ---------------------
805
806    function Tasking_Allowed return Boolean is
807    begin
808       return not Restrictions.Set (No_Tasking)
809         and then (not Restrictions.Set (Max_Tasks)
810                     or else Restrictions.Value (Max_Tasks) > 0);
811    end Tasking_Allowed;
812
813 end Restrict;