Fix crasher for when an object's __del__ creates a new weakref to itself.
Patch only fixes new-style classes; classic classes still buggy.

Closes bug #1377858.  Already backported.
diff --git a/Lib/test/crashers/weakref_in_del.py b/Lib/test/crashers/weakref_in_del.py
index 3bbcfc3..2e9b186 100644
--- a/Lib/test/crashers/weakref_in_del.py
+++ b/Lib/test/crashers/weakref_in_del.py
@@ -1,11 +1,12 @@
 import weakref
 
 # http://python.org/sf/1377858
+# Fixed for new-style classes in 2.5c1.
 
 ref = None
 
 def test_weakref_in_del():
-    class Target(object):
+    class Target():
         def __del__(self):
             global ref
             ref = weakref.ref(self)
diff --git a/Lib/test/test_weakref.py b/Lib/test/test_weakref.py
index d2e4d34..6ca283c 100644
--- a/Lib/test/test_weakref.py
+++ b/Lib/test/test_weakref.py
@@ -6,6 +6,8 @@
 
 from test import test_support
 
+# Used in ReferencesTestCase.test_ref_created_during_del() .
+ref_from_del = None
 
 class C:
     def method(self):
@@ -630,6 +632,18 @@
         finally:
             gc.set_threshold(*thresholds)
 
+    def test_ref_created_during_del(self):
+        # Bug #1377858
+        # A weakref created in an object's __del__() would crash the
+        # interpreter when the weakref was cleaned up since it would refer to
+        # non-existent memory.  This test should not segfault the interpreter.
+        class Target(object):
+            def __del__(self):
+                global ref_from_del
+                ref_from_del = weakref.ref(self)
+
+        w = Target()
+
 
 class SubclassableWeakrefTestCase(unittest.TestCase):
 
diff --git a/Misc/NEWS b/Misc/NEWS
index 65b0672..ad72b08 100644
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -12,6 +12,10 @@
 Core and builtins
 -----------------
 
+- Bug #1377858: Fix the segfaulting of the interpreter when an object created
+  a weakref on itself during a __del__ call for new-style classes (classic
+  classes still have the bug).
+
 - Bug #1579370: Make PyTraceBack_Here use the current thread, not the
   frame's thread state.
 
diff --git a/Objects/typeobject.c b/Objects/typeobject.c
index 0cf830a..6ea489a 100644
--- a/Objects/typeobject.c
+++ b/Objects/typeobject.c
@@ -666,6 +666,17 @@
 			goto endlabel;	/* resurrected */
 		else
 			_PyObject_GC_UNTRACK(self);
+		/* New weakrefs could be created during the finalizer call.
+		    If this occurs, clear them out without calling their
+		    finalizers since they might rely on part of the object
+		    being finalized that has already been destroyed. */
+		if (type->tp_weaklistoffset && !base->tp_weaklistoffset) {
+			/* Modeled after GET_WEAKREFS_LISTPTR() */
+			PyWeakReference **list = (PyWeakReference **) \
+				PyObject_GET_WEAKREFS_LISTPTR(self);
+			while (*list)
+				_PyWeakref_ClearRef(*list);
+		}
 	}
 
 	/*  Clear slots up to the nearest base with a different tp_dealloc */
diff --git a/Objects/weakrefobject.c b/Objects/weakrefobject.c
index 826f571..a404f29 100644
--- a/Objects/weakrefobject.c
+++ b/Objects/weakrefobject.c
@@ -57,6 +57,9 @@
             PyWeakref_GET_OBJECT(self));
 
         if (*list == self)
+	    /* If 'self' is the end of the list (and thus self->wr_next == NULL)
+	       then the weakref list itself (and thus the value of *list) will
+	       end up being set to NULL. */
             *list = self->wr_next;
         self->wr_object = Py_None;
         if (self->wr_prev != NULL)