OSDN Git Service

compiler: Fix crash in go/defer of some builtin functions.
authorian <ian@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 4 Dec 2012 05:17:43 +0000 (05:17 +0000)
committerian <ian@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 4 Dec 2012 05:17:43 +0000 (05:17 +0000)
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/gcc-4_7-branch@194113 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/go/gofrontend/expressions.cc
gcc/go/gofrontend/expressions.h
gcc/go/gofrontend/statements.cc

index 5358a7d..cceb60b 100644 (file)
@@ -89,10 +89,11 @@ Expression::do_traverse(Traverse*)
 // expression is being discarded.  By default, we give an error.
 // Expressions with side effects override.
 
-void
+bool
 Expression::do_discarding_value()
 {
   this->unused_value_error();
+  return false;
 }
 
 // This virtual function is called to export expressions.  This will
@@ -109,7 +110,7 @@ Expression::do_export(Export*) const
 void
 Expression::unused_value_error()
 {
-  error_at(this->location(), "value computed is not used");
+  this->report_error(_("value computed is not used"));
 }
 
 // Note that this expression is an error.  This is called by children
@@ -789,9 +790,9 @@ class Error_expression : public Expression
     return true;
   }
 
-  void
+  bool
   do_discarding_value()
-  { }
+  { return true; }
 
   Type*
   do_type()
@@ -1152,9 +1153,9 @@ class Sink_expression : public Expression
   { }
 
  protected:
-  void
+  bool
   do_discarding_value()
-  { }
+  { return true; }
 
   Type*
   do_type();
@@ -5323,13 +5324,19 @@ Binary_expression::do_numeric_constant_value(Numeric_constant* nc) const
 
 // Note that the value is being discarded.
 
-void
+bool
 Binary_expression::do_discarding_value()
 {
   if (this->op_ == OPERATOR_OROR || this->op_ == OPERATOR_ANDAND)
-    this->right_->discarding_value();
+    {
+      this->right_->discarding_value();
+      return true;
+    }
   else
-    this->unused_value_error();
+    {
+      this->unused_value_error();
+      return false;
+    }
 }
 
 // Get type.
@@ -6528,7 +6535,7 @@ class Builtin_call_expression : public Call_expression
   bool
   do_numeric_constant_value(Numeric_constant*) const;
 
-  void
+  bool
   do_discarding_value();
 
   Type*
@@ -7330,7 +7337,7 @@ Builtin_call_expression::do_numeric_constant_value(Numeric_constant* nc) const
 // discarding the value of an ordinary function call, but we do for
 // builtin functions, purely for consistency with the gc compiler.
 
-void
+bool
 Builtin_call_expression::do_discarding_value()
 {
   switch (this->code_)
@@ -7351,7 +7358,7 @@ Builtin_call_expression::do_discarding_value()
     case BUILTIN_OFFSETOF:
     case BUILTIN_SIZEOF:
       this->unused_value_error();
-      break;
+      return false;
 
     case BUILTIN_CLOSE:
     case BUILTIN_COPY:
@@ -7360,7 +7367,7 @@ Builtin_call_expression::do_discarding_value()
     case BUILTIN_PRINT:
     case BUILTIN_PRINTLN:
     case BUILTIN_RECOVER:
-      break;
+      return true;
     }
 }
 
index 63769dc..1b74b80 100644 (file)
@@ -360,10 +360,11 @@ class Expression
 
   // This is called if the value of this expression is being
   // discarded.  This issues warnings about computed values being
-  // unused.
-  void
+  // unused.  This returns true if all is well, false if it issued an
+  // error message.
+  bool
   discarding_value()
-  { this->do_discarding_value(); }
+  { return this->do_discarding_value(); }
 
   // Return whether this is an error expression.
   bool
@@ -689,7 +690,7 @@ class Expression
   { return false; }
 
   // Called by the parser if the value is being discarded.
-  virtual void
+  virtual bool
   do_discarding_value();
 
   // Child class holds type.
@@ -1205,7 +1206,7 @@ class Binary_expression : public Expression
   bool
   do_numeric_constant_value(Numeric_constant*) const;
 
-  void
+  bool
   do_discarding_value();
 
   Type*
@@ -1373,9 +1374,9 @@ class Call_expression : public Expression
   virtual Expression*
   do_lower(Gogo*, Named_object*, Statement_inserter*, int);
 
-  void
+  bool
   do_discarding_value()
-  { }
+  { return true; }
 
   virtual Type*
   do_type();
@@ -2051,9 +2052,9 @@ class Receive_expression : public Expression
   do_traverse(Traverse* traverse)
   { return Expression::traverse(&this->channel_, traverse); }
 
-  void
+  bool
   do_discarding_value()
-  { }
+  { return true; }
 
   Type*
   do_type();
index af34670..58057f8 100644 (file)
@@ -2006,6 +2006,8 @@ Thunk_statement::do_determine_types()
 void
 Thunk_statement::do_check_types(Gogo*)
 {
+  if (!this->call_->discarding_value())
+    return;
   Call_expression* ce = this->call_->call_expression();
   if (ce == NULL)
     {
@@ -2471,11 +2473,15 @@ Thunk_statement::build_thunk(Gogo* gogo, const std::string& thunk_name)
       Expression_statement* es =
        static_cast<Expression_statement*>(call_statement);
       Call_expression* ce = es->expr()->call_expression();
-      go_assert(ce != NULL);
-      if (may_call_recover)
-       ce->set_is_deferred();
-      if (recover_arg != NULL)
-       ce->set_recover_arg(recover_arg);
+      if (ce == NULL)
+       go_assert(saw_errors());
+      else
+       {
+         if (may_call_recover)
+           ce->set_is_deferred();
+         if (recover_arg != NULL)
+           ce->set_recover_arg(recover_arg);
+       }
     }
 
   // That is all the thunk has to do.