changeset 21369:105224df2330

also disallow assignment to keywords in assignin (bug #46459) * lex.ll (is_keyword): Don't treat "enumeration", "events", "methods", or "properties" as keywords. * oct-parse.in.yy, parse.h: New tests. (Fassignin): Check for assignments to keywords. (octave_base_parser::valid_id_for_assignment): Delete. (octave_base_parser::make_assign_op): Use is_keyword instead of valid_id_for_assignment.
author John W. Eaton <jwe@octave.org>
date Fri, 26 Feb 2016 20:35:45 -0500
parents e789571034bc
children df5922f77193
files libinterp/parse-tree/lex.ll libinterp/parse-tree/oct-parse.in.yy libinterp/parse-tree/parse.h
diffstat 3 files changed, 27 insertions(+), 18 deletions(-) [+]
line wrap: on
line diff
--- a/libinterp/parse-tree/lex.ll	Sat Feb 27 15:27:52 2016 +1100
+++ b/libinterp/parse-tree/lex.ll	Fri Feb 26 20:35:45 2016 -0500
@@ -1973,9 +1973,13 @@
   // "set" and "get" portions of the names using the same mechanism as
   // is used for keywords.  However, they are not really keywords in
   // the language, so omit them from the list of possible keywords.
+  // Likewise for "enumeration", "events", "methods", and
+  // "properties".
 
   return (octave_kw_hash::in_word_set (s.c_str (), s.length ()) != 0
-          && ! (s == "set" || s == "get"));
+          && ! (s == "set" || s == "get"
+                || s == "enumeration" || s == "events"
+                || s == "methods" || s == "properties"));
 }
 
 DEFUN (iskeyword, args, ,
--- a/libinterp/parse-tree/oct-parse.in.yy	Sat Feb 27 15:27:52 2016 +1100
+++ b/libinterp/parse-tree/oct-parse.in.yy	Fri Feb 26 20:35:45 2016 -0500
@@ -3035,7 +3035,7 @@
       tree_expression *tmp = lhs->remove_front ();
 
       if ((tmp->is_identifier () || tmp->is_index_expression ())
-          && ! valid_id_for_assignment (tmp->name ()))
+          && is_keyword (tmp->name ()))
         {
           std::string kw = tmp->name ();
 
@@ -3061,7 +3061,7 @@
         {
           std::string kw = *it;
 
-          if (! valid_id_for_assignment (kw))
+          if (is_keyword (kw))
             {
               delete lhs;
               delete rhs;
@@ -4024,18 +4024,6 @@
   parse_error_msg = output_buf.str ();
 }
 
-bool
-octave_base_parser::valid_id_for_assignment (const std::string& s)
-{
-  // is_keyword will return true for some identfiers that are only
-  // keywords in certain contexts.
-
-  return (! is_keyword (s)
-          || (! lexer.parsing_classdef
-              && (s == "enumeration" || s == "events"
-                  || s == "methods" || s == "properties")));
-}
-
 int
 octave_parser::run (void)
 {
@@ -5131,6 +5119,8 @@
 %! [a,] = gcd (1,2);
 %! [a,b,] = gcd (1, 2);
 
+%!error eval ("switch = 13;");
+
 */
 
 DEFUN (assignin, args, ,
@@ -5162,13 +5152,28 @@
   std::string nm = args(1).xstring_value ("assignin: VARNAME must be a string");
 
   if (valid_identifier (nm))
-    symbol_table::assign (nm, args(2));
+    {
+      // Put the check here so that we don't slow down assignments
+      // generally.  Any that go through Octave's parser should have
+      // already been checked.
+
+      if (is_keyword (nm))
+        error ("assignin: invalid assignment to keyword '%s'", nm.c_str ());
+
+      symbol_table::assign (nm, args(2));
+    }
   else
     error ("assignin: invalid variable name in argument VARNAME");
 
   return retval;
 }
 
+/*
+
+%!error assignin ("base", "switch", "13");
+
+*/
+
 DEFUN (evalin, args, nargout,
   "-*- texinfo -*-\n\
 @deftypefn  {} {} evalin (@var{context}, @var{try})\n\
@@ -5385,6 +5390,8 @@
 %! warning ("off", "quiet", "local");
 %! assert (evalc ("error ('foo')", "warning ('bar')"), "warning: bar\n");
 
+%!error evalc ("switch = 13;");
+
 */
 
 DEFUN (__parser_debug_flag__, args, nargout,
--- a/libinterp/parse-tree/parse.h	Sat Feb 27 15:27:52 2016 +1100
+++ b/libinterp/parse-tree/parse.h	Fri Feb 26 20:35:45 2016 -0500
@@ -393,8 +393,6 @@
   // Generic error messages.
   void bison_error (const std::string& s, int l = -1, int c = -1);
 
-  bool valid_id_for_assignment (const std::string& s);
-
   // Contains error message if Bison-generated parser returns non-zero
   // status.
   std::string parse_error_msg;