#define ck_subr(a) Perl_ck_subr(aTHX_ a)
#define ck_substr(a) Perl_ck_substr(aTHX_ a)
#define ck_svconst(a) Perl_ck_svconst(aTHX_ a)
+#define ck_tell(a) Perl_ck_tell(aTHX_ a)
#define ck_trunc(a) Perl_ck_trunc(aTHX_ a)
#define convert(a,b,c) Perl_convert(aTHX_ a,b,c)
#define core_prototype(a,b,c,d) Perl_core_prototype(aTHX_ a,b,c,d)
@{$priv{$_}}{32,64,96} = ("DREFAV", "DREFHV", "DREFSV")
for (qw(rv2gv rv2sv padsv aelem helem));
$priv{$_}{16} = "STATE" for ("padav", "padhv", "padsv");
-$priv{rv2gv}{4} = "NOINIT";
+@{$priv{rv2gv}}{4,16} = qw "NOINIT FAKE";
@{$priv{"entersub"}}{1,4,16,32,64} = qw( INARGS TARG DBG DEREF );
@{$priv{rv2cv}}{1,8,128} = ("CONST","AMPER","NO()");
$priv{"gv"}{32} = "EARLYCV";
}
OP *
+Perl_ck_tell(pTHX_ OP *o)
+{
+ OP *kid;
+ PERL_ARGS_ASSERT_CK_TELL;
+ o = ck_fun(o);
+ kid = cLISTOPo->op_first;
+ if (kid && kid->op_type == OP_RV2GV) kid->op_private |= OPpALLOW_FAKE;
+ return o;
+}
+
+OP *
Perl_ck_each(pTHX_ OP *o)
{
dVAR;
#define OPpEARLY_CV 32 /* foo() called before sub foo was parsed */
/* OP_?ELEM only */
#define OPpLVAL_DEFER 16 /* Defer creation of array/hash elem */
- /* OP_RV2?V, OP_GVSV, OP_ENTERITER only */
+ /* OP_RV2[SAH]V, OP_GVSV, OP_ENTERITER only */
#define OPpOUR_INTRO 16 /* Variable was in an our() */
/* OP_RV2[AGH]V, OP_PAD[AH]V, OP_[AH]ELEM, OP_[AH]SLICE OP_AV2ARYLEN,
OP_R?KEYS, OP_SUBSTR, OP_POS, OP_VEC */
#define OPpDONT_INIT_GV 4 /* Call gv_fetchpv with GV_NOINIT */
/* (Therefore will return whatever is currently in the symbol table, not
guaranteed to be a PVGV) */
+#define OPpALLOW_FAKE 16 /* OK to return fake glob */
/* Private for OP_ENTERITER and OP_ITER */
#define OPpITER_REVERSED 4 /* for (reverse ...) */
#define OPpOFFBYONE 128 /* Treat caller(1) as caller(2) */
/* Private for OP_COREARGS */
-/* These must not conflict with OPpDONT_INIT_GV. See pp.c:S_rv2gv. */
+/* These must not conflict with OPpDONT_INIT_GV or OPpALLOW_FAKE.
+ See pp.c:S_rv2gv. */
#define OPpCOREARGS_DEREF1 1 /* Arg 1 is a handle constructor */
#define OPpCOREARGS_DEREF2 2 /* Arg 2 is a handle constructor */
#define OPpCOREARGS_SCALARMOD 64 /* \$ rather than \[$@%*] */
Perl_ck_fun, /* sysread */
Perl_ck_fun, /* syswrite */
Perl_ck_eof, /* eof */
- Perl_ck_fun, /* tell */
+ Perl_ck_tell, /* tell */
Perl_ck_fun, /* seek */
Perl_ck_trunc, /* truncate */
Perl_ck_fun, /* fcntl */
SvFAKE_off(sv);
}
}
- if (SvFAKE(sv)) {
+ if (SvFAKE(sv) && !(PL_op->op_private & OPpALLOW_FAKE)) {
SV *newsv = sv_newmortal();
sv_setsv_flags(newsv, sv, 0);
SvFAKE_off(newsv);
#define PERL_ARGS_ASSERT_CK_SVCONST \
assert(o)
+PERL_CALLCONV OP * Perl_ck_tell(pTHX_ OP *o)
+ __attribute__warn_unused_result__
+ __attribute__nonnull__(pTHX_1);
+#define PERL_ARGS_ASSERT_CK_TELL \
+ assert(o)
+
PERL_CALLCONV OP * Perl_ck_trunc(pTHX_ OP *o)
__attribute__warn_unused_result__
__attribute__nonnull__(pTHX_1);
syswrite syswrite ck_fun imst@ F S S? S?
eof eof ck_eof is% F?
-tell tell ck_fun st% F?
+tell tell ck_tell st% F?
seek seek ck_fun s@ F S S
# truncate really behaves as if it had both "S S" and "F S"
truncate truncate ck_trunc is@ S S
require './test.pl';
}
-print "1..28\n";
+print "1..31\n";
$TST = 'TST';
{ print "ok 28$todo\n"; } else { print "not ok 28$todo\n"; }
close $tst;
+open FH, "test.pl";
+$fh = *FH; # coercible glob
+$not = "not " x! (tell $fh == 0);
+print "${not}ok 29 - tell on coercible glob\n";
+$not = "not " x! (tell == 0);
+print "${not}ok 30 - argless tell after tell \$coercible\n";
+tell *$fh;
+$not = "not " x! (tell == 0);
+print "${not}ok 31 - argless tell after tell *\$coercible\n";