[Ada] No_Implicit_Loops restriction and pragma Assert

Message ID 20210503092945.GA77465@adacore.com
State New
Headers show
Series
  • [Ada] No_Implicit_Loops restriction and pragma Assert
Related show

Commit Message

Pierre-Marie de Rodat May 3, 2021, 9:29 a.m.
When using e.g. pragma Assert (X'Initialized) combined with pragma
Restrictions (No_Implicit_Loops), a violation is flagged when assertions
are disabled, which is undesirable. Fixed by recognizing simple forms of
dead paths used by pragma Assert when assertions are disabled.

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

gcc/ada/

	* tbuild.adb (Make_Implicit_Loop_Statement): Disable restriction
	checking on dead paths.

Patch

diff --git a/gcc/ada/tbuild.adb b/gcc/ada/tbuild.adb
--- a/gcc/ada/tbuild.adb
+++ b/gcc/ada/tbuild.adb
@@ -35,6 +35,7 @@  with Opt;      use Opt;
 with Restrict; use Restrict;
 with Rident;   use Rident;
 with Sem_Aux;  use Sem_Aux;
+with Sem_Util; use Sem_Util;
 with Snames;   use Snames;
 with Stand;    use Stand;
 with Stringt;  use Stringt;
@@ -348,14 +349,42 @@  package body Tbuild is
       Has_Created_Identifier : Boolean := False;
       End_Label              : Node_Id := Empty) return Node_Id
    is
-   begin
-      Check_Restriction (No_Implicit_Loops, Node);
+      P                  : Node_Id;
+      Check_Restrictions : Boolean := True;
+   begin
+      --  Do not check restrictions if the implicit loop statement is part
+      --  of a dead branch: False and then ...
+      --  This will occur in particular as part of the expansion of pragma
+      --  Assert when assertions are disabled.
+
+      P := Parent (Node);
+      while Present (P) loop
+         if Nkind (P) = N_And_Then then
+            if Nkind (Left_Opnd (P)) = N_Identifier
+              and then Entity (Left_Opnd (P)) = Standard_False
+            then
+               Check_Restrictions := False;
+               exit;
+            end if;
 
-      if Present (Iteration_Scheme)
-        and then Nkind (Iteration_Scheme) /= N_Iterator_Specification
-        and then Present (Condition (Iteration_Scheme))
-      then
-         Check_Restriction (No_Implicit_Conditionals, Node);
+         --  Prevent the search from going too far
+
+         elsif Is_Body_Or_Package_Declaration (P) then
+            exit;
+         end if;
+
+         P := Parent (P);
+      end loop;
+
+      if Check_Restrictions then
+         Check_Restriction (No_Implicit_Loops, Node);
+
+         if Present (Iteration_Scheme)
+           and then Nkind (Iteration_Scheme) /= N_Iterator_Specification
+           and then Present (Condition (Iteration_Scheme))
+         then
+            Check_Restriction (No_Implicit_Conditionals, Node);
+         end if;
       end if;
 
       return Make_Loop_Statement (Sloc (Node),