/* This file contains some common functions needed to carry out certain
* ops. For example, both pp_sprintf() and pp_prtf() call the function
- * do_printf() found in this file.
+ * do_sprintf() found in this file.
*/
#include "EXTERN.h"
PERL_ARGS_ASSERT_DO_VOP;
if (sv != left || (optype != OP_BIT_AND && !SvOK(sv)))
- sv_setpvs(sv, ""); /* avoid undef warning on |= and ^= */
+ sv_setpvs(sv, ""); /* avoid undef warning on |= and ^= */
if (sv == left) {
lsave = lc = SvPV_force_nomg(left, leftlen);
}
if (sv == left || sv == right)
(void)sv_usepvn(sv, dcorig, needlen);
SvCUR_set(sv, dc - dcorig);
+ *SvEND(sv) = 0;
break;
case OP_BIT_XOR:
while (lulen && rulen) {
HV * const keys = MUTABLE_HV(POPs);
HE *entry;
SSize_t extend_size;
- const I32 gimme = GIMME_V;
+ const U8 gimme = GIMME_V;
const I32 dokv = (PL_op->op_type == OP_RV2HV || PL_op->op_type == OP_PADHV);
/* op_type is OP_RKEYS/OP_RVALUES if pp_rkeys delegated to here */
- const I32 dokeys = dokv || (PL_op->op_type == OP_KEYS);
- const I32 dovalues = dokv || (PL_op->op_type == OP_VALUES);
+ const I32 dokeys = dokv || (PL_op->op_type == OP_KEYS)
+ || ( PL_op->op_type == OP_AVHVSWITCH
+ && (PL_op->op_private & 3) + OP_EACH == OP_KEYS );
+ const I32 dovalues = dokv || (PL_op->op_type == OP_VALUES)
+ || ( PL_op->op_type == OP_AVHVSWITCH
+ && (PL_op->op_private & 3) + OP_EACH == OP_VALUES );
(void)hv_iterinit(keys); /* always reset iterator regardless */
RETURN;
}
+ if (UNLIKELY(PL_op->op_private & OPpMAYBE_LVSUB)) {
+ const I32 flags = is_lvalue_sub();
+ if (flags && !(flags & OPpENTERSUB_INARGS))
+ /* diag_listed_as: Can't modify %s in %s */
+ Perl_croak(aTHX_ "Can't modify keys in list assignment");
+ }
+
/* 2*HvUSEDKEYS() should never be big enough to truncate or wrap */
assert(HvUSEDKEYS(keys) <= (SSize_t_MAX >> 1));
extend_size = (SSize_t)HvUSEDKEYS(keys) * (dokeys + dovalues);