changeset 12171:d08901c05c1b

fix bug in class assignment to undefined object with index
author John W. Eaton <jwe@octave.org>
date Wed, 26 Jan 2011 20:39:15 -0500
parents 037f8b7608f3
children 2ba904181687
files src/ChangeLog src/ov-base.cc src/ov-base.h src/ov-class.cc src/ov-class.h src/ov.cc src/ov.h
diffstat 7 files changed, 74 insertions(+), 4 deletions(-) [+]
line wrap: on
line diff
--- a/src/ChangeLog	Wed Jan 26 17:58:07 2011 -0500
+++ b/src/ChangeLog	Wed Jan 26 20:39:15 2011 -0500
@@ -1,5 +1,17 @@
 2011-01-26  John W. Eaton  <jwe@octave.org>
 
+	Bug #32242.
+
+	* ov.h, ov.cc (octave_value::undef_subsasgn): New function.
+	* ov-class.h, ov-class.cc (octave_class::undef_subsasgn,
+	octave_class::subsasgn_common): New functions.
+	* ov-base.h, ov-base.cc (octave_base_value::subsasgn): If
+	undefined, undef_subsasgn on object returned by
+	octave_value::empty_conv.
+	(octave_base_value::undef_subsasgn): New virtual function.
+	(octave_base_value::subsasgn): Only handle case of undefined
+	values here.
+
 2011-01-26  Pascal Dupuis  <Pascal.Dupuis@worldonline.be>
 	    John W. Eaton  <jwe@octave.org>
 
--- a/src/ov-base.cc	Wed Jan 26 17:58:07 2011 -0500
+++ b/src/ov-base.cc	Wed Jan 26 20:39:15 2011 -0500
@@ -278,16 +278,27 @@
   else
     {
       // Create new object of appropriate type for given index and rhs
-      // types and then call subsasgn again for that object.
+      // types and then call undef_subsasgn for that object.
 
       octave_value tmp = octave_value::empty_conv (type, rhs);
 
-      retval = tmp.subsasgn (type, idx, rhs);
+      retval = tmp.undef_subsasgn (type, idx, rhs);
     }
 
   return retval;
 }
 
+octave_value
+octave_base_value::undef_subsasgn (const std::string& type,
+                                   const std::list<octave_value_list>& idx,
+                                   const octave_value& rhs)
+{
+  // In most cases, undef_subsasgn is handled the sams as subsasgn.  One
+  // exception is octave_class objects.
+
+  return subsasgn (type, idx, rhs);
+}
+
 octave_idx_type
 octave_base_value::nnz (void) const
 {
--- a/src/ov-base.h	Wed Jan 26 17:58:07 2011 -0500
+++ b/src/ov-base.h	Wed Jan 26 20:39:15 2011 -0500
@@ -281,6 +281,11 @@
             const std::list<octave_value_list>& idx,
             const octave_value& rhs);
 
+  virtual octave_value
+  undef_subsasgn (const std::string& type,
+                  const std::list<octave_value_list>& idx,
+                  const octave_value& rhs);
+
   virtual idx_vector index_vector (void) const;
 
   virtual dim_vector dims (void) const { return dim_vector (); }
--- a/src/ov-class.cc	Wed Jan 26 17:58:07 2011 -0500
+++ b/src/ov-class.cc	Wed Jan 26 20:39:15 2011 -0500
@@ -504,6 +504,28 @@
                         const std::list<octave_value_list>& idx,
                         const octave_value& rhs)
 {
+  count++;
+  return subsasgn_common (octave_value (this), type, idx, rhs);
+}
+
+octave_value
+octave_class::undef_subsasgn (const std::string& type,
+                              const std::list<octave_value_list>& idx,
+                              const octave_value& rhs)
+{
+  // For compatibility with Matlab, pass [] as the first argument to the
+  // the subsasgn function when the LHS of an indexed assignment is
+  // undefined.
+
+  return subsasgn_common (Matrix (), type, idx, rhs);
+}
+
+octave_value
+octave_class::subsasgn_common (const octave_value& obj,
+                               const std::string& type,
+                               const std::list<octave_value_list>& idx,
+                               const octave_value& rhs)
+{
   octave_value retval;
 
   if (! (in_class_method () || called_from_builtin ()))
@@ -529,8 +551,7 @@
           if (error_state)
             return octave_value_list ();
 
-          count++;
-          args(0) = octave_value (this);
+          args(0) = obj;
 
           // Now comes the magic. Count copies with me:
           // 1. myself (obsolete)
--- a/src/ov-class.h	Wed Jan 26 17:58:07 2011 -0500
+++ b/src/ov-class.h	Wed Jan 26 20:39:15 2011 -0500
@@ -104,6 +104,10 @@
                          const std::list<octave_value_list>& idx,
                          const octave_value& rhs);
 
+  octave_value undef_subsasgn (const std::string& type,
+                               const std::list<octave_value_list>& idx,
+                               const octave_value& rhs);
+
   idx_vector index_vector (void) const;
 
   dim_vector dims (void) const { return map.dims (); }
@@ -206,6 +210,11 @@
   bool in_class_method (void);
   std::string get_current_method_class (void);
 
+  octave_value subsasgn_common (const octave_value& obj,
+                                const std::string& type,
+                                const std::list<octave_value_list>& idx,
+                                const octave_value& rhs);
+
   int obsolete_copies;
 
 public:
--- a/src/ov.cc	Wed Jan 26 17:58:07 2011 -0500
+++ b/src/ov.cc	Wed Jan 26 20:39:15 2011 -0500
@@ -1300,6 +1300,14 @@
   return rep->subsasgn (type, idx, rhs);
 }
 
+octave_value
+octave_value::undef_subsasgn (const std::string& type,
+                              const std::list<octave_value_list>& idx,
+                              const octave_value& rhs)
+{
+  return rep->undef_subsasgn (type, idx, rhs);
+}
+
 octave_value&
 octave_value::assign (assign_op op, const std::string& type,
                       const std::list<octave_value_list>& idx,
--- a/src/ov.h	Wed Jan 26 17:58:07 2011 -0500
+++ b/src/ov.h	Wed Jan 26 20:39:15 2011 -0500
@@ -423,6 +423,10 @@
                                  const std::list<octave_value_list>& idx,
                                  const octave_value& rhs);
 
+  octave_value undef_subsasgn (const std::string& type,
+                               const std::list<octave_value_list>& idx,
+                               const octave_value& rhs);
+
   octave_value& assign (assign_op op, const std::string& type,
                        const std::list<octave_value_list>& idx,
                        const octave_value& rhs);