diff options
author | Father Chrysostomos <sprout@cpan.org> | 2010-09-20 22:05:34 -0700 |
---|---|---|
committer | Father Chrysostomos <sprout@cpan.org> | 2010-09-20 22:05:34 -0700 |
commit | 2474a784a94d8c70aea9c330d9f2a902b8a68b85 (patch) | |
tree | b09595a0bb76d458489b7aee6fef31f7286c1c9e /op.c | |
parent | af9838cc2fa3350e15e88a27008899ae3a3afdb6 (diff) | |
download | perl-2474a784a94d8c70aea9c330d9f2a902b8a68b85.tar.gz |
[perl #20444] regex not evaluated in constant ?:
$text =~ ( 1 ? /phoo/ : /bear/)
used to be constant-folded to
$text =~ /phoo/
This patch solves the problem by marking match and subst ops as
OPf_SPECIAL during constant folding, so the =~ operator can tell not
to take possession of it.
Diffstat (limited to 'op.c')
-rw-r--r-- | op.c | 16 |
1 files changed, 13 insertions, 3 deletions
@@ -2236,9 +2236,10 @@ Perl_bind_match(pTHX_ I32 type, OP *left, OP *right) 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; @@ -4876,6 +4877,11 @@ S_new_logop(pTHX_ I32 type, I32 flags, OP** firstp, OP** otherp) 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 { @@ -5028,6 +5034,10 @@ Perl_newCONDOP(pTHX_ I32 flags, OP *first, OP *trueop, OP *falseop) } 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); |