This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
Re: Bug in C++ tree inlining or in PPC backend?
Am Sun, 02 Jan 2000 schrieb Mark Mitchell:
>>>>>> "Franz" == Franz Sirl <Franz.Sirl-kernel@lauterbach.com> writes:
>
> Franz> Hmm, let me ask differently, do you see any possibility
> Franz> that the C++ tree inlining code causes this directly? Like
> Franz> not setting some memory attributes correctly? Or do you
>
>Anything is possible, and I have certainly been known to write buggy
>code. :-(
Well, considering the size and number of your changes, I consider your work
extremely reliable on average.
>However, there is no manipulation of alias sets by the inlining code
>-- it just copies declarations from the inlined function into the
>target function. It's possible (although I'm not sure how) that the
>inlining code is using some variable after that variable has gone out
>of scope, i.e., generating code after inlining that looks kind-of like
>this:
>
> {
> int i;
> i = 3;
> }
> f (i);
>
>This isn't legal C of course, but it can be represented in with trees.
>If the inliner is creating something like this, then the stack slot
>machinery could kill the slot for `i' before it is used. If the
>inlining code is to blame, that would be the most likely cause that I
>can think of.
I think I have tracked it down and have done a provisional patch.
What happens:
- compiler allocates a stack slot via function.c/assign_stack_temp_for_type()
called by this code around lin 8015 in expr.c:
target = assign_temp (type, 2, 0, 1);
/* All temp slots at this level must not conflict. */
preserve_temp_slots (target);
DECL_RTL (slot) = target;
if (TREE_ADDRESSABLE (slot))
{
TREE_ADDRESSABLE (slot) = 0;
mark_addressable (slot);mark_temp_addr_taken
}
- lateron this slot is marked as addr_taken via
function.c/mark_temp_addr_taken() called by this code around line 8229 in
expr.c:
else if (GET_CODE (op0) == MEM)
{
mark_temp_addr_taken (op0);
temp = XEXP (op0, 0);
}
- despite the set addr_taken flag for the slot,
function.c/free_temps_for_rtl_expr() frees it for reuse. It is called by this
code around line 6305 in expr.c:
case RTL_EXPR:
if (RTL_EXPR_SEQUENCE (exp))
{
if (RTL_EXPR_SEQUENCE (exp) == const0_rtx)
abort ();
emit_insns (RTL_EXPR_SEQUENCE (exp));
RTL_EXPR_SEQUENCE (exp) = const0_rtx;
}
preserve_rtl_expr_result (RTL_EXPR_RTL (exp));
free_temps_for_rtl_expr (exp);
return RTL_EXPR_RTL (exp);
The preceding preserve_rtl_expr_result(RTL_EXPR_RTL (exp)) call preserves a
different stack slot.
I fixed my testcase with this patch (no bootstrap yet):
Index: function.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/function.c,v
retrieving revision 1.146
diff -u -p -r1.146 function.c
--- function.c 2000/01/01 00:07:54 1.146
+++ function.c 2000/01/03 19:05:15
@@ -1040,7 +1040,11 @@ mark_temp_addr_taken (x)
p = find_temp_slot_from_address (XEXP (x, 0));
if (p != 0)
- p->addr_taken = 1;
+ {
+ p->addr_taken = 1;
+ if (p->rtl_expr)
+ preserve_rtl_expr_result (x);
+ }
}
/* If X could be a reference to a temporary slot, mark that slot as
But I'm not sure if this is the best and correct solution, cause even I saw
several different possibilities to fix the bug.
Appended the testcase I used in the end and the corresponding .ii file. Maybe
you can synthesize a testcase out of it, my C++ knowledge is certainly too bad
for that. It fails on powerpc-linux-gnu if compiled with -O[12]
-fno-strict-aliasing.
Franz.
#include <string>
string X = "Hello";
string Y = "world";
const char* s = ",";
void cattest()
{
string z;
z = X + s + ' ' + "..";
if (z.length() != 9) abort();
}
int main()
{
cattest();
return 0;
}
tstring.ii.bz2