SF bug [#467145] Python 2.2a4 build problem on HPUX 11.0.
The platform requires 8-byte alignment for doubles, but the GC header
was 12 bytes and that threw off the natural alignment of the double
members of a subtype of complex.  The fix puts the GC header into a
union with a double as the other member, to force no-looser-than
double alignment of GC headers.  On boxes that require 8-byte alignment
for doubles, this may add pad bytes to the GC header accordingly; ditto
for platforms that *prefer* 8-byte alignment for doubles.  On platforms
that don't care, it shouldn't change the memory layout (because the
size of the old GC header is certainly greater than the size of a double
on all platforms, so unioning with a double shouldn't change size or
alignment on such boxes).
diff --git a/Include/objimpl.h b/Include/objimpl.h
index db4cb6d..e8aad54 100644
--- a/Include/objimpl.h
+++ b/Include/objimpl.h
@@ -266,10 +266,13 @@
 #ifdef WITH_CYCLE_GC
 
 /* GC information is stored BEFORE the object structure */
-typedef struct _gc_head {
-	struct _gc_head *gc_next; /* not NULL if object is tracked */
-	struct _gc_head *gc_prev;
-	int gc_refs;
+typedef union _gc_head {
+	struct {
+		union _gc_head *gc_next; /* not NULL if object is tracked */
+		union _gc_head *gc_prev;
+		int gc_refs;
+	} gc;
+	double dummy;  /* force worst-case alignment */
 } PyGC_Head;
 
 extern PyGC_Head _PyGC_generation0;
@@ -278,20 +281,20 @@
  * collector it must be safe to call the ob_traverse method. */
 #define _PyObject_GC_TRACK(o) do { \
 	PyGC_Head *g = (PyGC_Head *)(o)-1; \
-	if (g->gc_next != NULL) \
+	if (g->gc.gc_next != NULL) \
 		Py_FatalError("GC object already in linked list"); \
-	g->gc_next = &_PyGC_generation0; \
-	g->gc_prev = _PyGC_generation0.gc_prev; \
-	g->gc_prev->gc_next = g; \
-	_PyGC_generation0.gc_prev = g; \
+	g->gc.gc_next = &_PyGC_generation0; \
+	g->gc.gc_prev = _PyGC_generation0.gc.gc_prev; \
+	g->gc.gc_prev->gc.gc_next = g; \
+	_PyGC_generation0.gc.gc_prev = g; \
     } while (0);
 
 /* Tell the GC to stop tracking this object. */
 #define _PyObject_GC_UNTRACK(o) do { \
 	PyGC_Head *g = (PyGC_Head *)(o)-1; \
-	g->gc_prev->gc_next = g->gc_next; \
-	g->gc_next->gc_prev = g->gc_prev; \
-	g->gc_next = NULL; \
+	g->gc.gc_prev->gc.gc_next = g->gc.gc_next; \
+	g->gc.gc_next->gc.gc_prev = g->gc.gc_prev; \
+	g->gc.gc_next = NULL; \
     } while (0);
 
 #define PyObject_GC_Track(op) _PyObject_GC_Track((PyObject *)op)
diff --git a/Modules/gcmodule.c b/Modules/gcmodule.c
index 34503e4..db35b3d 100644
--- a/Modules/gcmodule.c
+++ b/Modules/gcmodule.c
@@ -77,39 +77,39 @@
 static void
 gc_list_init(PyGC_Head *list)
 {
-	list->gc_prev = list;
-	list->gc_next = list;
+	list->gc.gc_prev = list;
+	list->gc.gc_next = list;
 }
 
 static void
 gc_list_append(PyGC_Head *node, PyGC_Head *list)
 {
-	node->gc_next = list;
-	node->gc_prev = list->gc_prev;
-	node->gc_prev->gc_next = node;
-	list->gc_prev = node;
+	node->gc.gc_next = list;
+	node->gc.gc_prev = list->gc.gc_prev;
+	node->gc.gc_prev->gc.gc_next = node;
+	list->gc.gc_prev = node;
 }
 
 static void
 gc_list_remove(PyGC_Head *node)
 {
-	node->gc_prev->gc_next = node->gc_next;
-	node->gc_next->gc_prev = node->gc_prev;
-	node->gc_next = NULL; /* object is not currently tracked */
+	node->gc.gc_prev->gc.gc_next = node->gc.gc_next;
+	node->gc.gc_next->gc.gc_prev = node->gc.gc_prev;
+	node->gc.gc_next = NULL; /* object is not currently tracked */
 }
 
 static void 
 gc_list_move(PyGC_Head *from, PyGC_Head *to)
 {
-	if (from->gc_next == from) {
+	if (from->gc.gc_next == from) {
 		/* empty from list */
 		gc_list_init(to);
 	}
 	else {
-		to->gc_next = from->gc_next;
-		to->gc_next->gc_prev = to;
-		to->gc_prev = from->gc_prev;
-		to->gc_prev->gc_next = to;
+		to->gc.gc_next = from->gc.gc_next;
+		to->gc.gc_next->gc.gc_prev = to;
+		to->gc.gc_prev = from->gc.gc_prev;
+		to->gc.gc_prev->gc.gc_next = to;
 	}
 	gc_list_init(from);
 }
@@ -119,12 +119,12 @@
 gc_list_merge(PyGC_Head *from, PyGC_Head *to)
 {
 	PyGC_Head *tail;
-	if (from->gc_next != from) {
-		tail = to->gc_prev;
-		tail->gc_next = from->gc_next;
-		tail->gc_next->gc_prev = tail;
-		to->gc_prev = from->gc_prev;
-		to->gc_prev->gc_next = to;
+	if (from->gc.gc_next != from) {
+		tail = to->gc.gc_prev;
+		tail->gc.gc_next = from->gc.gc_next;
+		tail->gc.gc_next->gc.gc_prev = tail;
+		to->gc.gc_prev = from->gc.gc_prev;
+		to->gc.gc_prev->gc.gc_next = to;
 	}
 	gc_list_init(from);
 }
@@ -134,7 +134,7 @@
 {
 	PyGC_Head *gc;
 	long n = 0;
-	for (gc = list->gc_next; gc != list; gc = gc->gc_next) {
+	for (gc = list->gc.gc_next; gc != list; gc = gc->gc.gc_next) {
 		n++;
 	}
 	return n;
@@ -148,9 +148,9 @@
 static void
 update_refs(PyGC_Head *containers)
 {
-	PyGC_Head *gc = containers->gc_next;
-	for (; gc != containers; gc=gc->gc_next) {
-		gc->gc_refs = FROM_GC(gc)->ob_refcnt;
+	PyGC_Head *gc = containers->gc.gc_next;
+	for (; gc != containers; gc=gc->gc.gc_next) {
+		gc->gc.gc_refs = FROM_GC(gc)->ob_refcnt;
 	}
 }
 
@@ -159,8 +159,8 @@
 {
 	if (op && PyObject_IS_GC(op)) {
 		PyGC_Head *gc = AS_GC(op);
-		if (gc->gc_next != NULL)
-			AS_GC(op)->gc_refs--;
+		if (gc->gc.gc_next != NULL)
+			AS_GC(op)->gc.gc_refs--;
 	}
 	return 0;
 }
@@ -170,8 +170,8 @@
 subtract_refs(PyGC_Head *containers)
 {
 	traverseproc traverse;
-	PyGC_Head *gc = containers->gc_next;
-	for (; gc != containers; gc=gc->gc_next) {
+	PyGC_Head *gc = containers->gc.gc_next;
+	for (; gc != containers; gc=gc->gc.gc_next) {
 		traverse = FROM_GC(gc)->ob_type->tp_traverse;
 		(void) traverse(FROM_GC(gc),
 			       (visitproc)visit_decref,
@@ -184,13 +184,13 @@
 move_roots(PyGC_Head *containers, PyGC_Head *roots)
 {
 	PyGC_Head *next;
-	PyGC_Head *gc = containers->gc_next;
+	PyGC_Head *gc = containers->gc.gc_next;
 	while (gc != containers) {
-		next = gc->gc_next;
-		if (gc->gc_refs > 0) {
+		next = gc->gc.gc_next;
+		if (gc->gc.gc_refs > 0) {
 			gc_list_remove(gc);
 			gc_list_append(gc, roots);
-			gc->gc_refs = GC_MOVED;
+			gc->gc.gc_refs = GC_MOVED;
 		}
 		gc = next;
 	}
@@ -201,10 +201,10 @@
 {
 	if (PyObject_IS_GC(op)) {
 		PyGC_Head *gc = AS_GC(op);
-		if (gc->gc_next != NULL && gc->gc_refs != GC_MOVED) {
+		if (gc->gc.gc_next != NULL && gc->gc.gc_refs != GC_MOVED) {
 			gc_list_remove(gc);
 			gc_list_append(gc, tolist);
-			gc->gc_refs = GC_MOVED;
+			gc->gc.gc_refs = GC_MOVED;
 		}
 	}
 	return 0;
@@ -215,8 +215,8 @@
 move_root_reachable(PyGC_Head *reachable)
 {
 	traverseproc traverse;
-	PyGC_Head *gc = reachable->gc_next;
-	for (; gc != reachable; gc=gc->gc_next) {
+	PyGC_Head *gc = reachable->gc.gc_next;
+	for (; gc != reachable; gc=gc->gc.gc_next) {
 		/* careful, reachable list is growing here */
 		PyObject *op = FROM_GC(gc);
 		traverse = op->ob_type->tp_traverse;
@@ -231,7 +231,7 @@
 move_finalizers(PyGC_Head *unreachable, PyGC_Head *finalizers)
 {
 	PyGC_Head *next;
-	PyGC_Head *gc = unreachable->gc_next;
+	PyGC_Head *gc = unreachable->gc.gc_next;
 	static PyObject *delstr = NULL;
 	if (delstr == NULL) {
 		delstr = PyString_InternFromString("__del__");
@@ -240,7 +240,7 @@
 	}
 	for (; gc != unreachable; gc=next) {
 		PyObject *op = FROM_GC(gc);
-		next = gc->gc_next;
+		next = gc->gc.gc_next;
 		if (PyInstance_Check(op) && PyObject_HasAttr(op, delstr)) {
 			gc_list_remove(gc);
 			gc_list_append(gc, finalizers);
@@ -253,8 +253,8 @@
 move_finalizer_reachable(PyGC_Head *finalizers)
 {
 	traverseproc traverse;
-	PyGC_Head *gc = finalizers->gc_next;
-	for (; gc != finalizers; gc=gc->gc_next) {
+	PyGC_Head *gc = finalizers->gc.gc_next;
+	for (; gc != finalizers; gc=gc->gc.gc_next) {
 		/* careful, finalizers list is growing here */
 		traverse = FROM_GC(gc)->ob_type->tp_traverse;
 		(void) traverse(FROM_GC(gc), 
@@ -297,8 +297,8 @@
 	if (garbage == NULL) {
 		garbage = PyList_New(0);
 	}
-	for (gc = finalizers->gc_next; gc != finalizers;
-			gc = finalizers->gc_next) {
+	for (gc = finalizers->gc.gc_next; gc != finalizers;
+			gc = finalizers->gc.gc_next) {
 		PyObject *op = FROM_GC(gc);
 		if ((debug & DEBUG_SAVEALL) || PyInstance_Check(op)) {
 			/* If SAVEALL is not set then just append
@@ -321,8 +321,8 @@
 {
 	inquiry clear;
 
-	while (unreachable->gc_next != unreachable) {
-		PyGC_Head *gc = unreachable->gc_next;
+	while (unreachable->gc.gc_next != unreachable) {
+		PyGC_Head *gc = unreachable->gc.gc_next;
 		PyObject *op = FROM_GC(gc);
 		if (debug & DEBUG_SAVEALL) {
 			PyList_Append(garbage, op);
@@ -334,7 +334,7 @@
 				Py_DECREF(op);
 			}
 		}
-		if (unreachable->gc_next == gc) {
+		if (unreachable->gc.gc_next == gc) {
 			/* object is still alive, move it, it may die later */
 			gc_list_remove(gc);
 			gc_list_append(gc, old);
@@ -396,8 +396,8 @@
 
 	/* Collect statistics on collectable objects found and print
 	 * debugging information. */
-	for (gc = unreachable.gc_next; gc != &unreachable;
-			gc = gc->gc_next) {
+	for (gc = unreachable.gc.gc_next; gc != &unreachable;
+			gc = gc->gc.gc_next) {
 		m++;
 		if (debug & DEBUG_COLLECTABLE) {
 			debug_cycle("collectable", FROM_GC(gc));
@@ -410,8 +410,8 @@
 
 	/* Collect statistics on uncollectable objects found and print
 	 * debugging information. */
-	for (gc = finalizers.gc_next; gc != &finalizers;
-			gc = gc->gc_next) {
+	for (gc = finalizers.gc.gc_next; gc != &finalizers;
+			gc = gc->gc.gc_next) {
 		n++;
 		if (debug & DEBUG_UNCOLLECTABLE) {
 			debug_cycle("uncollectable", FROM_GC(gc));
@@ -456,7 +456,7 @@
 		generation = 2;
 		gc_list_merge(&_PyGC_generation0, &generation2);
 		gc_list_merge(&generation1, &generation2);
-		if (generation2.gc_next != &generation2) {
+		if (generation2.gc.gc_next != &generation2) {
 			n = collect(&generation2, &generation2);
 		}
 		collections1 = 0;
@@ -465,7 +465,7 @@
 		generation = 1;
 		collections1++;
 		gc_list_merge(&_PyGC_generation0, &generation1);
-		if (generation1.gc_next != &generation1) {
+		if (generation1.gc.gc_next != &generation1) {
 			n = collect(&generation1, &generation2);
 		}
 		collections0 = 0;
@@ -473,7 +473,7 @@
 	else {
 		generation = 0;
 		collections0++;
-		if (_PyGC_generation0.gc_next != &_PyGC_generation0) {
+		if (_PyGC_generation0.gc.gc_next != &_PyGC_generation0) {
 			n = collect(&_PyGC_generation0, &generation1);
 		}
 	}
@@ -646,7 +646,7 @@
 	PyGC_Head *gc;
 	PyObject *obj;
 	traverseproc traverse;
-	for (gc = list->gc_next; gc != list; gc = gc->gc_next) {
+	for (gc = list->gc.gc_next; gc != list; gc = gc->gc.gc_next) {
 		obj = FROM_GC(gc);
 		traverse = obj->ob_type->tp_traverse;
 		if (obj == objs || obj == resultlist)
@@ -688,7 +688,7 @@
 append_objects(PyObject *py_list, PyGC_Head *gc_list)
 {
 	PyGC_Head *gc;
-	for (gc = gc_list->gc_next; gc != gc_list; gc = gc->gc_next) {
+	for (gc = gc_list->gc.gc_next; gc != gc_list; gc = gc->gc.gc_next) {
 		PyObject *op = FROM_GC(gc);
 		if (op != py_list) {
 			Py_INCREF(op);
@@ -807,7 +807,7 @@
 	PyGC_Head *g = PyObject_MALLOC(nbytes);
 	if (g == NULL)
 		return (PyObject *)PyErr_NoMemory();
-	g->gc_next = NULL;
+	g->gc.gc_next = NULL;
 	allocated++;
  	if (allocated > threshold0 &&
  	    enabled &&
@@ -866,7 +866,7 @@
 {
 #ifdef WITH_CYCLE_GC
 	PyGC_Head *g = AS_GC(op);
-	if (g->gc_next != NULL)
+	if (g->gc.gc_next != NULL)
 		gc_list_remove(g);
 	if (allocated > 0) {
 		allocated--;