This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Go patch committed: Avoid various compiler crashes


This patch to the Go frontend avoids various crashes on erroneous
input.  Bootstrapped and ran Go testsuite on x86_64-unknown-linux-gnu.
Committed to mainline.

Ian

diff -r 3d9a01a3a527 go/expressions.cc
--- a/go/expressions.cc	Wed Feb 29 14:41:03 2012 -0800
+++ b/go/expressions.cc	Wed Feb 29 15:31:47 2012 -0800
@@ -3942,10 +3942,6 @@
     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 @@
     case BUILTIN_INVALID:
     case BUILTIN_NEW:
     case BUILTIN_MAKE:
+    case BUILTIN_DELETE:
       return;
 
     case BUILTIN_LEN:
@@ -8670,13 +8667,17 @@
 	    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 @@
 	// 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 @@
 		    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 @@
 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 @@
       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 @@
 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);
 }
diff -r 3d9a01a3a527 go/statements.cc
--- a/go/statements.cc	Wed Feb 29 14:41:03 2012 -0800
+++ b/go/statements.cc	Wed Feb 29 15:31:47 2012 -0800
@@ -1013,7 +1013,7 @@
       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 @@
 	    {
 	      // 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);

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]