octave-bug-tracker
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Octave-bug-tracker] [bug #59602] incorrect "not a direct superclass" er


From: Rik
Subject: [Octave-bug-tracker] [bug #59602] incorrect "not a direct superclass" error
Date: Thu, 3 Dec 2020 15:08:15 -0500 (EST)
User-agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Safari/537.36

Follow-up Comment #6, bug #59602 (project octave):

This is really ugly, but I know a bit more about what is happening.  The root
cause is that two different calls to lookup_class are returning different
values when they should be returning the same thing.

The function lookup_class is overloaded and there are three versions.


  cdef_class
  lookup_class (const std::string& name, bool error_if_not_found,
                bool load_if_not_found)
  {
    cdef_manager& cdm = __get_cdef_manager__ ("lookup_class");

    return cdm.find_class (name, error_if_not_found, load_if_not_found);
  }

  cdef_class
  lookup_class (const cdef_class& cls)
  {
    // FIXME: placeholder for the time being, the purpose
    //        is to centralized any class update activity here.

    return cls;
  }

  cdef_class
  lookup_class (const octave_value& ov)
  {
    if (ov.is_string())
      return lookup_class (ov.string_value ());
    else
      {
        cdef_class cls (to_cdef (ov));

        return lookup_class (cls);
      }

    return cdef_class ();
  }


The first call to lookup_class uses a string as the argument.  The second
call, however, does not.  The code first gets a Cell array by querying the
SuperClasses field.  The individual entries of the Cell array are not the
string names of the superclasses, but rather meta.class objects wrapped inside
an octave_value.  This calls the third version of lookup_class where the input
is an octave_value.

The third version determines that the octave_value is not a string
(ov.is_string()) and therefore attempts a direct conversion from octave_value
to cdef_object.  The code for that is


  cdef_object
  to_cdef (const octave_value& val)
  {
    if (val.type_name () != "object")
      error ("cannot convert '%s' into 'object'", val.type_name().c_str ());

    return dynamic_cast<octave_classdef *> (val.internal_rep ())->get_object
();
  }


This looks problematic.  Octave is trying to dynamically convert a meta.class
object into a classB object and my guess is that the conversion doesn't work
perfectly.

When execution returns to the third version of lookup_class it creates a new
class from the object returned from to_cdef.  For whatever reason, the
cdef_class constructor is then creating and installing a new class with
cdef_manager such that they have different memory addresses.


        cdef_class cls (to_cdef (ov));


Long term, I think we need to untangle this code because it is so complex I
can't guarantee there aren't many other subtle problems here.

In the short term, for this bug report, it would probably be enough to change
is_superclass() to call lookup_class (std::string).  In order to do that, we
would need to get the Name field from the meta.class object wrapped inside an
octave_value.  I'm not sure how to do that, but it should be more
straightforward than dynamic_casting.

    _______________________________________________________

Reply to this item at:

  <https://savannah.gnu.org/bugs/?59602>

_______________________________________________
  Message sent via Savannah
  https://savannah.gnu.org/




reply via email to

[Prev in Thread] Current Thread [Next in Thread]