diff --git a/src/error.c b/src/error.c
index 3a9c7f66a1d33bdef8f4a02ef130c8a1877f5af7..3a9153286269c1961a2388164affeae47672010a 100644
--- a/src/error.c
+++ b/src/error.c
@@ -2,7 +2,7 @@
 || This file is part of Pike. For copyright information see COPYRIGHT.
 || Pike is distributed under GPL, LGPL and MPL. See the file COPYING
 || for more information.
-|| $Id: error.c,v 1.169 2010/02/21 22:42:19 srb Exp $
+|| $Id: error.c,v 1.170 2010/09/27 17:06:17 grubba Exp $
 */
 
 #define NO_PIKE_SHORTHAND
@@ -135,7 +135,8 @@ PMOD_EXPORT DECLSPEC(noreturn) void pike_throw(void) ATTRIBUTE((noreturn))
   {
     while(Pike_interpreter.recoveries->onerror)
     {
-      while(Pike_fp != Pike_interpreter.recoveries->onerror->frame_pointer)
+      ONERROR *err = Pike_interpreter.recoveries->onerror;
+      while(Pike_fp != err->frame_pointer)
       {
 #ifdef PIKE_DEBUG
 	if(!Pike_fp)
@@ -144,8 +145,8 @@ PMOD_EXPORT DECLSPEC(noreturn) void pike_throw(void) ATTRIBUTE((noreturn))
 	POP_PIKE_FRAME();
       }
 
-      (*Pike_interpreter.recoveries->onerror->func)(Pike_interpreter.recoveries->onerror->arg);
-      Pike_interpreter.recoveries->onerror=Pike_interpreter.recoveries->onerror->previous;
+      Pike_interpreter.recoveries->onerror = err->previous;
+      (*err->func)(err->arg);
     }
 
     {
@@ -170,7 +171,9 @@ PMOD_EXPORT DECLSPEC(noreturn) void pike_throw(void) ATTRIBUTE((noreturn))
 
   while(Pike_interpreter.recoveries->onerror)
   {
-    while(Pike_fp != Pike_interpreter.recoveries->onerror->frame_pointer)
+    ONERROR *err = Pike_interpreter.recoveries->onerror;
+
+    while(Pike_fp != err->frame_pointer)
     {
 #ifdef PIKE_DEBUG
       if(!Pike_fp)
@@ -178,8 +181,8 @@ PMOD_EXPORT DECLSPEC(noreturn) void pike_throw(void) ATTRIBUTE((noreturn))
 #endif
       POP_PIKE_FRAME();
     }
-    (*Pike_interpreter.recoveries->onerror->func)(Pike_interpreter.recoveries->onerror->arg);
-    Pike_interpreter.recoveries->onerror=Pike_interpreter.recoveries->onerror->previous;
+    Pike_interpreter.recoveries->onerror = err->previous;
+    (*err->func)(err->arg);
   }
 
   while(Pike_fp != Pike_interpreter.recoveries->frame_pointer)
diff --git a/src/pike_error.h b/src/pike_error.h
index 7924b6507250ff6cbbd41c2e5107404b7cd3257b..570981da926717668b8b1908a6015cf41f4b0891 100644
--- a/src/pike_error.h
+++ b/src/pike_error.h
@@ -2,7 +2,7 @@
 || This file is part of Pike. For copyright information see COPYRIGHT.
 || Pike is distributed under GPL, LGPL and MPL. See the file COPYING
 || for more information.
-|| $Id: pike_error.h,v 1.55 2010/02/19 10:15:49 srb Exp $
+|| $Id: pike_error.h,v 1.56 2010/09/27 17:05:57 grubba Exp $
 */
 
 #ifndef PIKE_ERROR_H
@@ -231,8 +231,8 @@ PMOD_EXPORT extern const char msg_assert_onerr[];
 #endif /* PIKE_DEBUG */
 
 #define CALL_AND_UNSET_ONERROR(X) do {		\
-     X.func(X.arg);				\
      UNSET_ONERROR(X);				\
+     X.func(X.arg);				\
   }while(0)
 
 #if defined(PIKE_DEBUG) && 0
diff --git a/src/testsuite.in b/src/testsuite.in
index 2457a8820fc8b0a881ea4b39096a0264a627b8de..ae07a9d3706a339b46c85b48c3075bc63b4375ca 100644
--- a/src/testsuite.in
+++ b/src/testsuite.in
@@ -1,5 +1,5 @@
 START_MARKER
-test_true([["$Id: testsuite.in,v 1.898 2010/07/27 15:33:35 mast Exp $"]]);
+test_true([["$Id: testsuite.in,v 1.899 2010/09/27 17:06:30 grubba Exp $"]]);
 
 // This triggered a bug only if run sufficiently early.
 test_compile_any([[#pike 7.2]])
@@ -3952,6 +3952,13 @@ test_any([[
   return Y(5)->x;
 ]], 7)
 
+test_eval_error([[
+  // Triggered infinite recursion and core dump.
+  // cf LysLysKOM 18719518/Pike mailinglist 12047.
+  object o = class{}();
+  o->foo += "";
+]])
+
 test_compile_error([[
   class X {
     int x;