summaryrefslogtreecommitdiff
path: root/perly.y
diff options
context:
space:
mode:
authorDave Mitchell <davem@fdisolutions.com>2006-12-13 17:16:22 +0000
committerDave Mitchell <davem@fdisolutions.com>2006-12-13 17:16:22 +0000
commit295222340ad6893caa0a1c3479155f88ea290dc3 (patch)
tree54db55ab76b89e5a588995a9578cc7c2d71df227 /perly.y
parentd2c837a0af0259b12bbac41550ec7dc972b876d9 (diff)
downloadperl-295222340ad6893caa0a1c3479155f88ea290dc3.tar.gz
misc MAD coredump fixes and parser leak fixes
- fix MAD coredump in tr/// - fix mad coredump in multi-line string literals - kill some MAD uninit value warnings - don't allow assignment to $n in perly.y - make op_dump handle op_latefree flags p4raw-id: //depot/perl@29548
Diffstat (limited to 'perly.y')
-rw-r--r--perly.y19
1 files changed, 11 insertions, 8 deletions
diff --git a/perly.y b/perly.y
index dd70c2bdee..e4515da2a2 100644
--- a/perly.y
+++ b/perly.y
@@ -32,6 +32,10 @@
* The main job of of this grammar is to call the various newFOO()
* functions in op.c to build a syntax tree of OP structs.
* It relies on the lexer in toke.c to do the tokenizing.
+ *
+ * Note: due to the way that the cleanup code works WRT to freeing ops on
+ * the parse stack, it is dangerous to assign to the $n variables within
+ * an action.
*/
/* Make the parser re-entrant. */
@@ -384,13 +388,11 @@ loop : label WHILE '(' remember texpr ')' mintro mblock cont
IVAL($2), scalar($7),
$12, $10, $9));
#ifdef MAD
- if (!$5)
- $5 = newOP(OP_NULL, 0);
forop = newUNOP(OP_NULL, 0, append_elem(OP_LINESEQ,
newSTATEOP(0,
(($1)->tk_lval.pval
?savepv(($1)->tk_lval.pval):Nullch),
- $5),
+ ($5 ? newOP(OP_NULL, 0) : $5) ),
forop));
token_getmad($2,forop,'3');
@@ -685,11 +687,12 @@ argexpr : argexpr ','
}
| argexpr ',' term
{
+ OP* term = $3;
DO_MAD(
- $3 = newUNOP(OP_NULL, 0, $3);
- token_getmad($2,$3,',');
+ term = newUNOP(OP_NULL, 0, term);
+ token_getmad($2,term,',');
)
- $$ = append_elem(OP_LIST, $1, $3);
+ $$ = append_elem(OP_LIST, $1, term);
}
| term %prec PREC_LOW
;
@@ -748,11 +751,11 @@ listop : LSTOP indirob argexpr /* map {...} @args or print $fh @args */
}
| LSTOPSUB startanonsub block /* sub f(&@); f { foo } ... */
{ SvREFCNT_inc(PL_compcv);
- $3 = newANONATTRSUB($2, 0, Nullop, $3); }
+ $<opval>$ = newANONATTRSUB($2, 0, Nullop, $3); }
listexpr %prec LSTOP /* ... @bar */
{ $$ = newUNOP(OP_ENTERSUB, OPf_STACKED,
append_elem(OP_LIST,
- prepend_elem(OP_LIST, $3, $5), $1));
+ prepend_elem(OP_LIST, $<opval>4, $5), $1));
}
;