compiler: Issue channel type errors earlier.
authorian <ian@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 17 Sep 2015 13:57:40 +0000 (13:57 +0000)
committerian <ian@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 17 Sep 2015 13:57:40 +0000 (13:57 +0000)
    When asking for the type of a receive operation, the compiler would
    return an error type if the receive operator was being used on an
    invalid channel type and the error would be reported in a later pass.
    There are several ways that the type checking pass would not see
    the original node and fail to issue the error.  This patch modifies
    receive operations to give an error immediately once it is known that
    the channel type is invalid.

    Fixes golang/go#12323.

    Reviewed-on: https://go-review.googlesource.com/13987

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@227863 138bc75d-0d04-0410-961f-82ee72b054a4

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

index c150747..f21c43a 100644 (file)
@@ -1,4 +1,4 @@
-1cb26dc898bda1e85f4dd2ee204adbce792e4813
+e069d4417a692c1261df99fe3323277e1a0193d2
 
 The first line of this file holds the git revision number of the last
 merge done from the gofrontend repository.
index 542f3de..7ad271f 100644 (file)
@@ -13502,9 +13502,14 @@ Expression::make_heap_expression(Expression* expr, Location location)
 Type*
 Receive_expression::do_type()
 {
+  if (this->is_error_expression())
+    return Type::make_error_type();
   Channel_type* channel_type = this->channel_->type()->channel_type();
   if (channel_type == NULL)
-    return Type::make_error_type();
+    {
+      this->report_error(_("expected channel"));
+      return Type::make_error_type();
+    }
   return channel_type->element_type();
 }
 
@@ -13516,6 +13521,7 @@ Receive_expression::do_check_types(Gogo*)
   Type* type = this->channel_->type();
   if (type->is_error())
     {
+      go_assert(saw_errors());
       this->set_is_error();
       return;
     }
index 5d102bf..a84203a 100644 (file)
@@ -3856,7 +3856,10 @@ Switch_statement::do_lower(Gogo*, Named_object*, Block* enclosing,
   if (this->val_ != NULL
       && (this->val_->is_error_expression()
          || this->val_->type()->is_error()))
-    return Statement::make_error_statement(loc);
+    {
+      go_assert(saw_errors());
+      return Statement::make_error_statement(loc);
+    }
 
   if (this->val_ != NULL
       && this->val_->type()->integer_type() != NULL