In perl.git, the branch blead has been updated

<http://perl5.git.perl.org/perl.git/commitdiff/3969ff3f8e4bff4c0c8d6577220d61d3962a9f56?hp=10380cb3585f27510276b532ec6e5450d1b16391>

- Log -----------------------------------------------------------------
commit 3969ff3f8e4bff4c0c8d6577220d61d3962a9f56
Author: Tony Cook <t...@develop-help.com>
Date:   Mon Jul 14 10:40:47 2014 +1000

    [perl #122107] ensure that BEGIN blocks with errors don't remain named subs

M       embed.fnc
M       embed.h
M       op.c
M       proto.h
M       t/op/sub.t

commit 2806bfd899e5e4e1c29077c080a6a9ebc3512295
Author: Tony Cook <t...@develop-help.com>
Date:   Thu Jul 10 11:37:39 2014 +1000

    [perl #122107] test that BEGIN blocks with errors don't remain named subs

M       t/op/sub.t
-----------------------------------------------------------------------

Summary of changes:
 embed.fnc  |  2 ++
 embed.h    |  1 +
 op.c       | 30 +++++++++++++++++++++++++++---
 proto.h    |  7 +++++++
 t/op/sub.t |  9 ++++++++-
 5 files changed, 45 insertions(+), 4 deletions(-)

diff --git a/embed.fnc b/embed.fnc
index 90c56ed..b70404d 100644
--- a/embed.fnc
+++ b/embed.fnc
@@ -1934,6 +1934,8 @@ s |OP*    |ref_array_or_hash|NULLOK OP* cond
 s      |void   |process_special_blocks |I32 floor \
                                        |NN const char *const fullname\
                                        |NN GV *const gv|NN CV *const cv
+s      |void   |clear_special_blocks   |NN const char *const fullname\
+                                       |NN GV *const gv|NN CV *const cv
 #endif
 Xpa    |void*  |Slab_Alloc     |size_t sz
 Xp     |void   |Slab_Free      |NN void *op
diff --git a/embed.h b/embed.h
index 7ca719d..3962901 100644
--- a/embed.h
+++ b/embed.h
@@ -1485,6 +1485,7 @@
 #define apply_attrs_my(a,b,c,d)        S_apply_attrs_my(aTHX_ a,b,c,d)
 #define bad_type_gv(a,b,c,d,e) S_bad_type_gv(aTHX_ a,b,c,d,e)
 #define bad_type_pv(a,b,c,d,e) S_bad_type_pv(aTHX_ a,b,c,d,e)
+#define clear_special_blocks(a,b,c)    S_clear_special_blocks(aTHX_ a,b,c)
 #define cop_free(a)            S_cop_free(aTHX_ a)
 #define dup_attrlist(a)                S_dup_attrlist(aTHX_ a)
 #define finalize_op(a)         S_finalize_op(aTHX_ a)
diff --git a/op.c b/op.c
index 7bdfbce..d2bd2e0 100644
--- a/op.c
+++ b/op.c
@@ -7669,7 +7669,6 @@ Perl_newATTRSUB_x(pTHX_ I32 floor, OP *o, OP *proto, OP 
*attrs,
        gv = gv_fetchpvs("__ANON__::__ANON__", gv_fetch_flags, SVt_PVCV);
        has_name = FALSE;
     }
-
     if (!ec)
         move_proto_attr(&proto, &attrs, gv);
 
@@ -7929,8 +7928,12 @@ Perl_newATTRSUB_x(pTHX_ I32 floor, OP *o, OP *proto, OP 
*attrs,
            }
        }
 
-       if (name && ! (PL_parser && PL_parser->error_count))
-           process_special_blocks(floor, name, gv, cv);
+        if (name) {
+            if (PL_parser && PL_parser->error_count)
+                clear_special_blocks(name, gv, cv);
+            else
+                process_special_blocks(floor, name, gv, cv);
+        }
     }
 
   done:
@@ -7945,6 +7948,27 @@ Perl_newATTRSUB_x(pTHX_ I32 floor, OP *o, OP *proto, OP 
*attrs,
 }
 
 STATIC void
+S_clear_special_blocks(pTHX_ const char *const fullname,
+                       GV *const gv, CV *const cv) {
+    const char *colon;
+    const char *name;
+
+    PERL_ARGS_ASSERT_CLEAR_SPECIAL_BLOCKS;
+
+    colon = strrchr(fullname,':');
+    name = colon ? colon + 1 : fullname;
+
+    if ((*name == 'B' && strEQ(name, "BEGIN"))
+        || (*name == 'E' && strEQ(name, "END"))
+        || (*name == 'U' && strEQ(name, "UNITCHECK"))
+        || (*name == 'C' && strEQ(name, "CHECK"))
+        || (*name == 'I' && strEQ(name, "INIT"))) {
+        GvCV_set(gv, NULL);
+        SvREFCNT_dec_NN(MUTABLE_SV(cv));
+    }
+}
+
+STATIC void
 S_process_special_blocks(pTHX_ I32 floor, const char *const fullname,
                         GV *const gv,
                         CV *const cv)
diff --git a/proto.h b/proto.h
index 6abd867..1e42903 100644
--- a/proto.h
+++ b/proto.h
@@ -6113,6 +6113,13 @@ STATIC void      S_bad_type_pv(pTHX_ I32 n, const char 
*t, const char *name, U32 flag
 #define PERL_ARGS_ASSERT_BAD_TYPE_PV   \
        assert(t); assert(name); assert(kid)
 
+STATIC void    S_clear_special_blocks(pTHX_ const char *const fullname, GV 
*const gv, CV *const cv)
+                       __attribute__nonnull__(pTHX_1)
+                       __attribute__nonnull__(pTHX_2)
+                       __attribute__nonnull__(pTHX_3);
+#define PERL_ARGS_ASSERT_CLEAR_SPECIAL_BLOCKS  \
+       assert(fullname); assert(gv); assert(cv)
+
 STATIC void    S_cop_free(pTHX_ COP *cop)
                        __attribute__nonnull__(pTHX_1);
 #define PERL_ARGS_ASSERT_COP_FREE      \
diff --git a/t/op/sub.t b/t/op/sub.t
index 7df8f49..1861623 100644
--- a/t/op/sub.t
+++ b/t/op/sub.t
@@ -6,7 +6,7 @@ BEGIN {
     require './test.pl';
 }
 
-plan( tests => 33 );
+plan( tests => 34 );
 
 sub empty_sub {}
 
@@ -222,3 +222,10 @@ ok !exists $INC{"re.pm"}, 're.pm not loaded yet';
     is $str[1], $str[0],
       'Pure-Perl sub clobbering sub whose DESTROY assigns to the glob';
 }
+
+# [perl #122107] previously this would return
+#  Subroutine BEGIN redefined at (eval 2) line 2.
+fresh_perl_is(<<'EOS', "", { stderr => 1 },
+use strict; use warnings; eval q/use File::{Spec}/; eval q/use File::Spec/;
+EOS
+              "check special blocks are cleared on error");

--
Perl5 Master Repository

Reply via email to