This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
Implement the loop in tryAMAGICunDEREF_var() using while, rather than goto.
authorNicholas Clark <nick@ccl4.org>
Tue, 2 Nov 2010 16:40:39 +0000 (16:40 +0000)
committerNicholas Clark <nick@ccl4.org>
Tue, 2 Nov 2010 16:40:39 +0000 (16:40 +0000)
Yes, it was a while loop implemented using goto, although this only became
clear by untangling the macros. I believe it need never have been implemented
as goto, given that the other user of tryAMAGICunW_var "broke" out of the
"if"'s block using a return, hence that "if" could have been a "while" all
along.

pp.h

diff --git a/pp.h b/pp.h
index 8c7967c..56337fc 100644 (file)
--- a/pp.h
+++ b/pp.h
@@ -453,18 +453,18 @@ Does not use C<TARG>.  See also C<XPUSHu>, C<mPUSHu> and C<PUSHu>.
     STMT_START {                                                       \
        SV *tmpsv;                                                      \
        SV *arg = *sp;                                                  \
-    am_again:                                                          \
-       if (SvAMAGIC(arg) &&                                            \
-           (tmpsv = amagic_call(arg, &PL_sv_undef, meth_enum,          \
-                                AMGf_noright | AMGf_unary))) {         \
+       while (SvAMAGIC(arg) &&                                         \
+              (tmpsv = amagic_call(arg, &PL_sv_undef, meth_enum,       \
+                                   AMGf_noright | AMGf_unary))) {      \
            SPAGAIN;                                                    \
            sv = tmpsv;                                                 \
            if (!SvROK(tmpsv))                                          \
                Perl_croak(aTHX_ "Overloaded dereference did not return a reference"); \
-           if (tmpsv != arg && SvRV(tmpsv) != SvRV(arg)) {             \
-               arg = tmpsv;                                            \
-               goto am_again;                                          \
+           if (tmpsv == arg || SvRV(tmpsv) == SvRV(arg)) {             \
+               /* Bail out if it returns us the same reference.  */    \
+               break;                                                  \
            }                                                           \
+           arg = tmpsv;                                                \
        }                                                               \
     } STMT_END