OSDN Git Service

Don't incorrectly parse expression as type switch.
authorian <ian@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 14 Dec 2010 05:54:33 +0000 (05:54 +0000)
committerian <ian@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 14 Dec 2010 05:54:33 +0000 (05:54 +0000)
Improve error reporting of invalid type assertions.

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

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

index 022f5ce..6320f09 100644 (file)
@@ -11620,24 +11620,29 @@ Type_guard_expression::do_check_types(Gogo*)
        this->report_error(_("invalid unsafe.Pointer conversion"));
     }
   else if (expr_type->interface_type() == NULL)
-    this->report_error(_("type assertion only valid for interface types"));
+    {
+      if (!expr_type->is_error_type() && !this->type_->is_error_type())
+       this->report_error(_("type assertion only valid for interface types"));
+      this->set_is_error();
+    }
   else if (this->type_->interface_type() == NULL)
     {
       std::string reason;
       if (!expr_type->interface_type()->implements_interface(this->type_,
                                                             &reason))
        {
-         if (reason.empty())
-           this->report_error(_("impossible type assertion: "
-                                "type does not implement interface"));
-         else
+         if (!this->type_->is_error_type())
            {
-             error_at(this->location(),
-                      ("impossible type assertion: "
-                       "type does not implement interface (%s)"),
-                      reason.c_str());
-             this->set_is_error();
+             if (reason.empty())
+               this->report_error(_("impossible type assertion: "
+                                    "type does not implement interface"));
+             else
+               error_at(this->location(),
+                        ("impossible type assertion: "
+                         "type does not implement interface (%s)"),
+                        reason.c_str());
            }
+         this->set_is_error();
        }
     }
 }
index c8b55c5..5f4cef5 100644 (file)
@@ -2647,12 +2647,18 @@ Parse::selector(Expression* left, bool* is_type_switch)
     {
       this->advance_token();
       Type* type = NULL;
-      if (is_type_switch == NULL
-         || !this->peek_token()->is_keyword(KEYWORD_TYPE))
+      if (!this->peek_token()->is_keyword(KEYWORD_TYPE))
        type = this->type();
       else
        {
-         *is_type_switch = true;
+         if (is_type_switch != NULL)
+           *is_type_switch = true;
+         else
+           {
+             error_at(this->location(),
+                      "use of %<.(type)%> outside type switch");
+             type = Type::make_error_type();
+           }
          this->advance_token();
        }
       if (!this->peek_token()->is_op(OPERATOR_RPAREN))
@@ -2866,7 +2872,7 @@ Parse::expression(Precedence precedence, bool may_be_sink,
       left = this->verify_not_sink(left);
       Expression* right = this->expression(right_precedence, false,
                                           may_be_composite_lit,
-                                          is_type_switch);
+                                          NULL);
       if (op == OPERATOR_CHANOP)
        left = Expression::make_send(left, right, binop_location);
       else
@@ -2959,8 +2965,7 @@ Parse::unary_expr(bool may_be_sink, bool may_be_composite_lit,
          return Expression::make_type(this->type(), location);
        }
 
-      Expression* expr = this->unary_expr(false, may_be_composite_lit,
-                                         is_type_switch);
+      Expression* expr = this->unary_expr(false, may_be_composite_lit, NULL);
       if (expr->is_error_expression())
        ;
       else if (op == OPERATOR_MULT && expr->is_type_expression())
index 10fe7e4..2d17797 100644 (file)
@@ -1296,7 +1296,8 @@ Tuple_type_guard_assignment_statement::do_lower(Gogo*, Block* enclosing)
   Type* expr_type = this->expr_->type();
   if (expr_type->interface_type() == NULL)
     {
-      this->report_error(_("type assertion only valid for interface types"));
+      if (!expr_type->is_error_type() && !this->type_->is_error_type())
+       this->report_error(_("type assertion only valid for interface types"));
       return Statement::make_error_statement(loc);
     }