TAINT_NOT;
if (gimme == G_SCALAR) {
- if (MARK < SP)
- *++newsp = (SvFLAGS(*SP) & flags)
- ? *SP
+ if (MARK < SP) {
+ SV *sv = *SP;
+
+ *++newsp = ((SvFLAGS(sv) & flags) && SvREFCNT(sv) == 1
+ && !SvMAGICAL(sv))
+ ? sv
: lvalue
- ? sv_2mortal(SvREFCNT_inc_simple_NN(*SP))
- : sv_mortalcopy(*SP);
+ ? sv_2mortal(SvREFCNT_inc_simple_NN(sv))
+ : sv_mortalcopy(sv);
+ }
else {
EXTEND(newsp, 1);
*++newsp = &PL_sv_undef;
else if (gimme == G_ARRAY) {
/* in case LEAVE wipes old return values */
while (++MARK <= SP) {
- if (SvFLAGS(*MARK) & flags)
- *++newsp = *MARK;
+ SV *sv = *MARK;
+ if ((SvFLAGS(sv) & flags) && SvREFCNT(sv) == 1
+ && !SvMAGICAL(sv))
+ *++newsp = sv;
else {
*++newsp = lvalue
- ? sv_2mortal(SvREFCNT_inc_simple_NN(*MARK))
- : sv_mortalcopy(*MARK);
+ ? sv_2mortal(SvREFCNT_inc_simple_NN(sv))
+ : sv_mortalcopy(sv);
TAINT_NOT; /* Each item is independent */
}
}
if (gimme == G_SCALAR) {
if (CxLVAL(cx) && !ref) { /* Leave it as it is if we can. */
if (MARK <= SP) {
- if ((SvPADTMP(TOPs) || SvREADONLY(TOPs)) &&
- !SvSMAGICAL(TOPs)) {
+ if ((SvPADTMP(TOPs) || SvREADONLY(TOPs))) {
what =
SvREADONLY(TOPs) ? (TOPs == &PL_sv_undef) ? "undef"
: "a readonly value" : "a temporary";