diff mbox

[Ada] Improve the support of No_Use_Entity

Message ID 20160616094413.GA55505@adacore.com
State New
Headers show

Commit Message

Arnaud Charlet June 16, 2016, 9:44 a.m. UTC
This patch performs a code cleanup of the previous implementation and extends
its functionality to facilitate the use of this restriction with entities of
the Ada83 package Text_IO. For example:

pragma Restrictions (No_Use_Of_Entity => Text_IO.Put_Line);

with Text_IO; use Text_IO;
procedure Restrict is
begin
   Put ("Hello");
   Put_Line ("Hello_World!");              -- Restriction failed

   Text_IO.Put ("Hello");
   Text_IO.Put_Line ("Hello_World!");      -- Restriction failed
end;

Command: gcc -c restrict.adb
Output:
restrict.adb:7:04: reference to "Put_Line" violates restriction
                   No_Use_Of_Entity at line 1
restrict.adb:10:11: reference to "Text_IO.Put_Line" violates restriction
                    No_Use_Of_Entity at line 1

Tested on x86_64-pc-linux-gnu, committed on trunk

2016-06-16  Javier Miranda  <miranda@adacore.com>

	* restrict.adb (Check_Restriction_No_Use_Of_Entity): Avoid
	never-ending loop, code cleanup; adding also support for Text_IO.
	* sem_ch8.adb (Find_Expanded_Name): Invoke
	Check_Restriction_No_Use_Entity.
diff mbox

Patch

Index: restrict.adb
===================================================================
--- restrict.adb	(revision 237429)
+++ restrict.adb	(working copy)
@@ -6,7 +6,7 @@ 
 --                                                                          --
 --                                 B o d y                                  --
 --                                                                          --
---          Copyright (C) 1992-2015, Free Software Foundation, Inc.         --
+--          Copyright (C) 1992-2016, Free Software Foundation, Inc.         --
 --                                                                          --
 -- GNAT is free software;  you can  redistribute it  and/or modify it under --
 -- terms of the  GNU General Public License as published  by the Free Soft- --
@@ -759,9 +759,16 @@ 
             Ent  := Entity (N);
             Expr := NE_Ent.Entity;
             loop
-               --  Here if at outer level of entity name in reference
+               --  Here if at outer level of entity name in reference (handle
+               --  also the direct use of Text_IO in the pragma). For example:
+               --  pragma Restrictions (No_Use_Of_Entity => Text_IO.Put);
 
-               if Scope (Ent) = Standard_Standard then
+               if Scope (Ent) = Standard_Standard
+                 or else (Nkind (Expr) = N_Identifier
+                           and then Chars (Ent) = Name_Text_IO
+                           and then Chars (Scope (Ent)) = Name_Ada
+                           and then Scope (Scope (Ent)) = Standard_Standard)
+               then
                   if Nkind_In (Expr, N_Identifier, N_Operator_Symbol)
                     and then Chars (Ent) = Chars (Expr)
                   then
@@ -774,22 +781,19 @@ 
                      return;
 
                   else
-                     goto Continue;
+                     exit;
                   end if;
 
                --  Here if at outer level of entity name in table
 
                elsif Nkind_In (Expr, N_Identifier, N_Operator_Symbol) then
-                  goto Continue;
+                  exit;
 
                --  Here if neither at the outer level
 
                else
                   pragma Assert (Nkind (Expr) = N_Selected_Component);
-
-                  if Chars (Selector_Name (Expr)) /= Chars (Ent) then
-                     goto Continue;
-                  end if;
+                  exit when Chars (Selector_Name (Expr)) /= Chars (Ent);
                end if;
 
                --  Move up a level
@@ -800,10 +804,6 @@ 
                end loop;
 
                Expr := Prefix (Expr);
-
-               --  Entry did not match
-
-               <<Continue>> null;
             end loop;
          end;
       end loop;
Index: sem_ch12.adb
===================================================================
--- sem_ch12.adb	(revision 237437)
+++ sem_ch12.adb	(working copy)
@@ -1112,7 +1112,7 @@ 
       --  Find actual that corresponds to a given a formal parameter. If the
       --  actuals are positional, return the next one, if any. If the actuals
       --  are named, scan the parameter associations to find the right one.
-      --  A_F is the corresponding entity in the analyzed generic,which is
+      --  A_F is the corresponding entity in the analyzed generic, which is
       --  placed on the selector name for ASIS use.
       --
       --  In Ada 2005, a named association may be given with a box, in which
@@ -1257,7 +1257,7 @@ 
 
          elsif No (Selector_Name (Actual)) then
             Found_Assoc := Actual;
-            Act := Explicit_Generic_Actual_Parameter (Actual);
+            Act         := Explicit_Generic_Actual_Parameter (Actual);
             Num_Matched := Num_Matched + 1;
             Next (Actual);
 
@@ -1271,12 +1271,17 @@ 
             Prev        := Empty;
 
             while Present (Actual) loop
-               if Chars (Selector_Name (Actual)) = Chars (F) then
+               if Nkind (Actual) = N_Others_Choice then
+                  Found_Assoc := Empty;
+                  Act         := Empty;
+
+               elsif Chars (Selector_Name (Actual)) = Chars (F) then
                   Set_Entity (Selector_Name (Actual), A_F);
                   Set_Etype  (Selector_Name (Actual), Etype (A_F));
                   Generate_Reference (A_F, Selector_Name (Actual));
+
                   Found_Assoc := Actual;
-                  Act := Explicit_Generic_Actual_Parameter (Actual);
+                  Act         := Explicit_Generic_Actual_Parameter (Actual);
                   Num_Matched := Num_Matched + 1;
                   exit;
                end if;
Index: sem_ch8.adb
===================================================================
--- sem_ch8.adb	(revision 237429)
+++ sem_ch8.adb	(working copy)
@@ -6224,6 +6224,8 @@ 
       if Is_Overloadable (Id) and then not Is_Overloaded (N) then
          Generate_Reference (Id, N);
       end if;
+
+      Check_Restriction_No_Use_Of_Entity (N);
    end Find_Expanded_Name;
 
    -------------------------