Mercurial > octave
changeset 32862:833f3d9bdf1a stable
Don't treat parent class constructor as inherited class method (bug #65037)
* fcn-info.cc (fcn_info::fcn_info_rep::find_method): Ignore any
methods that are actually parent class constructors.
* ov-classdef.cc (octave_classdef_meta::is_classdef_constructor):
Also consider methods and parent classes.
* test/bug-65037/bug-65037.tst, test/bug-65037/bug65037_base.m,
test/bug-65037/bug65037_derived.m, test/bug-65037/module.mk:
New test files.
* test/Makefile.am: Update.
author | John W. Eaton <jwe@octave.org> |
---|---|
date | Fri, 12 Jan 2024 16:28:48 -0500 |
parents | 0847c124488a |
children | 0c9675a32703 25784f22ead3 |
files | libinterp/corefcn/fcn-info.cc libinterp/octave-value/ov-classdef.cc test/Makefile.am test/bug-65037/bug-65037.tst test/bug-65037/bug65037_base.m test/bug-65037/bug65037_derived.m test/bug-65037/module.mk |
diffstat | 7 files changed, 78 insertions(+), 17 deletions(-) [+] |
line wrap: on
line diff
--- a/libinterp/corefcn/fcn-info.cc Fri Jan 26 14:19:39 2024 +0100 +++ b/libinterp/corefcn/fcn-info.cc Fri Jan 12 16:28:48 2024 -0500 @@ -972,28 +972,33 @@ auto q = class_methods.find (dispatch_type); if (q == class_methods.end ()) - { - octave_value val = load_class_method (dispatch_type); - - if (val.is_defined ()) - return val; - } + retval = load_class_method (dispatch_type); else { - octave_value& fval = q->second; + retval = q->second; - if (fval.is_defined ()) - out_of_date_check (fval, dispatch_type); + if (retval.is_defined ()) + out_of_date_check (retval, dispatch_type); + + if (! retval.is_defined ()) + retval = load_class_method (dispatch_type); + } - if (fval.is_defined ()) - return fval; - else - { - octave_value val = load_class_method (dispatch_type); + // Ignore any classdef constructors that were found by + // load_class_method above, either for dispatch_type or any + // superclasses of that class. - if (val.is_defined ()) - return val; - } + // FIXME: Maybe there is a better way of managing classdef + // constructors (which may actually be octave_classdef_meta objects) + // so they don't appear in both the class_methods and + // class_constructors maps? + + if (retval.is_classdef_meta ()) + { + octave_function *fcn = retval.function_value (); + + if (fcn && fcn->is_classdef_constructor (dispatch_type)) + retval = octave_value (); } return retval;
--- a/libinterp/octave-value/ov-classdef.cc Fri Jan 26 14:19:39 2024 +0100 +++ b/libinterp/octave-value/ov-classdef.cc Fri Jan 12 16:28:48 2024 -0500 @@ -476,6 +476,29 @@ retval = true; } } + else if (m_object.is_method ()) + { + octave::cdef_method meth (m_object); + + if (meth.is_constructor ()) + { + std::string meth_name = meth.get_name (); + + // Only consider METH to be a constructor if the dispatch + // class CNAME is the same as or derived from the class of + // METH. + + if (cname == meth_name) + retval = true; + else + { + octave::cdef_class meth_cls = octave::lookup_class (meth_name, false, false); + octave::cdef_class dispatch_cls = octave::lookup_class (cname, false, false); + + retval = octave::is_superclass (meth_cls, dispatch_cls); + } + } + } return retval; }
--- a/test/Makefile.am Fri Jan 26 14:19:39 2024 +0100 +++ b/test/Makefile.am Fri Jan 12 16:28:48 2024 -0500 @@ -110,6 +110,7 @@ include bug-61105/module.mk include bug-61191/module.mk include bug-63841/module.mk +include bug-65037/module.mk include class-concat/module.mk include classdef/module.mk include classdef-debug/module.mk
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/bug-65037/bug-65037.tst Fri Jan 12 16:28:48 2024 -0500 @@ -0,0 +1,9 @@ +%!test <65037> +%! base_1 = bug65037_base ('base class arg'); +%! derived = bug65037_derived ('derived class arg'); +%! base_2 = bug65037_base (base_1); +%! base_3 = bug65037_base (derived); +%! assert (base_1.ctor_nargin, 1); +%! assert (derived.ctor_nargin, 1); +%! assert (base_2.ctor_nargin, 1); +%! assert (base_3.ctor_nargin, 1);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/bug-65037/bug65037_base.m Fri Jan 12 16:28:48 2024 -0500 @@ -0,0 +1,10 @@ +classdef bug65037_base + properties + ctor_nargin; + end + methods + function obj = bug65037_base (varargin) + obj.ctor_nargin = nargin; + end + end +end