This is the mail archive of the gcc-bugs@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]

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


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