Mercurial > octave
changeset 26924:ab9520ef3895
ensure classdef dtor doesn't wipe out expression value (bug #53844, bug #55758)
* pt-eval.cc (tree_evaluator::visit_index_expression): Delete any
temporary values from intermediate expression evaluations prior to
pushing final result value(s).
* test/bug-55758/bug-55758.tst, test/bug-55758/class_bug_55758.m,
test/bug-55758/module.mk: New files.
author | John W. Eaton <jwe@octave.org> |
---|---|
date | Fri, 15 Mar 2019 17:26:12 +0000 |
parents | c81b471cdb28 |
children | 7fdbb03d5f76 |
files | libinterp/parse-tree/pt-eval.cc test/bug-55758/bug-55758.tst test/bug-55758/class_bug_55758.m test/bug-55758/module.mk test/module.mk |
diffstat | 5 files changed, 64 insertions(+), 0 deletions(-) [+] |
line wrap: on
line diff
--- a/libinterp/parse-tree/pt-eval.cc Fri Mar 15 10:37:21 2019 -0700 +++ b/libinterp/parse-tree/pt-eval.cc Fri Mar 15 17:26:12 2019 +0000 @@ -2257,6 +2257,12 @@ { // No more indices, so we are done. + // See note at end of function about deleting + // temporaries prior to pushing result. + + base_expr_val = octave_value (); + first_args = octave_value_list (); + push_result (retval); return; } @@ -2444,6 +2450,19 @@ } } + // Delete any temporary values prior to pushing the result and + // returning so that destructors for any temporary classdef handle + // objects will be called before we return. Otherwise, the + // destructor may push result values that will wipe out the result + // that we push below. Although the method name is "push_result" + // there is only a single register (either an octave_value or an + // octave_value_list) not a stack. + + idx.clear (); + partial_expr_val = octave_value (); + base_expr_val = octave_value (); + val = octave_value (); + push_result (retval); }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/bug-55758/bug-55758.tst Fri Mar 15 17:26:12 2019 +0000 @@ -0,0 +1,16 @@ +%!test +%! global class_bug_55758_dtor_called +%! class_bug_55758_dtor_called = false; +%! +%! assert (class_bug_55758 (5).value, 5); +%! assert (class_bug_55758_dtor_called); +%! +%! assert (class_bug_55758 (5)(1), 5); +%! assert (class_bug_55758_dtor_called); +%! +%! assert (size (class_bug_55758 (5)), [1, 1]); +%! assert (class_bug_55758_dtor_called); +%! +%! assert (numel (class_bug_55758 (5)), 1); +%! assert (class_bug_55758_dtor_called); +%! clear -global class_bug_55758_dtor_called; # cleanup after test
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/bug-55758/class_bug_55758.m Fri Mar 15 17:26:12 2019 +0000 @@ -0,0 +1,23 @@ +classdef class_bug_55758 < handle + properties + value + endproperties + + methods + function self = class_bug_55758 (val) + if (nargin < 1) + val = 0; + endif + self.value = val; + endfunction + + function delete (self) + global class_bug_55758_dtor_called; + class_bug_55758_dtor_called = true; + endfunction + + function ret = subsref (self, idx) + ret = self.value; + endfunction + endmethods +endclassdef
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/bug-55758/module.mk Fri Mar 15 17:26:12 2019 +0000 @@ -0,0 +1,5 @@ +bug_55758_TEST_FILES = \ + %reldir%/bug-55758.tst \ + %reldir%/class_bug_55758.m + +TEST_FILES += $(bug_55758_TEST_FILES)
--- a/test/module.mk Fri Mar 15 10:37:21 2019 -0700 +++ b/test/module.mk Fri Mar 15 17:26:12 2019 +0000 @@ -78,6 +78,7 @@ include %reldir%/bug-53027/module.mk include %reldir%/bug-53468/module.mk include %reldir%/bug-54995/module.mk +include %reldir%/bug-55758/module.mk include %reldir%/class-concat/module.mk include %reldir%/classdef/module.mk include %reldir%/classdef-multiple-inheritance/module.mk