compiler: Avoid various crashes on error conditions.
authorIan Lance Taylor <ian@gcc.gnu.org>
Wed, 29 Feb 2012 23:42:34 +0000 (23:42 +0000)
committerIan Lance Taylor <ian@gcc.gnu.org>
Wed, 29 Feb 2012 23:42:34 +0000 (23:42 +0000)
From-SVN: r184675

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

index 638cacbe2c937bdaf382a4cda81d6da42e2cde01..3778c4db8e85f654d6e31e96362224bb3018f4ad 100644 (file)
@@ -3942,10 +3942,6 @@ Unsafe_type_conversion_expression::do_get_tree(Translate_context* context)
     go_assert(et->map_type() != NULL);
   else if (t->channel_type() != NULL)
     go_assert(et->channel_type() != NULL);
-  else if (t->points_to() != NULL && t->points_to()->channel_type() != NULL)
-    go_assert((et->points_to() != NULL
-               && et->points_to()->channel_type() != NULL)
-              || et->is_nil_type());
   else if (t->points_to() != NULL)
     go_assert(et->points_to() != NULL || et->is_nil_type());
   else if (et->is_unsafe_pointer_type())
@@ -8502,6 +8498,7 @@ Builtin_call_expression::do_check_types(Gogo*)
     case BUILTIN_INVALID:
     case BUILTIN_NEW:
     case BUILTIN_MAKE:
+    case BUILTIN_DELETE:
       return;
 
     case BUILTIN_LEN:
@@ -8670,13 +8667,17 @@ Builtin_call_expression::do_check_types(Gogo*)
            this->report_error(_("too many arguments"));
            break;
          }
+       if (args->front()->type()->is_error()
+           || args->back()->type()->is_error())
+         break;
+
+       Array_type* at = args->front()->type()->array_type();
+       Type* e = at->element_type();
 
        // The language permits appending a string to a []byte, as a
        // special case.
        if (args->back()->type()->is_string_type())
          {
-           const Array_type* at = args->front()->type()->array_type();
-           const Type* e = at->element_type()->forwarded();
            if (e->integer_type() != NULL && e->integer_type()->is_byte())
              break;
          }
@@ -8685,8 +8686,7 @@ Builtin_call_expression::do_check_types(Gogo*)
        // assignable to a slice of the element type of the first
        // argument.  We already know the first argument is a slice
        // type.
-       Array_type* at = args->front()->type()->array_type();
-       Type* arg2_type = Type::make_array_type(at->element_type(), NULL);
+       Type* arg2_type = Type::make_array_type(e, NULL);
        std::string reason;
        if (!Type::are_assignable(arg2_type, args->back()->type(), &reason))
          {
@@ -8982,7 +8982,10 @@ Builtin_call_expression::do_get_tree(Translate_context* context)
                    fnname = "__go_print_slice";
                  }
                else
-                 go_unreachable();
+                 {
+                   go_assert(saw_errors());
+                   return error_mark_node;
+                 }
 
                tree call = Gogo::call_builtin(pfndecl,
                                               location,
@@ -9665,8 +9668,11 @@ Call_expression::result_count() const
 Temporary_statement*
 Call_expression::result(size_t i) const
 {
-  go_assert(this->results_ != NULL
-           && this->results_->size() > i);
+  if (this->results_ == NULL || this->results_->size() <= i)
+    {
+      go_assert(saw_errors());
+      return NULL;
+    }
   return (*this->results_)[i];
 }
 
@@ -10153,6 +10159,11 @@ Call_expression::set_results(Translate_context* context, tree call_tree)
       go_assert(field != NULL_TREE);
 
       Temporary_statement* temp = this->result(i);
+      if (temp == NULL)
+       {
+         go_assert(saw_errors());
+         return error_mark_node;
+       }
       Temporary_reference_expression* ref =
        Expression::make_temporary_reference(temp, loc);
       ref->set_is_lvalue();
@@ -10332,8 +10343,17 @@ tree
 Call_result_expression::do_get_tree(Translate_context* context)
 {
   Call_expression* ce = this->call_->call_expression();
-  go_assert(ce != NULL);
+  if (ce == NULL)
+    {
+      go_assert(this->call_->is_error_expression());
+      return error_mark_node;
+    }
   Temporary_statement* ts = ce->result(this->index_);
+  if (ts == NULL)
+    {
+      go_assert(saw_errors());
+      return error_mark_node;
+    }
   Expression* ref = Expression::make_temporary_reference(ts, this->location());
   return ref->get_tree(context);
 }
index e55dc74b3b7af38d13f70d9b3f86aaf7d6aee833..65c64c5e906f3a89d38f980a1d579da4e8608328 100644 (file)
@@ -1013,7 +1013,7 @@ Tuple_assignment_statement::do_lower(Gogo*, Named_object*, Block* enclosing,
       b->add_statement(s);
       ++ptemp;
     }
-  go_assert(ptemp == temps.end());
+  go_assert(ptemp == temps.end() || saw_errors());
 
   return Statement::make_block_statement(b, loc);
 }
@@ -3452,7 +3452,7 @@ Case_clauses::Case_clause::get_backend(Translate_context* context,
            {
              // Value was already present.
              error_at(this->location_, "duplicate case in switch");
-             continue;
+             e = Expression::make_error(this->location_);
            }
 
          tree case_tree = e->get_tree(context);