See
ff2a62e0c8 for the explanation. The bug fix in that commit did
not apply to foreach’s aliasing.
In short, ($a,$b)=($c,$d) needs to account for whether two of those
variable names could be referring to the same variable.
This commit causes the test suite to exercise a code path in scope.c
added by
ff2a62e0c8, which turned out to be buggy. (I forgot to test
it at the time.)
Amp |void |save_aelem |NN AV* av|SSize_t idx|NN SV **sptr
Ap |void |save_aelem_flags|NN AV* av|SSize_t idx|NN SV **sptr \
|const U32 flags
+p |void |save_aliased_sv|NN GV* gv
Ap |I32 |save_alloc |I32 size|I32 pad
Ap |void |save_aptr |NN AV** aptr
Ap |AV* |save_ary |NN GV* gv
#define rsignal_restore(a,b) Perl_rsignal_restore(aTHX_ a,b)
#define rsignal_save(a,b,c) Perl_rsignal_save(aTHX_ a,b,c)
#define rxres_save(a,b) Perl_rxres_save(aTHX_ a,b)
+#define save_aliased_sv(a) Perl_save_aliased_sv(aTHX_ a)
#define save_strlen(a) Perl_save_strlen(aTHX_ a)
#define sawparens(a) Perl_sawparens(aTHX_ a)
#define scalar(a) Perl_scalar(aTHX_ a)
save_pushptrptr(gv, SvREFCNT_inc(*svp), SAVEt_GVSV);
*svp = newSV(0);
itervar = (void *)gv;
+ save_aliased_sv(gv);
}
if (PL_op->op_private & OPpITER_DEF)
#define PERL_ARGS_ASSERT_SAVE_AELEM_FLAGS \
assert(av); assert(sptr)
+PERL_CALLCONV void Perl_save_aliased_sv(pTHX_ GV* gv)
+ __attribute__nonnull__(pTHX_1);
+#define PERL_ARGS_ASSERT_SAVE_ALIASED_SV \
+ assert(gv)
+
PERL_CALLCONV I32 Perl_save_alloc(pTHX_ I32 size, I32 pad);
PERL_CALLCONV void Perl_save_aptr(pTHX_ AV** aptr)
__attribute__nonnull__(pTHX_1);
return start;
}
+void
+Perl_save_aliased_sv(pTHX_ GV *gv)
+{
+ dSS_ADD;
+ PERL_ARGS_ASSERT_SAVE_ALIASED_SV;
+ SS_ADD_PTR(gp_ref(GvGP(gv)));
+ SS_ADD_UV(SAVEt_GP_ALIASED_SV | cBOOL(GvALIASED_SV(gv)) << 8);
+ SS_ADD_END(2);
+}
+
#define ARG0_SV MUTABLE_SV(arg0.any_ptr)
GP * const gp = (GP *)ARG0_PTR;
if (gp->gp_refcnt == 1) {
GV * const gv = (GV *)sv_2mortal(newSV_type(SVt_PVGV));
+ isGV_with_GP_on(gv);
GvGP_set(gv,gp);
gp_free(gv);
+ isGV_with_GP_off(gv);
}
else {
gp->gp_refcnt--;
}
if (import_flag == GVf_IMPORTED_SV) {
if (intro) {
- dSS_ADD;
- SS_ADD_PTR(gp_ref(GvGP(dstr)));
- SS_ADD_UV(SAVEt_GP_ALIASED_SV
- | cBOOL(GvALIASED_SV(dstr)) << 8);
- SS_ADD_END(2);
+ save_aliased_sv((GV *)dstr);
}
/* Turn off the flag if sref is not referenced elsewhere,
even by weak refs. (SvRMAGICAL is a pessimistic check for
require "test.pl";
}
-plan(106);
+plan(107);
# A lot of tests to check that reversed for works.
}->($a[0]);
is $@, "", 'vivify_defelem does not croak on &PL_sv_undef elements';
}
+
+for $x ($y) {
+ $x = 3;
+ ($x, my $z) = (1, $y);
+ is $z, 3, 'list assignment after aliasing via foreach';
+}