Mercurial > octave
diff libinterp/parse-tree/anon-fcn-validator.cc @ 27728:5e92bff668d6
disallow lvalue references in anonymous functions (bug #57255)
* libinterp/parse-tree/anon-fcn-validator.h,
libinterp/parse-tree/anon-fcn-validator.cc: New files.
* module.mk: Update.
* oct-parse.yy (anon_fcn_handle): Abort parse if make_anon_fcn_handle
returns invalid object.
(base_parser::make_anon_fcn_handle): Use new anon_fcn_validator class
to check anonymous function. Set parser error and return nullptr if
validation fails.
author | John W. Eaton <jwe@octave.org> |
---|---|
date | Wed, 20 Nov 2019 19:22:54 -0600 |
parents | |
children | b442ec6dda5c |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libinterp/parse-tree/anon-fcn-validator.cc Wed Nov 20 19:22:54 2019 -0600 @@ -0,0 +1,80 @@ +/* + +Copyright (C) 2019 John W. Eaton + +This file is part of Octave. + +Octave is free software: you can redistribute it and/or modify it +under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +Octave is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with Octave; see the file COPYING. If not, see +<https://www.gnu.org/licenses/>. + +*/ + +#if defined (HAVE_CONFIG_H) +# include "config.h" +#endif + +#include <string> + +#include "anon-fcn-validator.h" +#include "ov.h" +#include "pt-all.h" + +namespace octave +{ + anon_fcn_validator::anon_fcn_validator (tree_parameter_list *, + tree_expression *expr) + : m_ok (true), m_line (-1), m_column (-1), m_message () + { + expr->accept (*this); + } + + void anon_fcn_validator::visit_postfix_expression (tree_postfix_expression& expr) + { + octave_value::unary_op op = expr.op_type (); + + if (op == octave_value::op_incr || op == octave_value::op_decr) + error (expr); + else + tree_walker::visit_postfix_expression (expr); + } + + void anon_fcn_validator::visit_prefix_expression (tree_prefix_expression& expr) + { + octave_value::unary_op op = expr.op_type (); + + if (op == octave_value::op_incr || op == octave_value::op_decr) + error (expr); + else + tree_walker::visit_prefix_expression (expr); + } + + void anon_fcn_validator::visit_multi_assignment (tree_multi_assignment& expr) + { + error (expr); + } + + void anon_fcn_validator::visit_simple_assignment (tree_simple_assignment& expr) + { + error (expr); + } + + void anon_fcn_validator::error (tree_expression& expr) + { + m_ok = false; + m_line = expr.line (); + m_column = expr.column (); + m_message + = "invalid use of operator " + expr.oper () + " in anonymous function"; + } +}