changeset 32847:cb3163ba60c1 stable

be more explicit about creation of invalid vs anonymous symbol_scope objects In changeset ea3458c1d884, the meaning of symbol_scope() changed from creating a valid but anonymous (unnamed) scope to creating an invalid scope. Require the intent to be clear by deleting the default constructor so that one must pass either nullptr or a name and provide convenience functions to explicitly create invalid or anonymous scopes. * symscope.h (symbol_scope::invalid, symbol_scope::anonymous): New static functions. (symbol_scope (const std::shared_ptr<symbol_scope_rep>)): Eliminate default argument value. (symbol_scope::symbol_scope ()): Delete. Replace uses with symbol_scope::invalid or symbol_scope::anonymous as appropriate.
author John W. Eaton <jwe@octave.org>
date Thu, 25 Jan 2024 09:36:49 -0500
parents 5f6d699e88db
children 28f782f03fb8 b0c4286a481d
files libinterp/corefcn/call-stack.h libinterp/corefcn/symscope.h libinterp/corefcn/symtab.h libinterp/octave-value/ov-fcn.h libinterp/octave-value/ov-usr-fcn.h libinterp/parse-tree/lex.ll libinterp/parse-tree/oct-parse.yy libinterp/parse-tree/pt-eval.cc libinterp/parse-tree/pt-fcn-handle.cc libinterp/parse-tree/pt-fcn-handle.h
diffstat 10 files changed, 47 insertions(+), 32 deletions(-) [+]
line wrap: on
line diff
--- a/libinterp/corefcn/call-stack.h	Thu Jan 25 09:24:44 2024 -0500
+++ b/libinterp/corefcn/call-stack.h	Thu Jan 25 09:36:49 2024 -0500
@@ -102,7 +102,7 @@
   {
     // FIXME: Can m_curr_frame ever be invalid?
     return (m_curr_frame < m_cs.size ()
-            ? m_cs[m_curr_frame]->get_scope () : symbol_scope ());
+            ? m_cs[m_curr_frame]->get_scope () : symbol_scope::invalid ());
   }
 
   bool at_top_level () const
--- a/libinterp/corefcn/symscope.h	Thu Jan 25 09:24:44 2024 -0500
+++ b/libinterp/corefcn/symscope.h	Thu Jan 25 09:36:49 2024 -0500
@@ -371,14 +371,23 @@
 {
 public:
 
-  // Create a valid but possibly unnamed scope.
+  symbol_scope () = delete;
+
+  // Create a valid but possibly anonymous scope.  If NAME is empty, the
+  // scope is anonymous, but it is better to state that intent clearly
+  // by using the symbol_scope::anonymous function instead.
   symbol_scope (const std::string& name)
     : m_rep (new symbol_scope_rep (name))
   { }
 
-  // NEW_REP must be dynamically allocated or nullptr.  If it is
-  // nullptr, the scope is invalid.
-  symbol_scope (const std::shared_ptr<symbol_scope_rep> new_rep = nullptr)
+  // FIXME: is there a way to make the following constructor private and
+  // not expose the symbol_scope_rep object in the interface (see the
+  // parent_scope, primary_parent_scope, and get_rep functions)?
+
+  // If NEW_REP is nullptr, the scope is invalid.  But if you wish to
+  // create an invalid scope, it is probably better to state that intent
+  // clearly by using the symbol_scope::invalid function instead.
+  symbol_scope (const std::shared_ptr<symbol_scope_rep> new_rep)
     : m_rep (new_rep)
   { }
 
@@ -388,9 +397,19 @@
 
   ~symbol_scope () = default;
 
+  static symbol_scope invalid ()
+  {
+    return symbol_scope (std::shared_ptr<symbol_scope_rep> (nullptr));
+  }
+
+  static symbol_scope anonymous ()
+  {
+    return symbol_scope ("");
+  }
+
   bool is_valid () const { return bool (m_rep); }
 
-  explicit operator bool () const { return bool (m_rep); }
+  explicit operator bool () const { return is_valid (); }
 
   std::size_t num_symbols () const
   {
--- a/libinterp/corefcn/symtab.h	Thu Jan 25 09:24:44 2024 -0500
+++ b/libinterp/corefcn/symtab.h	Thu Jan 25 09:36:49 2024 -0500
@@ -85,12 +85,12 @@
 
   octave_value
   builtin_find (const std::string& name,
-                const symbol_scope& search_scope = symbol_scope ());
+                const symbol_scope& search_scope = symbol_scope::invalid ());
 
   octave_value
   fcn_table_find (const std::string& name,
                   const octave_value_list& args = ovl (),
-                  const symbol_scope& search_scope = symbol_scope ());
+                  const symbol_scope& search_scope = symbol_scope::invalid ());
 
   // If NAME is of the form @CLASS/FUNCTION, call
   //
@@ -102,7 +102,7 @@
 
   octave_value
   find_function (const std::string& name,
-                 const symbol_scope& search_scope = symbol_scope ());
+                 const symbol_scope& search_scope = symbol_scope::invalid ());
 
   // NAME should just be function name; dispatch type determined
   // from types of ARGS.
@@ -110,7 +110,7 @@
   octave_value
   find_function (const std::string& name,
                  const octave_value_list& args,
-                 const symbol_scope& search_scope = symbol_scope ());
+                 const symbol_scope& search_scope = symbol_scope::invalid ());
 
   octave_value find_user_function (const std::string& name);
 
--- a/libinterp/octave-value/ov-fcn.h	Thu Jan 25 09:24:44 2024 -0500
+++ b/libinterp/octave-value/ov-fcn.h	Thu Jan 25 09:36:49 2024 -0500
@@ -82,14 +82,14 @@
   virtual std::string parent_fcn_name () const { return ""; }
 
   virtual octave::symbol_scope parent_fcn_scope () const
-  { return octave::symbol_scope (); }
+  { return octave::symbol_scope::invalid (); }
 
   virtual std::list<std::string> parent_fcn_names () const
   { return std::list<std::string> (); }
 
   virtual void mark_fcn_file_up_to_date (const octave::sys::time&) { }
 
-  virtual octave::symbol_scope scope () { return octave::symbol_scope (); }
+  virtual octave::symbol_scope scope () { return octave::symbol_scope::invalid (); }
 
   virtual octave::sys::time time_parsed () const
   { return octave::sys::time (static_cast<OCTAVE_TIME_T> (0)); }
--- a/libinterp/octave-value/ov-usr-fcn.h	Thu Jan 25 09:24:44 2024 -0500
+++ b/libinterp/octave-value/ov-usr-fcn.h	Thu Jan 25 09:36:49 2024 -0500
@@ -59,7 +59,7 @@
 protected:
 
   octave_user_code (const std::string& fnm = "", const std::string& nm = "",
-                    const octave::symbol_scope& scope = octave::symbol_scope (),
+                    const octave::symbol_scope& scope = octave::symbol_scope::anonymous (),
                     octave::tree_statement_list *cmds = nullptr,
                     const std::string& ds = "")
     : octave_function (nm, ds), m_scope (scope), m_file_name (fnm),
@@ -154,12 +154,12 @@
   octave_user_script ();
 
   octave_user_script (const std::string& fnm, const std::string& nm,
-                      const octave::symbol_scope& scope = octave::symbol_scope (),
+                      const octave::symbol_scope& scope = octave::symbol_scope::anonymous (),
                       octave::tree_statement_list *cmds = nullptr,
                       const std::string& ds = "");
 
   octave_user_script (const std::string& fnm, const std::string& nm,
-                      const octave::symbol_scope& scope = octave::symbol_scope (),
+                      const octave::symbol_scope& scope = octave::symbol_scope::anonymous (),
                       const std::string& ds = "");
 
   OCTAVE_DISABLE_COPY_MOVE (octave_user_script)
@@ -204,7 +204,7 @@
 {
 public:
 
-  octave_user_function (const octave::symbol_scope& scope = octave::symbol_scope (),
+  octave_user_function (const octave::symbol_scope& scope = octave::symbol_scope::anonymous (),
                         octave::tree_parameter_list *pl = nullptr,
                         octave::tree_parameter_list *rl = nullptr,
                         octave::tree_statement_list *cl = nullptr);
--- a/libinterp/parse-tree/lex.ll	Thu Jan 25 09:24:44 2024 -0500
+++ b/libinterp/parse-tree/lex.ll	Thu Jan 25 09:36:49 2024 -0500
@@ -2146,7 +2146,7 @@
 
     return (sz > 1
             ? m_frame_stack[1]
-            : (sz == 1 ? m_frame_stack[0] : symbol_scope ()));
+            : (sz == 1 ? m_frame_stack[0] : symbol_scope::invalid ()));
   }
 
   lexical_feedback::~lexical_feedback ()
--- a/libinterp/parse-tree/oct-parse.yy	Thu Jan 25 09:24:44 2024 -0500
+++ b/libinterp/parse-tree/oct-parse.yy	Thu Jan 25 09:36:49 2024 -0500
@@ -1835,7 +1835,7 @@
                       }
 
                     // Create invalid parent scope.
-                    lexer.m_symtab_context.push (octave::symbol_scope ());
+                    lexer.m_symtab_context.push (octave::symbol_scope::anonymous ());
                     lexer.m_parsing_classdef = true;
                     lexer.m_parsing_classdef_decl = true;
                     lexer.m_classdef_element_names_are_keywords = true;
@@ -2453,7 +2453,7 @@
   public:
 
     parse_tree_validator ()
-      : m_scope (), m_error_list ()
+      : m_scope (symbol_scope::anonymous ()), m_error_list ()
     { }
 
     OCTAVE_DISABLE_COPY_MOVE (parse_tree_validator)
@@ -2614,7 +2614,7 @@
   symbol_scope
   base_parser::parent_scope_info::parent_scope () const
   {
-    return size () > 1 ? m_info[size()-2].first : symbol_scope ();
+    return size () > 1 ? m_info[size()-2].first : symbol_scope::invalid ();
   }
 
   std::string
@@ -2633,7 +2633,8 @@
     : m_endfunction_found (false), m_autoloading (false),
       m_fcn_file_from_relative_lookup (false),
       m_parsing_subfunctions (false), m_parsing_local_functions (false),
-      m_max_fcn_depth (-1), m_curr_fcn_depth (-1), m_primary_fcn_scope (),
+      m_max_fcn_depth (-1), m_curr_fcn_depth (-1),
+      m_primary_fcn_scope (symbol_scope::invalid ()),
       m_curr_class_name (), m_curr_package_name (), m_function_scopes (*this),
       m_primary_fcn (), m_subfunction_names (), m_classdef_object (),
       m_stmt_list (), m_lexer (lxr), m_parser_state (yypstate_new ())
@@ -2664,7 +2665,7 @@
     m_parsing_local_functions = false;
     m_max_fcn_depth = -1;
     m_curr_fcn_depth = -1;
-    m_primary_fcn_scope = symbol_scope ();
+    m_primary_fcn_scope = symbol_scope::invalid ();
     m_curr_class_name = "";
     m_curr_package_name = "";
     m_function_scopes.clear ();
@@ -4772,7 +4773,7 @@
             // Create a dummy function that is used until the real method
             // is loaded.
 
-            retval = new octave_user_function (symbol_scope (), pl);
+            retval = new octave_user_function (symbol_scope::anonymous (), pl);
 
             retval->stash_function_name (mname);
 
--- a/libinterp/parse-tree/pt-eval.cc	Thu Jan 25 09:24:44 2024 -0500
+++ b/libinterp/parse-tree/pt-eval.cc	Thu Jan 25 09:36:49 2024 -0500
@@ -3329,10 +3329,8 @@
   // FIXME: should CMD_LIST be limited to a single expression?
   // I think that is what Matlab does.
 
-  symbol_scope new_scope;
   symbol_scope scope = afh.scope ();
-  if (scope)
-    new_scope = scope.dup ();
+  symbol_scope new_scope = scope ? scope.dup () : symbol_scope::invalid ();
 
   tree_parameter_list *param_list = afh.parameter_list ();
   tree_parameter_list *param_list_dup
--- a/libinterp/parse-tree/pt-fcn-handle.cc	Thu Jan 25 09:24:44 2024 -0500
+++ b/libinterp/parse-tree/pt-fcn-handle.cc	Thu Jan 25 09:36:49 2024 -0500
@@ -81,10 +81,7 @@
   symbol_scope af_scope = m_scope;
   symbol_scope af_parent_scope = m_parent_scope;
 
-  symbol_scope new_scope;
-
-  if (af_scope)
-    new_scope = af_scope.dup ();
+  symbol_scope new_scope = af_scope ? af_scope.dup () : symbol_scope::invalid ();
 
   // FIXME: if new scope is nullptr, then we are in big trouble here...
 
--- a/libinterp/parse-tree/pt-fcn-handle.h	Thu Jan 25 09:24:44 2024 -0500
+++ b/libinterp/parse-tree/pt-fcn-handle.h	Thu Jan 25 09:36:49 2024 -0500
@@ -95,8 +95,8 @@
 
   tree_anon_fcn_handle (int l = -1, int c = -1)
     : tree_expression (l, c), m_parameter_list (nullptr),
-      m_expression (nullptr), m_scope (), m_parent_scope (),
-      m_file_name ()
+      m_expression (nullptr), m_scope (symbol_scope::anonymous ()),
+      m_parent_scope (symbol_scope::invalid ()), m_file_name ()
   { }
 
   tree_anon_fcn_handle (tree_parameter_list *pl, tree_expression *ex,