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
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/bug-65037/bug65037_derived.m	Fri Jan 12 16:28:48 2024 -0500
@@ -0,0 +1,7 @@
+classdef bug65037_derived < bug65037_base
+  methods
+    function obj = bug65037_derived (varargin)
+      obj@bug65037_base (varargin{:});
+    end
+  end
+end
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/bug-65037/module.mk	Fri Jan 12 16:28:48 2024 -0500
@@ -0,0 +1,6 @@
+bug_65037_TEST_FILES = \
+  %reldir%/bug-65037.tst \
+  %reldir%/bug65037_base.m \
+  %reldir%/bug65037_derived.m
+
+TEST_FILES += $(bug_65037_TEST_FILES)