Clean up handling of undefined types.
authorIan Lance Taylor <ian@gcc.gnu.org>
Fri, 25 Mar 2011 20:42:20 +0000 (20:42 +0000)
committerIan Lance Taylor <ian@gcc.gnu.org>
Fri, 25 Mar 2011 20:42:20 +0000 (20:42 +0000)
From-SVN: r171528

gcc/go/gofrontend/expressions.cc
gcc/go/gofrontend/gogo-tree.cc
gcc/go/gofrontend/gogo.cc
gcc/go/gofrontend/statements.cc
gcc/go/gofrontend/types.h

index 2ee4a696db9a4abe08f347671b34e831c1e8b34d..19ac03e9347e93dffdf2999d7df46b1c2da6da37 100644 (file)
@@ -205,17 +205,9 @@ Expression::convert_for_assignment(Translate_context* context, Type* lhs_type,
   if (lhs_type == rhs_type)
     return rhs_tree;
 
-  if (lhs_type->is_error_type() || rhs_type->is_error_type())
+  if (lhs_type->is_error() || rhs_type->is_error())
     return error_mark_node;
 
-  if (lhs_type->is_undefined() || rhs_type->is_undefined())
-    {
-      // Make sure we report the error.
-      lhs_type->base();
-      rhs_type->base();
-      return error_mark_node;
-    }
-
   if (rhs_tree == error_mark_node || TREE_TYPE(rhs_tree) == error_mark_node)
     return error_mark_node;
 
@@ -2628,7 +2620,7 @@ Const_expression::do_determine_type(const Type_context* context)
 void
 Const_expression::check_for_init_loop()
 {
-  if (this->type_ != NULL && this->type_->is_error_type())
+  if (this->type_ != NULL && this->type_->is_error())
     return;
 
   if (this->seen_)
@@ -2647,7 +2639,7 @@ Const_expression::check_for_init_loop()
 
   if (find_named_object.found())
     {
-      if (this->type_ == NULL || !this->type_->is_error_type())
+      if (this->type_ == NULL || !this->type_->is_error())
        {
          this->report_error(_("constant refers to itself"));
          this->type_ = Type::make_error_type();
@@ -2661,7 +2653,7 @@ Const_expression::check_for_init_loop()
 void
 Const_expression::do_check_types(Gogo*)
 {
-  if (this->type_ != NULL && this->type_->is_error_type())
+  if (this->type_ != NULL && this->type_->is_error())
     return;
 
   this->check_for_init_loop();
@@ -3311,14 +3303,8 @@ Type_conversion_expression::do_check_types(Gogo*)
   Type* expr_type = this->expr_->type();
   std::string reason;
 
-  if (type->is_error_type()
-      || type->is_undefined()
-      || expr_type->is_error_type()
-      || expr_type->is_undefined())
+  if (type->is_error() || expr_type->is_error())
     {
-      // Make sure we emit an error for an undefined type.
-      type->base();
-      expr_type->base();
       this->set_is_error();
       return;
     }
@@ -4027,7 +4013,7 @@ void
 Unary_expression::do_check_types(Gogo*)
 {
   Type* type = this->expr_->type();
-  if (type->is_error_type())
+  if (type->is_error())
     {
       this->set_is_error();
       return;
@@ -5447,9 +5433,9 @@ Binary_expression::do_type()
       {
        Type* left_type = this->left_->type();
        Type* right_type = this->right_->type();
-       if (left_type->is_error_type())
+       if (left_type->is_error())
          return left_type;
-       else if (right_type->is_error_type())
+       else if (right_type->is_error())
          return right_type;
        else if (!Type::are_compatible_for_binop(left_type, right_type))
          {
@@ -5688,7 +5674,7 @@ Binary_expression::do_check_types(Gogo*)
 
   Type* left_type = this->left_->type();
   Type* right_type = this->right_->type();
-  if (left_type->is_error_type() || right_type->is_error_type())
+  if (left_type->is_error() || right_type->is_error())
     {
       this->set_is_error();
       return;
@@ -7001,7 +6987,7 @@ Builtin_call_expression::do_integer_constant_value(bool iota_is_constant,
       if (arg == NULL)
        return false;
       Type* arg_type = arg->type();
-      if (arg_type->is_error_type() || arg_type->is_undefined())
+      if (arg_type->is_error())
        return false;
       if (arg_type->is_abstract())
        return false;
@@ -7354,8 +7340,7 @@ Builtin_call_expression::check_one_arg()
       return false;
     }
   if (args->front()->is_error_expression()
-      || args->front()->type()->is_error_type()
-      || args->front()->type()->is_undefined())
+      || args->front()->type()->is_error())
     {
       this->set_is_error();
       return false;
@@ -7389,7 +7374,7 @@ Builtin_call_expression::do_check_types(Gogo*)
              arg_type = arg_type->points_to();
            if (this->code_ == BUILTIN_CAP)
              {
-               if (!arg_type->is_error_type()
+               if (!arg_type->is_error()
                    && arg_type->array_type() == NULL
                    && arg_type->channel_type() == NULL)
                  this->report_error(_("argument must be array or slice "
@@ -7397,7 +7382,7 @@ Builtin_call_expression::do_check_types(Gogo*)
              }
            else
              {
-               if (!arg_type->is_error_type()
+               if (!arg_type->is_error()
                    && !arg_type->is_string_type()
                    && arg_type->array_type() == NULL
                    && arg_type->map_type() == NULL
@@ -7429,7 +7414,7 @@ Builtin_call_expression::do_check_types(Gogo*)
                 ++p)
              {
                Type* type = (*p)->type();
-               if (type->is_error_type()
+               if (type->is_error()
                    || type->is_string_type()
                    || type->integer_type() != NULL
                    || type->float_type() != NULL
@@ -7493,7 +7478,7 @@ Builtin_call_expression::do_check_types(Gogo*)
          }
        Type* arg1_type = args->front()->type();
        Type* arg2_type = args->back()->type();
-       if (arg1_type->is_error_type() || arg2_type->is_error_type())
+       if (arg1_type->is_error() || arg2_type->is_error())
          break;
 
        Type* e1;
@@ -7568,9 +7553,9 @@ Builtin_call_expression::do_check_types(Gogo*)
        else if (args->size() > 2)
          this->report_error(_("too many arguments"));
        else if (args->front()->is_error_expression()
-                || args->front()->type()->is_error_type()
+                || args->front()->type()->is_error()
                 || args->back()->is_error_expression()
-                || args->back()->type()->is_error_type())
+                || args->back()->type()->is_error())
          this->set_is_error();
        else if (!Type::are_identical(args->front()->type(),
                                      args->back()->type(), true, NULL))
@@ -8540,7 +8525,7 @@ Call_expression::do_check_types(Gogo*)
   Function_type* fntype = this->get_function_type();
   if (fntype == NULL)
     {
-      if (!this->fn_->type()->is_error_type())
+      if (!this->fn_->type()->is_error())
        this->report_error(_("expected function"));
       return;
     }
@@ -9060,7 +9045,7 @@ Index_expression::do_lower(Gogo*, Named_object*, int)
   Expression* end = this->end_;
 
   Type* type = left->type();
-  if (type->is_error_type())
+  if (type->is_error())
     return Expression::make_error(location);
   else if (left->is_type_expression())
     {
@@ -9236,7 +9221,7 @@ Array_index_expression::do_check_types(Gogo*)
   Array_type* array_type = this->array_->type()->array_type();
   if (array_type == NULL)
     {
-      gcc_assert(this->array_->type()->is_error_type());
+      gcc_assert(this->array_->type()->is_error());
       return;
     }
 
@@ -9318,7 +9303,7 @@ Array_index_expression::do_get_tree(Translate_context* context)
   Array_type* array_type = this->array_->type()->array_type();
   if (array_type == NULL)
     {
-      gcc_assert(this->array_->type()->is_error_type());
+      gcc_assert(this->array_->type()->is_error());
       return error_mark_node;
     }
 
@@ -9979,7 +9964,7 @@ Type*
 Field_reference_expression::do_type()
 {
   Type* type = this->expr_->type();
-  if (type->is_error_type())
+  if (type->is_error())
     return type;
   Struct_type* struct_type = type->struct_type();
   gcc_assert(struct_type != NULL);
@@ -9992,7 +9977,7 @@ void
 Field_reference_expression::do_check_types(Gogo*)
 {
   Type* type = this->expr_->type();
-  if (type->is_error_type())
+  if (type->is_error())
     return;
   Struct_type* struct_type = type->struct_type();
   gcc_assert(struct_type != NULL);
@@ -11140,7 +11125,7 @@ Open_array_construction_expression::do_get_tree(Translate_context* context)
   Array_type* array_type = this->type()->array_type();
   if (array_type == NULL)
     {
-      gcc_assert(this->type()->is_error_type());
+      gcc_assert(this->type()->is_error());
       return error_mark_node;
     }
 
@@ -11659,7 +11644,7 @@ Composite_literal_expression::do_lower(Gogo* gogo, Named_object* function, int)
        type = type->map_type()->val_type();
       else
        {
-         if (!type->is_error_type())
+         if (!type->is_error())
            error_at(this->location(),
                     ("may only omit types within composite literals "
                      "of slice, array, or map type"));
@@ -11667,7 +11652,7 @@ Composite_literal_expression::do_lower(Gogo* gogo, Named_object* function, int)
        }
     }
 
-  if (type->is_error_type())
+  if (type->is_error())
     return Expression::make_error(this->location());
   else if (type->struct_type() != NULL)
     return this->lower_struct(gogo, type);
@@ -12132,7 +12117,7 @@ Type_guard_expression::do_check_types(Gogo*)
     }
   else if (expr_type->interface_type() == NULL)
     {
-      if (!expr_type->is_error_type() && !this->type_->is_error_type())
+      if (!expr_type->is_error() && !this->type_->is_error())
        this->report_error(_("type assertion only valid for interface types"));
       this->set_is_error();
     }
@@ -12142,7 +12127,7 @@ Type_guard_expression::do_check_types(Gogo*)
       if (!expr_type->interface_type()->implements_interface(this->type_,
                                                             &reason))
        {
-         if (!this->type_->is_error_type())
+         if (!this->type_->is_error())
            {
              if (reason.empty())
                this->report_error(_("impossible type assertion: "
@@ -12294,7 +12279,7 @@ void
 Receive_expression::do_check_types(Gogo*)
 {
   Type* type = this->channel_->type();
-  if (type->is_error_type())
+  if (type->is_error())
     {
       this->set_is_error();
       return;
@@ -12319,7 +12304,7 @@ Receive_expression::do_get_tree(Translate_context* context)
   Channel_type* channel_type = this->channel_->type()->channel_type();
   if (channel_type == NULL)
     {
-      gcc_assert(this->channel_->type()->is_error_type());
+      gcc_assert(this->channel_->type()->is_error());
       return error_mark_node;
     }
   Type* element_type = channel_type->element_type();
index 238a0d72487c36919a3d39ca2debda90c318e026..2f52aa20b6ce0d97af8892d025a9ba0b87684514 100644 (file)
@@ -914,14 +914,10 @@ Named_object::get_tree(Gogo* gogo, Named_object* function)
            Type* type = named_constant->type();
            if (type != NULL && !type->is_abstract())
              {
-               if (!type->is_undefined())
+               if (!type->is_error())
                  expr_tree = fold_convert(type->get_tree(gogo), expr_tree);
                else
-                 {
-                   // Make sure we report the error.
-                   type->base();
-                   expr_tree = error_mark_node;
-                 }
+                 expr_tree = error_mark_node;
              }
            if (expr_tree == error_mark_node)
              decl = error_mark_node;
@@ -1047,12 +1043,8 @@ Named_object::get_tree(Gogo* gogo, Named_object* function)
       {
        Result_variable* result = this->u_.result_var_value;
        Type* type = result->type();
-       if (type->is_error_type() || type->is_undefined())
-         {
-           // Force the error.
-           type->base();
-           decl = error_mark_node;
-         }
+       if (type->is_error())
+         decl = error_mark_node;
        else
          {
            gcc_assert(result->function() == function->func_value());
index be308035b58d5ee6d360e3f184cf0550b6658772..a09ffb3aaec95529a9574c598ef9d10fb69bbce9 100644 (file)
@@ -1527,7 +1527,7 @@ Check_types_traverse::constant(Named_object* named_object, bool)
       && !ctype->is_boolean_type()
       && !ctype->is_string_type())
     {
-      if (!ctype->is_error_type())
+      if (!ctype->is_error())
        error_at(constant->location(), "invalid constant type");
       constant->set_error();
     }
index d24d98f4f88e28f4ea5c59e130b1176bfd17e4be..6843d6d8958653d65f1064cc1ad3440833f39bae 100644 (file)
@@ -517,7 +517,7 @@ Assignment_statement::do_check_types(Gogo*)
       && this->lhs_->map_index_expression() == NULL
       && !this->lhs_->is_sink_expression())
     {
-      if (!this->lhs_->type()->is_error_type())
+      if (!this->lhs_->type()->is_error())
        this->report_error(_("invalid left hand side of assignment"));
       return;
     }
@@ -535,16 +535,8 @@ Assignment_statement::do_check_types(Gogo*)
       this->set_is_error();
     }
 
-  if (lhs_type->is_error_type()
-      || rhs_type->is_error_type()
-      || lhs_type->is_undefined()
-      || rhs_type->is_undefined())
-    {
-      // Make sure we get the error for an undefined type.
-      lhs_type->base();
-      rhs_type->base();
-      this->set_is_error();
-    }
+  if (lhs_type->is_error() || rhs_type->is_error())
+    this->set_is_error();
 }
 
 // Build a tree for an assignment statement.
@@ -817,9 +809,9 @@ Tuple_assignment_statement::do_lower(Gogo*, Named_object*, Block* enclosing)
       gcc_assert(prhs != this->rhs_->end());
 
       if ((*plhs)->is_error_expression()
-         || (*plhs)->type()->is_error_type()
+         || (*plhs)->type()->is_error()
          || (*prhs)->is_error_expression()
-         || (*prhs)->type()->is_error_type())
+         || (*prhs)->type()->is_error())
        continue;
 
       if ((*plhs)->is_sink_expression())
@@ -843,9 +835,9 @@ Tuple_assignment_statement::do_lower(Gogo*, Named_object*, Block* enclosing)
        ++plhs, ++prhs)
     {
       if ((*plhs)->is_error_expression()
-         || (*plhs)->type()->is_error_type()
+         || (*plhs)->type()->is_error()
          || (*prhs)->is_error_expression()
-         || (*prhs)->type()->is_error_type())
+         || (*prhs)->type()->is_error())
        continue;
 
       if ((*plhs)->is_sink_expression())
@@ -1363,7 +1355,7 @@ Tuple_type_guard_assignment_statement::do_lower(Gogo*, Named_object*,
   Type* expr_type = this->expr_->type();
   if (expr_type->interface_type() == NULL)
     {
-      if (!expr_type->is_error_type() && !this->type_->is_error_type())
+      if (!expr_type->is_error() && !this->type_->is_error())
        this->report_error(_("type assertion only valid for interface types"));
       return Statement::make_error_statement(loc);
     }
@@ -2624,16 +2616,8 @@ Return_statement::do_check_types(Gogo*)
                     i, reason.c_str());
          this->set_is_error();
        }
-      else if (pt->type()->is_error_type()
-              || (*pe)->type()->is_error_type()
-              || pt->type()->is_undefined()
-              || (*pe)->type()->is_undefined())
-       {
-         // Make sure we get the error for an undefined type.
-         pt->type()->base();
-         (*pe)->type()->base();
-         this->set_is_error();
-       }
+      else if (pt->type()->is_error() || (*pe)->type()->is_error())
+       this->set_is_error();
     }
 
   if (pt != results->end())
@@ -3001,7 +2985,7 @@ void
 If_statement::do_check_types(Gogo*)
 {
   Type* type = this->cond_->type();
-  if (type->is_error_type())
+  if (type->is_error())
     this->set_is_error();
   else if (!type->is_boolean_type())
     this->report_error(_("expected boolean expression"));
@@ -3023,7 +3007,7 @@ tree
 If_statement::do_get_tree(Translate_context* context)
 {
   gcc_assert(this->cond_->type()->is_boolean_type()
-            || this->cond_->type()->is_error_type());
+            || this->cond_->type()->is_error());
   tree cond_tree = this->cond_->get_tree(context);
   tree then_tree = this->then_block_->get_tree(context);
   tree else_tree = (this->else_block_ == NULL
@@ -3554,7 +3538,7 @@ Switch_statement::do_lower(Gogo*, Named_object*, Block* enclosing)
 
   if (this->val_ != NULL
       && (this->val_->is_error_expression()
-         || this->val_->type()->is_error_type()))
+         || this->val_->type()->is_error()))
     return Statement::make_error_statement(loc);
 
   if (this->val_ != NULL
@@ -4023,7 +4007,7 @@ void
 Send_statement::do_check_types(Gogo*)
 {
   Type* type = this->channel_->type();
-  if (type->is_error_type())
+  if (type->is_error())
     {
       this->set_is_error();
       return;
@@ -4739,7 +4723,7 @@ For_range_statement::do_lower(Gogo* gogo, Named_object*, Block* enclosing)
       index_type = range_type->channel_type()->element_type();
       if (this->value_var_ != NULL)
        {
-         if (!this->value_var_->type()->is_error_type())
+         if (!this->value_var_->type()->is_error())
            this->report_error(_("too many variables for range clause "
                                 "with channel"));
          return Statement::make_error_statement(this->location());
index 8e91dfcab072edf11caedbf3aff1a330a7c2d484..24f425bd8b99dba0cf4809dc33453cd6d4d273ed 100644 (file)
@@ -587,11 +587,19 @@ class Type
   has_pointer() const
   { return this->do_has_pointer(); }
 
-  // Return true if this is an error type.  An error type indicates a
-  // parsing error.
+  // Return true if this is the error type.  This returns false for a
+  // type which is not defined, as it is called by the parser before
+  // all types are defined.
   bool
   is_error_type() const;
 
+  // Return true if this is the error type or if the type is
+  // undefined.  If the type is undefined, this will give an error.
+  // This should only be called after parsing is complete.
+  bool
+  is_error() const
+  { return this->base()->is_error_type(); }
+
   // Return true if this is a void type.
   bool
   is_void_type() const