This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Fix obscure bug with const/non-const in integrate.c


expand_inline_function converts each actual to the corresponding formal type.
 
When the latter is readonly and the former is not, we end up with a rtx for
the actual mistakenly flagged unchanging in the caller, which may cause
various sorts of trouble.
 
In the testcase at hand, a couple of load insns are wrongly moved out of a
loop, resulting in the disappearance of the loop condition variables updates,
in turn leading to an unexpected hang.
 
The patch below fixes that by retroactivly removing the /u flag.

The following test case shows the problem on HP PA.

Tested on i686-pc-linux-gnu.

procedure P is

   type Time_T is record
      Val : Integer;
   end record;

   function "<" (Left, Right : Time_T) return Boolean is
      pragma Inline ("<");
   begin
      return Left.Val < Right.Val;
   end "<";

  type Iterator_T is limited record
     Start : Time_T;
     Stop  : Time_T;
  end record;

  procedure Step (Iterator : in out Iterator_T) is
  begin
     Iterator.Start.Val := Iterator.Start.Val + 1;
  end Step;

  Iterator : Iterator_T;

begin
   Iterator.Start.Val := 1;
   Iterator.Stop.Val  := 3;

   while Iterator.Start < Iterator.Stop loop
      Step (Iterator);
   end loop;
end;

Thu Aug 22  18:58:25 2002  Olivier Hainque <hainque at act-europe dot fr>

        * integrate.c (expand_inline_function): Ensure non-const actuals
        don't end up const in the caller's flow after conversion to possibly
        const formal type.

*** gcc/integrate.c	14 Apr 2003 21:33:05 -0000	1.216
--- gcc/integrate.c	15 Apr 2003 18:16:11 -0000
*************** expand_inline_function (fndecl, parms, t
*** 811,814 ****
--- 811,822 ----
  	arg_vals[i] = 0;
  
+       /* If the formal type was const but the actual was not, we might
+ 	 end up here with an rtx wrongly tagged unchanging in the caller's
+ 	 context.  Fix that.  */
+       if (arg_vals[i] != 0 
+ 	  && (GET_CODE (arg_vals[i]) == REG || GET_CODE (arg_vals[i]) == MEM)
+ 	  && ! TREE_READONLY (TREE_VALUE (actual)))
+ 	RTX_UNCHANGING_P (arg_vals[i]) = 0;      
+ 
        if (arg_vals[i] != 0
  	  && (! TREE_READONLY (formal)


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]