This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Fix obscure bug with const/non-const in integrate.c
- From: kenner at vlsi1 dot ultra dot nyu dot edu (Richard Kenner)
- To: gcc-patches at gcc dot gnu dot org
- Date: Fri, 18 Apr 03 18:18:26 EDT
- Subject: 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)