From dc93d7fb33f6b20933ff809c56ba68b8513d02c8 Mon Sep 17 00:00:00 2001 From: Nicholas Clark Date: Sun, 23 Sep 2012 22:48:42 +0200 Subject: [PATCH] Flush PL_stashcache when assigning a file handle to a typeglob. File handles take priority over stashes for method dispatch. Assigning a file handle to a typeglob potentially creates a file handle where one did not exist before. As PL_stashcache only contains entries for names which unambiguously resolve to stashes, such a change may mean that PL_stashcache now contains an invalid entry. As it's hard to work out exactly which entries might be affected, simply flush the entire cache and let it rebuild itself. --- sv.c | 8 ++++++++ t/op/method.t | 3 --- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/sv.c b/sv.c index bd8afb7..2417e86 100644 --- a/sv.c +++ b/sv.c @@ -3883,6 +3883,14 @@ S_glob_assign_ref(pTHX_ SV *const dstr, SV *const sstr) assert(mg); Perl_magic_clearisa(aTHX_ NULL, mg); } + else if (stype == SVt_PVIO) { + DEBUG_o(Perl_deb(aTHX_ "glob_assign_ref clearing PL_stashcache\n")); + /* It's a cache. It will rebuild itself quite happily. + It's a lot of effort to work out exactly which key (or keys) + might be invalidated by the creation of the this file handle. + */ + hv_clear(PL_stashcache); + } break; } SvREFCNT_dec(dref); diff --git a/t/op/method.t b/t/op/method.t index 29cb82b..5ed8f76 100644 --- a/t/op/method.t +++ b/t/op/method.t @@ -581,14 +581,11 @@ SKIP: { *Color::H1 = *Colour::H1{IO}; is(Colour::H1->getline(), , 'read from a file'); - { local $::TODO = "regression introduced when PL_stashcache was first added"; is(Color::H1->getline(), , 'file handles take priority after typeglob assignment'); - } *Color::H1 = *CLOSED{IO}; { - local $::TODO = "regression introduced when PL_stashcache was first added"; no warnings 'io'; is(Color::H1->getline(), undef, "assigning a closed a file handle doesn't change object resolution"); -- 1.8.3.1