# HG changeset patch # User John W. Eaton # Date 1497965328 14400 # Node ID da89ce0d49ebf182c6c016882e2af3ccaac4a5d3 # Parent 3bb0a937c071303d46d14cdd364d40a0fd63f026 avoid possible memory leak in parser * parse.h, oct-parse.in.yy (base_parser::validate_param_list): New function, adapted from tree_parameter_list::validate. * pt-misc.h, pt-misc.cc (tree_parameter_list::validate): Delete. (tree_parameter_list::mark_varargs, tree_parameter_list::mark_varargs_only): Now public. diff -r 3bb0a937c071 -r da89ce0d49eb libinterp/parse-tree/oct-parse.in.yy --- a/libinterp/parse-tree/oct-parse.in.yy Tue Jun 20 06:57:59 2017 -0400 +++ b/libinterp/parse-tree/oct-parse.in.yy Tue Jun 20 09:28:48 2017 -0400 @@ -1332,7 +1332,8 @@ | param_list2 { $1->mark_as_formal_parameters (); - if ($1->validate (octave::tree_parameter_list::in)) + + if (parser.validate_param_list ($1, octave::tree_parameter_list::in)) { lexer.mark_as_variables ($1->variable_names ()); $$ = $1; @@ -1380,7 +1381,7 @@ // a single identifier, we still need to validate it // to check for varargin or varargout. - if (tmp->validate (octave::tree_parameter_list::out)) + if (parser.validate_param_list (tmp, octave::tree_parameter_list::out)) $$ = tmp; else { @@ -1395,7 +1396,7 @@ // Check for duplicate parameter names, varargin, // or varargout. - if ($2->validate (octave::tree_parameter_list::out)) + if (parser.validate_param_list ($2, octave::tree_parameter_list::out)) $$ = $2; else { @@ -3907,6 +3908,67 @@ } bool + base_parser::validate_param_list (tree_parameter_list *lst, + tree_parameter_list::in_or_out type) + { + std::set dict; + + for (tree_decl_elt *elt : *lst) + { + tree_identifier *id = elt->ident (); + + if (id) + { + std::string name = id->name (); + + if (id->is_black_hole ()) + { + if (type != tree_parameter_list::in) + { + bison_error ("invalid use of ~ in output list"); + return false; + } + } + else if (dict.find (name) != dict.end ()) + { + bison_error ("'" + name + + "' appears more than once in parameter list"); + return false; + } + else + dict.insert (name); + } + } + + std::string va_type = (type == tree_parameter_list::in + ? "varargin" : "varargout"); + + size_t len = lst->length (); + + if (len > 0) + { + tree_decl_elt *elt = lst->back (); + + tree_identifier *id = elt->ident (); + + if (id && id->name () == va_type) + { + if (len == 1) + lst->mark_varargs_only (); + else + lst->mark_varargs (); + + tree_parameter_list::iterator p = lst->end (); + --p; + delete *p; + lst->erase (p); + } + } + + return true; + } + + bool base_parser::validate_array_list (tree_expression *e) { bool retval = true; diff -r 3bb0a937c071 -r da89ce0d49eb libinterp/parse-tree/parse.h --- a/libinterp/parse-tree/parse.h Tue Jun 20 06:57:59 2017 -0400 +++ b/libinterp/parse-tree/parse.h Tue Jun 20 09:28:48 2017 -0400 @@ -35,6 +35,7 @@ #include "lex.h" #include "symtab.h" +#include "pt-misc.h" #include "token.h" class octave_comment_list; @@ -358,6 +359,9 @@ tree_decl_command * make_decl_command (int tok, token *tok_val, tree_decl_init_list *lst); + // Validate an function parameter list. + bool validate_param_list (tree_parameter_list *lst, + tree_parameter_list::in_or_out type); // Validate matrix or cell bool validate_array_list (tree_expression *e); diff -r 3bb0a937c071 -r da89ce0d49eb libinterp/parse-tree/pt-misc.cc --- a/libinterp/parse-tree/pt-misc.cc Tue Jun 20 06:57:59 2017 -0400 +++ b/libinterp/parse-tree/pt-misc.cc Tue Jun 20 09:28:48 2017 -0400 @@ -57,61 +57,6 @@ elt->mark_as_formal_parameter (); } - bool - tree_parameter_list::validate (in_or_out type) - { - bool retval = true; - - std::set dict; - - for (tree_decl_elt *elt : *this) - { - tree_identifier *id = elt->ident (); - - if (id) - { - std::string name = id->name (); - - if (id->is_black_hole ()) - { - if (type != in) - error ("invalid use of ~ in output list"); - } - else if (dict.find (name) != dict.end ()) - error ("'%s' appears more than once in parameter list", - name.c_str ()); - else - dict.insert (name); - } - } - - std::string va_type = (type == in ? "varargin" : "varargout"); - - size_t len = length (); - - if (len > 0) - { - tree_decl_elt *elt = back (); - - tree_identifier *id = elt->ident (); - - if (id && id->name () == va_type) - { - if (len == 1) - mark_varargs_only (); - else - mark_varargs (); - - iterator p = end (); - --p; - delete *p; - erase (p); - } - } - - return retval; - } - std::list tree_parameter_list::variable_names (void) const { diff -r 3bb0a937c071 -r da89ce0d49eb libinterp/parse-tree/pt-misc.h --- a/libinterp/parse-tree/pt-misc.h Tue Jun 20 06:57:59 2017 -0400 +++ b/libinterp/parse-tree/pt-misc.h Tue Jun 20 09:28:48 2017 -0400 @@ -68,7 +68,9 @@ void mark_as_formal_parameters (void); - bool validate (in_or_out type); + void mark_varargs (void) { marked_for_varargs = 1; } + + void mark_varargs_only (void) { marked_for_varargs = -1; } bool takes_varargs (void) const { return marked_for_varargs != 0; } @@ -88,10 +90,6 @@ private: int marked_for_varargs; - - void mark_varargs (void) { marked_for_varargs = 1; } - - void mark_varargs_only (void) { marked_for_varargs = -1; } }; // Return lists. Used to hold the right hand sides of multiple