diff options
author | David Mitchell <davem@iabyn.com> | 2019-04-05 12:49:50 +0100 |
---|---|---|
committer | David Mitchell <davem@iabyn.com> | 2019-04-05 14:02:09 +0100 |
commit | 017192018b7f9fc4b889bb344bd75df8f6b78929 (patch) | |
tree | c7c3f0039797e09b8571be51a39dcb3ace30e0a0 /perly.y | |
parent | 2b902307c53477ab56cb732ac14b1e3371aed097 (diff) | |
download | perl-017192018b7f9fc4b889bb344bd75df8f6b78929.tar.gz |
parser: change LABEL type from pval to opval
The items pushed onto the parser stack can be one of several types:
ival, opval, pval etc. The only remaining use of pval is when a "label:"
is encountered.
When an error occurs during parsing, ops on the parse stack get
automatically reaped these days as part of the OP slab mechanism;
but bare strings (pvals) still leak.
Convert this one remaining pval into an opval, making the toker return
an OP_CONST with an SV holding the label.
Since newSTATEOP() still expects a raw string for the label, the parser
just grabs the value returned by the toker and makes a copy of the
string from it, then immediately frees the OP_CONST and its associated
SV.
The leak was showing up in ext/XS-APItest/t/stmtasexpr.t, which expects
to parse a statement where labels are banned.
Diffstat (limited to 'perly.y')
-rw-r--r-- | perly.y | 12 |
1 files changed, 9 insertions, 3 deletions
@@ -50,7 +50,7 @@ %token <opval> BAREWORD METHOD FUNCMETH THING PMFUNC PRIVATEREF QWLIST %token <opval> FUNC0OP FUNC0SUB UNIOPSUB LSTOPSUB %token <opval> PLUGEXPR PLUGSTMT -%token <pval> LABEL +%token <opval> LABEL %token <ival> FORMAT SUB SIGSUB ANONSUB ANON_SIGSUB PACKAGE USE %token <ival> WHILE UNTIL IF UNLESS ELSE ELSIF CONTINUE FOR %token <ival> GIVEN WHEN DEFAULT @@ -253,11 +253,17 @@ fullstmt: barestmt labfullstmt: LABEL barestmt { - $$ = newSTATEOP(SVf_UTF8 * $1[strlen($1)+1], $1, $2); + SV *label = cSVOPx_sv($1); + $$ = newSTATEOP(SvFLAGS(label) & SVf_UTF8, + savepv(SvPVX_const(label)), $2); + op_free($1); } | LABEL labfullstmt { - $$ = newSTATEOP(SVf_UTF8 * $1[strlen($1)+1], $1, $2); + SV *label = cSVOPx_sv($1); + $$ = newSTATEOP(SvFLAGS(label) & SVf_UTF8, + savepv(SvPVX_const(label)), $2); + op_free($1); } ; |