changeset 29832:6d1224698acf stable

fix scoping issue for handles to sibling nested functions (bug #60845) * pt-eval.cc (tree_evaluator::make_fcn_handle): Also use parent stack frame as context for handle to nested function when the function is a sibling of the current function. * bug60845.m, handle-to-sibling.tst: New test files. * test/fcn-handle/module.mk: Update.
author John W. Eaton <jwe@octave.org>
date Tue, 29 Jun 2021 05:25:34 -0400
parents 290eff7148bb
children f0da0d901d8e 1a7ed0751cd6
files libinterp/parse-tree/pt-eval.cc test/fcn-handle/bug60845.m test/fcn-handle/handle-to-sibling.tst test/fcn-handle/module.mk
diffstat 4 files changed, 65 insertions(+), 8 deletions(-) [+]
line wrap: on
line diff
--- a/libinterp/parse-tree/pt-eval.cc	Mon Jun 28 10:30:11 2021 +0200
+++ b/libinterp/parse-tree/pt-eval.cc	Tue Jun 29 05:25:34 2021 -0400
@@ -1148,14 +1148,20 @@
                       = m_call_stack.get_current_stack_frame ();
 
                     // If we are creating a handle to the current
-                    // function, then use the calling stack frame as the
-                    // context.
-
-                    std::string curr_fcn_name;
-                    if (curr_fcn)
-                      curr_fcn_name = curr_fcn->name ();
-
-                    if (fcn_name == curr_fcn_name)
+                    // function or a handle to a sibling function (i.e.,
+                    // not a child of the current function), then use
+                    // the calling stack frame as the context instead of
+                    // the current stack frame.
+
+                    // FIXME:  Do we need both checks here or is it
+                    // sufficient to check that the parent of curr_fcn
+                    // is the same as the parent of fcn?  Is there any
+                    // case where curr_fcn could be nullptr, or does
+                    // that indicate an internal error of some kind?
+
+                    if (curr_fcn
+                        && (fcn_name == curr_fcn->name ()
+                            || fcn->parent_fcn_name () == curr_fcn->parent_fcn_name ()))
                       frame = frame->access_link ();
 
                     octave_fcn_handle *fh
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/fcn-handle/bug60845.m	Tue Jun 29 05:25:34 2021 -0400
@@ -0,0 +1,23 @@
+function output = bug60845 (varargin)
+  ## ahandle is a boolean variable
+  [Ahandle, static, fcn_handle] = checkInput (varargin{:});
+
+  ## execute nested function using handle
+  output = fcn_handle ();
+
+  function [Ahandle, static, fcn_handle] = checkInput (varargin)
+    ## initialize
+    Ahandle = true;
+    static = false;
+    ## get a handle to nested (sibling) function.
+    fcn_handle = @nestfcn;
+  endfunction
+
+  function r = nestfcn ()
+    if (islogical (Ahandle))
+      r = true;
+    else
+      r = false;
+    end
+  endfunction
+endfunction
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/fcn-handle/handle-to-sibling.tst	Tue Jun 29 05:25:34 2021 -0400
@@ -0,0 +1,26 @@
+########################################################################
+##
+## Copyright (C) 2020-2021 The Octave Project Developers
+##
+## See the file COPYRIGHT.md in the top-level directory of this
+## distribution or <https://octave.org/copyright/>.
+##
+## This file is part of Octave.
+##
+## Octave is free software: you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation, either version 3 of the License, or
+## (at your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+## GNU General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <https://www.gnu.org/licenses/>.
+##
+########################################################################
+
+%!assert <60845> (bug60845 (), true)
--- a/test/fcn-handle/module.mk	Mon Jun 28 10:30:11 2021 +0200
+++ b/test/fcn-handle/module.mk	Tue Jun 29 05:25:34 2021 -0400
@@ -18,8 +18,10 @@
   %reldir%/bug57941a.m \
   %reldir%/bug57941b.m \
   %reldir%/bug58519.tst \
+  %reldir%/bug60845.m \
   %reldir%/derived-resolution.tst \
   %reldir%/f1.m \
+  %reldir%/handle-to-sibling.m \
   %reldir%/keyword.tst \
   %reldir%/object-method.tst \
   %reldir%/package-function.tst \