Patchwork Go patch committed: Fix named results when cloning

login
register
mail settings
Submitter Ian Taylor
Date Dec. 22, 2010, 3:11 p.m.
Message ID <mcr4oa5j116.fsf@google.com>
Download mbox | patch
Permalink /patch/76417/
State New
Headers show

Comments

Ian Taylor - Dec. 22, 2010, 3:11 p.m.
This patch to the Go frontend fixes the handling of named result
variables when cloning a function which calls recover.  The compiler was
failing to updating the backpointer from the named result variable to
the function.  Bootstrapped and ran Go testsuite on
x86_64-unknown-linux-gnu.  Committed to mainline.

Ian

Patch

diff -r bf3edc9b2487 go/gogo.cc
--- a/go/gogo.cc	Tue Dec 21 22:32:27 2010 -0800
+++ b/go/gogo.cc	Wed Dec 22 07:06:02 2010 -0800
@@ -2177,6 +2177,10 @@ 
   Convert_recover convert_recover(can_recover_no);
   new_func->traverse(&convert_recover);
 
+  // Update the function pointers in any named results.
+  new_func->update_named_result_variables();
+  orig_func->update_named_result_variables();
+
   return TRAVERSE_CONTINUE;
 }
 
@@ -2505,6 +2509,21 @@ 
     }
 }
 
+// Update the named result variables when cloning a function which
+// calls recover.
+
+void
+Function::update_named_result_variables()
+{
+  if (this->named_results_ == NULL)
+    return;
+
+  for (Named_results::iterator p = this->named_results_->begin();
+       p != this->named_results_->end();
+       ++p)
+    (*p)->result_var_value()->set_function(this);
+}
+
 // Return the closure variable, creating it if necessary.
 
 Named_object*
diff -r bf3edc9b2487 go/gogo.h
--- a/go/gogo.h	Tue Dec 21 22:32:27 2010 -0800
+++ b/go/gogo.h	Wed Dec 22 07:06:02 2010 -0800
@@ -787,6 +787,11 @@ 
   void
   create_named_result_variables(Gogo*);
 
+  // Update the named result variables when cloning a function which
+  // calls recover.
+  void
+  update_named_result_variables();
+
   // Add a new field to the closure variable.
   void
   add_closure_field(Named_object* var, source_location loc)
@@ -1318,6 +1323,12 @@ 
   is_in_heap() const
   { return this->is_address_taken_; }
 
+  // Set the function.  This is used when cloning functions which call
+  // recover.
+  void
+  set_function(Function* function)
+  { this->function_ = function; }
+
  private:
   // Type of result variable.
   Type* type_;