Patchwork [Ada] Subprograms should not be treated as Pure if limited arguments

login
register
mail settings
Submitter Arnaud Charlet
Date Sept. 10, 2010, 9:31 a.m.
Message ID <20100910093114.GA3302@adacore.com>
Download mbox | patch
Permalink /patch/64359/
State New
Headers show

Comments

Arnaud Charlet - Sept. 10, 2010, 9:31 a.m.
This patch corrects the oversight of not implementing the restriction
in the RM that calls to Pure subprograms cannot be eliminated if one
or more of the arguments is limited. The fix is to reset the Is_Pure
flag on affected subprogram entities.

The following test program:

package PureLimited is
   pragma Pure;
   type r is limited null record;
   function f1 (x : integer) return integer;
   function f2 (x : r) return integer;
end;

package body PureLimited is
   function f1 (x : integer) return integer
   is
   begin
      return 1;
   end;

   function f2 (x : r) return integer
   is
   begin
      return 1;
   end;
end;

compiled with -gnatdt >log generates a log file which when
processed with grep Is_Pure log outputs:

    |    Is_Pure = True

Prior to the patch, two lines were output

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

2010-09-10  Robert Dewar  <dewar@adacore.com>

	* exp_ch6.adb (Expand_N_Subprogram_Body): Reset Is_Pure if limited
	arguments.

Patch

Index: exp_ch6.adb
===================================================================
--- exp_ch6.adb	(revision 164092)
+++ exp_ch6.adb	(working copy)
@@ -4096,6 +4096,7 @@  package body Exp_Ch6 is
    --  Initialize scalar out parameters if Initialize/Normalize_Scalars
 
    --  Reset Pure indication if any parameter has root type System.Address
+   --  or has any parameters of limited types.
 
    --  Wrap thread body
 
@@ -4287,7 +4288,9 @@  package body Exp_Ch6 is
          begin
             F := First_Formal (Spec_Id);
             while Present (F) loop
-               if Is_Descendent_Of_Address (Etype (F)) then
+               if Is_Descendent_Of_Address (Etype (F))
+                 or else Is_Limited_Type (Etype (F))
+               then
                   Set_Is_Pure (Spec_Id, False);
 
                   if Spec_Id /= Body_Id then