https://gcc.gnu.org/bugzilla/show_bug.cgi?id=85260

Jakub Jelinek <jakub at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |dmalcolm at gcc dot gnu.org,
                   |                            |rsandifo at gcc dot gnu.org

--- Comment #2 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
Actually, it seems to be a python bug to me.
Reduced testcase:

typedef struct S {
  long ob_refcnt;
  void *ob_type;
  void *in_class;
  void *in_dict;
  void *in_weakreflist;
} PyClassObject;
PyClassObject *foo (void);
typedef union U {
  struct {
    union U *gc_next;
    union U *gc_prev;
    long gc_refs;
  } gc;
  long double dummy;
} PyGC_Head;

void *
bar (void *klass, void *dict)
{
  PyClassObject *inst = foo ();
  inst->in_class = klass;
  inst->in_dict = dict;
  PyGC_Head *g = (PyGC_Head *)inst - 1;
  g->gc.gc_prev->gc.gc_next = g;
  return inst;
}

While PyClassObject seems to have 8-byte alignment, the code assumes there is a
PYGC_Head object in front of it, and that because of the long double member has
16-byte alignment.  So, I believe if the function (_PyObject_GC_New in the
original testcase) returns something that is not 16-byte aligned, which is what
happens when it segfaults, then it is an application bug - UB because
g->gc.gc_prev is then access to misaligned *g.  Richard's changes derive
alignment information from that access and assume that inst must be also
16-byte aligned.

Reply via email to