[Ada] Inhibit exception push/pop when not needed

Arnaud Charlet charlet@adacore.com
Fri Nov 4 14:31:00 GMT 2011


This patch inhibits the generation of exception push/pop nodes if
restriction No_Exception_Handlers is active (when they are always
useless), or in CodePeer mode (where they are never needed and can
intefere with the analysis).

The following program

     1. pragma Restrictions (No_Exception_Propagation);
     2. pragma Restrictions (No_Exception_Handlers);
     3. function NoPush (X : Integer) return Integer is
     4. begin
     5.    return 10 / X;
     6. end;

should generate the following -gnatG output:

Source recreated from tree for Nopush (body)

pragma restrictions (no_exception_propagation);
pragma restrictions (no_exception_handlers);

function nopush (x : integer) return integer is
begin
   [constraint_error when
     x = 0
     "divide by zero"]
   return integer(10 / x);
end nopush;

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

2011-11-04  Robert Dewar  <dewar@adacore.com>

	* exp_ch11.adb (Generate_Push_Pop): Inhibit push/pop nodes in
	CodePeer mode or if restriction No_Exception_Handlers is present.
	* exp_ch6.adb (Expand_N_Subprogram_Body): (Inhibit push/pop
	nodes in CodePeer mode or if restriction No_Exception_Handlers
	is present.

-------------- next part --------------
Index: exp_ch11.adb
===================================================================
--- exp_ch11.adb	(revision 180934)
+++ exp_ch11.adb	(working copy)
@@ -334,7 +334,7 @@
       --  raise statements into gotos, e.g. all N_Raise_xxx_Error nodes are
       --  left unchanged and passed to the back end.
 
-      --  Instead, the front end generates two nodes
+      --  Instead, the front end generates three nodes
 
       --     N_Push_Constraint_Error_Label
       --     N_Push_Program_Error_Label
@@ -356,6 +356,10 @@
       --  field in the Push node will be empty signifying that for this region
       --  of code, no optimization is possible.
 
+      --  These Push/Pop nodes are inhibited if No_Exception_Handlers is set
+      --  since they are useless in this case, and in CodePeer mode, where
+      --  they serve no purpose and can intefere with the analysis.
+
       --  The back end must maintain three stacks, one for each exception case,
       --  the Push node pushes an entry onto the corresponding stack, and Pop
       --  node pops off the entry. Then instead of calling Rcheck_nn, if the
@@ -503,6 +507,12 @@
 
          procedure Generate_Push_Pop (H : Node_Id) is
          begin
+            if Restriction_Active (No_Exception_Handlers)
+              or else CodePeer_Mode
+            then
+               return;
+            end if;
+
             if Exc_Locally_Handled then
                return;
             else
Index: exp_ch6.adb
===================================================================
--- exp_ch6.adb	(revision 180934)
+++ exp_ch6.adb	(working copy)
@@ -5679,10 +5679,14 @@
       end if;
 
       --  If local-exception-to-goto optimization active, insert dummy push
-      --  statements at start, and dummy pop statements at end.
+      --  statements at start, and dummy pop statements at end, but inhibit
+      --  this if we have No_Exception_Handlers, since they are useless and
+      --  intefere with analysis, e.g. by codepeer.
 
       if (Debug_Flag_Dot_G
            or else Restriction_Active (No_Exception_Propagation))
+        and then not Restriction_Active (No_Exception_Handlers)
+        and then not CodePeer_Mode
         and then Is_Non_Empty_List (L)
       then
          declare


More information about the Gcc-patches mailing list