Mercurial > octave
changeset 27189:946c6f117091
use dummy stack frame when creating meta class (bug #55766 and #55768)
* pt-classdef.h (tree_classdef::m_scope): New data member.
(tree_classdef::tree_classdef): New arg, SCOPE.
* oct-parse.yy (base_parser::make_classdef): Pass current dummy scope
to tree_classdef constructor.
* cdef_class.cc (cdef_class::make_meta_class): Push dummy stack frame
when for expression evaluation while creating meta class object.
author | John W. Eaton <jwe@octave.org> |
---|---|
date | Sat, 15 Jun 2019 11:04:52 -0500 |
parents | 792fe198c105 |
children | 8ebe70b98e97 |
files | libinterp/octave-value/cdef-class.cc libinterp/parse-tree/oct-parse.yy libinterp/parse-tree/pt-classdef.h |
diffstat | 3 files changed, 26 insertions(+), 5 deletions(-) [+] |
line wrap: on
line diff
--- a/libinterp/octave-value/cdef-class.cc Fri Jun 14 15:34:44 2019 -0500 +++ b/libinterp/octave-value/cdef-class.cc Sat Jun 15 11:04:52 2019 -0500 @@ -49,6 +49,7 @@ #include "pt-misc.h" #include "pt-stmt.h" #include "pt-walk.h" +#include "unwind-prot.h" // Define to 1 to enable debugging statements. #define DEBUG_TRACE 0 @@ -861,6 +862,18 @@ std::cerr << "class: " << full_class_name << std::endl; #endif + // Push a dummy scope frame on the call stack that corresponds to + // the scope that was used when parsing classdef object. Without + // this, we may pick up stray values from the current scope when + // evaluating expressions found in things like attribute lists. + + unwind_protect frame; + + tree_evaluator& tw = interp.get_evaluator (); + + tw.push_dummy_scope (full_class_name); + frame.add_method (tw, &octave::tree_evaluator::pop_scope); + std::list<cdef_class> slist; if (t->superclass_list ()) @@ -899,8 +912,6 @@ // Class attributes - tree_evaluator& tw = interp.get_evaluator (); - if (t->attribute_list ()) { for (const auto& attr : (*t->attribute_list ()))
--- a/libinterp/parse-tree/oct-parse.yy Fri Jun 14 15:34:44 2019 -0500 +++ b/libinterp/parse-tree/oct-parse.yy Sat Jun 15 11:04:52 2019 -0500 @@ -3624,7 +3624,8 @@ if (! body) body = new tree_classdef_body (); - retval = new tree_classdef (a, id, sc, body, lc, tc, + retval = new tree_classdef (m_lexer.m_symtab_context.curr_scope (), + a, id, sc, body, lc, tc, m_curr_package_name, l, c); } else
--- a/libinterp/parse-tree/pt-classdef.h Fri Jun 14 15:34:44 2019 -0500 +++ b/libinterp/parse-tree/pt-classdef.h Sat Jun 15 11:04:52 2019 -0500 @@ -727,13 +727,14 @@ { public: - tree_classdef (tree_classdef_attribute_list *a, tree_identifier *i, + tree_classdef (const octave::symbol_scope& scope, + tree_classdef_attribute_list *a, tree_identifier *i, tree_classdef_superclass_list *sc, tree_classdef_body *b, comment_list *lc, comment_list *tc, const std::string& pn = "", int l = -1, int c = -1) - : tree_command (l, c), m_attr_list (a), m_id (i), + : tree_command (l, c), m_scope (scope), m_attr_list (a), m_id (i), m_supclass_list (sc), m_element_list (b), m_lead_comm (lc), m_trail_comm (tc), m_pack_name (pn) { } @@ -754,6 +755,8 @@ delete m_trail_comm; } + octave::symbol_scope scope (void) { return m_scope; } + tree_classdef_attribute_list * attribute_list (void) { return m_attr_list; } @@ -779,6 +782,12 @@ private: + // The scope that was used when parsing the classdef object and that + // corresponds to any identifiers that were found in attribute lists + // (for example). Used again when computing the meta class object. + + octave::symbol_scope m_scope; + tree_classdef_attribute_list *m_attr_list; tree_identifier *m_id;