case OP_AELEM:
case OP_HELEM:
+ {
+ bool negate = FALSE;
+
if (PL_op == obase)
/* $a[uninit_expr] or $h{uninit_expr} */
return find_uninit_var(cBINOPx(obase)->op_last, uninit_sv, match);
if (!sv)
break;
+ if (kid && kid->op_type == OP_NEGATE) {
+ negate = TRUE;
+ kid = cUNOPx(kid)->op_first;
+ }
+
if (kid && kid->op_type == OP_CONST && SvOK(cSVOPx_sv(kid))) {
/* index is constant */
+ SV* kidsv;
+ if (negate) {
+ kidsv = sv_2mortal(newSVpvs("-"));
+ sv_catsv(kidsv, cSVOPx_sv(kid));
+ }
+ else
+ kidsv = cSVOPx_sv(kid);
if (match) {
if (SvMAGICAL(sv))
break;
if (obase->op_type == OP_HELEM) {
- HE* he = hv_fetch_ent(MUTABLE_HV(sv), cSVOPx_sv(kid), 0, 0);
+ HE* he = hv_fetch_ent(MUTABLE_HV(sv), kidsv, 0, 0);
if (!he || HeVAL(he) != uninit_sv)
break;
}
else {
- SV * const * const svp = av_fetch(MUTABLE_AV(sv), SvIV(cSVOPx_sv(kid)), FALSE);
+ SV * const * const svp = av_fetch(MUTABLE_AV(sv),
+ negate ? - SvIV(cSVOPx_sv(kid)) : SvIV(cSVOPx_sv(kid)),
+ FALSE);
if (!svp || *svp != uninit_sv)
break;
}
}
if (obase->op_type == OP_HELEM)
return varname(gv, '%', o->op_targ,
- cSVOPx_sv(kid), 0, FUV_SUBSCRIPT_HASH);
+ kidsv, 0, FUV_SUBSCRIPT_HASH);
else
return varname(gv, '@', o->op_targ, NULL,
- SvIV(cSVOPx_sv(kid)), FUV_SUBSCRIPT_ARRAY);
+ negate ? - SvIV(cSVOPx_sv(kid)) : SvIV(cSVOPx_sv(kid)),
+ FUV_SUBSCRIPT_ARRAY);
}
else {
/* index is an expression;
o->op_targ, NULL, 0, FUV_SUBSCRIPT_WITHIN);
}
break;
+ }
case OP_AASSIGN:
/* only examine RHS */