Mercurial > hg > octave-lyh
changeset 16285:3389152014ca
improve validation of left hand side of assignment expressions in parser
* pt-arg-list.cc (tree_argument_list::is_valid_lvalue_list):
* oct-parse.in.yy (octave_parser::validate_for_assignment):
Improve checks.
author | John W. Eaton <jwe@octave.org> |
---|---|
date | Mon, 11 Mar 2013 18:19:10 -0400 |
parents | 09881dab3aaf |
children | f58257a6d18c 04a7953496a7 |
files | libinterp/parse-tree/oct-parse.in.yy libinterp/parse-tree/pt-arg-list.cc libinterp/parse-tree/pt-arg-list.h |
diffstat | 3 files changed, 61 insertions(+), 19 deletions(-) [+] |
line wrap: on
line diff
--- a/libinterp/parse-tree/oct-parse.in.yy +++ b/libinterp/parse-tree/oct-parse.in.yy @@ -2947,29 +2947,46 @@ if (e->is_constant ()) { - bison_error ("invalid empty LHS in [] = ... assignment"); + octave_value ov = e->rvalue1 (); + + if (ov.is_empty ()) + bison_error ("invalid empty left hand side of assignment"); + else + bison_error ("invalid constant left hand side of assignment"); + delete e; } - else if (e->is_matrix ()) - { - tree_matrix *mat = dynamic_cast<tree_matrix *> (e); - - if (mat && mat->size () == 1) - { - retval = mat->front (); - mat->pop_front (); - delete e; - } - else - { - bison_error ("invalid LHS in '[LHS] = ...' assignment"); - delete e; - } - } else { - retval = new tree_argument_list (e); - retval->mark_as_simple_assign_lhs (); + bool is_simple_assign = true; + + tree_argument_list *tmp = 0; + + if (e->is_matrix ()) + { + tree_matrix *mat = dynamic_cast<tree_matrix *> (e); + + if (mat && mat->size () == 1) + { + tmp = mat->front (); + mat->pop_front (); + delete e; + is_simple_assign = false; + } + } + else + tmp = new tree_argument_list (e); + + if (tmp && tmp->is_valid_lvalue_list ()) + retval = tmp; + else + { + bison_error ("invalid left hand side of assignment"); + delete tmp; + } + + if (retval && is_simple_assign) + retval->mark_as_simple_assign_lhs (); } return retval;
--- a/libinterp/parse-tree/pt-arg-list.cc +++ b/libinterp/parse-tree/pt-arg-list.cc @@ -99,6 +99,29 @@ return true; } +bool +tree_argument_list::is_valid_lvalue_list (void) const +{ + bool retval = true; + + for (const_iterator p = begin (); p != end (); p++) + { + tree_expression *elt = *p; + + // There is no need for a separate check for the magic "~" because + // it represented by tree_black_hole, and that is derived from + // tree_identifier. + + if (! (elt->is_identifier () || elt->is_index_expression ())) + { + retval = false; + break; + } + } + + return retval; +} + static const octave_value *indexed_object = 0; static int index_position = 0; static int num_indices = 0;
--- a/libinterp/parse-tree/pt-arg-list.h +++ b/libinterp/parse-tree/pt-arg-list.h @@ -77,6 +77,8 @@ bool all_elements_are_constant (void) const; + bool is_valid_lvalue_list (void) const; + octave_value_list convert_to_const_vector (const octave_value *object = 0); std::list<octave_lvalue> lvalue_list (void);