Revert "Re: [perl #51636] segmentation fault with array ties"
David Mitchell [Fri, 4 Jun 2010 20:01:43 +0000 (21:01 +0100)]
This reverts commit 90630e3c741716305d7f1da4df5eab5c1bee42cc.

This fix turns out to be wrong, and also made ($<,$>)=(...) fail
(RT #75212).

The original problem was a SEGV in av_clear(). This was mis-diagnosed
as recursive PL_delaymagic issue, and the fix was to temprarily reset
PL_delaymagic to zero. This stopped the mg_set() of $> and $> being
delayed.

The real problem was that mg_free wasn't clearing the [GSR]MG flags
after freeing xmg_magic. This was independently fixed by commit
68f8932eb570af656553ed44c11a23f0a216a3ec.

pp_hot.c

index a8c06b8..0607b76 100644 (file)
--- a/pp_hot.c
+++ b/pp_hot.c
@@ -1041,14 +1041,8 @@ PP(pp_aassign)
                *(relem++) = sv;
                didstore = av_store(ary,i++,sv);
                if (magic) {
-                   if (SvSMAGICAL(sv)) {
-                       /* More magic can happen in the mg_set callback, so we
-                        * backup the delaymagic for now. */
-                       U16 dmbak = PL_delaymagic;
-                       PL_delaymagic = 0;
+                   if (SvSMAGICAL(sv))
                        mg_set(sv);
-                       PL_delaymagic = dmbak;
-                   }
                    if (!didstore)
                        sv_2mortal(sv);
                }
@@ -1078,12 +1072,8 @@ PP(pp_aassign)
                        duplicates += 2;
                    didstore = hv_store_ent(hash,sv,tmpstr,0);
                    if (magic) {
-                       if (SvSMAGICAL(tmpstr)) {
-                           U16 dmbak = PL_delaymagic;
-                           PL_delaymagic = 0;
+                       if (SvSMAGICAL(tmpstr))
                            mg_set(tmpstr);
-                           PL_delaymagic = dmbak;
-                       }
                        if (!didstore)
                            sv_2mortal(tmpstr);
                    }
@@ -1107,13 +1097,7 @@ PP(pp_aassign)
            }
            else
                sv_setsv(sv, &PL_sv_undef);
-
-           if (SvSMAGICAL(sv)) {
-               U16 dmbak = PL_delaymagic;
-               PL_delaymagic = 0;
-               mg_set(sv);
-               PL_delaymagic = dmbak;
-           }
+           SvSETMAGIC(sv);
            break;
        }
     }