summaryrefslogtreecommitdiff
path: root/perly.y
diff options
context:
space:
mode:
authorDavid Mitchell <davem@iabyn.com>2019-04-05 12:49:50 +0100
committerDavid Mitchell <davem@iabyn.com>2019-04-05 14:02:09 +0100
commit017192018b7f9fc4b889bb344bd75df8f6b78929 (patch)
treec7c3f0039797e09b8571be51a39dcb3ace30e0a0 /perly.y
parent2b902307c53477ab56cb732ac14b1e3371aed097 (diff)
downloadperl-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.y12
1 files changed, 9 insertions, 3 deletions
diff --git a/perly.y b/perly.y
index da0b3e364a..1170df80f2 100644
--- a/perly.y
+++ b/perly.y
@@ -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);
}
;