type == OP_NOT)
yyerror("Using !~ with s///r doesn't make sense");
- ismatchop = rtype == OP_MATCH ||
- rtype == OP_SUBST ||
- rtype == OP_TRANS;
+ ismatchop = (rtype == OP_MATCH ||
+ rtype == OP_SUBST ||
+ rtype == OP_TRANS)
+ && !(right->op_flags & OPf_SPECIAL);
if (ismatchop && right->op_private & OPpTARGET_MY) {
right->op_targ = 0;
right->op_private &= ~OPpTARGET_MY;
op_free(first);
if (other->op_type == OP_LEAVE)
other = newUNOP(OP_NULL, OPf_SPECIAL, other);
+ else if (other->op_type == OP_MATCH
+ || other->op_type == OP_SUBST
+ || other->op_type == OP_TRANS)
+ /* Mark the op as being unbindable with =~ */
+ other->op_flags |= OPf_SPECIAL;
return other;
}
else {
}
if (live->op_type == OP_LEAVE)
live = newUNOP(OP_NULL, OPf_SPECIAL, live);
+ else if (live->op_type == OP_MATCH || live->op_type == OP_SUBST
+ || live->op_type == OP_TRANS)
+ /* Mark the op as being unbindable with =~ */
+ live->op_flags |= OPf_SPECIAL;
return live;
}
NewOp(1101, logop, 1, LOGOP);
/* On OP_HELEM and OP_HSLICE, localization will be followed
by assignment, so do not wipe the target if it is special
(e.g. a glob or a magic SV) */
+ /* On OP_MATCH, OP_SUBST & OP_TRANS, the
+ operand of a logical or conditional
+ that was optimised away, so it should
+ not be bound via =~ */
/* old names; don't use in new code, but don't break them, either */
#define OPf_LIST OPf_WANT_LIST
# we've not yet verified that use works.
# use strict;
-print "1..13\n";
+print "1..19\n";
my $test = 0;
# Historically constant folding was performed by evaluating the ops, and if
failed($got, "'$expect'", $name);
}
+sub ok {
+ my ($got, $name) = @_;
+ $test = $test + 1;
+ if ($got) {
+ print "ok $test - $name\n";
+ return 1;
+ }
+ failed($got, "a true value", $name);
+}
+
my $a;
$a = eval '$b = 0/0 if 0; 3';
is ($a, 3, 'constants in conditionals don\'t affect constant folding');
like ($@, qr/division/, "eval caught division");
is($c, 2, "missing die hook");
}
+
+# [perl #20444] Constant folding should not change the meaning of match
+# operators.
+{
+ local *_;
+ $_="foo"; my $jing = 1;
+ ok scalar $jing =~ (1 ? /foo/ : /bar/),
+ 'lone m// is not bound via =~ after ? : folding';
+ ok scalar $jing =~ (0 || /foo/),
+ 'lone m// is not bound via =~ after || folding';
+ ok scalar $jing =~ (1 ? s/foo/foo/ : /bar/),
+ 'lone s/// is not bound via =~ after ? : folding';
+ ok scalar $jing =~ (0 || s/foo/foo/),
+ 'lone s/// is not bound via =~ after || folding';
+ $jing = 3;
+ ok scalar $jing =~ (1 ? y/fo// : /bar/),
+ 'lone y/// is not bound via =~ after ? : folding';
+ ok scalar $jing =~ (0 || y/fo//),
+ 'lone y/// is not bound via =~ after || folding';
+}