diff mbox

Go patch committed: Fix some type determination issues

Message ID mcrr4fqkuwc.fsf@iant-glaptop.roam.corp.google.com
State New
Headers show

Commit Message

Ian Lance Taylor June 25, 2013, 4:38 p.m. UTC
This patch to the Go frontend fixes some type determination issues that
show up in the current master Go testsuite.  There were some cases where
types were not being determined, which lead to incorrect error messages
and in some cases the wrong thing happening.  Bootstrapped and ran Go
testsuite on x86_64-unknown-linux-gnu.  Committed to mainline and 4.8
branch.

Ian
diff mbox

Patch

diff -r 478ec87a337f go/expressions.cc
--- a/go/expressions.cc	Mon Jun 24 16:09:40 2013 -0700
+++ b/go/expressions.cc	Tue Jun 25 09:21:43 2013 -0700
@@ -5668,6 +5668,7 @@ 
       if (tleft->is_abstract()
 	  && subcontext.type != NULL
 	  && !subcontext.may_be_abstract
+	  && subcontext.type->interface_type() == NULL
 	  && subcontext.type->integer_type() == NULL)
 	this->report_error(("invalid context-determined non-integer type "
 			    "for left operand of shift"));
@@ -7383,6 +7384,8 @@ 
   Type* uintptr_type = Type::lookup_integer_type("uintptr");
   int uintptr_bits = uintptr_type->integer_type()->bits();
 
+  Type_context int_context(Type::lookup_integer_type("int"), false);
+
   ++parg;
   Expression* len_arg;
   if (parg == args->end())
@@ -7401,6 +7404,7 @@ 
   else
     {
       len_arg = *parg;
+      len_arg->determine_type(&int_context);
       if (!this->check_int_value(len_arg, true))
 	return Expression::make_error(this->location());
       if (len_arg->type()->integer_type() != NULL
@@ -7413,6 +7417,7 @@ 
   if (is_slice && parg != args->end())
     {
       cap_arg = *parg;
+      cap_arg->determine_type(&int_context);
       if (!this->check_int_value(cap_arg, false))
 	return Expression::make_error(this->location());
 
@@ -8030,6 +8035,8 @@ 
     case BUILTIN_REAL:
     case BUILTIN_IMAG:
       arg_type = Builtin_call_expression::complex_type(context->type);
+      if (arg_type == NULL)
+	arg_type = Type::lookup_complex_type("complex128");
       is_print = false;
       break;
 
@@ -8038,6 +8045,8 @@ 
 	// For the complex function the type of one operand can
 	// determine the type of the other, as in a binary expression.
 	arg_type = Builtin_call_expression::real_imag_type(context->type);
+	if (arg_type == NULL)
+	  arg_type = Type::lookup_float_type("float64");
 	if (args != NULL && args->size() == 2)
 	  {
 	    Type* t1 = args->front()->type();
@@ -10379,13 +10388,20 @@ 
 void
 Array_index_expression::do_check_types(Gogo*)
 {
-  if (this->start_->type()->integer_type() == NULL)
+  Numeric_constant nc;
+  unsigned long v;
+  if (this->start_->type()->integer_type() == NULL
+      && !this->start_->type()->is_error()
+      && (!this->start_->numeric_constant_value(&nc)
+	  || nc.to_unsigned_long(&v) == Numeric_constant::NC_UL_NOTINT))
     this->report_error(_("index must be integer"));
   if (this->end_ != NULL
       && this->end_->type()->integer_type() == NULL
       && !this->end_->type()->is_error()
       && !this->end_->is_nil_expression()
-      && !this->end_->is_error_expression())
+      && !this->end_->is_error_expression()
+      && (!this->end_->numeric_constant_value(&nc)
+	  || nc.to_unsigned_long(&v) == Numeric_constant::NC_UL_NOTINT))
     this->report_error(_("slice end must be integer"));
 
   Array_type* array_type = this->array_->type()->array_type();
diff -r 478ec87a337f go/statements.cc
--- a/go/statements.cc	Mon Jun 24 16:09:40 2013 -0700
+++ b/go/statements.cc	Tue Jun 25 09:21:43 2013 -0700
@@ -569,7 +569,10 @@ 
 Assignment_statement::do_determine_types()
 {
   this->lhs_->determine_type_no_context();
-  Type_context context(this->lhs_->type(), false);
+  Type* rhs_context_type = this->lhs_->type();
+  if (rhs_context_type->is_sink_type())
+    rhs_context_type = NULL;
+  Type_context context(rhs_context_type, false);
   this->rhs_->determine_type(&context);
 }