PP(pp_sassign)
{
dVAR; dSP; dPOPTOPssrl;
+ U32 wasfake = 0;
if (PL_op->op_private & OPpASSIGN_BACKWARDS) {
SV * const temp = left;
}
}
+ /* Allow glob assignments like *$x = ..., which, when the glob has a
+ SVf_FAKE flag, cannot be distinguished from $x = ... without looking
+ at the op tree. */
+ if( SvTYPE(right) == SVt_PVGV && cBINOP->op_last->op_type == OP_RV2GV
+ && (wasfake = SvFLAGS(right) & SVf_FAKE) )
+ SvFLAGS(right) &= ~SVf_FAKE;
SvSetMagicSV(right, left);
+ if(wasfake) SvFLAGS(right) |= SVf_FAKE;
SETs(right);
RETURN;
}
SvROK_on(rv);
if (pkg) {
- HV* const stash = gv_stashpv(SvPV_nolen(pkg), GV_ADD);
+ HV *const stash = gv_stashsv(pkg, GV_ADD);
SvREFCNT_dec(pkg);
(void)sv_bless(rv, stash);
}
if (MARK == SP) {
/* Temporaries are bad unless they happen to be elements
* of a tied hash or array */
- if (SvFLAGS(TOPs) & (SVs_TEMP | SVs_PADTMP | SVf_READONLY) &&
+ if ((SvFLAGS(TOPs) & (SVs_TEMP | SVs_PADTMP) ||
+ (SvFLAGS(TOPs) & (SVf_READONLY | SVf_FAKE))
+ == SVf_READONLY
+ ) &&
!(SvRMAGICAL(TOPs) && mg_find(TOPs, PERL_MAGIC_tiedelem))) {
LEAVE;
cxstack_ix--;