i386 code generation bug (-O2 and greater)

Martin v. Loewis martin@mira.isdn.cs.tu-berlin.de
Thu Sep 30 19:57:00 GMT 1999


> 13686:     if (mxDateTime_FreeList) {
> 13687:         datetime = mxDateTime_FreeList;
> 13688:         mxDateTime_FreeList = *(mxDateTimeObject**)mxDateTime_FreeList;
> 13689:         datetime->ob_type = &mxDateTime_Type;
> 13690:         (( datetime )->ob_refcnt = 1) ;
> 13691:     }

Chad,

Thanks for your bug report. I could not quite reproduce it; with -O6,
the compiler inlines mxDateTime_New, and with -g, you get debugging
information in-between the statements; it was not clear from your
report in what ways you've edited the assembly in your example.

It seems to me that this function is not valid C: The object
pointed-to by mxDateTime_FreeList is both accessed as
mxDateTimeObject, and as mxDateTimeObject*. In ISO C, an object must
not be accessed as two different types.

gcc 2.95 makes use of this restriction to re-order memory accesses
which cannot alias because of type issues.

Please let me know whether this fixes your problem. The feature is
currently under heavy discussion. GCC offers a C extension for such
cases: you need to declare the different types which you want to alias
as members of a union. In your case, that would be a union of
mxDateTimeObject* and mxDateTimeObject, which is probably not very
convenient.

More realistically, you could do the chaining of free objects via a
union in another field, like

  union{
    PyObject *argument;
    mxDateTimeObject *chain;
  } c_or_a;

Then, inside _New/_Free, you'd find the chain in c_or_a.chain. While
the object is alive, you'd only use c_or_a.argument. I believe that
would be conforming and portable C (i.e. you are never accessing the
union under anything but the current variant).

Hope this helps,
Martin



More information about the Gcc-bugs mailing list