diff options
author | Father Chrysostomos <sprout@cpan.org> | 2010-11-26 07:22:47 -0800 |
---|---|---|
committer | Father Chrysostomos <sprout@cpan.org> | 2010-11-26 09:39:51 -0800 |
commit | 75bd28cfd597653e1169cbeb4920b7ba42eb8503 (patch) | |
tree | 4ce63bcfc2b1cb321bf8127b0e8293eded8bb985 | |
parent | abf9167d3fff002ddaed53abb44d638387bca978 (diff) | |
download | perl-75bd28cfd597653e1169cbeb4920b7ba42eb8503.tar.gz |
[perl #78634] Conflict in defining constant INIT
When gv_init tries to turn a constant named INIT into a CV, the auto-
matic special processing of the INIT ‘block’ kicks in, which removes
the CV from the GV.
This should not happen with gv_init, as $::{INIT} = \5 is supposed
to be equivalent to *INIT = sub(){5}, which does not do that.
This commit makes gv_init check for that, increase the reference
count, and reassign the CV. It does not stop the CV from being called
as a special block, but it is harmless to call a constant CV.
-rw-r--r-- | gv.c | 3 | ||||
-rw-r--r-- | t/op/blocks.t | 6 |
2 files changed, 8 insertions, 1 deletions
@@ -317,6 +317,9 @@ Perl_gv_init(pTHX_ GV *gv, HV *stash, const char *name, STRLEN len, int multi) /* newCONSTSUB takes ownership of the reference from us. */ cv = newCONSTSUB(stash, (name0 ? name0 : name), has_constant); + /* In case op.c:S_process_special_blocks stole it: */ + if (!GvCV(gv)) + GvCV(gv) = SvREFCNT_inc_simple_NN(cv); assert(GvCV(gv) == cv); /* newCONSTSUB should have set this */ if (name0) Safefree(name0); diff --git a/t/op/blocks.t b/t/op/blocks.t index 717be4cdf2..8460371fd8 100644 --- a/t/op/blocks.t +++ b/t/op/blocks.t @@ -6,7 +6,7 @@ BEGIN { require './test.pl'; } -plan tests => 4; +plan tests => 5; my @expect = qw( b1 @@ -109,3 +109,7 @@ SCRIPT3 fresh_perl_is(<<'SCRIPT70614', "still here",{switches => [''], stdin => '', stderr => 1 },'eval-UNITCHECK-eval (bug 70614)'); eval "UNITCHECK { eval 0 }"; print "still here"; SCRIPT70614 + +# [perl #78634] Make sure block names can be used as constants. +use constant INIT => 5; +::is INIT, 5, 'constant named after a special block'; |